diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index ad0dc66..09f21ae 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v4 - name: Run unit tests run: docker build . --file docker/unittest.dockerfile --tag unittest env: @@ -16,15 +16,55 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - name: Set up R 4.4.2 + uses: r-lib/actions/setup-r@v2 + with: + r-version: '4.4.2' + - name: Install R development packages + run: | + sudo apt-get update + sudo apt-get install -y \ + r-base-dev \ + libcurl4-openssl-dev \ + libssl-dev \ + libxml2-dev \ + libgit2-dev \ + libmagick++-dev + - name: Setup R packages using docker-compatible script + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_REMOTES_NO_ERRORS_FROM_WARNINGS: "true" + run: | + R -e "install.packages('remotes', repos='https://cran.r-project.org')" + Rscript setup_docker_compatible_renv.R + - name: Verify R packages installation + run: | + R -e " + essential_packages <- c('BiocManager', 'rjson', 'GSVA', 'dpGMM', 'AUCell') + cat('Verifying R packages installation:\\n') + all_ok <- TRUE + for (pkg in essential_packages) { + if (require(pkg, quietly = TRUE, character.only = TRUE)) { + cat(sprintf(' ✓ %s\\n', pkg)) + } else { + cat(sprintf(' ✗ %s (MISSING)\\n', pkg)) + all_ok <- FALSE + } + } + if (!all_ok) { + cat('Some packages are missing, this will cause test failures\\n') + quit(status = 1) + } + cat('All essential R packages verified successfully\\n') + " - name: Install poetry run: pipx install poetry - - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: 'poetry' diff --git a/.gitignore b/.gitignore index f1b4079..b3a1b4a 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,12 @@ share/python-wheels/ *.egg MANIFEST +# Build artifacts +build/* +dist/* +*.whl +*.tar.gz + # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. @@ -134,4 +140,54 @@ dmypy.json /data /plots /results -*.json \ No newline at end of file +*.json + +# R specific +renv/library/ +renv/staging/ +renv/local/ +.Rproj.user +.Rhistory +.RData +.Ruserdata +*.Rproj + +# Python environment +.venv/ +venv/ +.env +env/ + +# Testing and coverage +.pytest_cache/ +.coverage +htmlcov/ +.tox/ +.nox/ + +# IDEs +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Temporary files +*.tmp +*.temp +*.log +*.out +*.err + +# Docker +.docker/ +Dockerfile.tmp \ No newline at end of file diff --git a/README.md b/README.md index 4dc77e3..34d2281 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,98 @@ -# enrichment-auc +# pyFUNCellA ![Run unit tests](https://github.com/ZAEDPolSl/enrichment-auc/actions/workflows/unittest.yml/badge.svg) [![CodeFactor](https://www.codefactor.io/repository/github/zaedpolsl/enrichment-auc/badge?s=0a2708157028b922c097a34ac955fe1c363866be)](https://www.codefactor.io/repository/github/zaedpolsl/enrichment-auc) + +This repository is a Python implementation of the [FUNCellA R package](https://github.com/ZAEDPolSl/FUNCellA/tree/master). +You can use the original R version or run this Python version with the instructions below. + +The presented package provides a wrapper solution for single-sample pathway enrichment algorithms. Additional functionality includes sample-level thresholding. + +Implemented single-sample enrichment algorithms: +1) AUCell scoring (Aibar et al. 2017) - scRNA-Seq only +2) BINA (Zyla et al. 2025?) - scRNA-Seq only +3) CERNO AUC (Zyla et al. 2019) +4) JASMINE (Noureen et al. 2022) - scRNA-Seq only +5) Mean +6) ssGSEA (Barbie et al. 2009, Hänzelmann et al. 2013) +7) Z-score (Lee et al. 2008) + +Implemented thresholding solutions: +1) AUCell package thresholding (Aibar et al. 2017) +2) k-means +3) GMM thresholding with Top 1 and k-means adjustment (Zyla et al. 2025?) + +## Installation & Usage +The application is available [here](https://dssoftware.aei.polsl.pl/FUNCellA). It is free of charge and it does not store your data. Feel free to use it! +If you want to run it locally, there are several options: +### 🐳 Docker + +#### 🚀 Quick Start - Run Pre-built App +```bash +# Pull and run the app directly (fastest option) +docker run -p 8501:8501 amrukwa/funcella:latest +``` +The app will be available at **http://localhost:8501** + +#### 🏗️ Build Locally with Cache (faster builds) +```bash +# Use cached builder for faster builds +docker build -f docker/streamlit.dockerfile --cache-from amrukwa/funcella:builder -t funcella . +docker run -p 8501:8501 funcella +``` + +#### 🔧 Build from Scratch +```bash +# Full build (slower, but completely from source) +docker build -f docker/streamlit.dockerfile -t funcella . +docker run -p 8501:8501 funcella +``` + +### 🛠️ Manual Installation + +1. **R dependencies** (Required for GMM and AUCell thresholding) +```bash +# Recommended: Use the setup script for reliable installation +Rscript setup_docker_compatible_renv.R +``` + +**Alternative R setup methods:** +```R +# Option 1: Using renv (may require manual package fixes) +install.packages("renv") +renv::restore() + +# Option 2: Manual installation +install.packages("BiocManager") +BiocManager::install("GSVA") +BiocManager::install("AUCell") +remotes::install_github("ZAEDPolSl/dpGMM") +``` + +**Note:** If you encounter GitHub authentication issues when installing dpGMM, the setup script handles this automatically by using alternative installation methods. + +2. **Python dependencies** +```bash +# Install Poetry +curl -sSL https://install.python-poetry.org | python3 - + +# Install dependencies +poetry install + +# Run the app +streamlit run app.py +``` + +## 🔧 Troubleshooting + +### R Package Issues +If you encounter errors related to missing R package dpGMM: + - The package will attempt automatic installation + - Alternatively, download and install manually from the repository environment. + +## REFERENCES +Aibar, S., Bravo González-Blas, C., Moerman, T., Huynh-Thu, V.A., Imrichová, H., Hulselmans, G., Rambow, F., Marine, J.C., Geurts, P., Aerts, J., van den Oord, J., Kalender Atak, Z., Wouters, J., & Aerts, S (2017). SCENIC: Single-cell regulatory network inference and clustering. *Nature Methods*, *14*, 1083–1086.\ +Barbie, D.A., Tamayo, P., Boehm, J.S., et al. (2009). Systematic RNA interference reveals that oncogenic KRAS-driven cancers require TBK1. *Nature*, *462*(7273), 108–112.\ +Hänzelmann, S., Castelo, R., & Guinney, J. (2013). GSVA: gene set variation analysis for microarray and RNA-seq data. *BMC Bioinformatics*, *14*, 7.\ +Lee, E., Chuang, H.Y., Kim, J.W., Ideker, T., & Lee, D. (2008). Inferring pathway activity toward precise disease classification. *PLoS Computational Biology*, *4*(11), e1000217.\ +Noureen, N., Ye, Z., Chen, Y., Wang, X., & Zheng, S. (2022). Signature-scoring methods developed for bulk samples are not adequate for cancer single-cell RNA sequencing data. *Elife*, *11*, e71994.\ +Zyla, J., Marczyk, M., Domaszewska, T., Kaufmann, S. H., Polanska, J., & Weiner III, J. (2019). Gene set enrichment for reproducible science: comparison of CERNO and eight other algorithms. *Bioinformatics*, *35*(24), 5146–5154. diff --git a/app.py b/app.py new file mode 100644 index 0000000..6bed34c --- /dev/null +++ b/app.py @@ -0,0 +1,21 @@ +import streamlit as st + +st.set_page_config(page_title="FUNCellA", page_icon="🧬") + +from app.pas_tab import pas_tab +from app.threshold_tab import threshold_tab +from app.upload_tab import upload_tab + +st.title("FUNCellA (Functional Cell Analysis)") +st.write( + "Upload your data and genesets, choose method and filtering options, calculate PAS and thresholding." +) + +tabs = st.tabs(["Upload Files", "PAS Calculation", "Thresholding"]) + +with tabs[0]: + upload_tab() +with tabs[1]: + pas_tab() +with tabs[2]: + threshold_tab() diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..973e57b --- /dev/null +++ b/app/__init__.py @@ -0,0 +1 @@ +# Makes app a package for import diff --git a/enrichment_auc/gmm/__init__.py b/app/main.py similarity index 100% rename from enrichment_auc/gmm/__init__.py rename to app/main.py diff --git a/app/pas_tab.py b/app/pas_tab.py new file mode 100644 index 0000000..56ccdc2 --- /dev/null +++ b/app/pas_tab.py @@ -0,0 +1,118 @@ +import streamlit as st +from pyfuncella.gene2path import gene2path + + +def pas_tab(): + st.header("Step 2: PAS Calculation") + method = st.selectbox( + "Select calculation method", + ["CERNO", "MEAN", "BINA", "AUCELL", "JASMINE", "ZSCORE", "SSGSEA"], + index=0, + key="method_select", + ) + filt_cov = st.slider( + "Minimum pathway coverage (filt_cov)", 0.0, 1.0, 0.0, 0.01, key="filt_cov" + ) + filt_min = st.number_input( + "Minimum pathway size (filt_min)", min_value=0, value=15, key="filt_min" + ) + filt_max = st.number_input( + "Maximum pathway size (filt_max)", min_value=1, value=500, key="filt_max" + ) + variance_filter_threshold = st.slider( + "Variance filter threshold (fraction of genes to keep)", + 0.0, + 1.0, + 0.0, + 0.01, + key="variance_filter", + ) + aucell_threshold = None + if method == "AUCELL": + aucell_threshold = st.slider( + "AUCELL threshold (fraction of top genes)", + 0.0, + 1.0, + 0.05, + 0.01, + key="aucell_thr", + ) + type_option = None + if method == "JASMINE": + type_option = st.selectbox( + "JASMINE effect size type", + ["oddsratio", "likelihood"], + index=0, + key="jasmine_type", + ) + + if st.button("Run PAS calculation", key="run_pas"): + import os + import tempfile + + data = st.session_state.get("data") + genes = st.session_state.get("genes") + genesets = st.session_state.get("genesets") + if data is None or genesets is None or len(genesets) == 0: + st.error("Both data and genesets must be loaded and non-empty.") + st.stop() + if method == "SSGSEA": + tmp_dir = "tmp" + os.makedirs(tmp_dir, exist_ok=True) + kwargs = dict( + data=data, + genesets=genesets, + genes=genes, + method=method, + filt_cov=filt_cov, + filt_min=filt_min, + filt_max=filt_max, + variance_filter_threshold=( + variance_filter_threshold if variance_filter_threshold > 0 else None + ), + ) + if method == "AUCELL": + kwargs["aucell_threshold"] = ( + aucell_threshold if aucell_threshold is not None else 0.05 + ) + if method == "JASMINE": + kwargs["type"] = type_option + + # Execute analysis + if method in ["SSGSEA"]: + with st.status(f"Running {method} analysis...", expanded=True) as status: + try: + result = gene2path(**kwargs) + status.update( + label=f"{method} analysis completed!", state="complete" + ) + st.session_state["pas_result"] = result + st.session_state["pas_method"] = method + st.success( + f"PAS calculation completed. Result shape: {result.shape}" + ) + st.dataframe(result) + st.download_button( + "Download results as CSV", + result.to_csv(), + file_name=f"{method}_results.csv", + on_click="ignore", + ) + except Exception as e: + status.update(label=f"{method} analysis failed", state="error") + st.error(f"Error running {method}: {e}") + else: + try: + result = gene2path(**kwargs) + st.session_state["pas_result"] = result + st.session_state["pas_method"] = method + st.success(f"PAS calculation completed. Result shape: {result.shape}") + st.dataframe(result) + st.download_button( + "Download results as CSV", + result.to_csv(), + file_name=f"{method}_results.csv", + on_click="ignore", + ) + except Exception as e: + st.error(f"Error running {method}: {e}") diff --git a/app/static/EN-logo-poziome-rgb.png b/app/static/EN-logo-poziome-rgb.png new file mode 100644 index 0000000..d36e4fe Binary files /dev/null and b/app/static/EN-logo-poziome-rgb.png differ diff --git a/app/static/politechnika_sl_logo_poziom_inwersja_en_rgb.png b/app/static/politechnika_sl_logo_poziom_inwersja_en_rgb.png new file mode 100644 index 0000000..1c7b551 Binary files /dev/null and b/app/static/politechnika_sl_logo_poziom_inwersja_en_rgb.png differ diff --git a/app/threshold_tab.py b/app/threshold_tab.py new file mode 100644 index 0000000..9b742fb --- /dev/null +++ b/app/threshold_tab.py @@ -0,0 +1,215 @@ +import numpy as np +import pandas as pd +import streamlit as st + +from app.utils.streamlit_progress import create_streamlit_progress_callback +from app.utils.visualize import visualize_scatter, visualize_dist + + +def _run_kmeans_thresholding(result, progress_callback): + """Run K-Means thresholding on PAS results.""" + from pyfuncella.thr_KM import thr_KM + + thresholded_df = thr_KM(result, verbose=False, progress_callback=progress_callback) + + # thr_KM returns a DataFrame with binary and cluster columns when input is DataFrame + assert isinstance(thresholded_df, pd.DataFrame), "Expected DataFrame from thr_KM" + + binary_cols = [col for col in thresholded_df.columns if col.endswith("_binary")] + cluster_cols = [col for col in thresholded_df.columns if col.endswith("_cluster")] + return thresholded_df[binary_cols], thresholded_df[cluster_cols] + + +def _run_gmm_thresholding(result, progress_callback, status): + """Run GMM thresholding on PAS results.""" + from pyfuncella.GMMdecomp import GMMdecomp + from pyfuncella.thr_GMM import thr_GMM + + # Step 1: GMM Decomposition + status.update(label="Running GMM decomposition...", state="running") + gmms = GMMdecomp(result, verbose=False, progress_callback=progress_callback) + st.session_state["gmm_params"] = gmms + + # Step 2: Threshold calculation + status.update(label="Calculating GMM thresholds...", state="running") + gmm_thresholds = thr_GMM(gmms, progress_callback=progress_callback) + st.session_state["gmm_thresholds"] = gmm_thresholds + + thresholded = pd.DataFrame(0, index=result.index, columns=result.columns) + for pathway in result.index: + thr = gmm_thresholds.get(pathway, {}).get("Kmeans_thr", float("nan")) + thresholded.loc[pathway] = (result.loc[pathway] >= thr).astype(int) + + return thresholded, None + + +def _run_aucell_thresholding(result, progress_callback): + """Run AUCell thresholding on PAS results.""" + from pyfuncella.thr_AUCell import thr_AUCell + + aucell_thresholds = thr_AUCell(result, progress_callback=progress_callback) + st.session_state["aucell_thresholds"] = aucell_thresholds + + thresholded = pd.DataFrame(0, index=result.index, columns=result.columns) + for pathway in result.index: + thr = aucell_thresholds.get(pathway, float("nan")) + thresholded.loc[pathway] = (result.loc[pathway] >= thr).astype(int) + + return thresholded, None + + +def _handle_r_not_available_error(method, status, e): + """Handle R not available errors.""" + status.update( + label=f"{method} thresholding failed - R not available", + state="error", + ) + st.error("**R Not Available**") + st.error(f"Error: {str(e)}") + st.info("**Try:**") + st.info("• Using K-Means thresholding instead (doesn't require R)") + st.info("• Checking that R is properly installed and accessible") + + +def _handle_package_missing_error(method, status, e, package_name): + """Handle missing R package errors.""" + status.update( + label=f"{method} thresholding failed - package missing", + state="error", + ) + st.error(f"**{package_name} Package Missing**") + st.error(f"Error: {str(e)}") + st.info("**Try:**") + st.info("• Using K-Means thresholding instead") + if package_name == "AUCell": + st.info("• Installing AUCell: BiocManager::install('AUCell')") + + +def _handle_missing_values_error(method, status, e): + """Handle missing values in data errors.""" + status.update(label=f"{method} thresholding failed", state="error") + st.error( + f"{method} failed due to missing values in the data. This may be caused by:" + ) + st.error("• Pathways with insufficient data points") + st.error("• NaN/infinite values in PAS scores") + st.error("• Data distribution issues preventing histogram calculation") + st.info( + "Try using K-Means thresholding instead, which is more robust to data quality issues." + ) + + +def _handle_general_error(method, status, e): + """Handle general thresholding errors.""" + status.update(label=f"{method} thresholding failed", state="error") + st.error(f"{method} thresholding failed: {str(e)}") + st.info("**Try:**") + st.info("• Using K-Means thresholding instead") + st.info("• Checking that R and required packages are properly installed") + + +def threshold_tab(): + """Main threshold tab function with refactored helper functions.""" + st.header("Step 3: Thresholding and Post-processing") + result = st.session_state.get("pas_result") + if result is not None: + st.write("Choose thresholding method and apply to PAS results.") + method = st.selectbox( + "Thresholding method", + ["K-Means", "GMM", "AUCell"], + index=0, + key="threshold_method", + ) + + # Use session_state to persist thresholded results and cluster assignments + if ( + "thresholded" not in st.session_state + or "cluster_assignments" not in st.session_state + or st.session_state.get("last_threshold_method") != method + ): + st.session_state["thresholded"] = None + st.session_state["cluster_assignments"] = None + + run_threshold = st.button("Run thresholding", key="run_threshold") + if run_threshold: + with st.status(f"Running {method}...", expanded=True) as status: + progress_callback = create_streamlit_progress_callback() + + try: + if method == "K-Means": + thresholded, cluster_assignments = _run_kmeans_thresholding( + result, progress_callback + ) + st.session_state["thresholded"] = thresholded + st.session_state["cluster_assignments"] = cluster_assignments + status.update( + label="K-Means thresholding completed!", state="complete" + ) + + elif method == "GMM": + thresholded, cluster_assignments = _run_gmm_thresholding( + result, progress_callback, status + ) + st.session_state["thresholded"] = thresholded + st.session_state["cluster_assignments"] = cluster_assignments + status.update( + label="GMM thresholding completed!", state="complete" + ) + + elif method == "AUCell": + thresholded, cluster_assignments = _run_aucell_thresholding( + result, progress_callback + ) + st.session_state["thresholded"] = thresholded + st.session_state["cluster_assignments"] = cluster_assignments + status.update( + label="AUCell thresholding completed!", state="complete" + ) + + st.session_state["last_threshold_method"] = method + + except RuntimeError as e: + if "R is not available" in str(e): + _handle_r_not_available_error(method, status, e) + elif "AUCell package" in str(e): + _handle_package_missing_error(method, status, e, "AUCell") + else: + _handle_general_error(method, status, e) + except Exception as e: + if "missing value where TRUE/FALSE needed" in str(e): + _handle_missing_values_error(method, status, e) + else: + _handle_general_error(method, status, e) + thresholded = st.session_state.get("thresholded") + cluster_assignments = st.session_state.get("cluster_assignments") + if thresholded is not None: + st.dataframe(thresholded) + st.download_button( + "Download thresholded results as CSV", + thresholded.to_csv(), + file_name=f"{method}_thresholded_results.csv", + on_click="ignore", + ) + selected_pathway = st.selectbox( + "Select a single pathway to visualize", + list(result.index), + key="visualize_pathway", + ) + st.markdown(f"**Selected pathway:** `{selected_pathway}`") + # Only show distribution plots for methods that use thresholds + if method in ["AUCell", "GMM"]: + visualize_dist(result, method, selected_pathway) + if method == "K-Means" and cluster_assignments is not None: + ranked_labels = cluster_assignments.loc[selected_pathway].values + visualize_scatter( + result, + thresholded, + method, + selected_pathway, + ranked_labels=ranked_labels, + ) + else: + visualize_scatter(result, thresholded, method, selected_pathway) + st.markdown("---") + else: + st.info("Run PAS calculation first to see results here.") diff --git a/app/upload_tab.py b/app/upload_tab.py new file mode 100644 index 0000000..bbab1cc --- /dev/null +++ b/app/upload_tab.py @@ -0,0 +1,79 @@ +import streamlit as st +import pandas as pd +import io + + +def load_csv(file): + content = file.getvalue().decode() + sep = "\t" if "\t" in content.splitlines()[0] else "," + lines = content.splitlines() + genesets = {} + for line in lines: + parts = line.strip().split(sep) + if len(parts) < 2: + continue + pathway = parts[0] + genes = [g for g in parts[1:] if g] + genesets[pathway] = genes + return genesets + + +def upload_tab(): + st.header("Step 1: Upload Data and Genesets") + data_file = st.file_uploader( + "Upload gene expression data (CSV)", type=["csv"], key="data_file" + ) + geneset_file = st.file_uploader( + "Upload genesets file (JSON or CSV)", type=["json", "csv"], key="geneset_file" + ) + geneset_source = st.radio( + "Genesets source", + ["Upload genesets file", "Use default genesets"], + key="geneset_source", + ) + + if st.button("Upload", key="save_files"): + missing = [] + # Data file check + if data_file is not None: + try: + st.session_state["data"] = pd.read_csv(data_file, index_col=0) + st.session_state["genes"] = list(st.session_state["data"].index) + st.success("Data file loaded.") + except Exception as e: + st.error(f"Error loading data file: {e}") + else: + st.session_state["data"] = None + st.session_state["genes"] = None + missing.append("gene expression data file") + # Genesets check + genesets_loaded = False + if geneset_source == "Upload genesets file" and geneset_file is not None: + try: + import json + + if geneset_file.name.endswith(".json"): + genesets = json.load(io.StringIO(geneset_file.getvalue().decode())) + elif geneset_file.name.endswith(".csv"): + genesets = load_csv(geneset_file) + else: + raise ValueError( + "Unsupported geneset file type. Please upload JSON or CSV." + ) + st.session_state["genesets"] = genesets + st.success("Genesets file loaded.") + genesets_loaded = True + except Exception as e: + st.error(f"Error loading geneset file: {e}") + elif geneset_source == "Use default genesets": + from pyfuncella import load_pathways + + st.session_state["genesets"] = load_pathways("data") + st.success("Default genesets selected.") + genesets_loaded = True + else: + st.session_state["genesets"] = None + missing.append("genesets (upload or select default)") + # Show info if anything is missing + if missing: + st.info(f"Please provide: {', '.join(missing)} before proceeding.") diff --git a/app/utils/streamlit_progress.py b/app/utils/streamlit_progress.py new file mode 100644 index 0000000..21d5bd1 --- /dev/null +++ b/app/utils/streamlit_progress.py @@ -0,0 +1,30 @@ +""" +Streamlit progress callback utilities for web interface. +""" + +import streamlit as st +from typing import Callable + + +def create_streamlit_progress_callback() -> Callable: + """ + Create a progress callback that uses Streamlit progress bar and text. + + Returns + ------- + callable + Progress callback function that accepts (current, total, message) parameters + """ + progress_bar = st.progress(0) + progress_text = st.empty() + + def callback(current: int, total: int, message: str = ""): + progress = int(100 * current / total) + progress_bar.progress(progress) + + if message: + progress_text.text(f"Processing: {message} ({current}/{total})") + else: + progress_text.text(f"Progress: {current}/{total}") + + return callback diff --git a/app/utils/visualize.py b/app/utils/visualize.py new file mode 100644 index 0000000..2e8b1bf --- /dev/null +++ b/app/utils/visualize.py @@ -0,0 +1,173 @@ +""" +Visualization utilities for pathway analysis. +""" + +import numpy as np +import pandas as pd +import streamlit as st +from sklearn.decomposition import PCA +from sklearn.manifold import TSNE + +from pyfuncella.plot.plot_distributed_data import plot_pas_distribution +from pyfuncella.plot.plot_scatter_flow import scatterplot_subplots + + +def calculate_pca_tsne_coordinates(): + """ + Calculate PCA (40 components) + t-SNE (2D) coordinates from original data. + This is computed once for all pathways and stored in session state. + """ + data = st.session_state.get("data") + if data is None: + return None + + # Check if coordinates are already calculated + if "pca_tsne_coords" in st.session_state: + return st.session_state["pca_tsne_coords"] + + try: + # Transpose data so samples are rows and features are columns + data_T = data.T + + # Apply PCA to reduce to 40 components + pca = PCA(n_components=min(40, data_T.shape[1])) + pca_result = pca.fit_transform(data_T) + + # Apply t-SNE to reduce to 2D + tsne = TSNE( + n_components=2, random_state=42, perplexity=min(30, data_T.shape[0] - 1) + ) + tsne_result = tsne.fit_transform(pca_result) + + # Store coordinates in session state + coords = {"x": tsne_result[:, 0], "y": tsne_result[:, 1]} + st.session_state["pca_tsne_coords"] = coords + return coords + except Exception as e: + st.error(f"Error calculating PCA + t-SNE coordinates: {str(e)}") + return None + + +def visualize_scatter( + result, thresholded, method, selected_pathway, ranked_labels=None +): + """ + Visualize PAS scatterplots for AUCell, GMM, and K-Means thresholding. + Uses PCA + t-SNE coordinates for x and y positions. + """ + # Get or calculate PCA + t-SNE coordinates + coords = calculate_pca_tsne_coordinates() + if coords is None: + st.warning( + "Could not calculate PCA + t-SNE coordinates. Falling back to sample indices." + ) + pas_scores = result.loc[selected_pathway].values + x = np.arange(len(pas_scores)) + y = pas_scores + else: + pas_scores = result.loc[selected_pathway].values + x = coords["x"] + y = coords["y"] + + binary_labels = ( + thresholded.loc[selected_pathway].values if thresholded is not None else None + ) + continuous_labels = pas_scores + title = f"{selected_pathway} ({method})" + pas_method = st.session_state.get("pas_method", "PAS") + + if method == "AUCell": + fig = scatterplot_subplots( + x=x, + y=y, + continuous_labels=continuous_labels, + binary_labels=binary_labels, + ranked_labels=ranked_labels, + title=title, + pas_method=pas_method, + ) + elif method == "GMM": + gmm_thresholds = st.session_state.get("gmm_thresholds") + thr = None + all_thr = None + if gmm_thresholds: + thr = gmm_thresholds.get(selected_pathway, {}).get( + "Kmeans_thr", float("nan") + ) + all_thr = gmm_thresholds.get(selected_pathway, {}).get("All_thr", []) + if thr is None: + thr = float("nan") + binary_labels = (pas_scores >= thr).astype(int) + # Calculate group index for each PAS score based on All_thr + if all_thr and len(all_thr) > 0: + # Sort thresholds and assign group index by np.digitize + sorted_thr = np.sort(np.array(all_thr)) + gmm_groups = np.digitize(pas_scores, sorted_thr) + else: + gmm_groups = binary_labels + + # Don't show ranked labels if there are only 2 or fewer groups + if gmm_groups is not None and len(np.unique(gmm_groups)) <= 2: + gmm_groups = None + + fig = scatterplot_subplots( + x=x, + y=y, + continuous_labels=continuous_labels, + binary_labels=binary_labels, + ranked_labels=gmm_groups, + title=title, + pas_method=pas_method, + ) + elif method == "K-Means": + if ranked_labels is not None and len(np.unique(ranked_labels)) <= 2: + ranked_labels = None + + fig = scatterplot_subplots( + x=x, + y=y, + continuous_labels=continuous_labels, + binary_labels=binary_labels, + ranked_labels=ranked_labels, + title=title, + pas_method=pas_method, + ) + st.plotly_chart(fig, use_container_width=True) + + +def visualize_dist(result, method, selected_pathway): + """ + Visualize PAS score distribution for AUCell and GMM thresholding. + """ + pas_scores = result.loc[selected_pathway].values + pathway_name = selected_pathway + pas_method = st.session_state.get("pas_method", "PAS") + fig = None + + if method == "AUCell": + aucell_thresholds = st.session_state.get("aucell_thresholds") + thr = aucell_thresholds.get(pathway_name) if aucell_thresholds else None + if thr is None: + st.warning( + f"AUCell threshold not found for pathway {pathway_name}. Please re-run thresholding." + ) + return + fig = plot_pas_distribution(pas_scores, pas_method, pathway_name, thr) + + elif method == "GMM": + gmm_params = st.session_state.get("gmm_params", {}) + gmm_model = ( + gmm_params.get(pathway_name, {}).get("model") if gmm_params else None + ) + gmm_thresholds = st.session_state.get("gmm_thresholds") + thr = None + if gmm_thresholds: + thr = gmm_thresholds.get(pathway_name, {}).get("Kmeans_thr", float("nan")) + if thr is None: + thr = float("nan") + fig = plot_pas_distribution( + pas_scores, pas_method, pathway_name, thr, gmm=gmm_model + ) + + if fig is not None: + st.plotly_chart(fig, use_container_width=True) diff --git a/build/lib.linux-x86_64-cpython-310/enrichment_auc/__init__.py b/build/lib.linux-x86_64-cpython-310/enrichment_auc/__init__.py deleted file mode 100644 index 4b1ac5b..0000000 --- a/build/lib.linux-x86_64-cpython-310/enrichment_auc/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Single cell enrichment analysis via GMM""" -import os - -try: - import importlib.metadata as importlib_metadata -except ModuleNotFoundError: - import importlib_metadata - -if os.environ.get("READTHEDOCS") == "True": - import toml - - dirname = os.path.dirname(__file__) - with open(os.path.join(dirname, "../pyproject.toml")) as f: - __version__ = toml.load(f)["tool"]["poetry"]["version"] -else: - __version__ = importlib_metadata.version(__name__) - - -__all__ = [ - "__version__", -] diff --git a/build/lib.linux-x86_64-cpython-310/enrichment_auc/_matlab_legacy.py b/build/lib.linux-x86_64-cpython-310/enrichment_auc/_matlab_legacy.py deleted file mode 100644 index 211248b..0000000 --- a/build/lib.linux-x86_64-cpython-310/enrichment_auc/_matlab_legacy.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Access to MATLAB legacy functionalities.""" -import faulthandler -from contextlib import contextmanager - -import numpy as np - -import gamred_native as gn - - -@contextmanager -def sigsegv_handler(): - was_enabled = faulthandler.is_enabled() - faulthandler.enable() - yield - if not was_enabled: - faulthandler.disable() - - -def find_thresholds(values: np.ndarray, max_components: int = 10) -> np.ndarray: - """Find candidate thresholds for decomposition of values by GMM. - - Parameters - ---------- - values: - vector of values to decompose - - max_components: - maximal number of components to decompose into - - Returns - ------- - array of candidate thresholds from crossings between GMM components - """ - if values.size <= max_components: - max_components = values.size - if values.size == 0: - return np.array([]) - if max_components <= 0: - raise ValueError("max_components must be positive") - if values.ndim != 1: - raise ValueError("values must be 1D array") - values = np.ascontiguousarray(values) - offset = np.min(values) - if np.min(values) == np.max(values): - return np.array([]) - with sigsegv_handler(): - res = gn.find_thresholds(values - offset, max_components) - thresholds = res["thresholds"] + offset - return res["components_no"], thresholds - - -def find_gaussian_mixtures(x: np.ndarray, counts: np.ndarray, KS: int = 10) -> dict: - """Find parameters for decomposition of values by GMM. - - Parameters - ---------- - values: - vector of values to decompose - - KS: - number of Gaussian components - - Returns - ------- - dictionary with arrays of weights, means, standard deviations and log likelihood of decomposition - """ - if x.size <= KS: - KS = x.size - if x.size == 0: - return { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - "TIC": np.nan, - "l_lik": np.nan, - } - if KS <= 0: - raise ValueError("KS must be positive") - if x.ndim != 1: - raise ValueError("x must be 1D array") - if counts.ndim != 1: - raise ValueError("counts must be 1D array") - x = np.ascontiguousarray(x) - offset = np.min(x) - counts = np.ascontiguousarray(counts) - if np.min(x) == np.max(x): - return { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - "TIC": np.nan, - "l_lik": np.nan, - } - with sigsegv_handler(): - distribution = gn.find_gaussian_mixtures(x - offset, counts, KS) - distribution["mu"] = distribution["mu"] + offset - return distribution diff --git a/build/lib.linux-x86_64-cpython-310/enrichment_auc/distributions.py b/build/lib.linux-x86_64-cpython-310/enrichment_auc/distributions.py deleted file mode 100644 index 63dd24b..0000000 --- a/build/lib.linux-x86_64-cpython-310/enrichment_auc/distributions.py +++ /dev/null @@ -1,208 +0,0 @@ -import numpy as np -import numpy_indexed as npi -from scipy import stats -from sklearn.cluster import KMeans -from sklearn.metrics import silhouette_score - -from enrichment_auc._matlab_legacy import find_gaussian_mixtures - - -def _merge_gmm(dist, sigma_dev=1.0, alpha_limit=0.001): - print("foo") - KS = dist["mu"].size # components number - mu = np.array([dist["mu"][0]]) - sigma = np.array([dist["sigma"][0]]) - print("sigma", sigma) - alpha = np.array([dist["weights"][0]]) - for i in range(1, KS): - mu_diff = dist["mu"][i] - mu[-1] - min_displacement = np.min(np.append(sigma, dist["sigma"][i])) * sigma_dev - if mu_diff < min_displacement or dist["weights"][i] < alpha_limit: - # merge - pp_est = np.array([dist["weights"][i], alpha[-1]]) - mu_est = np.array([dist["mu"][i], mu[-1]]) - sigma_est = np.array([dist["sigma"][i], sigma[-1]]) - ww_temp = np.sum(pp_est) - mu_temp = ( - dist["weights"][i] * dist["mu"][i] + alpha[-1] * mu[-1] - ) / ww_temp - print("x") - print(np.sum(pp_est * (mu_est**2 + sigma_est**2)) / ww_temp) - print( mu[-1] ** 2) - sigma_temp = np.sqrt( - np.sum(pp_est * (mu_est**2 + sigma_est**2)) / ww_temp - mu[-1] ** 2 - ) - print(sigma_temp) - mu[-1] = mu_temp - sigma[-1] = sigma_temp - alpha[-1] = ww_temp - else: - # add new distribution - mu = np.append(mu, dist["mu"][i]) - sigma = np.append(sigma, dist["sigma"][i]) - alpha = np.append(alpha, dist["weights"][i]) - return { - "weights": np.array(alpha), - "mu": np.array(mu), - "sigma": np.array(sigma), - } - - -def find_distribution(scores, gs_name="", sigma_dev=2.5, alpha_limit=0.001): - if np.var(scores) == 0: - print("All scores were of the same value in {}.".format(gs_name)) - return { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - "TIC": np.nan, - "l_lik": np.nan, - } - offset = np.min(scores) - # find proper Gaussian Mixture model approximating the scores' distribution - counts = np.ones(scores.shape) - if stats.shapiro(scores).pvalue > 0.05: # check if distribution is normal - cur_dist = find_gaussian_mixtures(scores - offset, counts, 1) - else: # if not, approximate with Gaussian Mixture model - min_BIC = np.Inf - cur_dist = {} - for components_no in range(1, 11): - distribution = find_gaussian_mixtures(scores - offset, counts, components_no) - l_lik = distribution["l_lik"] - BIC = -2 * l_lik + (3 * components_no - 1) * np.log(scores.size) - - if ( - min_BIC > BIC - and not np.isnan(BIC) - and not np.isnan(distribution["TIC"]) - ): - cur_dist = distribution - min_BIC = BIC - - if min_BIC == np.inf: - cur_dist = { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - "TIC": np.nan, - "l_lik": np.nan, - } - # merge the special cases - print(cur_dist) - dist = _merge_gmm(cur_dist, sigma_dev, alpha_limit) - cur_dist["mu"] = cur_dist["mu"] + offset - return dist - - -def find_pdfs(mu, sig, alpha, x_temp): - x_temp = x_temp.reshape( - x_temp.shape[0], -1 - ) # so that scipy can recast it together with distribution parameters - pdfs = ( - stats.norm.pdf(x_temp, mu, sig) * alpha - ) # calculate pdfs for all distributions - pdfs = pdfs.transpose() - return pdfs - - -def find_crossing(pdf1, pdf2, mu1, mu2, x_temp): - # find crossing between two given pdfs - idxs = np.argwhere(np.diff(np.sign(pdf1 - pdf2))).flatten() - if idxs.size == 0: - return None - thrs = x_temp[idxs] - if thrs[-1] > mu1 and thrs[-1] < mu2: - return thrs[-1] - if thrs[0] > mu1 and thrs[0] < mu2: - return thrs[0] - # do the closest to means' mean - means = np.mean(np.array([mu1, mu2])) - if np.abs(thrs[-1] - means) < np.abs(thrs[0] - means): - return thrs[-1] - return thrs[0] - - -def _remove_redundant_thresholds(thresholds, scores, counter): - if thresholds.shape[0] == 0: - return thresholds, counter - if len(np.where(scores > thresholds[-1])[0]) <= 1: - # thresholds = thresholds[:-1] - # if thresholds.shape[0] == 0: - # return thresholds - counter += 1 - if len(np.where(scores <= thresholds[0])[0]) <= 1: - # thresholds = thresholds[1:] - counter += 1 - return thresholds, counter - - -def find_thresholds(distributions, scores, gs_name, counter): - # for one distribution only - if distributions["mu"].size == 0: - return np.array([]) - thresholds = [] - x_temp = np.linspace(np.min(scores), np.max(scores), 10**6) - pdfs = find_pdfs( - distributions["mu"], distributions["sigma"], distributions["weights"], x_temp - ) - for i in range(distributions["mu"].size - 1): - thr = find_crossing( - pdfs[i, :], - pdfs[i + 1, :], - distributions["mu"][i], - distributions["mu"][i + 1], - x_temp, - ) - if thr is not None: - thresholds.append(thr) - if len(thresholds) != distributions["mu"].size - 1: - print( - "{}: {} thresholds fonud for {} distributions.".format( - gs_name, len(thresholds), distributions["mu"].size - ) - ) - thresholds = np.array(thresholds) - thresholds, counter = _remove_redundant_thresholds(thresholds, scores, counter) - return thresholds, counter - - -def correct_via_kmeans(distributions, thresholds): - if distributions["mu"].size <= 2: - return thresholds - mu = distributions["mu"] - sig = distributions["sigma"] - alpha = distributions["weights"] - features = np.stack([mu, sig, alpha]).T - # scale the features - features = features - features.min(axis=0) - features = features / features.max(axis=0) - best_sil = -1.1 - localizer = np.zeros(mu.size) - for k in range(2, mu.size - 1): - km = KMeans(k, n_init="auto") - labels = km.fit_predict(features) - sil = silhouette_score(features, labels) - if sil > best_sil: - best_sil = sil - localizer = labels - thresholds = _filter_thresholds(localizer, mu, thresholds) - return thresholds - - -def _filter_thresholds(localizer, mu, thresholds): - # sort the clusters to go in the correct order - _, group_min = npi.group_by(localizer).min(mu) - localizer = np.nonzero(localizer[:, None] == group_min.argsort())[1] - # check if neighbouring distributions are together - differences = np.diff(localizer) - if np.all(differences >= 0): - # perform the correction - thresholds = thresholds[np.where(differences)] - return thresholds - - -def categorize_by_thresholds(score, thresholds): - group = np.zeros(score.shape[0]) - for i in range(score.shape[0]): - group[i] = (thresholds <= score[i]).sum() - return group diff --git a/build/lib.linux-x86_64-cpython-310/enrichment_auc/evaluate_classification.py b/build/lib.linux-x86_64-cpython-310/enrichment_auc/evaluate_classification.py deleted file mode 100644 index f9646af..0000000 --- a/build/lib.linux-x86_64-cpython-310/enrichment_auc/evaluate_classification.py +++ /dev/null @@ -1,52 +0,0 @@ -import pandas as pd -from sklearn import metrics - - -class Scores: - def __init__(self): - self.scoring_methods = [ - metrics.balanced_accuracy_score, - metrics.adjusted_rand_score, - metrics.f1_score, - metrics.recall_score, - metrics.matthews_corrcoef, - metrics.jaccard_score, - metrics.hamming_loss, - metrics.precision_score, - ] - self.names = [ - "Balanced_accuracy_", - "ARI_", - "F1_", - "Recall_", - "Matthews_", - "Jaccard_", - "Hamming_", - "Precision_", - "FDR_", - ] - self.scores = [[] for _ in self.names] - - def get_classification_scores(self, y_true, y_pred): - for i, scoring in enumerate(self.scoring_methods): - res = scoring(y_true, y_pred) - self.scores[i].append(res) - self.scores[-1].append(1 - res) - - def save_confusion_matrix( - self, y_true, y_pred, resfolder, plottype, scorename, gs_name - ): - mx = metrics.confusion_matrix(y_true, y_pred) - df = pd.DataFrame(mx) - df.index.name = "true label" - df.columns.name = "predicted label" - df.to_csv( - resfolder - + "confusion_matrix_" - + plottype - + "/" - + gs_name - + "_" - + scorename - + ".csv" - ) diff --git a/build/lib.linux-x86_64-cpython-310/gamred_native.cpython-310-x86_64-linux-gnu.so b/build/lib.linux-x86_64-cpython-310/gamred_native.cpython-310-x86_64-linux-gnu.so deleted file mode 100755 index 2f69e8f..0000000 Binary files a/build/lib.linux-x86_64-cpython-310/gamred_native.cpython-310-x86_64-linux-gnu.so and /dev/null differ diff --git a/build/lib.linux-x86_64-cpython-39/enrichment_auc/__init__.py b/build/lib.linux-x86_64-cpython-39/enrichment_auc/__init__.py deleted file mode 100644 index 4b1ac5b..0000000 --- a/build/lib.linux-x86_64-cpython-39/enrichment_auc/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Single cell enrichment analysis via GMM""" -import os - -try: - import importlib.metadata as importlib_metadata -except ModuleNotFoundError: - import importlib_metadata - -if os.environ.get("READTHEDOCS") == "True": - import toml - - dirname = os.path.dirname(__file__) - with open(os.path.join(dirname, "../pyproject.toml")) as f: - __version__ = toml.load(f)["tool"]["poetry"]["version"] -else: - __version__ = importlib_metadata.version(__name__) - - -__all__ = [ - "__version__", -] diff --git a/build/lib.linux-x86_64-cpython-39/enrichment_auc/_matlab_legacy.py b/build/lib.linux-x86_64-cpython-39/enrichment_auc/_matlab_legacy.py deleted file mode 100644 index 211248b..0000000 --- a/build/lib.linux-x86_64-cpython-39/enrichment_auc/_matlab_legacy.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Access to MATLAB legacy functionalities.""" -import faulthandler -from contextlib import contextmanager - -import numpy as np - -import gamred_native as gn - - -@contextmanager -def sigsegv_handler(): - was_enabled = faulthandler.is_enabled() - faulthandler.enable() - yield - if not was_enabled: - faulthandler.disable() - - -def find_thresholds(values: np.ndarray, max_components: int = 10) -> np.ndarray: - """Find candidate thresholds for decomposition of values by GMM. - - Parameters - ---------- - values: - vector of values to decompose - - max_components: - maximal number of components to decompose into - - Returns - ------- - array of candidate thresholds from crossings between GMM components - """ - if values.size <= max_components: - max_components = values.size - if values.size == 0: - return np.array([]) - if max_components <= 0: - raise ValueError("max_components must be positive") - if values.ndim != 1: - raise ValueError("values must be 1D array") - values = np.ascontiguousarray(values) - offset = np.min(values) - if np.min(values) == np.max(values): - return np.array([]) - with sigsegv_handler(): - res = gn.find_thresholds(values - offset, max_components) - thresholds = res["thresholds"] + offset - return res["components_no"], thresholds - - -def find_gaussian_mixtures(x: np.ndarray, counts: np.ndarray, KS: int = 10) -> dict: - """Find parameters for decomposition of values by GMM. - - Parameters - ---------- - values: - vector of values to decompose - - KS: - number of Gaussian components - - Returns - ------- - dictionary with arrays of weights, means, standard deviations and log likelihood of decomposition - """ - if x.size <= KS: - KS = x.size - if x.size == 0: - return { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - "TIC": np.nan, - "l_lik": np.nan, - } - if KS <= 0: - raise ValueError("KS must be positive") - if x.ndim != 1: - raise ValueError("x must be 1D array") - if counts.ndim != 1: - raise ValueError("counts must be 1D array") - x = np.ascontiguousarray(x) - offset = np.min(x) - counts = np.ascontiguousarray(counts) - if np.min(x) == np.max(x): - return { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - "TIC": np.nan, - "l_lik": np.nan, - } - with sigsegv_handler(): - distribution = gn.find_gaussian_mixtures(x - offset, counts, KS) - distribution["mu"] = distribution["mu"] + offset - return distribution diff --git a/build/lib.linux-x86_64-cpython-39/enrichment_auc/distributions.py b/build/lib.linux-x86_64-cpython-39/enrichment_auc/distributions.py deleted file mode 100644 index 2dd60ca..0000000 --- a/build/lib.linux-x86_64-cpython-39/enrichment_auc/distributions.py +++ /dev/null @@ -1,200 +0,0 @@ -import numpy as np -import numpy_indexed as npi -from scipy import stats -from sklearn.cluster import KMeans -from sklearn.metrics import silhouette_score - -from enrichment_auc._matlab_legacy import find_gaussian_mixtures - - -def _merge_gmm(dist, sigma_dev=1.0, alpha_limit=0.001): - KS = dist["mu"].size # components number - mu = np.array([dist["mu"][0]]) - sigma = np.array([dist["sigma"][0]]) - alpha = np.array([dist["weights"][0]]) - for i in range(1, KS): - mu_diff = dist["mu"][i] - mu[-1] - min_displacement = np.min(np.append(sigma, dist["sigma"][i])) * sigma_dev - if mu_diff < min_displacement or dist["weights"][i] < alpha_limit: - # merge - pp_est = np.array([dist["weights"][i], alpha[-1]]) - mu_est = np.array([dist["mu"][i], mu[-1]]) - sigma_est = np.array([dist["sigma"][i], sigma[-1]]) - ww_temp = np.sum(pp_est) - mu_temp = ( - dist["weights"][i] * dist["mu"][i] + alpha[-1] * mu[-1] - ) / ww_temp - sigma_temp = np.sqrt( - np.sum(pp_est * (mu_est**2 + sigma_est**2)) / ww_temp - mu[-1] ** 2 - ) - mu[-1] = mu_temp - sigma[-1] = sigma_temp - alpha[-1] = ww_temp - else: - # add new distribution - mu = np.append(mu, dist["mu"][i]) - sigma = np.append(sigma, dist["sigma"][i]) - alpha = np.append(alpha, dist["weights"][i]) - return { - "weights": np.array(alpha), - "mu": np.array(mu), - "sigma": np.array(sigma), - } - - -def find_distribution(scores, gs_name="", sigma_dev=1.0, alpha_limit=0.001): - if np.var(scores) == 0: - print("All scores were of the same value in {}.".format(gs_name)) - return { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - "TIC": np.nan, - "l_lik": np.nan, - } - # find proper Gaussian Mixture model approximating the scores' distribution - counts = np.ones(scores.shape) - if stats.shapiro(scores).pvalue > 0.05: # check if distribution is normal - cur_dist = find_gaussian_mixtures(scores, counts, 1) - else: # if not, approximate with Gaussian Mixture model - min_BIC = np.Inf - cur_dist = {} - for components_no in range(1, 11): - distribution = find_gaussian_mixtures(scores, counts, components_no) - l_lik = distribution["l_lik"] - BIC = -2 * l_lik + (3 * components_no - 1) * np.log(scores.size) - - if ( - min_BIC > BIC - and not np.isnan(BIC) - and not np.isnan(distribution["TIC"]) - ): - cur_dist = distribution - min_BIC = BIC - - if min_BIC == np.inf: - cur_dist = { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - "TIC": np.nan, - "l_lik": np.nan, - } - # merge the special cases - dist = _merge_gmm(cur_dist, sigma_dev, alpha_limit) - return dist - - -def find_pdfs(mu, sig, alpha, x_temp): - x_temp = x_temp.reshape( - x_temp.shape[0], -1 - ) # so that scipy can recast it together with distribution parameters - pdfs = ( - stats.norm.pdf(x_temp, mu, sig) * alpha - ) # calculate pdfs for all distributions - pdfs = pdfs.transpose() - return pdfs - - -def find_crossing(pdf1, pdf2, mu1, mu2, x_temp): - # find crossing between two given pdfs - idxs = np.argwhere(np.diff(np.sign(pdf1 - pdf2))).flatten() - if idxs.size == 0: - return None - thrs = x_temp[idxs] - if thrs[-1] > mu1 and thrs[-1] < mu2: - return thrs[-1] - if thrs[0] > mu1 and thrs[0] < mu2: - return thrs[0] - # do the closest to means' mean - means = np.mean(np.array([mu1, mu2])) - if np.abs(thrs[-1] - means) < np.abs(thrs[0] - means): - return thrs[-1] - return thrs[0] - - -def _remove_redundant_thresholds(thresholds, scores, counter): - if thresholds.shape[0] == 0: - return thresholds - if len(np.where(scores > thresholds[-1])[0]) <= 1: - # thresholds = thresholds[:-1] - # if thresholds.shape[0] == 0: - # return thresholds - counter += 1 - if len(np.where(scores <= thresholds[0])[0]) <= 1: - # thresholds = thresholds[1:] - counter += 1 - return thresholds, counter - - -def find_thresholds(distributions, scores, gs_name, counter): - # for one distribution only - if distributions["mu"].size == 0: - return np.array([]) - thresholds = [] - x_temp = np.linspace(np.min(scores), np.max(scores), 10**6) - pdfs = find_pdfs( - distributions["mu"], distributions["sigma"], distributions["weights"], x_temp - ) - for i in range(distributions["mu"].size - 1): - thr = find_crossing( - pdfs[i, :], - pdfs[i + 1, :], - distributions["mu"][i], - distributions["sigma"], - distributions["mu"][i + 1], - x_temp, - ) - if thr is not None: - thresholds.append(thr) - if len(thresholds) != distributions["mu"].size - 1: - print( - "{}: {} thresholds fonud for {} distributions.".format( - gs_name, len(thresholds), distributions["mu"].size - ) - ) - thresholds = np.array(thresholds) - thresholds, counter = _remove_redundant_thresholds(thresholds, scores, counter) - return thresholds, counter - - -def correct_via_kmeans(distributions, thresholds): - if distributions["mu"].size == 2: - return thresholds - mu = distributions["mu"] - sig = distributions["sigma"] - alpha = distributions["weights"] - features = np.stack([mu, sig, alpha]).T - # scale the features - features = features - features.min(axis=0)[:, None] - features = features / features.max(axis=0)[:, None] - best_sil = -1.1 - localizer = np.zeros(mu.size) - for k in range(2, mu.size - 1): - km = KMeans(k, n_init="auto") - labels = km.fit_predict(features) - sil = silhouette_score(features, labels) - if sil > best_sil: - best_sil = sil - localizer = labels - thresholds = _filter_thresholds(localizer, mu, thresholds) - return thresholds - - -def _filter_thresholds(localizer, mu, thresholds): - # sort the clusters to go in the correct order - _, group_min = npi.group_by(localizer).min(mu) - localizer = np.nonzero(localizer[:, None] == group_min.argsort())[1] - # check if neighbouring distributions are together - differences = np.diff(localizer) - if np.all(differences >= 0): - # perform the correction - thresholds = thresholds[np.where(differences)] - return thresholds - - -def categorize_by_thresholds(score, thresholds): - group = np.zeros(score.shape[0]) - for i in range(score.shape[0]): - group[i] = (thresholds <= score[i]).sum() - return group diff --git a/build/lib.linux-x86_64-cpython-39/enrichment_auc/evaluate_classification.py b/build/lib.linux-x86_64-cpython-39/enrichment_auc/evaluate_classification.py deleted file mode 100644 index f9646af..0000000 --- a/build/lib.linux-x86_64-cpython-39/enrichment_auc/evaluate_classification.py +++ /dev/null @@ -1,52 +0,0 @@ -import pandas as pd -from sklearn import metrics - - -class Scores: - def __init__(self): - self.scoring_methods = [ - metrics.balanced_accuracy_score, - metrics.adjusted_rand_score, - metrics.f1_score, - metrics.recall_score, - metrics.matthews_corrcoef, - metrics.jaccard_score, - metrics.hamming_loss, - metrics.precision_score, - ] - self.names = [ - "Balanced_accuracy_", - "ARI_", - "F1_", - "Recall_", - "Matthews_", - "Jaccard_", - "Hamming_", - "Precision_", - "FDR_", - ] - self.scores = [[] for _ in self.names] - - def get_classification_scores(self, y_true, y_pred): - for i, scoring in enumerate(self.scoring_methods): - res = scoring(y_true, y_pred) - self.scores[i].append(res) - self.scores[-1].append(1 - res) - - def save_confusion_matrix( - self, y_true, y_pred, resfolder, plottype, scorename, gs_name - ): - mx = metrics.confusion_matrix(y_true, y_pred) - df = pd.DataFrame(mx) - df.index.name = "true label" - df.columns.name = "predicted label" - df.to_csv( - resfolder - + "confusion_matrix_" - + plottype - + "/" - + gs_name - + "_" - + scorename - + ".csv" - ) diff --git a/build/lib.linux-x86_64-cpython-39/gamred_native.cpython-39-x86_64-linux-gnu.so b/build/lib.linux-x86_64-cpython-39/gamred_native.cpython-39-x86_64-linux-gnu.so deleted file mode 100755 index 2e78deb..0000000 Binary files a/build/lib.linux-x86_64-cpython-39/gamred_native.cpython-39-x86_64-linux-gnu.so and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/calculate_SW.o b/build/temp.linux-x86_64-cpython-310/gamred_native/calculate_SW.o deleted file mode 100644 index 980a1e3..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/calculate_SW.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/dyn_pr_split_w.o b/build/temp.linux-x86_64-cpython-310/gamred_native/dyn_pr_split_w.o deleted file mode 100644 index 37792ee..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/dyn_pr_split_w.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds.o b/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds.o deleted file mode 100644 index cef1dd6..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_data.o b/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_data.o deleted file mode 100644 index c06d716..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_data.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_emxAPI.o b/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_emxAPI.o deleted file mode 100644 index 3c1f60a..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_emxAPI.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_emxutil.o b/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_emxutil.o deleted file mode 100644 index 4c41254..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_emxutil.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_initialize.o b/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_initialize.o deleted file mode 100644 index dbb37cc..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_initialize.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_rtwutil.o b/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_rtwutil.o deleted file mode 100644 index c9b3fdd..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_rtwutil.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_terminate.o b/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_terminate.o deleted file mode 100644 index 04c8278..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/fetch_thresholds_terminate.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/fminbnd.o b/build/temp.linux-x86_64-cpython-310/gamred_native/fminbnd.o deleted file mode 100644 index d497337..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/fminbnd.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/g_mix_est_fast_lik.o b/build/temp.linux-x86_64-cpython-310/gamred_native/g_mix_est_fast_lik.o deleted file mode 100644 index 56522b9..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/g_mix_est_fast_lik.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple.o b/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple.o deleted file mode 100644 index d87d0b9..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple_initialize.o b/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple_initialize.o deleted file mode 100644 index c6ac3b7..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple_initialize.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple_terminate.o b/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple_terminate.o deleted file mode 100644 index 709fd24..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/gaussian_mixture_simple_terminate.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/gmm_uborder_fun.o b/build/temp.linux-x86_64-cpython-310/gamred_native/gmm_uborder_fun.o deleted file mode 100644 index 43778f9..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/gmm_uborder_fun.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/histcounts.o b/build/temp.linux-x86_64-cpython-310/gamred_native/histcounts.o deleted file mode 100644 index f52bd45..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/histcounts.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/main.o b/build/temp.linux-x86_64-cpython-310/gamred_native/main.o deleted file mode 100644 index c0b9e41..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/main.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/mean.o b/build/temp.linux-x86_64-cpython-310/gamred_native/mean.o deleted file mode 100644 index 793bfcb..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/mean.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/my_qu_ix_w.o b/build/temp.linux-x86_64-cpython-310/gamred_native/my_qu_ix_w.o deleted file mode 100644 index 9f7873b..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/my_qu_ix_w.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/rtGetInf.o b/build/temp.linux-x86_64-cpython-310/gamred_native/rtGetInf.o deleted file mode 100644 index 2968f03..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/rtGetInf.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/rtGetNaN.o b/build/temp.linux-x86_64-cpython-310/gamred_native/rtGetNaN.o deleted file mode 100644 index e596422..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/rtGetNaN.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/rt_nonfinite.o b/build/temp.linux-x86_64-cpython-310/gamred_native/rt_nonfinite.o deleted file mode 100644 index a99de5b..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/rt_nonfinite.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/sort.o b/build/temp.linux-x86_64-cpython-310/gamred_native/sort.o deleted file mode 100644 index e41390b..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/sort.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/sortIdx.o b/build/temp.linux-x86_64-cpython-310/gamred_native/sortIdx.o deleted file mode 100644 index d18c136..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/sortIdx.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/std.o b/build/temp.linux-x86_64-cpython-310/gamred_native/std.o deleted file mode 100644 index 5ddd1f3..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/std.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-310/gamred_native/sum.o b/build/temp.linux-x86_64-cpython-310/gamred_native/sum.o deleted file mode 100644 index 5d33089..0000000 Binary files a/build/temp.linux-x86_64-cpython-310/gamred_native/sum.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/calculate_SW.o b/build/temp.linux-x86_64-cpython-39/gamred_native/calculate_SW.o deleted file mode 100644 index 2679a2a..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/calculate_SW.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/dyn_pr_split_w.o b/build/temp.linux-x86_64-cpython-39/gamred_native/dyn_pr_split_w.o deleted file mode 100644 index c48c52b..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/dyn_pr_split_w.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds.o b/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds.o deleted file mode 100644 index 0233d88..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_data.o b/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_data.o deleted file mode 100644 index eb85d9f..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_data.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_emxAPI.o b/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_emxAPI.o deleted file mode 100644 index 1dff4db..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_emxAPI.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_emxutil.o b/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_emxutil.o deleted file mode 100644 index aedb465..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_emxutil.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_initialize.o b/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_initialize.o deleted file mode 100644 index 45278df..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_initialize.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_rtwutil.o b/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_rtwutil.o deleted file mode 100644 index 42e98d4..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_rtwutil.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_terminate.o b/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_terminate.o deleted file mode 100644 index bad6f76..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/fetch_thresholds_terminate.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/fminbnd.o b/build/temp.linux-x86_64-cpython-39/gamred_native/fminbnd.o deleted file mode 100644 index 42511bf..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/fminbnd.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/g_mix_est_fast_lik.o b/build/temp.linux-x86_64-cpython-39/gamred_native/g_mix_est_fast_lik.o deleted file mode 100644 index 2a01356..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/g_mix_est_fast_lik.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple.o b/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple.o deleted file mode 100644 index a6c36a7..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple_initialize.o b/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple_initialize.o deleted file mode 100644 index 574ad77..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple_initialize.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple_terminate.o b/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple_terminate.o deleted file mode 100644 index 61ba379..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/gaussian_mixture_simple_terminate.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/gmm_uborder_fun.o b/build/temp.linux-x86_64-cpython-39/gamred_native/gmm_uborder_fun.o deleted file mode 100644 index e392dda..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/gmm_uborder_fun.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/histcounts.o b/build/temp.linux-x86_64-cpython-39/gamred_native/histcounts.o deleted file mode 100644 index 925823d..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/histcounts.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/main.o b/build/temp.linux-x86_64-cpython-39/gamred_native/main.o deleted file mode 100644 index 4423cef..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/main.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/mean.o b/build/temp.linux-x86_64-cpython-39/gamred_native/mean.o deleted file mode 100644 index 08e43f9..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/mean.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/my_qu_ix_w.o b/build/temp.linux-x86_64-cpython-39/gamred_native/my_qu_ix_w.o deleted file mode 100644 index c9dffc4..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/my_qu_ix_w.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/rtGetInf.o b/build/temp.linux-x86_64-cpython-39/gamred_native/rtGetInf.o deleted file mode 100644 index dfe3db0..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/rtGetInf.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/rtGetNaN.o b/build/temp.linux-x86_64-cpython-39/gamred_native/rtGetNaN.o deleted file mode 100644 index 20509a0..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/rtGetNaN.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/rt_nonfinite.o b/build/temp.linux-x86_64-cpython-39/gamred_native/rt_nonfinite.o deleted file mode 100644 index 404729d..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/rt_nonfinite.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/sort.o b/build/temp.linux-x86_64-cpython-39/gamred_native/sort.o deleted file mode 100644 index b953680..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/sort.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/sortIdx.o b/build/temp.linux-x86_64-cpython-39/gamred_native/sortIdx.o deleted file mode 100644 index 8ae3083..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/sortIdx.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/std.o b/build/temp.linux-x86_64-cpython-39/gamred_native/std.o deleted file mode 100644 index 6ffc169..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/std.o and /dev/null differ diff --git a/build/temp.linux-x86_64-cpython-39/gamred_native/sum.o b/build/temp.linux-x86_64-cpython-39/gamred_native/sum.o deleted file mode 100644 index 2fa66a7..0000000 Binary files a/build/temp.linux-x86_64-cpython-39/gamred_native/sum.o and /dev/null differ diff --git a/docker/deploy.dockerfile b/docker/deploy.dockerfile index b0d1c19..f959b7d 100644 --- a/docker/deploy.dockerfile +++ b/docker/deploy.dockerfile @@ -1,46 +1,122 @@ -FROM python:3.10-slim AS base -ENV PYTHONUNBUFFERED TRUE -RUN mkdir -p /root/.config/matplotlib &&\ - echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc -WORKDIR /app -RUN apt-get update &&\ - apt-get install -y libgomp1 &&\ - rm -rf /var/lib/apt/lists/* +# Build stage - contains all build dependencies +FROM rocker/r-ver:4.4.2 AS builder - -FROM base as builder -SHELL ["/bin/bash", "-c"] -RUN mkdir -p /install/lib/python3.7/site-packages -ENV PYTHONPATH .:/install/lib/python3.7/site-packages RUN apt-get update &&\ - apt-get install -y gcc curl &&\ + apt-get install -y \ + software-properties-common \ + curl \ + git \ + gcc \ + g++ \ + build-essential \ + r-base-dev \ + gfortran \ + libgomp1 \ + libgfortran5 \ + libcurl4-openssl-dev \ + libssl-dev \ + libxml2-dev \ + libgit2-dev \ + zlib1g-dev \ + libjpeg-dev \ + libpng-dev \ + libfreetype6-dev \ + libdeflate-dev \ + libpcre2-dev \ + liblzma-dev \ + libbz2-dev \ + libicu-dev \ + libreadline-dev \ + libmagick++-dev \ + pkg-config \ + cmake \ + ssh \ + openssl &&\ + add-apt-repository ppa:deadsnakes/ppa &&\ + apt-get update &&\ + apt-get install -y \ + python3.11 \ + python3.11-dev \ + python3.11-venv \ + python3.11-distutils &&\ rm -rf /var/lib/apt/lists/* +# Set Python 3.11 as default +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 +RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.11 + +# Install Poetry ENV POETRY_HOME="/opt/poetry" -RUN curl -sSL https://install.python-poetry.org | python - +RUN curl -sSL https://install.python-poetry.org | python3.11 - ENV PATH="${POETRY_HOME}/bin:${PATH}" +# Install R packages using renv +WORKDIR /app +COPY renv.lock ./ +COPY setup_docker_compatible_renv.R ./ +RUN chmod +x setup_docker_compatible_renv.R && Rscript setup_docker_compatible_renv.R + +# Export Python dependencies and install +COPY pyproject.toml poetry.lock /app/ +RUN poetry install --no-interaction --no-root + +# Build the package +COPY README.md /app/ +COPY pyfuncella /app/pyfuncella +RUN poetry build -FROM builder AS deps_builder -COPY . /app -RUN poetry install &&\ - poetry build +# Production stage - minimal image for deployment +FROM rocker/r-ver:4.4.2 AS production + +ENV PYTHONUNBUFFERED=TRUE +RUN mkdir -p /root/.config/matplotlib && \ + echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc + +# Install minimal runtime dependencies +RUN apt-get update && \ + apt-get install -y \ + software-properties-common \ + libgomp1 \ + libgfortran5 \ + libjpeg-turbo8 \ + libpng16-16 \ + libfreetype6 \ + libicu-dev \ + libmagick++-6.q16-9t64 \ + libmagick++-6-headers \ + imagemagick \ + && add-apt-repository ppa:deadsnakes/ppa \ + && apt-get update \ + && apt-get install -y \ + python3.11 \ + python3.11-dev \ + python3.11-venv \ + python3.11-distutils \ + libpcre2-dev \ + libdeflate-dev \ + liblzma-dev \ + libbz2-dev \ + zlib1g-dev \ + gcc \ + g++ \ + build-essential \ + curl \ + && rm -rf /var/lib/apt/lists/* +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 +RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.11 + +WORKDIR /app +COPY --from=builder /usr/local/lib/R/site-library /usr/local/lib/R/site-library +ENV R_LIBS_USER=/usr/local/lib/R/site-library -FROM builder AS deps_install -COPY --from=deps_builder /app/dist /app/dist -COPY requirements.txt requirements.txt -RUN pip install -r requirements.txt \ - --prefix=/install \ - --no-cache-dir \ - --no-warn-script-location &&\ - pip install /app/dist/enrichment-auc*.whl \ - --prefix=/install \ - --no-cache-dir \ - --no-warn-script-location +# Ensure R can find the packages by setting up the library path +RUN mkdir -p /usr/local/lib/R/etc +RUN echo 'options(repos = c(CRAN = "https://cloud.r-project.org/"))' >> /usr/local/lib/R/etc/Rprofile.site +RUN echo '.libPaths(c("/usr/local/lib/R/site-library", .libPaths()))' >> /usr/local/lib/R/etc/Rprofile.site +COPY --from=builder /app/dist /app/dist +RUN pip install /app/dist/*.whl -FROM base EXPOSE 8050 VOLUME /data WORKDIR /data -COPY --from=deps_install /install /usr/local diff --git a/docker/development.dockerfile b/docker/development.dockerfile index 24ac098..d0ad19e 100644 --- a/docker/development.dockerfile +++ b/docker/development.dockerfile @@ -1,36 +1,103 @@ -FROM python:3.10-slim AS base -ENV PYTHONUNBUFFERED TRUE -RUN mkdir -p /root/.config/matplotlib &&\ - echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc -WORKDIR /app +FROM rocker/r-ver:4.4.2 AS builder RUN apt-get update &&\ apt-get install -y \ - libgomp1 \ - gcc \ + software-properties-common \ curl \ git \ - ssh \ - openssl \ - libssl-dev \ + gcc \ + g++ \ + build-essential \ + r-base-dev \ + gfortran \ + libgomp1 \ + libgfortran5 \ libcurl4-openssl-dev \ + libssl-dev \ libxml2-dev \ - r-base &&\ + libgit2-dev \ + zlib1g-dev \ + libjpeg-dev \ + libpng-dev \ + libfreetype6-dev \ + libdeflate-dev \ + libpcre2-dev \ + liblzma-dev \ + libbz2-dev \ + libicu-dev \ + libreadline-dev \ + libmagick++-dev \ + pkg-config \ + cmake \ + ssh \ + openssl &&\ + add-apt-repository ppa:deadsnakes/ppa &&\ + apt-get update &&\ + apt-get install -y \ + python3.11 \ + python3.11-dev \ + python3.11-venv \ + python3.11-distutils &&\ rm -rf /var/lib/apt/lists/* +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 +RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.11 +RUN mkdir -p /tmp/R && chmod 777 /tmp/R +ENV R_LIBS_USER=/usr/local/lib/R/site-library ENV POETRY_HOME="/opt/poetry" -RUN curl -sSL https://install.python-poetry.org | python - +RUN curl -sSL https://install.python-poetry.org | python3.11 - ENV PATH="${POETRY_HOME}/bin:${PATH}" +RUN poetry self add poetry-plugin-export +WORKDIR /app +COPY renv.lock ./ +COPY setup_docker_compatible_renv.R ./ +RUN chmod +x setup_docker_compatible_renv.R && Rscript setup_docker_compatible_renv.R +COPY pyproject.toml poetry.lock README.md /app/ +COPY pyfuncella /app/pyfuncella +RUN python3.11 -m venv /app/venv &&\ + . /app/venv/bin/activate &&\ + pip install --upgrade pip &&\ + poetry install --only=main,dev +ENV PATH="/app/venv/bin:$PATH" +RUN poetry build -COPY pyproject.toml poetry.lock /app/ -COPY README.md /app/ -COPY enrichment_auc /app/enrichment_auc -RUN poetry config virtualenvs.create false &&\ - poetry install --with dev &&\ - poetry build - -RUN R -e "install.packages('renv', repos = c(CRAN = 'https://cloud.r-project.org'))" -COPY renv.lock renv.lock -COPY .Rprofile .Rprofile -RUN mkdir -p renv -COPY renv/activate.R renv/activate.R -COPY renv/settings.json renv/settings.json -RUN R -e "renv::restore()" +FROM rocker/r-ver:4.4.2 AS development +ENV PYTHONUNBUFFERED=TRUE +RUN mkdir -p /root/.config/matplotlib && \ + echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc +RUN apt-get update && \ + apt-get install -y \ + software-properties-common \ + libgomp1 \ + libgfortran5 \ + libjpeg-turbo8 \ + libpng16-16 \ + libfreetype6 \ + && add-apt-repository ppa:deadsnakes/ppa \ + && apt-get update \ + && apt-get install -y \ + python3.11 \ + python3.11-venv \ + python3.11-dev \ + libpcre2-dev \ + libdeflate-dev \ + liblzma-dev \ + libbz2-dev \ + zlib1g-dev \ + gcc \ + g++ \ + build-essential \ + && rm -rf /var/lib/apt/lists/* +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 +RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.11 +WORKDIR /app +COPY --from=builder /usr/local/lib/R/site-library /usr/local/lib/R/site-library +COPY --from=builder /app/venv /app/venv +ENV PATH="/app/venv/bin:$PATH" +ENV R_LIBS_USER=/usr/local/lib/R/site-library +RUN mkdir -p /usr/local/lib/R/etc +RUN echo 'options(repos = c(CRAN = "https://cloud.r-project.org/"))' >> /usr/local/lib/R/etc/Rprofile.site +RUN echo '.libPaths(c("/usr/local/lib/R/site-library", .libPaths()))' >> /usr/local/lib/R/etc/Rprofile.site +COPY --from=builder /app/dist /app/dist +RUN /app/venv/bin/pip install /app/dist/*.whl +COPY pyfuncella /app/pyfuncella +COPY test /app/test +COPY . /app/ diff --git a/docker/profiling.dockerfile b/docker/profiling.dockerfile index 41b3a4c..ee13e3f 100644 --- a/docker/profiling.dockerfile +++ b/docker/profiling.dockerfile @@ -1,18 +1,13 @@ -FROM enrichment_auc:dev +FROM pyfuncella:dev AS profiling EXPOSE 8888 -RUN apt-get update \ - && apt-get install -y \ +RUN apt-get update &&\ + apt-get install -y \ gcc \ git \ - ssh \ - && rm -rf /var/lib/apt/lists/* - -RUN pip install \ - --no-cache-dir \ - jupyterlab \ - line_profiler \ - memory_profiler + ssh &&\ + rm -rf /var/lib/apt/lists/* +RUN /app/venv/bin/pip install --no-cache-dir jupyterlab line_profiler memory_profiler CMD ["jupyter", "lab", "--no-browser", "--allow-root", "--ip=0.0.0.0", "--NotebookApp.token=''"] diff --git a/docker/streamlit.dockerfile b/docker/streamlit.dockerfile new file mode 100644 index 0000000..6c32d2c --- /dev/null +++ b/docker/streamlit.dockerfile @@ -0,0 +1,134 @@ +# Build stage +FROM rocker/r-ver:4.4.2 AS builder + +RUN apt-get update && \ + apt-get install -y \ + software-properties-common \ + curl \ + git \ + gcc \ + g++ \ + build-essential \ + r-base-dev \ + gfortran \ + libgomp1 \ + libgfortran5 \ + libcurl4-openssl-dev \ + libssl-dev \ + libxml2-dev \ + libgit2-dev \ + zlib1g-dev \ + libjpeg-dev \ + libpng-dev \ + libfreetype6-dev \ + libdeflate-dev \ + libpcre2-dev \ + liblzma-dev \ + libbz2-dev \ + libicu-dev \ + libreadline-dev \ + libmagick++-dev \ + pkg-config \ + cmake \ + libtirpc-dev \ + libtirpc3 && \ + add-apt-repository ppa:deadsnakes/ppa && \ + apt-get update && \ + apt-get install -y \ + python3.11 \ + python3.11-dev \ + python3.11-venv \ + python3.11-distutils && \ + rm -rf /var/lib/apt/lists/* + +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 +RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.11 + +ENV POETRY_HOME="/opt/poetry" +RUN curl -sSL https://install.python-poetry.org | python3.11 - +ENV PATH="${POETRY_HOME}/bin:${PATH}" +RUN poetry self add poetry-plugin-export + +WORKDIR /app +COPY renv.lock ./ +COPY setup_docker_compatible_renv.R ./ +RUN chmod +x setup_docker_compatible_renv.R && Rscript setup_docker_compatible_renv.R + +COPY pyproject.toml poetry.lock README.md /app/ +COPY pyfuncella /app/pyfuncella + +ENV R_HOME=/usr/lib/R +ENV R_USER=/usr/lib/R/site-library + +RUN python3.11 -m venv /app/venv && \ + . /app/venv/bin/activate && \ + pip install --upgrade pip && \ + poetry install +ENV PATH="/app/venv/bin:$PATH" +RUN poetry build + +# Runtime stage +FROM rocker/r-ver:4.4.2 AS app + +ENV PYTHONUNBUFFERED=TRUE +RUN mkdir -p /root/.config/matplotlib &&\ + echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc + +RUN apt-get update &&\ + apt-get install -y \ + software-properties-common \ + libgomp1 \ + libgfortran5 \ + libjpeg-turbo8 \ + libpng16-16 \ + libfreetype6 \ + r-base-dev \ + libcurl4-openssl-dev \ + libssl-dev \ + libxml2-dev \ + libtirpc-dev \ + libtirpc3 \ + libmagick++-6.q16-9t64 \ + libmagick++-6-headers \ + imagemagick &&\ + add-apt-repository ppa:deadsnakes/ppa &&\ + apt-get update &&\ + apt-get install -y \ + python3.11 \ + python3.11-venv \ + python3.11-dev &&\ + rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# Copy R packages and Python dependencies from builder +COPY --from=builder /usr/local/lib/R/site-library /usr/local/lib/R/site-library +COPY --from=builder /app/venv /app/venv +ENV PATH="/app/venv/bin:$PATH" +ENV R_LIBS_USER=/usr/local/lib/R/site-library + +ENV R_HOME=/usr/lib/R +ENV R_USER=/usr/lib/R/site-library +ENV LD_LIBRARY_PATH=/usr/lib/R/lib + +# Ensure R can find the packages by setting up the library path +RUN mkdir -p /usr/local/lib/R/etc +RUN echo 'options(repos = c(CRAN = "https://cloud.r-project.org/"))' >> /usr/local/lib/R/etc/Rprofile.site +RUN echo '.libPaths(c("/usr/local/lib/R/site-library", .libPaths()))' >> /usr/local/lib/R/etc/Rprofile.site + +# Copy built package and install +COPY --from=builder /app/dist /app/dist +RUN /app/venv/bin/pip install /app/dist/*.whl + + +# Install Streamlit and any extra dependencies for the app +RUN /app/venv/bin/pip install streamlit + +# Copy app folder (tab modules) and main app.py +COPY app/ /app/app/ +COPY app.py /app/app.py + +EXPOSE 8501 + +# Simple Streamlit startup +CMD ["/app/venv/bin/streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0", "--server.headless=true"] \ No newline at end of file diff --git a/docker/unittest.dockerfile b/docker/unittest.dockerfile index 3ff9062..6daf848 100644 --- a/docker/unittest.dockerfile +++ b/docker/unittest.dockerfile @@ -1,25 +1,119 @@ -FROM python:3.9-slim AS base -ENV PYTHONUNBUFFERED TRUE -RUN mkdir -p /root/.config/matplotlib &&\ - echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc -WORKDIR /app +# Build stage - contains all build dependencies +FROM rocker/r-ver:4.4.2 AS builder + +# Install minimal system dependencies needed for Python and R packages RUN apt-get update &&\ apt-get install -y \ - libgomp1 \ - gcc \ + software-properties-common \ curl \ git \ - ssh &&\ + gcc \ + g++ \ + build-essential \ + r-base-dev \ + gfortran \ + libgomp1 \ + libgfortran5 \ + libcurl4-openssl-dev \ + libssl-dev \ + libxml2-dev \ + libgit2-dev \ + zlib1g-dev \ + libjpeg-dev \ + libpng-dev \ + libfreetype6-dev \ + libdeflate-dev \ + libpcre2-dev \ + liblzma-dev \ + libbz2-dev \ + libicu-dev \ + libreadline-dev \ + libmagick++-dev \ + pkg-config \ + cmake &&\ + add-apt-repository ppa:deadsnakes/ppa &&\ + apt-get update &&\ + apt-get install -y \ + python3.11 \ + python3.11-dev \ + python3.11-venv \ + python3.11-distutils &&\ rm -rf /var/lib/apt/lists/* + +# Set Python 3.11 as default +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 +RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.11 + +# Setup R environment and temp directories +RUN mkdir -p /tmp/R && chmod 777 /tmp/R +ENV R_LIBS_USER=/usr/local/lib/R/site-library + +# Install Poetry ENV POETRY_HOME="/opt/poetry" -RUN curl -sSL https://install.python-poetry.org | python - +RUN curl -sSL https://install.python-poetry.org | python3.11 - ENV PATH="${POETRY_HOME}/bin:${PATH}" -COPY pyproject.toml poetry.lock /app/ -COPY README.md /app/ -COPY enrichment_auc /app/enrichment_auc -RUN poetry config virtualenvs.create false &&\ - poetry install --with dev &&\ - poetry build +# Install R packages using renv +WORKDIR /app +COPY renv.lock ./ +COPY setup_docker_compatible_renv.R ./ +RUN chmod +x setup_docker_compatible_renv.R && Rscript setup_docker_compatible_renv.R + +# Install Python dependencies using Poetry +COPY pyproject.toml poetry.lock README.md /app/ +COPY pyfuncella /app/pyfuncella +RUN python3.11 -m venv /app/venv &&\ + . /app/venv/bin/activate &&\ + pip install --upgrade pip &&\ + poetry install --only=main,dev +ENV PATH="/app/venv/bin:$PATH" + +# Build the package +RUN poetry build + +# Runtime stage - minimal image for running tests +FROM rocker/r-ver:4.4.2 AS runtime + +ENV PYTHONUNBUFFERED=TRUE +RUN mkdir -p /root/.config/matplotlib &&\ + echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc + +# Install minimal runtime dependencies +RUN apt-get update &&\ + apt-get install -y \ + software-properties-common \ + libgomp1 \ + libgfortran5 \ + libjpeg-turbo8 \ + libpng16-16 \ + libfreetype6 &&\ + add-apt-repository ppa:deadsnakes/ppa &&\ + apt-get update &&\ + apt-get install -y \ + python3.11 \ + python3.11-venv &&\ + rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# Copy R packages and Python dependencies from builder +COPY --from=builder /usr/local/lib/R/site-library /usr/local/lib/R/site-library +COPY --from=builder /app/venv /app/venv +ENV PATH="/app/venv/bin:$PATH" +ENV R_LIBS_USER=/usr/local/lib/R/site-library + +# Ensure R can find the packages by setting up the library path +RUN mkdir -p /usr/local/lib/R/etc +RUN echo 'options(repos = c(CRAN = "https://cloud.r-project.org/"))' >> /usr/local/lib/R/etc/Rprofile.site +RUN echo '.libPaths(c("/usr/local/lib/R/site-library", .libPaths()))' >> /usr/local/lib/R/etc/Rprofile.site + +# Copy built package and install +COPY --from=builder /app/dist /app/dist +RUN /app/venv/bin/pip install /app/dist/*.whl + +# Copy source code and tests +COPY pyfuncella /app/pyfuncella COPY test /app/test -RUN pytest + +# Run all tests +RUN /app/venv/bin/python -m pytest test/ diff --git a/enrichment_auc/__init__.py b/enrichment_auc/__init__.py deleted file mode 100644 index 4b1ac5b..0000000 --- a/enrichment_auc/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Single cell enrichment analysis via GMM""" -import os - -try: - import importlib.metadata as importlib_metadata -except ModuleNotFoundError: - import importlib_metadata - -if os.environ.get("READTHEDOCS") == "True": - import toml - - dirname = os.path.dirname(__file__) - with open(os.path.join(dirname, "../pyproject.toml")) as f: - __version__ = toml.load(f)["tool"]["poetry"]["version"] -else: - __version__ = importlib_metadata.version(__name__) - - -__all__ = [ - "__version__", -] diff --git a/enrichment_auc/evaluate_classification.py b/enrichment_auc/evaluate_classification.py deleted file mode 100644 index f9646af..0000000 --- a/enrichment_auc/evaluate_classification.py +++ /dev/null @@ -1,52 +0,0 @@ -import pandas as pd -from sklearn import metrics - - -class Scores: - def __init__(self): - self.scoring_methods = [ - metrics.balanced_accuracy_score, - metrics.adjusted_rand_score, - metrics.f1_score, - metrics.recall_score, - metrics.matthews_corrcoef, - metrics.jaccard_score, - metrics.hamming_loss, - metrics.precision_score, - ] - self.names = [ - "Balanced_accuracy_", - "ARI_", - "F1_", - "Recall_", - "Matthews_", - "Jaccard_", - "Hamming_", - "Precision_", - "FDR_", - ] - self.scores = [[] for _ in self.names] - - def get_classification_scores(self, y_true, y_pred): - for i, scoring in enumerate(self.scoring_methods): - res = scoring(y_true, y_pred) - self.scores[i].append(res) - self.scores[-1].append(1 - res) - - def save_confusion_matrix( - self, y_true, y_pred, resfolder, plottype, scorename, gs_name - ): - mx = metrics.confusion_matrix(y_true, y_pred) - df = pd.DataFrame(mx) - df.index.name = "true label" - df.columns.name = "predicted label" - df.to_csv( - resfolder - + "confusion_matrix_" - + plottype - + "/" - + gs_name - + "_" - + scorename - + ".csv" - ) diff --git a/enrichment_auc/gmm/distributions.py b/enrichment_auc/gmm/distributions.py deleted file mode 100644 index 29fe322..0000000 --- a/enrichment_auc/gmm/distributions.py +++ /dev/null @@ -1,66 +0,0 @@ -import numpy as np -from scipy import stats - -from enrichment_auc.gmm.gaussian_mixture_hist import gaussian_mixture_hist - - -def _merge_gmm(dist, sigma_dev=1.0, alpha_limit=0.001): - KS = dist["mu"].size # components number - mu = np.array([dist["mu"][0]]) - sigma = np.array([dist["sigma"][0]]) - alpha = np.array([dist["weights"][0]]) - for i in range(1, KS): - mu_diff = dist["mu"][i] - mu[-1] - min_displacement = np.min(np.append(sigma, dist["sigma"][i])) * sigma_dev - if mu_diff < min_displacement or dist["weights"][i] < alpha_limit: - # merge - pp_est = np.array([dist["weights"][i], alpha[-1]]) - mu_est = np.array([dist["mu"][i], mu[-1]]) - sigma_est = np.array([dist["sigma"][i], sigma[-1]]) - ww_temp = np.sum(pp_est) - mu[-1] = (dist["weights"][i] * dist["mu"][i] + alpha[-1] * mu[-1]) / ww_temp - sigma[-1] = np.sqrt( - np.sum(pp_est * (mu_est**2 + sigma_est**2)) / ww_temp - mu[-1] ** 2 - ) - alpha[-1] = ww_temp - else: - # add new distribution - mu = np.append(mu, dist["mu"][i]) - sigma = np.append(sigma, dist["sigma"][i]) - alpha = np.append(alpha, dist["weights"][i]) - return { - "weights": np.array(alpha), - "mu": np.array(mu), - "sigma": np.array(sigma), - } - - -def find_distribution(scores, gs_name="", sigma_dev=1.0, alpha_limit=0.001, SW=0.25): - if scores.max() - scores.min() <= 10 ** (-20): - print("All scores were of the same value in {}.".format(gs_name)) - return { - "weights": np.array([]), - "mu": np.array([]), - "sigma": np.array([]), - } - # find proper Gaussian Mixture model approximating the scores' distribution - counts = np.ones(scores.shape) - scores = np.sort(scores) - if stats.shapiro(scores).pvalue > 0.05: # check if distribution is normal - pp, mu, sig = gaussian_mixture_hist(scores, counts, SW=SW, n_clusters=1, KS=1) - else: # if not, approximate with Gaussian Mixture model - pp, mu, sig = gaussian_mixture_hist( - scores, - counts, - KS=10, - SW=SW, - n_clusters=None, - ) - cur_dist = { - "weights": pp, - "mu": mu, - "sigma": sig, - } - # merge the special cases - dist = _merge_gmm(cur_dist, sigma_dev, alpha_limit) - return dist diff --git a/enrichment_auc/gmm/gaussian_mixture_hist.py b/enrichment_auc/gmm/gaussian_mixture_hist.py deleted file mode 100644 index 378a84f..0000000 --- a/enrichment_auc/gmm/gaussian_mixture_hist.py +++ /dev/null @@ -1,313 +0,0 @@ -import math -import multiprocessing - -import matplotlib.pyplot as plt -import numpy as np -import scipy.stats as stats -import seaborn as sns - - -def sort(arr): - # Given arr should be 1D - arr_ind = np.arange(0, len(arr)) - dict_arr = dict(zip(arr_ind, arr)) - sorted_dict_arr = sorted(dict_arr.items(), key=lambda x: x[1]) - arr_sorted = np.array([pair[1] for pair in sorted_dict_arr]) - ind_after_sort = np.array([pair[0] for pair in sorted_dict_arr]) - return arr_sorted, ind_after_sort - - -def gaussian_mixture_hist( - x, - y, - KS=10, - cores=0, - criterion="bic", - path_visualisation_name=None, - SW=0.25, - stopping_threshold=0.2, - min_clusters=5, - n_clusters=None, -): - TIC = sum(y) - BIC = [] - logL = [i for i in range(0, KS)] - D = [] - alpha = dict.fromkeys([i for i in range(0, KS)]) - mu = dict.fromkeys([i for i in range(0, KS)]) - sigma = dict.fromkeys([i for i in range(0, KS)]) - i_bias_factor = 0 - # handling vector mode in hist implementation - if np.all((y == 1)): - _x = x - _y = y - y, x = np.histogram(x, bins=max(min(20, round(math.sqrt(x.shape[0]))), 400)) - x = [(el[0] + el[1]) / 2 for el in list(zip(x, x[1:]))] - else: - _x = x - _y = y - - # 1 component - [alpha[0], mu[0], sigma[0], logL[0]] = EM_iter_hist( - _x, - _y, - np.array([1]), - np.array([np.mean(x)]), - np.array([np.std(x, ddof=1)]), - TIC, - SW=SW, - ) - bic = -2 * logL[0] + 2 * np.log(TIC) - BIC.append(bic) - if n_clusters == 1 or KS == 1: - return alpha[0], mu[0], sigma[0] - - # >2 components - stop = False - k = 2 - Nb = len(x) - if cores == 0: - aux_mx = dyn_pr_split_w_aux(x, y) - else: - _step = Nb // cores - _missing = Nb % cores - _start = [_step * i for i in range(0, cores)] - _stop = [_step * i for i in range(1, cores + 1)] - _stop[-1] = ( - _stop[-1] + _missing - 1 - ) # -1 because that was in original fun on the end - - with multiprocessing.Pool(processes=cores) as pool: - results = pool.starmap( - dyn_pr_split_w_aux_core, - [(x, y, _start[i], _stop[i]) for i in range(0, cores)], - ) - aux_mx = sum(results) - - while not stop and k < KS: - if n_clusters is not None: - k = n_clusters - cmp_nb = k - 1 - stop = True - _, opt_part = dyn_pr_split_w(x, y, k - 1, aux_mx) - - part_cl = np.concatenate(([0], opt_part, [Nb + 1]), axis=0) # 1 to 0 - pp_ini = np.zeros( - k, - ) - mu_ini = np.zeros( - k, - ) - sig_ini = np.zeros( - k, - ) - - for kkps in range(0, k): - invec = x[int(part_cl[kkps]) : int(part_cl[kkps + 1])] - yinvec = y[int(part_cl[kkps]) : int(part_cl[kkps + 1])] - - wwec = yinvec / np.sum(yinvec) - - pp_ini[kkps] = np.sum(yinvec) / np.sum(y) # yinvec and y are only 1D - mu_ini[kkps] = np.sum(invec * wwec) - sig_ini[kkps] = 0.5 * (np.max(invec) - np.min(invec)) - - # decomposition - alpha[k - 1], mu[k - 1], sigma[k - 1], logL[k - 1] = EM_iter_hist( - _x, _y, pp_ini, mu_ini, sig_ini, TIC, SW=SW - ) - - # check convergence - bic = -2 * logL[k - 1] + (3 * k) * np.log(TIC) - BIC.append(bic) - d = -2 * logL[k - 2] + 2 * logL[k - 1] - D.append(d) - - # criterion choice - if criterion == "bic": - if 1 - stats.chi2.cdf(d, 3) > stopping_threshold and k > min_clusters: - stop = True - elif criterion == "bias_factor": - bias_factor = np.exp((BIC[k - 2] - BIC[k - 1]) / 2) - if bias_factor < 100: - i_bias_factor = k - 1 - stop = True - k += 1 - bic_arr = np.array(BIC) - if n_clusters is None: - if criterion == "bic": - cmp_nb = np.unravel_index(bic_arr.argmin(), bic_arr.shape)[0] - elif criterion == "bias_factor": - cmp_nb = i_bias_factor - - pp_est = alpha[cmp_nb] - mu_est = mu[cmp_nb] - sig_est = sigma[cmp_nb] - - if path_visualisation_name is not None: - plot_bic(BIC, cmp_nb, path_visualisation_name) - - return pp_est, mu_est, sig_est - - -def EM_iter_hist(x, y, alpha, mu, sig, TIC, SW=0.25): - [x, ind] = sort(x) - y = y[ind] - N = len(y) - sig2 = sig**2 - change = np.Inf - count = 1 - KS = np.max(alpha.shape) - # NOT READY FOR PRIME TIME - # more emphasis on SW in documentation - add warning to look at the histogram before procceding - SW = np.power((max(x) - min(x)) / (4 * KS), 2) - min_sigdev = np.power((max(x) - min(x)) * SW / KS, 2) - eps_change = 1e-4 - - while change > eps_change and count < 10000: - old_alpha = alpha.copy() - old_sig2 = sig2.copy() - sig = np.sqrt(sig2) - - f = np.zeros((KS, N)) - for a in range(0, KS): - f[a, :] = normal_pdf(x, mu[a], sig[a]) - - px = np.matmul(alpha, f) - px[np.isnan(px)] = 5e-324 - px[px == 0] = 5e-324 - - for a in range(0, KS): - pk = (alpha[a] * f[a, :] * y) / px - denom = np.sum(pk, axis=0) - - # mu - mu[a] = np.matmul(pk, x) / (denom + 1e-10) - sig2num = np.sum(np.matmul(pk, ((x - mu[a]) ** 2))) - - # sig - if sig2num / denom < min_sigdev: - sig2[a] = min_sigdev - else: - sig2[a] = sig2num / denom - - # alpha - alpha[a] = denom / TIC - - change = np.sum(np.abs(alpha - old_alpha)) + np.sum( - ((np.abs(sig2 - old_sig2)) / sig2) - ) / (len(alpha)) - count += 1 - # returns - logL = np.sum(np.log(px) * y) - mu_est, ind = sort(mu) - sig_est = np.sqrt(sig2[ind]) - pp_est = alpha[ind] - - return pp_est, mu_est, sig_est, logL - - -def dyn_pr_split_w_aux(data, ygreki): # (x,y) - N = len(data) - aux_mx = np.zeros((N, N), dtype=np.float32) - for kk in range(0, N - 1): - for jj in range(kk + 1, N): - aux_mx[kk, jj] = my_qu_ix_w(data[kk:jj], ygreki[kk:jj]) - return aux_mx - - -def dyn_pr_split_w_aux_core(data, ygreki, start, stop): - N = len(data) - aux_mx = np.zeros((N, N)) - for kk in range(start, stop): - for jj in range(kk + 1, N): - aux_mx[kk, jj] = my_qu_ix_w(data[kk:jj], ygreki[kk:jj]) - return aux_mx - - -def dyn_pr_split_w_aux_gpu(data, ygreki, aux_mx): # (x,y) - N = len(data) - for kk in range(0, N - 1): - for jj in range(kk + 1, N): - invec = data[kk:jj] - yinwec = ygreki[kk:jj] - PAR = 1 - PAR_sig_min = 0.1 - if (invec[len(invec)] - invec[0]) <= PAR_sig_min or np.sum( - yinwec - ) <= 1.0e-3: - wyn = np.inf - else: - wwec = yinwec / (np.sum(yinwec)) - wyn = ( - PAR - + math.sqrt(np.sum(((invec - np.sum(invec * wwec)) ** 2) * wwec)) - ) / ( - np.max(invec) - np.min(invec) - ) # lots of matrix operations - aux_mx[kk, jj] = wyn - return aux_mx - - -def dyn_pr_split_w(data, ygreki, K_gr, aux_mx): - # init - Q = np.zeros((K_gr,)) - N = len(data) - p_opt_idx = np.zeros((N,)) - p_aux = np.zeros((N,)) - opt_pals = np.zeros((K_gr, N)) - for kk in range(0, N): - p_opt_idx[kk] = my_qu_ix_w(data[kk:N], ygreki[kk:N]) - # iter - for kster in range(0, K_gr): - for kk in range(0, N - kster - 1): - for jj in range(kk + 1, N - kster): # deleted ",N-kster+1" - p_aux[jj] = aux_mx[kk, jj] + p_opt_idx[jj] - holder_p_aux = p_aux[kk + 1 : N - kster] # just for convenience purpose - mm = np.min(holder_p_aux) - ix = np.unravel_index( - holder_p_aux.argmin(), holder_p_aux.shape - ) # pos of min element - # ix -> tuple (892,) - p_opt_idx[kk] = mm - opt_pals[kster, kk] = kk + ix[0] + 1 - Q[kster] = p_opt_idx[0] - - # restore optimal decision - opt_part = np.zeros((K_gr,)) - opt_part[0] = opt_pals[K_gr - 1, 0] # it was just "Kgr, 0" - - K_iter = K_gr - 1 - for i in range(0, K_iter): - opt_part[i + 1] = opt_pals[K_iter - i - 1, int(opt_part[i])] - return Q, opt_part - - -def my_qu_ix_w(invec, yinwec): - PAR = 1 - PAR_sig_min = 0.1 - if (invec[-1] - invec[0]) <= PAR_sig_min or np.sum(yinwec) <= 1.0e-3: - wyn = np.inf - else: - wwec = yinwec / (np.sum(yinwec)) - wyn = (PAR + np.sqrt(np.sum(((invec - np.sum(invec * wwec)) ** 2) * wwec))) / ( - np.max(invec) - np.min(invec) - ) # lots of matrix operations - return wyn - - -def normal_pdf(x, mu, sigma): - return np.divide( - np.exp(-0.5 * np.power(np.divide(x - mu, sigma), 2)), 2.506628274631 * sigma - ) - - -def plot_bic(BIC, index, path_visualisation_name): - bic_arr = np.array(BIC) - # idx = np.unravel_index(bic_arr.argmin(), bic_arr.shape)[0] - fig, ax = plt.subplots(1, figsize=(10, 10)) - color = ["#56A8CBFF" for _ in range(len(BIC))] - color[index] = "#FF4F58FF" - sns.barplot([j for j in range(2, len(BIC) + 2)], BIC, palette=color, ax=ax) - fig.savefig(path_visualisation_name) - plt.close(fig) diff --git a/enrichment_auc/gmm/thresholds.py b/enrichment_auc/gmm/thresholds.py deleted file mode 100644 index 74428b9..0000000 --- a/enrichment_auc/gmm/thresholds.py +++ /dev/null @@ -1,187 +0,0 @@ -import numpy as np -import numpy_indexed as npi -from scipy import stats -from sklearn.cluster import KMeans -from sklearn.metrics import silhouette_score - - -def categorize_by_thresholds(score, thresholds): - group = np.zeros(score.shape[0]) - for i in range(score.shape[0]): - group[i] = (thresholds <= score[i]).sum() - return group - - -def correct_via_kmeans(distributions, thresholds): - if distributions["mu"].size <= 2 or thresholds.size != distributions["mu"].size - 1: - return thresholds - mu = distributions["mu"] - sig = distributions["sigma"] - alpha = distributions["weights"] - features = np.stack([mu, sig, alpha]).T - # scale the features - features = features - features.min(axis=0) - features = np.divide( - features, - features.max(axis=0), - out=np.zeros_like(features), - where=features.max(axis=0) != 0, - ) - best_sil = -1.1 - localizer = np.zeros(mu.size) - for k in range(2, mu.size - 1): - km = KMeans(k, n_init="auto") - labels = km.fit_predict(features) - sil = silhouette_score(features, labels) - if sil > best_sil: - best_sil = sil - localizer = labels - thresholds = _filter_thresholds(localizer, mu, thresholds) - return thresholds - - -def _filter_thresholds(localizer, mu, thresholds): - # sort the clusters to go in the correct order - _, group_min = npi.group_by(localizer).min(mu) - localizer = np.nonzero(localizer[:, None] == group_min.argsort())[1] - # check if neighbouring distributions are together - differences = np.diff(localizer) - if np.all(differences >= 0): - # perform the correction - thresholds = thresholds[np.where(differences)] - return thresholds - - -def _find_thr_by_params(distributions, x_temp, pdfs, sigma_dev=2.5): - tol = 1e-10 - thresholds = [] - thrs_from_dists = np.array([]) - for i in range(distributions["mu"].size - 1): - A = 1 / (2 * distributions["sigma"][i] ** 2) - 1 / ( - 2 * distributions["sigma"][i + 1] ** 2 - ) - B = distributions["mu"][i + 1] / ( - distributions["sigma"][i + 1] ** 2 - ) - distributions["mu"][i] / (distributions["sigma"][i] ** 2) - C = ( - distributions["mu"][i] ** 2 / (2 * distributions["sigma"][i] ** 2) - - distributions["mu"][i + 1] ** 2 / (2 * distributions["sigma"][i + 1] ** 2) - - np.log( - (distributions["weights"][i] * distributions["sigma"][i + 1]) - / (distributions["weights"][i + 1] * distributions["sigma"][i]) - ) - ) - if np.abs(A) < tol: - if np.abs(B) < tol: - print("the Gaussians are the same.") - else: - x1 = -C / B - thresholds.append(x1) - else: - delta = B**2 - 4 * A * C - if delta < 0: - if thrs_from_dists.size == 0: - thrs_from_dists = _find_thr_by_dist( - distributions, x_temp, pdfs, sigma_dev - ) - if np.isfinite(thrs_from_dists[i]): - thresholds.append(thrs_from_dists[i]) - pass - else: - x1 = (-B - np.sqrt(delta)) / (2 * A) - x2 = (-B + np.sqrt(delta)) / (2 * A) - if x1 > distributions["mu"][i] and x1 < distributions["mu"][i + 1]: - thresholds.append(x1) - elif x2 > distributions["mu"][i] and x2 < distributions["mu"][i + 1]: - thresholds.append(x2) - else: - d1 = np.min( - np.array( - [ - np.abs(x1 - distributions["mu"][i]), - np.abs(x1 - distributions["mu"][i + 1]), - ] - ) - ) - d2 = np.min( - np.array( - [ - np.abs(x2 - distributions["mu"][i]), - np.abs(x2 - distributions["mu"][i + 1]), - ] - ) - ) - if d1 < d2: - thresholds.append(x1) - else: - thresholds.append(x2) - return np.array(thresholds) - - -def _find_thr_by_dist(distributions, x_temp, pdfs, sigma_dev=2.5): - ranges = np.array( - [ - distributions["mu"][0] - sigma_dev * distributions["sigma"][0], - distributions["mu"][-1] + sigma_dev * distributions["sigma"][-1], - ] - ) - x_temp, pdfs = _restrict_thr_ranges(ranges, x_temp, pdfs) - # sum of all consecutive pdfs except for last one, summing from first - f1 = np.cumsum(pdfs, axis=0)[:-1, :] - # sum of all consecutive pdfs except for first one, but summing from last - f2 = np.cumsum(pdfs[::-1, :], axis=0)[::-1, :][1:, :] - to_discard = _detect_noncrossing(f1, f2) - thrs = _find_closest_location(f1, f2, x_temp) - thrs[to_discard] = np.nan - return thrs - - -def _find_closest_location(f1, f2, x_temp): - f_diff = np.abs(f1 - f2) - idx = np.argmin(f_diff, axis=1) - # x_temp from argmin - thrs = x_temp[idx] - return thrs - - -def _detect_noncrossing(f1, f2): - checks = np.sum(f2 > f1, axis=1) - idxs = np.where((checks == 0) | (checks == f1.shape[1])) - return idxs - - -def _restrict_thr_ranges(ranges, x_temp, pdfs): - to_keep = np.where((x_temp > ranges[0]) & (x_temp < ranges[1])) - x_temp = x_temp[to_keep] - x_temp = x_temp[1:-1] - pdfs = pdfs[:, to_keep].squeeze() - pdfs = pdfs[:, 1:-1] - return x_temp, pdfs - - -def find_pdfs(mu, sig, alpha, x_temp): - x_temp = x_temp.reshape( - x_temp.shape[0], -1 - ) # so that scipy can recast it together with distribution parameters - pdfs = ( - stats.norm.pdf(x_temp, mu, sig) * alpha - ) # calculate pdfs for all distributions - pdfs = pdfs.transpose() - return pdfs - - -def find_thresholds(distributions, scores, gs_name): - if distributions["mu"].size == 0: - return np.array([]) - x_temp = np.linspace(np.min(scores), np.max(scores), 10**6) - pdfs = find_pdfs( - distributions["mu"], distributions["sigma"], distributions["weights"], x_temp - ) - thresholds = _find_thr_by_params(distributions, x_temp, pdfs) - if thresholds.size != distributions["mu"].size - 1: - print( - "{}: {} thresholds found for {} distributions.".format( - gs_name, thresholds.size, distributions["mu"].size - ) - ) - return thresholds diff --git a/enrichment_auc/metrics/gsea.R b/enrichment_auc/metrics/gsea.R deleted file mode 100644 index b170947..0000000 --- a/enrichment_auc/metrics/gsea.R +++ /dev/null @@ -1,26 +0,0 @@ -if (!require("BiocManager", quietly = TRUE)) - install.packages("BiocManager", repos = "http://cran.us.r-project.org") -BiocManager::install(version = "3.18") -if (!require("GSVA", quietly = TRUE)) - BiocManager::install("GSVA") -if (!require("rjson", quietly = TRUE)) - install.packages("rjson", repos = "http://cran.us.r-project.org") - -library("rjson") -library("GSVA") - - -args <- commandArgs(trailingOnly=TRUE) -method <- args[1] -outpath <- args[2] -pathways <- fromJSON(file=paste(outpath, "tmp/genesets_genes.json", sep="")) -gene_expr <- read.csv(paste(outpath, "tmp/data.csv", sep=""), row.names=1, header=TRUE, check.names=FALSE) -res <- gene_expr -tryCatch( -{ - res <- gsva(as.matrix(gene_expr), pathways, method = method, kcdf = "Gaussian", mx.diff = F) -}, -error=function(e) { - conditionMessage(e) -}) -write.csv(as.data.frame(res), paste(outpath, "tmp/res.csv", sep="")) diff --git a/enrichment_auc/metrics/gsea.py b/enrichment_auc/metrics/gsea.py deleted file mode 100644 index 5c3e1ff..0000000 --- a/enrichment_auc/metrics/gsea.py +++ /dev/null @@ -1,37 +0,0 @@ -import json -import os -import shutil -import sys -import subprocess - -import pandas as pd - - -def _run_analysis(genesets, data, genes, method): - if not os.path.isdir("tmp"): - os.makedirs("tmp") - df = pd.DataFrame(data, index=genes) - df.to_csv("tmp/data.csv") - del df - with open("tmp/genesets_genes.json", "w") as fp: - json.dump(genesets, fp) - rscript = "enrichment_auc/metrics/gsea.R" - outpath = os.getcwd() + "/" - cmd = ["Rscript", rscript] + [x for x in [method, outpath]] - cmd = " ".join(cmd) - subprocess.call(cmd, shell=True) - res = pd.read_csv("tmp/res.csv", index_col=0, header=0) - shutil.rmtree("tmp") - return res.to_numpy() - - -def GSVA(genesets, data, genes): - method = "gsva" - gsea = _run_analysis(genesets, data, genes, method) - return gsea - - -def SSGSEA(genesets, data, genes): - method = "ssgsea" - gsea = _run_analysis(genesets, data, genes, method) - return gsea diff --git a/enrichment_auc/metrics/jasmine.py b/enrichment_auc/metrics/jasmine.py deleted file mode 100644 index 34789be..0000000 --- a/enrichment_auc/metrics/jasmine.py +++ /dev/null @@ -1,40 +0,0 @@ -import numpy as np -from tqdm import tqdm -from scipy.stats.mstats import rankdata - - -def dropout(data): - ma_data = np.ma.masked_equal(data, 0) - return ma_data - - -def rank_genes(masked_data): - ranks = np.zeros(masked_data.data.shape) - N = np.count_nonzero(masked_data.mask == 0, axis=0) - good_idx = np.where(N != 0) - ranks[:, good_idx] = rankdata(masked_data[:, good_idx], axis=0, use_missing=False) - ranks = np.ma.masked_array(ranks, masked_data.mask) - return ranks - - -def _jasmine(geneset, ranks, genes, gs_name=""): - genes_in_ds = [gene in geneset for gene in genes] - # find the number of nonzero genes for each cell - N = np.count_nonzero(ranks.mask == 0, axis=0) - jasmine = ranks[genes_in_ds, :].mean(axis=0) / N - return jasmine.filled(0) - - -def JASMINE(genesets, data, genes): - jasmine = np.empty((len(genesets), data.shape[1])) - masked_data = dropout(data) - ranks = rank_genes(masked_data) - for i, (gs_name, geneset_genes) in tqdm( - enumerate(genesets.items()), total=len(genesets) - ): - jasmine[i] = _jasmine(geneset_genes, ranks, genes, gs_name) - # standardize the results for each geneset - jasmine = (jasmine - jasmine.min(axis=1)[:, None]) / ( - jasmine.max(axis=1) - jasmine.min(axis=1) - )[:, None] - return jasmine diff --git a/enrichment_auc/metrics/vae.py b/enrichment_auc/metrics/vae.py deleted file mode 100644 index bc0eaf2..0000000 --- a/enrichment_auc/metrics/vae.py +++ /dev/null @@ -1,103 +0,0 @@ -import numpy as np -from sklearn.base import BaseEstimator, TransformerMixin -from tqdm import tqdm - -from enrichment_auc.metrics.vae_bn import VAE_BN -import enrichment_auc.metrics.mean as mean - - -class VAE(BaseEstimator, TransformerMixin): - def __init__( - self, - intermediate_dim=512, - latent_dim=5, - epochs=100, - normalize=True, - batch_size=128, - shuffle="batch", - learning_rate=1e-3, - learning_rate_schedule=None, - verbose="auto", - random_state=None, - ): - self.intermediate_dim = intermediate_dim - self.latent_dim = latent_dim - self.epochs = epochs - self.normalize = normalize - self.batch_size = batch_size - self.shuffle = shuffle - self.learning_rate = learning_rate - self.learning_rate_schedule = learning_rate_schedule - self.verbose = verbose - self.random_state = random_state - - def fit(self, X, y=None): - div = X.sum(axis=1, keepdims=True) - X = np.divide(X, div, out=np.zeros_like(X), where=div != 0) - vae_bn = VAE_BN( - nSpecFeatures=X.shape[1], - intermediate_dim=self.intermediate_dim, - latent_dim=self.latent_dim, - seed=self.random_state, - ) - self.vae_, self.encoder_ = vae_bn.get_architecture( - verbose=self.verbose, lr=self.learning_rate - ) - self.history_ = self.vae_.fit( - X, - verbose=self.verbose, - epochs=self.epochs, - batch_size=self.batch_size, - shuffle=self.shuffle, - ) - return self - - def transform(self, X, y=None): - div = X.sum(axis=1, keepdims=True) - X = np.divide(X, div, out=np.zeros_like(X), where=div != 0) - return self.encoder_.predict(X, verbose=self.verbose)[2] - - -def _vae_pas(geneset, data, genes, gs_name=""): - genes_in_ds = [gene in geneset for gene in genes] - in_gs = data[:, genes_in_ds] - if in_gs.shape[0] == 0 or in_gs.shape[1] == 0: - print("Incorrect geneset format:", gs_name) - return np.zeros(data.shape[0]) - # train small vae - return np.zeros(data.shape[0]) - - -def VAE_PAS(genesets, data, genes): - pas = np.empty((len(genesets), data.shape[1])) - # train main VAE - # transpose the result - data = data.T - # get the embedding as well - for i, (gs_name, geneset_genes) in tqdm( - enumerate(genesets.items()), total=len(genesets) - ): - pas[i] = _vae_pas(geneset_genes, data, genes, gs_name) - return pas - - -def find_most_enriched(genesets, data, genes): - res = mean.MEAN(genesets, data, genes) - most_enriched_idx = np.argmax(res, axis=1) - return most_enriched_idx - - -def correct_pas(pas, enriched_idx): - if pas[enriched_idx] >= np.mean(pas): - return pas - return pas * (-1) - - -def correct_order(data, genesets, genes, pas): - most_enriched_idx = find_most_enriched(genesets, data, genes) - for i, (gs_name, geneset_genes) in tqdm( - enumerate(genesets.items()), total=len(genesets) - ): - current_pas = pas[i, :] - pas[i, :] = correct_pas(current_pas, most_enriched_idx[i]) - return pas diff --git a/enrichment_auc/metrics/vae_bn.py b/enrichment_auc/metrics/vae_bn.py deleted file mode 100644 index d283df0..0000000 --- a/enrichment_auc/metrics/vae_bn.py +++ /dev/null @@ -1,110 +0,0 @@ -from keras import backend as K -from tensorflow.keras.initializers import GlorotUniform -from tensorflow.keras.layers import BatchNormalization, Dense, Input, Lambda, ReLU -from tensorflow.keras.losses import categorical_crossentropy -from tensorflow.keras.models import Model -from tensorflow.keras.optimizers.legacy import Adam - -# from tensorflow.keras.utils import plot_model -from tensorflow.random import set_seed - - -class VAE_BN(object): - def __init__(self, nSpecFeatures, intermediate_dim, latent_dim, seed): - self.nSpecFeatures = nSpecFeatures - self.intermediate_dim = intermediate_dim - self.latent_dim = latent_dim - self.seed = seed - - def sampling(self, args): - z_mean, z_log_var = args - batch = K.shape(z_mean)[0] - dim = K.int_shape(z_mean)[1] - epsilon = K.random_normal( - shape=(batch, dim), seed=self.seed - ) # random_normal (mean=0 and std=1) - return z_mean + K.exp(0.5 * z_log_var) * epsilon - - def get_architecture(self, verbose=False, lr=1e-3): - set_seed(self.seed) - # =========== 1. Encoder Model================ - input_shape = (self.nSpecFeatures,) - inputs = Input(shape=input_shape, name="encoder_input") - - try: - dims = tuple(self.intermediate_dim) - except TypeError: # not iterable - dims = (self.intermediate_dim,) - - h = inputs - - for dim in dims: - h = Dense(dim, kernel_initializer=GlorotUniform(seed=self.seed))(h) - h = BatchNormalization()(h) - h = ReLU()(h) - - z_mean = Dense( - self.latent_dim, - name="z_mean", - kernel_initializer=GlorotUniform(seed=self.seed), - )(h) - z_mean = BatchNormalization()(z_mean) - z_log_var = Dense( - self.latent_dim, - name="z_log_var", - kernel_initializer=GlorotUniform(seed=self.seed), - )(h) - z_log_var = BatchNormalization()(z_log_var) - - # Reparametrization Trick: - z = Lambda(self.sampling, output_shape=(self.latent_dim,), name="z")( - [z_mean, z_log_var] - ) - encoder = Model(inputs, [z_mean, z_log_var, z], name="encoder") - if verbose == "auto" or verbose > 1: - print("==== Encoder Architecture...") - encoder.summary() - # plot_model(encoder, to_file="VAE_BN_encoder.png", show_shapes=True) - - # =========== 2. Decoder Model================ - latent_inputs = Input(shape=(self.latent_dim,), name="Latent_Space") - - hdec = latent_inputs - - for dim in dims[::-1]: - hdec = Dense(dim, kernel_initializer=GlorotUniform(seed=self.seed))(hdec) - hdec = BatchNormalization()(hdec) - hdec = ReLU()(hdec) - - outputs = Dense( - self.nSpecFeatures, - activation="sigmoid", - kernel_initializer=GlorotUniform(seed=self.seed), - )(hdec) - decoder = Model(latent_inputs, outputs, name="decoder") - if verbose == "auto" or verbose > 1: - print("==== Decoder Architecture...") - decoder.summary() - # plot_model(decoder, to_file='VAE_BN__decoder.png', show_shapes=True) - - # =========== VAE_BN: Encoder_Decoder ================ - outputs = decoder(encoder(inputs)[2]) - VAE_BN_model = Model(inputs, outputs, name="VAE_BN") - - # ====== Cost Function (Variational Lower Bound) ============== - "KL-div (regularizes encoder) and reconstruction loss (of the decoder): see equation(3) in our paper" - # 1. KL-Divergence: - kl_Loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) - kl_Loss = K.sum(kl_Loss, axis=-1) - kl_Loss *= -0.5 - # 2. Reconstruction Loss - reconstruction_loss = categorical_crossentropy( - inputs, outputs - ) # Use sigmoid at output layer - reconstruction_loss *= self.nSpecFeatures - - # ========== Compile VAE_BN model =========== - model_Loss = K.mean(reconstruction_loss + kl_Loss) - VAE_BN_model.add_loss(model_Loss) - VAE_BN_model.compile(optimizer=Adam(learning_rate=lr)) - return VAE_BN_model, encoder diff --git a/enrichment_auc/plot/plot_boxplots.py b/enrichment_auc/plot/plot_boxplots.py deleted file mode 100644 index 03317d6..0000000 --- a/enrichment_auc/plot/plot_boxplots.py +++ /dev/null @@ -1,275 +0,0 @@ -import numpy as np -import plotly.express as px -import plotly.graph_objects as go -import plotly.subplots as sp -from scipy.stats import f_oneway, ttest_1samp, tukey_hsd - -plot_scorenames = { - "AUCell": "aucell", - "CERNO": "auc", - "JASMINE": "jasmine", - "DropRatio": "ratios", - "Mean": "mean", - "Vision": "vision", - "Vision abs": "vision_abs", - "z-score": "z", - "z-score abs": "z_abs", - "PLAGE": "svd", - "PLAGE abs": "svd_abs", - "SparsePCA": "sparse_pca", - "SparsePCA abs": "sparse_pca_abs", - "GSVA": "gsva", - "ssGSEA": "ssgsea", - "VAE": "vae", - "VAE corr": "vae_corr", -} - -palette = { - "AUCell": "#077187", - "CERNO": "#398D9F", - "JASMINE": "#6AAAB7", - "DropRatio": "#586BA4", - "Mean": "#F4A460", - "Vision": "#FFC125", - "Vision abs": "rgba(255,193,37,0.71)", - "z-score": "#FFD700", - "z-score abs": "rgba(255,215,0,0.71)", - "PLAGE": "#A54D69", - "PLAGE abs": "rgba(165,77,105,0.71)", - "SparsePCA": "#BC7A8F", - "SparsePCA abs": "rgba(188,122,143,0.71)", - "GSVA": "#228B22", - "ssGSEA": "#006400", - "VAE": "#000000", - "VAE corr": "#323232", -} - - -def check_differences(df, name): - pval = f_oneway( - *[list(df[name + sc_name]) for sc_name in list(plot_scorenames.values())] - ).pvalue - subtitle = "
ANOVA p-value : {}".format(np.round(pval, 3)) - pvals = np.ones( - (len(list(plot_scorenames.values())), len(list(plot_scorenames.values()))) - ) - if pval < 0.05: - pvals = tukey_hsd( - *[list(df[name + sc_name]) for sc_name in list(plot_scorenames.values())] - ).pvalue - if pval < 0.001: - subtitle = "
ANOVA p-value < 0.001" - return pvals, subtitle - - -def get_brackets(pvals): - dtype = [("start_idx", int), ("end_idx", int), ("dist", int), ("pvalue", "S10")] - brackets = np.empty(0, dtype=dtype) - for i in range(pvals.shape[0]): - for j in range(i + 1, pvals.shape[1]): - if pvals[i, j] <= 0.05: - text = str(np.round(pvals[i, j], 3)) - if pvals[i, j] < 0.001: - text = "<0.001" - bracket = (i, j, j - i, text) - bracket = np.array(bracket, dtype=dtype) - brackets = np.append(brackets, bracket) - brackets = np.sort(brackets, order=["dist", "start_idx"]) - return brackets - - -def add_brackets(brackets, fig): - lower = 1.0 - upper = 1.05 - for bracket in brackets: - i = bracket["start_idx"] - j = bracket["end_idx"] - x = ( - [list(plot_scorenames.keys())[i]] - + list(plot_scorenames.keys())[i:j] - + [list(plot_scorenames.keys())[j]] * 2 - ) - y = [lower] + [upper] * (j - i + 1) + [lower] - fig.add_trace( - go.Scatter( - x=x, - y=y, - fill=None, - mode="lines", - line=dict(color="rgba(0,0,0,1)", width=1), - showlegend=False, - ) - ) - fig.add_annotation( - text=str(bracket["pvalue"].decode("UTF-8")), - name="p-value", - x=(j + i) / 2, - y=upper + 0.04, - showarrow=False, - font=dict(size=10, color="black"), - ) - lower = lower + 0.1 - upper = upper + 0.1 - return fig - - -def add_heatmap(fig, pvals, subtitle): - fig1 = px.imshow( - pvals, - x=[k for k, v in plot_scorenames.items()], - y=[k for k, v in plot_scorenames.items()], - text_auto=".2f", - color_continuous_scale="RdBu", - ) - z_text = pvals.tolist() - z_text = [["{:.2f}".format(z) if z >= 0.01 else "<0.01" for z in z_list] for z_list in z_text] - fig1.update_traces( - dict(showscale=False, coloraxis=None, colorscale="RdBu", zmin=0, zmax=1), - selector={"type": "heatmap"}, - ) - fig1.update_traces(text=z_text, texttemplate="%{text}") - - fig_final = sp.make_subplots( - rows=2, cols=1, subplot_titles=(subtitle, "Tukey HSD p-values") - ) - for i, figure in enumerate([fig, fig1]): - for trace in range(len(figure["data"])): - fig_final.append_trace(figure["data"][trace], row=i + 1, col=1) - fig_final.update_layout(height=1200, width=800) - return fig_final - - -def mark_different_boxes(fig, pvals, celltype, subtitle): - if np.sum(pvals <= 0.05) >= 10: - fig_final = add_heatmap(fig, pvals, subtitle) - else: - brackets = get_brackets(pvals) - fig_final = add_brackets(brackets, fig) - celltype = celltype + subtitle - fig_final.update_layout(template="plotly_white", title=celltype) - return fig_final - - -def visualize_methods(df, cell_types, namescores, plot_folder): - for celltype in cell_types: - for name in namescores: - vis = df.loc[df["Celltype"].isin([celltype]), df.columns.str.contains(name)] - pvals, subtitle = check_differences(vis, name) - vis.columns = vis.columns.str.replace(name, "") - vis = vis.melt() - vis = vis.rename(columns={"variable": "method"}) - vis["method"] = vis["method"].map( - {v: k for k, v in plot_scorenames.items()} - ) - fig = px.box( - vis, - x="method", - y="value", - color="method", - color_discrete_map=palette, - title=celltype + subtitle, - template="plotly_white", - labels={"method": "PAS method", "value": name[:-1].replace("_", " ")}, - category_orders={"method": list(plot_scorenames.keys())}, - height=600, - width=750, - ) - fig = mark_different_boxes(fig, pvals, celltype, subtitle) - fig.update_xaxes(tickangle=45) - fig.write_image( - plot_folder + celltype.replace(" ", "_") + "_" + name[:-1] + ".png" - ) - for name in namescores: - vis = df.loc[:,df.columns.str.contains(name)] - pvals, subtitle = check_differences(vis, name) - vis.columns = vis.columns.str.replace(name, "") - vis = vis.melt() - vis = vis.rename(columns={"variable": "method"}) - vis["method"] = vis["method"].map( - {v: k for k, v in plot_scorenames.items()} - ) - fig = px.box( - vis, - x="method", - y="value", - color="method", - color_discrete_map=palette, - title="merged" + subtitle, - template="plotly_white", - labels={"method": "PAS method", "value": name[:-1].replace("_", " ")}, - category_orders={"method": list(plot_scorenames.keys())}, - height=600, - width=750, - ) - fig = mark_different_boxes(fig, pvals, "merged", subtitle) - fig.update_xaxes(tickangle=45) - fig.write_image( - plot_folder + "merged_" + name[:-1] + ".png" - ) - - -def visualize_difference(df1, df2, namescores, plot_folder, name1, name2): - df = df1.subtract(df2) - for name in namescores: - vis = df.loc[:, df.columns.str.contains(name)] - vis.columns = vis.columns.str.replace(name, "") - vis = vis.melt() - vis = vis.rename(columns={"variable": "method"}) - vis["method"] = vis["method"].map({v: k for k, v in plot_scorenames.items()}) - fig = px.box( - vis, - x="method", - y="value", - color="method", - color_discrete_map=palette, - title=name[:-1].replace("_", " "), - template="plotly_white", - labels={ - "method": "PAS method", - "value": "Difference [{} - {}]".format(name1, name2), - }, - category_orders={"method": list(plot_scorenames.keys())}, - height=600, - width=750, - ) - fig.add_hline(y=0.0, line=dict(dash="dash", color="firebrick", width=1)) - fig.update_xaxes(tickangle=45) - for score in list(plot_scorenames.keys()): - vals = vis.loc[vis["method"] == score] - pval = ttest_1samp(vals["value"], 0.0).pvalue - if pval < 0.05: - text = str(np.round(pval, 3)) - if pval < 0.001: - text = "<0.001" - y = vals["value"].min() - 0.05 - if vals["value"].mean() > 0: - y = vals["value"].max() + 0.05 - fig.add_annotation( - text=text, - name="p-value", - x=score, - y=y, - showarrow=False, - font=dict(size=10, color="red"), - ) - if name[:-1] == "FDR": - name1, name2 = name2, name1 - fig.add_annotation( - text="Better {}".format(name1), - name="p-value", - x=0.5, - y=vis["value"].max() + 0.15, - xref="paper", - showarrow=False, - font=dict(size=12, color="black"), - ) - fig.add_annotation( - text="Better {}".format(name2), - name="p-value", - x=0.5, - y=vis["value"].min() - 0.15, - xref="paper", - showarrow=False, - font=dict(size=12, color="black"), - ) - fig.write_image(plot_folder + "difference_" + name[:-1] + ".png") diff --git a/enrichment_auc/plot/plot_distributed_data.py b/enrichment_auc/plot/plot_distributed_data.py deleted file mode 100644 index 0a519c9..0000000 --- a/enrichment_auc/plot/plot_distributed_data.py +++ /dev/null @@ -1,76 +0,0 @@ -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -import scipy.stats as stats -import seaborn as sns - -from enrichment_auc.gmm.thresholds import categorize_by_thresholds - -from .legend_handler import move_legend - - -def plot_mixtures( - geneset_name, - distributions, - score, - thr, - thrs, - name, - save_dir="plots", - file_only=True, -): - comp_colors_density = "#808080" - comp_colors = {"Non significant": "#0C5AA6", "Significant": "#FF9700"} - label_meaning = ["Non significant", "Significant"] - f, ax = plt.subplots(figsize=(7, 5)) - # get binary labels - binary_labels = (score > thr).astype(int) - ns_count = len(binary_labels) - sum(binary_labels) - s_count = sum(binary_labels) - binary_labels = [label_meaning[label] for label in binary_labels.tolist()] - df = pd.DataFrame([score, binary_labels]).T - df.columns = ["score", "labels"] - # label plot - plt.ylabel("Frequency") - plt.xlabel(name) - plt.title(geneset_name, fontsize=18) - # add binary rugplot - _ = sns.rugplot( - df, x="score", height=-0.02, clip_on=False, hue="labels", palette=comp_colors - ) - # show density plot and histogram - try: - _ = sns.histplot(score, color="#B0B0B0", alpha=0.25, kde=False, stat="density") - except (ValueError, np.core._exceptions._ArrayMemoryError, OverflowError): - sns.histplot( - x=score, - element="step", - bins="sturges", - color="#B0B0B0", - alpha=0.25, - kde=False, - stat="density", - ) - # _ = sns.kdeplot(score, linewidth=2, color='k') - move_legend(ax, "upper right", [ns_count, s_count]) - # add the distributions - for i in range(distributions["mu"].shape[0]): - mu = distributions["mu"][i] - sigma = distributions["sigma"][i] - x = np.linspace(mu - 3 * sigma, mu + 3 * sigma, 100) - vals = stats.norm.pdf(x, mu, sigma) * distributions["weights"][i] - plt.plot(x, vals, linestyle="dashed", color=comp_colors_density) - # add the rest of thresholds - rugplot - if thrs.shape[0] > 1: - labels = categorize_by_thresholds(score, thrs) - df = pd.DataFrame([score, labels]).T - df.columns = ["score", "labels"] - _ = sns.rugplot(df, x="score", clip_on=False, hue="labels", legend=False) - # finishing touches - ax.set_ylim(bottom=0) - f.set_facecolor("w") - geneset_name = geneset_name.replace("/", "_") - geneset_name = geneset_name.replace(":", "_") - plt.savefig(save_dir + "/dens_" + geneset_name + "_" + name + ".png") - if file_only: - plt.close() diff --git a/enrichment_auc/plot/plot_scatter_flow.py b/enrichment_auc/plot/plot_scatter_flow.py deleted file mode 100644 index b51b626..0000000 --- a/enrichment_auc/plot/plot_scatter_flow.py +++ /dev/null @@ -1,84 +0,0 @@ -import numpy as np -import plotly.express as px -from plotly.subplots import make_subplots -import plotly.graph_objects as go - -from enrichment_auc.gmm.thresholds import categorize_by_thresholds - - -def clean_up_layout(fig, gs_name, labels_len, embed_name): - fig.update_layout( - height=1200, - width=1000, - template="plotly_white", - title_text="Visualizations for {}".format(gs_name), - legend_tracegroupgap=600 - (labels_len + 1) * 10, - legend=dict(yanchor="top", y=1.0), - ) - x_range = fig.full_figure_for_development(warn=False).layout.xaxis.range - y_range = fig.full_figure_for_development(warn=False).layout.yaxis.range - for i in range(1, 4): - fig.update_yaxes( - title_text="{} 2".format(embed_name), range=y_range, row=i, col=1 - ) - fig.update_xaxes(title_text="{} 1".format(embed_name), range=x_range, row=3, col=1) - return fig - - -def prepare_subplot(fig, embed, labels, subplot_name, row): - palette = px.colors.qualitative.Bold - if np.unique(labels).shape[0] > 11: - palette = px.colors.qualitative.Light24 - for i, label in enumerate(np.unique(labels)): - cell_idx = np.where(labels == label)[0] - fig.add_trace( - go.Scatter( - x=embed[cell_idx, 0], - y=embed[cell_idx, 1], - name=str(label), - marker=dict(color=palette[i]), - legendgroup=subplot_name, - legendgrouptitle_text=subplot_name, - mode="markers", - ), - row=row, - col=1, - ) - - fig.update_layout(legend=dict(groupclick="toggleitem")) - return fig - - -def plot_flow( - embed, pas, thrs, labels, name, gs_name="", embed_name="", save_dir="plots/" -): - fig = make_subplots( - rows=3, cols=1, shared_xaxes=True, shared_yaxes=True, vertical_spacing=0.02 - ) - - fig = prepare_subplot(fig, embed, labels, "Original", 1) - - fig.add_trace( - go.Scatter( - x=embed[:, 0], - y=embed[:, 1], - showlegend=False, - legendgroup="flow", - name=name, - marker=dict( - color=pas, colorbar=dict(title=name, len=0.25), colorscale="teal" - ), - mode="markers", - ), - row=2, - col=1, - ) - - preds_bin = categorize_by_thresholds(pas, thrs).astype(int) - fig = prepare_subplot(fig, embed, preds_bin, "Clustered", 3) - - labels_len = np.unique(labels).shape[0] - fig = clean_up_layout(fig, gs_name, labels_len, embed_name) - gs_name = gs_name.replace("/", "_") - gs_name = gs_name.replace(":", "_") - fig.write_html(save_dir + "scatter_{}_{}.html".format(gs_name, name)) diff --git a/enrichment_auc/preprocess/filter.py b/enrichment_auc/preprocess/filter.py deleted file mode 100644 index 55ac99e..0000000 --- a/enrichment_auc/preprocess/filter.py +++ /dev/null @@ -1,28 +0,0 @@ -import sys - -import numpy as np -import pandas as pd - - -def filter(cells, leave_best=0.25): - # input: cells - pd df of gene expressions - # leave_best - the percentage of genes to leave after filtering - # output: cells - pd df of filtered gene expressions - leave_best = max(0, min(leave_best, 1)) - cells.dropna(inplace=True) - vars = np.var(cells, axis=1) - vars = vars[vars != 0] - vars = vars.sort_values() - cells = cells.loc[vars[int((1 - leave_best) * vars.shape[0]) :].index] - return cells - - -if __name__ == "__main__": - folder = sys.argv[1] - datatype = sys.argv[2] - path = sys.argv[3] - infile = path + folder + "/" + datatype + "_data.csv" - outfile = path + folder + "/" + datatype + "_filtered_data.csv" - cells = pd.read_csv(infile, index_col=0) - cells = filter(cells) - cells.to_csv(outfile) diff --git a/notebooks/datasets_characteristics.ipynb b/notebooks/datasets_characteristics.ipynb deleted file mode 100644 index b4bfea6..0000000 --- a/notebooks/datasets_characteristics.ipynb +++ /dev/null @@ -1,194 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "e284a22c-ce71-44ef-b886-6d046a2c74d4", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import os\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "4bb5ddac-fa57-4b56-8cc6-08fe8f8220f6", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "path = os.getcwd().replace('notebooks', '')" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "f32ade0f-dabf-4c5e-83f3-057a3294cf2f", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "tissue = \"Liver\"\n", - "norm = \"seurat\"\n", - "datafolder = path + \"data/\" + tissue + \"/\"" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "ef58b4ee-644e-460d-9071-a6cbb6c41720", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "CellType\n", - "T cell 7676\n", - "endothelial cell of hepatic sinusoid 2285\n", - "macrophage 1625\n", - "natural killer cell 919\n", - "hepatocyte 746\n", - "Kupffer cell 619\n", - "B cell 405\n", - "cholangiocyte 292\n", - "plasma cell 162\n", - "cycling cell 57\n", - "endothelial cell of vascular tree 39\n", - "hematopoietic stem cell 27\n", - "Name: count, dtype: int64" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "labels = pd.read_csv(datafolder + \"true_labels.csv\", index_col=0)\n", - "labels['CellType'].value_counts()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "bcd9696d-2c03-4a96-9193-6d3ea9b6435f", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "t_cells = [\"CD4+ T cell\", \"Cytotoxic T cell\"]\n", - "nk_cells = [\"Natural killer cell\", \"natural killer cell\"]\n", - "b_cells = [\"mature B cell\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "e6c84556-aabc-4fc1-b4fd-d3e5d3537898", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "CellType\n", - "T cell 7676\n", - "endothelial cell of hepatic sinusoid 2285\n", - "macrophage 1625\n", - "NK cell 919\n", - "hepatocyte 746\n", - "Kupffer cell 619\n", - "B cell 405\n", - "cholangiocyte 292\n", - "plasma cell 162\n", - "cycling cell 57\n", - "endothelial cell of vascular tree 39\n", - "hematopoietic stem cell 27\n", - "Name: count, dtype: int64" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "labels.loc[labels[\"CellType\"].isin(t_cells), \"CellType\"] = \"T cell\"\n", - "labels.loc[labels[\"CellType\"].isin(nk_cells), \"CellType\"] = \"NK cell\"\n", - "labels.loc[labels[\"CellType\"].isin(b_cells), \"CellType\"] = \"B cell\"\n", - "labels['CellType'].value_counts()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "5865e614-3e00-4b4b-ba01-c0c88053ef89", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "CellType\n", - "T cell 7676\n", - "other 5852\n", - "NK cell 919\n", - "B cell 405\n", - "Name: count, dtype: int64" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "labels.loc[~labels[\"CellType\"].isin(\n", - " [\"NK cell\", \"T cell\", \"B cell\"])\n", - " , \"CellType\"] = \"other\"\n", - "labels['CellType'].value_counts()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "02c60e64-88f1-4c9d-b37c-42501693d46d", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "enrich", - "language": "python", - "name": "enrich" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/filter_dataset.ipynb b/notebooks/filter_dataset.ipynb deleted file mode 100644 index 65a634f..0000000 --- a/notebooks/filter_dataset.ipynb +++ /dev/null @@ -1,1269 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f2cab688", - "metadata": {}, - "source": [ - "## PBMC" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "94daff48-7e02-4963-a46b-67d003ffc2cb", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from divik._matlab_legacy import find_thresholds\n", - "import matplotlib.pyplot as plt\n", - "import seaborn as sns" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "8eaf6627-fc0c-4c29-aac8-e9166498cf31", - "metadata": {}, - "outputs": [], - "source": [ - "data = pd.read_csv(\"data.csv\", index_col=0)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "17f4e03c-690d-48d7-8248-b8f38d24d377", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(33694, 3222)" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "af378a0a-52b4-43ea-b2d7-4216498b8202", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data.columns[data.isna().any()].tolist()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "8090a1e8-544e-4fbf-82ab-50e254a273ae", - "metadata": {}, - "outputs": [], - "source": [ - "x = np.count_nonzero(data, axis=1)\n", - "x = np.log(x+np.full(x.shape,1))" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "2d970452-5c4b-4626-8e9b-bc960f649752", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/opt/conda/lib/python3.8/site-packages/seaborn/distributions.py:2619: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).\n", - " warnings.warn(msg, FutureWarning)\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbkAAAEvCAYAAADYa792AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAkuUlEQVR4nO3daXBc13nm8f/bG/YdIEEC4CouohZaEkTZcWIplu1Qjm1NJk6NJDsua6IwmtiZOLNZk5qyZypTM5NxJltZtsJSFMVxbMWLYssObUWyYsu2rIXaaJEgJYobQIIkAGIjdnS/86EbJAiBQBPoiwYvnl9VV6PvPX37ZReJh+fcc881d0dERCSMIvkuQEREJCgKORERCS2FnIiIhJZCTkREQkshJyIioaWQExGR0Irlu4BLVVtb62vWrMl3GSIisoi8+OKLne5eN3X7ZRdya9asYffu3fkuQ0REFhEzOzrddg1XiohIaCnkREQktBRyIiISWgo5EREJLYWciIiElkJORERCSyEnIiKhpZATEZHQUsiJiEhoKeRERCS0FHIiIhJal93alZe7rzx3bMb9d920aoEqEREJP/XkREQktBRyIiISWgo5EREJLYWciIiEVmAhZ2YPmdlpM3tthja3mNkrZrbXzH4UVC0iIrI0BdmTexjYfrGdZlYJfAH4kLtfBfxGgLWIiMgSFFjIufvTwJkZmtwFPOruxzLtTwdVi4iILE35PCe3Eagysx+a2Ytm9rE81iIiIiGUz4vBY8ANwK1AEfAzM3vW3V+f2tDMdgA7AFat0sXSIiKSnXz25NqA77v7gLt3Ak8DW6dr6O473b3Z3Zvr6uoWtEgREbl85TPkvg38kpnFzKwYuAloyWM9IiISMoENV5rZV4FbgFozawM+C8QB3P0Bd28xs+8De4AU8KC7X/RyAxERkUsVWMi5+51ZtPkc8LmgahARkaVNK56IiEhoKeRERCS0FHIiIhJaCjkREQkthZyIiISWQk5EREJLISciIqGlkBMRkdBSyImISGgp5EREJLQUciIiEloKORERCS2FnIiIhJZCTkREQkshJyIioaWQExGR0FLIiYhIaCnkREQktBRyIiISWgo5EREJLYWciIiElkJORERCK7CQM7OHzOy0mb02S7sbzSxpZh8OqhYREVmaguzJPQxsn6mBmUWBPwYeD7AOERFZogIL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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(7,5))\n", - "sns.distplot(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "6d6c966d-fe68-4fc0-b953-d58bcdbb0eed", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([4.99209389e-03, 7.02826950e-01, 1.11058349e+00, 1.39961916e+00,\n", - " 1.62376517e+00, 1.80585203e+00, 2.38739252e+00, 3.27126684e+00,\n", - " 7.89715933e+00])" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "find_thresholds(x, max_components=10)" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "a77fcb16-bb88-45c0-8a10-5e1c5c9950c9", - "metadata": {}, - "outputs": [], - "source": [ - "thr = 1.6" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "42172aff-ff8f-42c2-8b62-9ed030278a00", - "metadata": {}, - "outputs": [], - "source": [ - "is_in_filtered = x > thr" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "1cda7cfc-8ae1-40ec-b3a4-5eb9bad361a2", - "metadata": {}, - "outputs": [], - "source": [ - "filtered = data[is_in_filtered]" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "7e79e465-0d64-49d8-9c2d-8ff6f425a471", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(15821, 3222)" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "filtered.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "2aca90e1-2f77-4b99-84be-d7958c209a26", - "metadata": {}, - "outputs": [], - "source": [ - "filtered = pd.DataFrame(filtered)\n", - "filtered.to_csv(\"filtered_pbmc.csv\")" - ] - }, - { - "cell_type": "markdown", - "id": "87f4848b", - "metadata": {}, - "source": [ - "## Data preprocessing" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "0a388c2e", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "import seaborn as sns" - ] - }, - { - "cell_type": "code", - "execution_count": 188, - "id": "5e5af8d1", - "metadata": {}, - "outputs": [], - "source": [ - "datatype = \"seurat\"\n", - "# datatype = \"row\"" - ] - }, - { - "cell_type": "markdown", - "id": "18eec102", - "metadata": {}, - "source": [ - "### Liver & breast cancer" - ] - }, - { - "cell_type": "code", - "execution_count": 189, - "id": "ccb18bc7", - "metadata": {}, - "outputs": [], - "source": [ - "folder = \"Liver\"\n", - "# folder = \"BreastCancer\"" - ] - }, - { - "cell_type": "code", - "execution_count": 190, - "id": "565f8826", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
external_gene_name
genes
ENSG00000000003TSPAN6
ENSG00000000005TNMD
ENSG00000000419DPM1
ENSG00000000457SCYL3
ENSG00000000460C1orf112
\n", - "
" - ], - "text/plain": [ - " external_gene_name\n", - "genes \n", - "ENSG00000000003 TSPAN6\n", - "ENSG00000000005 TNMD\n", - "ENSG00000000419 DPM1\n", - "ENSG00000000457 SCYL3\n", - "ENSG00000000460 C1orf112" - ] - }, - "execution_count": 190, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "genes = pd.read_csv(\"data/\"+folder+\"/genes.csv\", usecols=[\"genes\", \"external_gene_name\"], index_col=\"genes\")\n", - "genes.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 191, - "id": "60357c73", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "62" - ] - }, - "execution_count": 191, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "genes.isnull().values.sum()" - ] - }, - { - "cell_type": "code", - "execution_count": 192, - "id": "7e14fae0", - "metadata": {}, - "outputs": [], - "source": [ - "genes.dropna(inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 193, - "id": "8d63db31", - "metadata": {}, - "outputs": [], - "source": [ - "v = genes[genes.duplicated('external_gene_name', keep=False)].index.tolist()" - ] - }, - { - "cell_type": "code", - "execution_count": 194, - "id": "ce4a6890", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
external_gene_name
genes
ENSG00000188626GOLGA8M
ENSG00000278186GOLGA8M
\n", - "
" - ], - "text/plain": [ - " external_gene_name\n", - "genes \n", - "ENSG00000188626 GOLGA8M\n", - "ENSG00000278186 GOLGA8M" - ] - }, - "execution_count": 194, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "genes[genes.duplicated('external_gene_name', keep=False)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0a3b11d1", - "metadata": {}, - "outputs": [], - "source": [ - "cells = pd.read_csv(\"data/\"+folder+\"/\"+ datatype+\"_data.csv\", index_col=0)\n", - "cells.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 196, - "id": "3153f0e2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['GOLGA8M'], dtype=object)" - ] - }, - "execution_count": 196, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pd.unique(genes[genes.duplicated('external_gene_name',\n", - "keep=False)].external_gene_name)" - ] - }, - { - "cell_type": "code", - "execution_count": 197, - "id": "11e2313d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['GOLGA8M'], dtype=object)" - ] - }, - "execution_count": 197, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pd.unique(genes[genes.duplicated('external_gene_name',\n", - "keep=False)][\"external_gene_name\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 158, - "id": "cc2a5970", - "metadata": {}, - "outputs": [], - "source": [ - "duplicates = pd.unique(genes[genes.duplicated('external_gene_name',\n", - "keep=False)].external_gene_name)\n", - "duplicated_rows = genes[genes.duplicated('external_gene_name', keep=False)]\n", - "for name in duplicates:\n", - " id = genes[genes[\"external_gene_name\"]==name].index\n", - " to_stay = cells.loc[id].var(axis=1).idxmax()\n", - " duplicated_rows = duplicated_rows.drop(index=to_stay)\n", - "genes = genes.drop(index=duplicated_rows.index)" - ] - }, - { - "cell_type": "code", - "execution_count": 159, - "id": "4fef3242", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(15587, 1)" - ] - }, - "execution_count": 159, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "genes.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 160, - "id": "2016fea2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(15587, 14853)" - ] - }, - "execution_count": 160, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "new_cells = pd.concat([cells, genes], join=\"inner\", axis=1)\n", - "new_cells.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 161, - "id": "98ccc3dd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
SAMEA11294524-AAACCTGAGTCTCCTCSAMEA11294524-AAACCTGCAATGTAAGSAMEA11294524-AAACCTGCACCGATATSAMEA11294524-AAACCTGCAGTCAGAGSAMEA11294524-AAACCTGGTATCAGTCSAMEA11294524-AAACCTGGTCAATGTCSAMEA11294524-AAACCTGGTTCCACTCSAMEA11294524-AAACCTGTCCGTACAASAMEA11294524-AAACCTGTCGGACAAGSAMEA11294524-AAACCTGTCTTTAGGG...SAMEA11294531-TTTGCGCTCCAGAGGASAMEA11294531-TTTGCGCTCTGTCCGTSAMEA11294531-TTTGGTTAGCCCAGCTSAMEA11294531-TTTGGTTAGTCTCAACSAMEA11294531-TTTGGTTCAAGGTTTCSAMEA11294531-TTTGGTTCAATAACGASAMEA11294531-TTTGGTTCACGGTTTASAMEA11294531-TTTGGTTTCCAAATGCSAMEA11294531-TTTGTCAAGATCTGCTSAMEA11294531-TTTGTCAAGCTAGTCT
TSPAN61.0530260.0000000.0000000.0000000.00.0000000.00.00.0000000.0...0.00.00.00.00.00.0000000.00.00.0000000.0
TNMD0.0000000.0000000.0000000.0000000.00.0000000.00.00.0000000.0...0.00.00.00.00.00.0000000.00.00.0000000.0
DPM10.0000000.4912651.0143711.2379050.00.6365580.00.01.9866450.0...0.00.00.00.00.00.3314610.00.01.0712140.0
SCYL30.0000000.0000000.0000000.0000000.00.0000000.00.00.0000000.0...0.00.00.00.00.00.0000000.00.00.0000000.0
C1orf1120.0000000.0000000.0000000.0000000.00.0000000.00.00.0000000.0...0.00.00.00.00.00.0000000.00.00.0000000.0
\n", - "

5 rows × 14852 columns

\n", - "
" - ], - "text/plain": [ - " SAMEA11294524-AAACCTGAGTCTCCTC SAMEA11294524-AAACCTGCAATGTAAG \n", - "TSPAN6 1.053026 0.000000 \\\n", - "TNMD 0.000000 0.000000 \n", - "DPM1 0.000000 0.491265 \n", - "SCYL3 0.000000 0.000000 \n", - "C1orf112 0.000000 0.000000 \n", - "\n", - " SAMEA11294524-AAACCTGCACCGATAT SAMEA11294524-AAACCTGCAGTCAGAG \n", - "TSPAN6 0.000000 0.000000 \\\n", - "TNMD 0.000000 0.000000 \n", - "DPM1 1.014371 1.237905 \n", - "SCYL3 0.000000 0.000000 \n", - "C1orf112 0.000000 0.000000 \n", - "\n", - " SAMEA11294524-AAACCTGGTATCAGTC SAMEA11294524-AAACCTGGTCAATGTC \n", - "TSPAN6 0.0 0.000000 \\\n", - "TNMD 0.0 0.000000 \n", - "DPM1 0.0 0.636558 \n", - "SCYL3 0.0 0.000000 \n", - "C1orf112 0.0 0.000000 \n", - "\n", - " SAMEA11294524-AAACCTGGTTCCACTC SAMEA11294524-AAACCTGTCCGTACAA \n", - "TSPAN6 0.0 0.0 \\\n", - "TNMD 0.0 0.0 \n", - "DPM1 0.0 0.0 \n", - "SCYL3 0.0 0.0 \n", - "C1orf112 0.0 0.0 \n", - "\n", - " SAMEA11294524-AAACCTGTCGGACAAG SAMEA11294524-AAACCTGTCTTTAGGG ... \n", - "TSPAN6 0.000000 0.0 ... \\\n", - "TNMD 0.000000 0.0 ... \n", - "DPM1 1.986645 0.0 ... \n", - "SCYL3 0.000000 0.0 ... \n", - "C1orf112 0.000000 0.0 ... \n", - "\n", - " SAMEA11294531-TTTGCGCTCCAGAGGA SAMEA11294531-TTTGCGCTCTGTCCGT \n", - "TSPAN6 0.0 0.0 \\\n", - "TNMD 0.0 0.0 \n", - "DPM1 0.0 0.0 \n", - "SCYL3 0.0 0.0 \n", - "C1orf112 0.0 0.0 \n", - "\n", - " SAMEA11294531-TTTGGTTAGCCCAGCT SAMEA11294531-TTTGGTTAGTCTCAAC \n", - "TSPAN6 0.0 0.0 \\\n", - "TNMD 0.0 0.0 \n", - "DPM1 0.0 0.0 \n", - "SCYL3 0.0 0.0 \n", - "C1orf112 0.0 0.0 \n", - "\n", - " SAMEA11294531-TTTGGTTCAAGGTTTC SAMEA11294531-TTTGGTTCAATAACGA \n", - "TSPAN6 0.0 0.000000 \\\n", - "TNMD 0.0 0.000000 \n", - "DPM1 0.0 0.331461 \n", - "SCYL3 0.0 0.000000 \n", - "C1orf112 0.0 0.000000 \n", - "\n", - " SAMEA11294531-TTTGGTTCACGGTTTA SAMEA11294531-TTTGGTTTCCAAATGC \n", - "TSPAN6 0.0 0.0 \\\n", - "TNMD 0.0 0.0 \n", - "DPM1 0.0 0.0 \n", - "SCYL3 0.0 0.0 \n", - "C1orf112 0.0 0.0 \n", - "\n", - " SAMEA11294531-TTTGTCAAGATCTGCT SAMEA11294531-TTTGTCAAGCTAGTCT \n", - "TSPAN6 0.000000 0.0 \n", - "TNMD 0.000000 0.0 \n", - "DPM1 1.071214 0.0 \n", - "SCYL3 0.000000 0.0 \n", - "C1orf112 0.000000 0.0 \n", - "\n", - "[5 rows x 14852 columns]" - ] - }, - "execution_count": 161, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "new_cells = new_cells.set_index(\"external_gene_name\")\n", - "new_cells.index.name = None\n", - "new_cells.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 162, - "id": "5cd9e0fd", - "metadata": {}, - "outputs": [], - "source": [ - "new_cells.to_csv(\"data/\"+folder+\"/\"+ datatype+\"_data.csv\")" - ] - }, - { - "cell_type": "markdown", - "id": "e71edbaf", - "metadata": {}, - "source": [ - "### Others" - ] - }, - { - "cell_type": "code", - "execution_count": 93, - "id": "1d2a1742", - "metadata": {}, - "outputs": [], - "source": [ - "# folder = \"Pancreas\"\n", - "# folder = \"BM\"\n", - "# folder = \"COVID\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "41dd29ee", - "metadata": {}, - "outputs": [], - "source": [ - "cells = pd.read_csv(\"data/\"+folder+\"/\"+ datatype+\"_data.csv\", index_col=0)\n", - "cells.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 174, - "id": "69f1cb07", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(15587, 14852)" - ] - }, - "execution_count": 174, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cells.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 175, - "id": "ca30ff73", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(15587, 14852)\n" - ] - } - ], - "source": [ - "cells.dropna(inplace=True)\n", - "print(cells.shape)" - ] - }, - { - "cell_type": "code", - "execution_count": 176, - "id": "0050007a", - "metadata": {}, - "outputs": [], - "source": [ - "vars = np.var(cells, axis=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 177, - "id": "49400769", - "metadata": {}, - "outputs": [], - "source": [ - "vars = vars[vars != 0]" - ] - }, - { - "cell_type": "code", - "execution_count": 178, - "id": "34ec2537", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(15573,)" - ] - }, - "execution_count": 178, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vars.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 182, - "id": "9b357f25", - "metadata": {}, - "outputs": [], - "source": [ - "cells = cells.loc[vars.sort_values()[int(0.75 * vars.shape[0]) :].index]" - ] - }, - { - "cell_type": "code", - "execution_count": 183, - "id": "4b0b9662", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(3894, 14852)" - ] - }, - "execution_count": 183, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cells.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 186, - "id": "e764e282", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
SAMEA11294524-AAACCTGAGTCTCCTCSAMEA11294524-AAACCTGCAATGTAAGSAMEA11294524-AAACCTGCACCGATATSAMEA11294524-AAACCTGCAGTCAGAGSAMEA11294524-AAACCTGGTATCAGTCSAMEA11294524-AAACCTGGTCAATGTCSAMEA11294524-AAACCTGGTTCCACTCSAMEA11294524-AAACCTGTCCGTACAASAMEA11294524-AAACCTGTCGGACAAGSAMEA11294524-AAACCTGTCTTTAGGG...SAMEA11294531-TTTGCGCTCCAGAGGASAMEA11294531-TTTGCGCTCTGTCCGTSAMEA11294531-TTTGGTTAGCCCAGCTSAMEA11294531-TTTGGTTAGTCTCAACSAMEA11294531-TTTGGTTCAAGGTTTCSAMEA11294531-TTTGGTTCAATAACGASAMEA11294531-TTTGGTTCACGGTTTASAMEA11294531-TTTGGTTTCCAAATGCSAMEA11294531-TTTGTCAAGATCTGCTSAMEA11294531-TTTGTCAAGCTAGTCT
CD400.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
NFAT50.00.00.01.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.01.00.0
CNR20.02.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.01.50.0
YPEL10.00.00.00.00.00.00.00.00.00.0...1.00.01.00.00.00.00.00.00.00.0
OGT0.00.00.00.00.00.00.00.00.01.0...0.00.00.01.00.00.00.00.00.01.0
\n", - "

5 rows × 14852 columns

\n", - "
" - ], - "text/plain": [ - " SAMEA11294524-AAACCTGAGTCTCCTC SAMEA11294524-AAACCTGCAATGTAAG \n", - "CD40 0.0 0.0 \\\n", - "NFAT5 0.0 0.0 \n", - "CNR2 0.0 2.0 \n", - "YPEL1 0.0 0.0 \n", - "OGT 0.0 0.0 \n", - "\n", - " SAMEA11294524-AAACCTGCACCGATAT SAMEA11294524-AAACCTGCAGTCAGAG \n", - "CD40 0.0 0.0 \\\n", - "NFAT5 0.0 1.0 \n", - "CNR2 0.0 0.0 \n", - "YPEL1 0.0 0.0 \n", - "OGT 0.0 0.0 \n", - "\n", - " SAMEA11294524-AAACCTGGTATCAGTC SAMEA11294524-AAACCTGGTCAATGTC \n", - "CD40 0.0 0.0 \\\n", - "NFAT5 0.0 0.0 \n", - "CNR2 0.0 0.0 \n", - "YPEL1 0.0 0.0 \n", - "OGT 0.0 0.0 \n", - "\n", - " SAMEA11294524-AAACCTGGTTCCACTC SAMEA11294524-AAACCTGTCCGTACAA \n", - "CD40 0.0 0.0 \\\n", - "NFAT5 0.0 0.0 \n", - "CNR2 0.0 0.0 \n", - "YPEL1 0.0 0.0 \n", - "OGT 0.0 0.0 \n", - "\n", - " SAMEA11294524-AAACCTGTCGGACAAG SAMEA11294524-AAACCTGTCTTTAGGG ... \n", - "CD40 0.0 0.0 ... \\\n", - "NFAT5 0.0 0.0 ... \n", - "CNR2 0.0 0.0 ... \n", - "YPEL1 0.0 0.0 ... \n", - "OGT 0.0 1.0 ... \n", - "\n", - " SAMEA11294531-TTTGCGCTCCAGAGGA SAMEA11294531-TTTGCGCTCTGTCCGT \n", - "CD40 0.0 0.0 \\\n", - "NFAT5 0.0 0.0 \n", - "CNR2 0.0 0.0 \n", - "YPEL1 1.0 0.0 \n", - "OGT 0.0 0.0 \n", - "\n", - " SAMEA11294531-TTTGGTTAGCCCAGCT SAMEA11294531-TTTGGTTAGTCTCAAC \n", - "CD40 0.0 0.0 \\\n", - "NFAT5 0.0 0.0 \n", - "CNR2 0.0 0.0 \n", - "YPEL1 1.0 0.0 \n", - "OGT 0.0 1.0 \n", - "\n", - " SAMEA11294531-TTTGGTTCAAGGTTTC SAMEA11294531-TTTGGTTCAATAACGA \n", - "CD40 0.0 0.0 \\\n", - "NFAT5 0.0 0.0 \n", - "CNR2 0.0 0.0 \n", - "YPEL1 0.0 0.0 \n", - "OGT 0.0 0.0 \n", - "\n", - " SAMEA11294531-TTTGGTTCACGGTTTA SAMEA11294531-TTTGGTTTCCAAATGC \n", - "CD40 0.0 0.0 \\\n", - "NFAT5 0.0 0.0 \n", - "CNR2 0.0 0.0 \n", - "YPEL1 0.0 0.0 \n", - "OGT 0.0 0.0 \n", - "\n", - " SAMEA11294531-TTTGTCAAGATCTGCT SAMEA11294531-TTTGTCAAGCTAGTCT \n", - "CD40 0.0 0.0 \n", - "NFAT5 1.0 0.0 \n", - "CNR2 1.5 0.0 \n", - "YPEL1 0.0 0.0 \n", - "OGT 0.0 1.0 \n", - "\n", - "[5 rows x 14852 columns]" - ] - }, - "execution_count": 186, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cells.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 187, - "id": "4c269de3", - "metadata": {}, - "outputs": [], - "source": [ - "cells.to_csv(\"data/\" + folder + \"/\" + datatype + \"_filtered_data.csv\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/filter_pas.ipynb b/notebooks/filter_pas.ipynb deleted file mode 100644 index 8207a13..0000000 --- a/notebooks/filter_pas.ipynb +++ /dev/null @@ -1,154 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import numpy as np\n", - "import pandas as pd\n", - "import os\n", - "from tqdm import tqdm" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "dataset = \"Liver\" # \"PBMC\" \"BM\" \"COVID\" \"Liver\"\n", - "datatype = \"seurat\" # \"row\"\n", - "datafolder = \"C:\\\\Users\\\\amruk\\\\source\\\\enrichment-auc\\\\results\\\\\"+dataset+\"\\\\\"+datatype+\"\\\\\"" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "157" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "with open(\"C:\\\\Users\\\\amruk\\\\source\\\\enrichment-auc\\\\data\\\\\"+dataset+\"\\\\filtered_genesets_genes.json\") as file:\n", - " genesets = json.load(file)\n", - "gs_names = list(genesets.keys())\n", - "len(genesets)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "files = sorted([f.name for f in os.scandir(datafolder) if f.is_file()])\n", - "no_change = ['ranks_gsva.csv', 'ranks_ssgsea.csv', 'times.csv']\n", - "files = [file for file in files if file not in no_change]" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "auc.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "aucell.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "cerno.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "gsva.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "jasmine.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "mean.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "pvals_005.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "pvals_cerno005.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "qvals_005.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "qvals_cerno005.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "ratios.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "sparse_pca.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "ssgsea.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "svd.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "vision.csv\n", - "(165, 14852)\n", - "(157, 14852)\n", - "z.csv\n", - "(165, 14852)\n", - "(157, 14852)\n" - ] - } - ], - "source": [ - "for file in files:\n", - " print(file)\n", - " res = pd.read_csv(datafolder+file, index_col=0)\n", - " print(res.shape)\n", - " res = res.loc[res.index.isin(gs_names)]\n", - " print(res.shape)\n", - " res.to_csv(datafolder+file, index=True)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "enrich", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.11" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/genesets_summary.ipynb b/notebooks/genesets_summary.ipynb deleted file mode 100644 index 5ab83aa..0000000 --- a/notebooks/genesets_summary.ipynb +++ /dev/null @@ -1,778 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import numpy as np\n", - "import pandas as pd\n", - "from tqdm import tqdm" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "dataset = \"PBMC\" # \"PBMC\" \"BM\" \"COVID\" \"Liver\"\n", - "datatype = \"seurat\" # \"row\"\n", - "datafolder = \"C:\\\\Users\\\\amruk\\\\source\\\\enrichment-auc\\\\data\\\\\"+dataset+\"\\\\\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Geneset - remove empty IDs" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
IDTitlesourceDataBase
101MonocyteMonocyteCMCellMarker
111MyeloidMyeloidCMCellMarker
121Natural killer cellNatural killer cellCMCellMarker
131NeutrophilNeutrophilCMCellMarker
141T cellT cellCMCellMarker
\n", - "
" - ], - "text/plain": [ - " ID Title source DataBase\n", - "101 Monocyte Monocyte CM CellMarker\n", - "111 Myeloid Myeloid CM CellMarker\n", - "121 Natural killer cell Natural killer cell CM CellMarker\n", - "131 Neutrophil Neutrophil CM CellMarker\n", - "141 T cell T cell CM CellMarker" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "geneset_info = pd.read_csv(datafolder+\"genesets_modules.csv\", index_col=0)\n", - "geneset_info.tail()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
IDTitlesourceDataBase
101MonocyteMonocyteCMCellMarker
111MyeloidMyeloidCMCellMarker
121Natural killer cellNatural killer cellCMCellMarker
131NeutrophilNeutrophilCMCellMarker
141T cellT cellCMCellMarker
\n", - "
" - ], - "text/plain": [ - " ID Title source DataBase\n", - "101 Monocyte Monocyte CM CellMarker\n", - "111 Myeloid Myeloid CM CellMarker\n", - "121 Natural killer cell Natural killer cell CM CellMarker\n", - "131 Neutrophil Neutrophil CM CellMarker\n", - "141 T cell T cell CM CellMarker" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "geneset_info['ID'] = np.where(geneset_info['ID'] == \"-\", geneset_info['Title'], geneset_info['ID'])\n", - "geneset_info.tail()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "geneset_info.to_csv(datafolder+ \"genesets_modules.csv\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Filter geneset by occuring genes" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "geneset_info = pd.read_csv(datafolder+\"genesets_modules.csv\", index_col=0)\n", - "gene_expr = pd.read_csv(datafolder + datatype + \"_filtered_data.csv\", index_col=0)\n", - "patients_names = gene_expr.columns.to_list()\n", - "genes = gene_expr.index.tolist()\n", - "gene_expr = gene_expr.to_numpy().astype(float)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "159" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "with open(datafolder + \"genesets_genes.json\") as file:\n", - " genesets = json.load(file)\n", - "gs_names = list(genesets.keys())\n", - "len(genesets)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - " 0%| | 0/159 [00:00\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
IDTitleCategoryDatabaseGSsizeGenesInGSPercCelltypeCelltype_unclear
Sig.:21Sig.:21T CELLS GAMMA DELTASignature of PBMCSignature363597.222222otherno
\n", - "" - ], - "text/plain": [ - " ID Title Category Database GSsize \n", - "Sig.:21 Sig.:21 T CELLS GAMMA DELTA Signature of PBMC Signature 36 \\\n", - "\n", - " GenesInGS Perc Celltype Celltype_unclear \n", - "Sig.:21 35 97.222222 other no " - ] - }, - "execution_count": 100, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "title_condition = by_celltype['Title'].str.contains(\"nk cell|natural killer|b cell|t cell\", case=False)\n", - "other_cells = by_celltype['Celltype'].str.contains(\"other|unknown\", case=False)\n", - "not_mast = ~by_celltype['Title'].str.contains(\"mast cell\", case=False)\n", - "other_applicable = by_celltype[title_condition & other_cells & not_mast]\n", - "other_applicable" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "other_applicable[\"Celltype\"] = \" T cell\"" - ] - }, - { - "cell_type": "code", - "execution_count": 106, - "metadata": {}, - "outputs": [], - "source": [ - "chosen = pd.concat([by_celltype[by_celltype['Celltype'].str.contains(\"nk cell|natural killer|t cell|b cell\", case=False)], other_applicable])" - ] - }, - { - "cell_type": "code", - "execution_count": 114, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
IDTitleCategoryDatabaseGSsizeGenesInGSPercCelltypeCelltype_unclear
hsa04062hsa04062KEGG: Chemokine signaling pathwayKEGG: Organismal Systems; Immune systemKEGG19213972.395833T cellno
hsa04610hsa04610KEGG: Complement and coagulation cascadesKEGG: Organismal Systems; Immune systemKEGG854654.117647B cell; T cellno
hsa04612hsa04612KEGG: Antigen processing and presentationKEGG: Organismal Systems; Immune systemKEGG786684.615385NK cell; T cellno
hsa04650hsa04650KEGG: Natural killer cell mediated cytotoxicityKEGG: Organismal Systems; Immune systemKEGG1319471.755725NK cellno
hsa04657hsa04657KEGG: IL-17 signaling pathwayKEGG: Organismal Systems; Immune systemKEGG946367.021277NK cell; T cellno
\n", - "
" - ], - "text/plain": [ - " ID Title \n", - "hsa04062 hsa04062 KEGG: Chemokine signaling pathway \\\n", - "hsa04610 hsa04610 KEGG: Complement and coagulation cascades \n", - "hsa04612 hsa04612 KEGG: Antigen processing and presentation \n", - "hsa04650 hsa04650 KEGG: Natural killer cell mediated cytotoxicity \n", - "hsa04657 hsa04657 KEGG: IL-17 signaling pathway \n", - "\n", - " Category Database GSsize GenesInGS \n", - "hsa04062 KEGG: Organismal Systems; Immune system KEGG 192 139 \\\n", - "hsa04610 KEGG: Organismal Systems; Immune system KEGG 85 46 \n", - "hsa04612 KEGG: Organismal Systems; Immune system KEGG 78 66 \n", - "hsa04650 KEGG: Organismal Systems; Immune system KEGG 131 94 \n", - "hsa04657 KEGG: Organismal Systems; Immune system KEGG 94 63 \n", - "\n", - " Perc Celltype Celltype_unclear \n", - "hsa04062 72.395833 T cell no \n", - "hsa04610 54.117647 B cell; T cell no \n", - "hsa04612 84.615385 NK cell; T cell no \n", - "hsa04650 71.755725 NK cell no \n", - "hsa04657 67.021277 NK cell; T cell no " - ] - }, - "execution_count": 114, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chosen.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 128, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(69, 9)" - ] - }, - "execution_count": 128, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chosen.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 129, - "metadata": {}, - "outputs": [], - "source": [ - "chosen.to_csv(data_folder+\"chosen_paths.txt\", sep='\\t', mode='a')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/notebooks/msc-plots.ipynb b/notebooks/msc-plots.ipynb deleted file mode 100644 index b3f112a..0000000 --- a/notebooks/msc-plots.ipynb +++ /dev/null @@ -1,5012 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "0fb9391c-6bda-4309-a414-b294ad08268d", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import os\n", - "import pandas as pd\n", - "import numpy as np\n", - "import plotly.express as px\n", - "import scipy.stats as st " - ] - }, - { - "cell_type": "markdown", - "id": "7fe917e3-0140-4a47-8050-b230fe4d8486", - "metadata": {}, - "source": [ - "# 2D VAE dim choice" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "ad783570-c175-4180-b175-a3140be9fae3", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "cells = [\"3222\", \"3918\", \"4903\", \"14852\"]\n", - "dimensions = [2048, 4096, 4096, 8192]" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "1a847a2d-e0a2-4a78-bfdb-a2dc318aad4a", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "hovertemplate": "x=%{x}
y=%{y}", - "legendgroup": "", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "", - "offsetgroup": "", - "orientation": "v", - "showlegend": false, - "textposition": "auto", - "type": "bar", - "x": [ - "3222", - "3918", - "4903", - "14852" - ], - "xaxis": "x", - "y": [ - 2048, - 4096, - 4096, - 8192 - ], - "yaxis": "y" - } - ], - "layout": { - "barmode": "relative", - "height": 500, - "legend": { - "tracegroupgap": 0 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "white", - "showlakes": true, - "showland": true, - "subunitcolor": "#C8D4E3" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "white", - "polar": { - "angularaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - }, - "bgcolor": "white", - "radialaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "yaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "zaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "baxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "bgcolor": "white", - "caxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - } - } - }, - "title": { - "text": "The dependence of the VAE layer size on the cell number" - }, - "width": 600, - "xaxis": { - "anchor": "y", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.5, - 3.5 - ], - "title": { - "text": "cell number" - }, - "type": "category" - }, - "yaxis": { - "anchor": "x", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - 0, - 8623.157894736842 - ], - "title": { - "text": "Layer size" - }, - "type": "linear" - } - } - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAABQ8AAAH0CAYAAACTo9tmAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3X+wXvV9H/jvvcIyNFUx2DVYKYEY7yzGdsKGUGs6CWVDtpvCsqG0KHhIF1uuoohmUgMjjYSHpSxjxEgLokmKoihRSFpvqNyQdCmk2ZYMJZm1EoYOUyios4tiQo2B2iZUyQqwfmzP45yb5x49z3Of8zznx/d7zuv+Y1/uec738319vvfRve/7PecsnDx58mTwQaADAtlCXujAPEyBAAECBAgQIECAAAECBAgQIBCLwILwMJZWqIMAAQIECBAgQIAAAQIECBAgQIBAXALCw7j6oRoCBAgQIECAAAECBAgQIECAAAEC0QgID6NphUIIECBAgAABAgQIECBAgAABAgTaE3BDtFH2wsP2VqSRCRAgQIAAAQIECBAgQIAAAQIECEQtIDyMuj2KI0CAAAECBAgQIECAAAECBAgQINCegPCwPXsjZwJ2BFsHBAgQIECAAAECBAgQIECAAIFoBYSH0bZGYQQIECBAgAABAgQIECBAgAABAgTaFRAetutvdAIECBAgQIAAAQIECBAgQIAAAQLRCggPo22NwggQIECAAAECBAgQIECAAAECBAi0KyA8bNff6AQIECBAgAABAgQIECBAgAABAgSiFRAettkaDwtpU9/YBAgQIECAAAECBAgQIECAAAECKwgIDy0RAgQIECBAgAABAgQIECBAgAABAgRGCggPLQwCBAgQIECAAAECBAgQIECAAAECBISH1gABAgQIECAQiYBbd0TSCGUQIECAAAECBAgQmCxg56EVQoAAAQIECHRGQCbZmVaaCAECBAgQIECAQCQCwsNIGqEMAgQIECBAoNsCgs1u99fsCBAgQIAAAQJdFRAedrWz5kWAAAECBAgQIECAAAECBAgQIEBgTgHh4ZyAXk6AAAECBAgQIECAAAECBAgQIECgqwLCw6521rwIECBAIGoBl7BG3Z75itPc+fy8mgABAgQIECBAICoB4WFU7VAMAQIECBAgQIAAAQIECBAgQIAAgXgEhIfx9EIlBAgQIECAAAECBAgQIECAAAECBE4RaPPiFuGhBUmAAAECBAgQIECAAAECBAgQIECAwEgB4aGFQYAAAQIECBAgQIAAAQIECBAgQICA8NAaIECAAAECBAgQIECA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IECgpIDwsCSYwwkQIECAAAECBAgQIECAAAECBAj0RUB42JdOmycBAgQIECBAgAABAgQIECBAgACBkgLCw5JgDidAgAABAgQIECBAgAABAgQIECDQFwHhYV86bZ4ECBAgQIAAAQIECBAgQIAAAQIESgoID0uCOZwAAQIECBAgQIAAAQIECBAgQIBAXwSEh33ptHkSIECAAAECDQh4LnUDyIYgQIAAAQIECBBoUEB42CC2oQgQIECAQNMCoqymxY1HgAABAgQIECBAoFsCwsNu9dNsCBAgQIAAAQIECBAgQIAAAQIECFQmIDysjNKJCBAgQIAAAQIECBAgQIAAAQIECHRLQHjYrX6aDQECBAgQIECAAAECBAgQIECAAIHKBNoJD92AqbIGOhEBAgQIECBAgAABAgQIECBAgACBugTaCQ/rmo3zEiBAgAABAgQIECBAgAABAgQIECBQmYDwsDJKJyJAgAABAgQIECBAgAABAgQIECDQLQHhYbf6aTYECBAgQIAAAQIECBAgQIAAAQIEKhMQHlZG6UQECBAgQIAAAQIECBAgQIAAAQIEuiUgPOxWP6eajefVTMXkIAIECBAgQIAAAQIECBAgQIBA7wWEh71fAgAIECBAgAABAgQIECBAgAABAgQIjBYQHloZBAgQIECAAIGYBFwiEFM31EKAAAECBAgQ6L2A8LD3SwAAAQIECBAgQIAAAQIECBAgQIAAgdECwkMrg0DjAraUNE5uQAIECBAgQIAAAQIECBAgQGAmAeHhTGxeRIAAAQIECBAgQIAAAQIECBAgQKD7AsLD7vfYDAkQIECAAAECBAgQIECAAAECBAjMJCA8nInNiwgQIECAAAECBAgQIDBOwG1qrA0CBAgQ6I6A8LA7vTQTAgQIECBAgAABAgQIECBAgAABApUKCA8r5XQyAgQIECBAgAABAmUF7FIrK+Z4AgQIEOi3gH85m+2/8LBZb6MRIECAAAECBAgQIECAQAsCf/SfTobfePx4ePedFgY3JAECSwJ/479fFb734wtEEhIQHibULKUSIECAAAECBAgQIECAwGwCf/jyyXD/nmPh6NHZXu9VBAhUI/D3/u6qsO77F6s5mbM0ItCZ8PCRx58Kd+zcP0D70DnvD3t33hYuPH/t4PO33343/K+79ofHnjg4+PzurRvCdVddvgT85ltHwuZtu8NzLx4e/LeHHtgWLrvkoqWvD5/76ivXhbu2bAhnnL66kQYZhAABAgQIECBAgAABAgTmFxAezm/oDASqEBAeVqHY7Dk6ER4+/eyhcN/eA2HPvbeEs85cE4qf37/3wED11k3rQx4U3rZp/SAgPPr2u+HOXfvDuksvHgSKL738avj8jn3hC9s3DsLHSedqtlVGI0CAAAECBAgQIECAAIFZBYSHs8p5HYFqBYSH1Xo2cbZOhIfZzsCDz7ywtCNwOAA8+31rwvZ79oUtN9+wtBNxOEzMjt314MNhx+0bB8FjMUzMjr3gvHOXdioWw8QmmmQMAgQqEHBH3QoQnYIAAQIECBAgkK6A8DDd3qm8WwLCw/T62YnwMN9N+F1rPzgIEH/rdw6Gr7zy2mCnYXEnYdai4bDx+UOHl+1azL6eh4ubb7p22a7E7Gujzpde21VMgAABAgQIECBAgACBfgkID/vVb7ONV0B4GG9vxlXWifAwD/z+40uvhN/7g+eW3fOwuLNwVHj4pUefXHYfw2J4eP01VyzdA7EYHr7zrRPpdV3FBAgkJ5DdTti7TXJtUzCBJAUWF0M44Q0nyd4pmkBqAosLIZzIrg5p6OOVr4bwj37+uAemNORtGALjBD7746vC913SrM973+MBLfOIdyI8zHYS5jsNM4zs0uLtO/YNHpqSfQzfw3BUeDh8v8Q8iMz+d5qdh0f+v2/N4++1BAgQmEpg1eJiOO63+amsHESAwHwC3m/m8/NqAgSmF2j6/ea11xbDz/zCCeHh9C1yJIFaBDbcuBg+8fFm/1K55i+8p5a59OWknQgPi/clHH4oyke++zvd87Avq9k8CRAgQIAAAQIECBAgMEbAZcuWBoE4BFy2HEcfylTRifAw23l44NEnlz1tOd95mD0x2dOWyywJxxIgQIAAAQIECBAgQKB7AsLD7vXUjNIUEB6m17dOhIcZexYQ/tKvPT7owIfOef/gkuUsOMw+8icoP/bEwcHnd2/dsPT05OzzfKficy8eHnz9oQe2Ld3jMPs8Cyfv2Ll/8LWrr1y37P6I6bVcxQQIECBAgAABAgQIEOifgPCwfz034zgFhIdx9mVSVZ0JD9OjV3F1AtldlheqO50zESBAgAABAgQINCvgx7lmvXs6mvCwp4037egEhIfRtWTFgioPD/27v6K5AwgQIECAAAECBAgQIECgYQHhYcPghiMwRkB4mN7SqDw8TI9AxQQIECBAgAABAgQIECDQdQHhYdc7nMj8sovmsl1XPf4QHqbXfOFhej1TMQECBAgQIECAAAECBAiUFBAelgRzOIGaBISHNcHWeFrhYY24Tk2AAAECBAgQIECAAAECcQgID+PoQ1eqcMu22TspPJzdrq1XCg/bkm9iXO9mTSgbgwABAgQIECBAgACBBASEhwk0SYm9EBAeptdm4WF6PVMxAQIECBAgQIAAAQIECJQUEB6WBHM4gZoEhIc1wdZ4WuFhjbhOTYAAAQIECBAgQIAAAQJxCAgP4+iDKggID9NbA8LD9HqWeMWupU68gconQIBASwL+/WgJ3rAEuivgbaW7vR0zM+Fh71puwpEKCA8jbcyEsoSH6fVMxQQIECBAgAABAgQIECBQUkB4WBLM4QRqEuhdeNiBP1YJD2v6ZnBaAgQIECBAgAABAgQIEIhHQHgYTy9U0m+B3oWHHWi38LADTZxnCh0IwOeZvtcSIECAAAECBAgQINATAeFhTxptmtELCA+jb9EpBQoP0+uZigkQIECAAAECBAgQIECgpIDwsCSYwwnUJCA8rAm2xtMKD2vEdWoCBMYJ2PNqbRAgQIAAAQIECDQrIDxs1ttoBMYJCA/TWxvCw/R6pmICBAgQIECAAAECBAgQKClQOjxcCCFkf/P2QYBApQLCw0o5GzmZ8LARZoMQIECAAIFTBezBtSoIECBAgEBzAqXDw+ZKM1KfBITSQXiY3oIXHqbXMxUTIECAAAECdQlIdOuSdV4CBAi0LiA8bL0FCiAwEBAeprcQhIfp9UzFBAgQIECAAAECBAgQIFBSQHhYEszhBGoSEB7WBFvjaYWHNeI6NQECBAgQIECAAAECLQnYSdwSfLzDCg/j7Y3K+iUgPEyv38LD9HqmYgIECBAgQIAAAQIECBAoKXBKeOjecyUFHU6gGgHhYTWOTZ5FeNiktrEIECBAgAABAgQIECBAoBUBOw9bYTcogVMEhIfpLQrhYXo9UzGB5AVcRZR8C02AAAECBAgQIJCcgPAwuZYpuKMCwsP0Gis8TK9nKiZAgAABAgQIECBAgACBkgLCw5JgDidQk4DwsCbYGk8rPKwR16kJECBAgAABAgQIECBAIA4B4WEcfVAFAeFhemtAeJhez1RMgAABAgQIECBAgAABAiUFhIclwRxOoCYB4WFNsDWeVnhYI65TEyBAgAABAgQIECBAgEAcAsLDOPqgCgLCw/TWgPAwvZ6pmACB6AU8Eib6FimQAAECBAgQ6J2A8LB3LTfhSAWEh5E2ZkJZwsP0eqZiAgQIECBAgAABAgRiFfA3xFg7E4SH0bZGYT0TEB6m1/BOhIePPP5UuGPn/lP07966IVx31eXh6Nvvhjt37Q+PPXGCmEbtAAAgAElEQVRwcEz+3/MXvPnWkbB52+7w3IuHB//poQe2hcsuuWjpfMPnv/rKdeGuLRvCGe9dHcJCeg1XMQECBAgQIECAAAECBPooIDzsY9fNOUYB4WGMXZlcUyfCw+IUszBw+z37wpabbwgXnr823L/3wOCQWzetD3lQeNum9YOAMA8W11168SBofOnlV8Pnd+wLX9i+cfDap589FO7beyDsufeWcNaZa5adK712q5gAAQIECBAgQIAAAQL9FBAe9rPvZh2fQPLhYQ93mHcyPMx2Cn7lldeWwsLhIDH7thkOE7OwcNeDD4cdt28chIPFMDE79oLzzh0Ei9lHMUyM79tQRQQIECBAgAABAgQIECBQFBAeWhME4hBIPjyMg7HRKjoXHhZ3HRZ3Ema6Wbh48JkXBpcfP3/o8LKdhcPh4uabrh1c7pzvSsy+Nup8jXbMYAQIECBAgAABAgQIECBQWkB4WJrMCwjUIiA8rIW11pN2Ljwc3nWYh33DOwtHhYdfevTJb9/H8PTVA+x8Z2IeHl5/zRVL90AshoffOnai1gY5OQECBL4tkN1kNdsf74MAAQL1Cni3qdfX2QkQGBZo9h3nj/5TCA/8/PFw9KguECDQpsBn/+6q8P2XNFvBe05bbHbAjo3WqfBw1K7AuXYe/i/Xhjv/98k7D9/60291bEmYDgECMQqsWrUQjh8XHsbYGzUR6JrAaasWw7Hj/jjatb6aD4EoBApZ4eJiCCcafLt57bXF8HP7TggPo1gMiuizwIYbF8PHP3ai0a0RZ37He/pMPvfcOxUeDt/LMJcpXsac/Xf3PJx73TgBAQIECBAgQIAAAQIpC/Twhv8uW055waq9SwIuW06vm50JDyfdi9DTltNbmComQIAAAQIECBAgQIBAlQLCwyo1nYvA7ALCw9nt2nplJ8LD4hOSi5j51x974uDgS3dv3bD09OTs82x34uZtu8NzLx4efP2hB7Yt3eMw+zy7j+IdO/cPvnb1leuW3R+xrcYZlwABAgTqFejhhox6QZ2dAAECBAi0LCA8bLkBhifwZwLCw/SWQifCw/TYVUyAAAECBAgQIECAAAECTQoID5vUNhaB8QLCw/RWh/AwvZ6pmAABAgQIECBAgAABAgRKCggPS4J15fBmH+rdFbVa5yE8rJW3lpMLD2thdVICBAgQIECAAAECBAgQiElAeBhTN9TSZwHhYXrdFx6m1zMVEyBAgAABAgQIECBAgEBJAeFhSTCHE6hJQHhYE2yNpxUe1ojr1AQIECBAgAABAgQIECAQh4DwMI4+qIKA8DC9NSA8TK9nKiZAgAABAgQIECBAgACBkgLCw5JgDidQk4DwsCbYGk8rPKwR16kJECBAgAABAgS6KHAyhJDdgd8HAQIpCQgPU+qWWrssIDxMr7vCw/R6pmICBAgQIECAAAECBAgQKCkgPCwJltThHqmcUruEhyl169u1Cg/T65mKCRAgQIAAAQIECBAgQKCkgPCwJJjDCdQkIDysCbbG0woPa8R1agIzCbgSaiY2LyJAgAABAgQIECAwSUB4aH0QiENAeBhHH8pUkX54KGgp02/HEiBAgAABAgQIECBAoJcCwsNett2kIxQQHkbYlBVKSj88TM9cxQQIECBAgAABAgQIECDQsIDwsGHwfDi3I2wJPt5hhYfx9mZcZcLD9HqmYgIECBAgQIAAAQIECBAoKSA8LAnmcAI1CQgPa4Kt8bTCwxpxnZoAAQIECBAgQIAAAQIE4hAQHsbRB1UQEB6mtwZ6GB66SWJ6y1TFBAgQIECAAAECBAgQmE9AeDifn1cTqEpAeFiVZHPn6WF42ByukQgQIECAAAECBAgQIEAgDgHhYRx9UAUB4WF6a0B4mF7PVEyAAAECBFoWsIu/5QYYngABAgRmEBAezoDmJQRqEBAe1oBa+SmX/7wvPKwc2AkJECBAgAABAgQIECBAIDYB4WFsHVFPXwWEh+l1XniYXs9UTIAAAQIECBAgQIAAAQIlBYSHJcEcTqAmAeFhTbA1nlZ4WCOuUxMgQIAAAQIECBAgQIBAHALCwzj6oAoCwsP01oDwML2eqZgAAQIECBAgQIAAAQIESgoID0uCOZxATQLCw5pgazyt8LBGXKcmQIAAAQIECBAgQIAAgTgEhIdx9EEVBISH6a0B4WF6PVMxAQIECBAgQIAAAQIECJQUEB6WBHM4gZoEhIc1wdZ4WuFhjbhOTYAAAQIECBAgQIAAAQJxCAgP4+iDKggID9NbA8LD9HqmYgIEEhA4GUJYSKBOJRIgQIAAAQIE+iIgPOxLp80zdgHhYewdOrU+4WF6PVMxAQIECBAgQIAAAQIECJQUEB6WBHM4gZoEJoWHNmHUhD7naYWHcwJ6OQECBAgQIECAAAECBAjELyA8jL9HKuyHgJ2H6fVZeJhez1RMgAABAgQIECBAgACBKQTs4RlGEh5OsWQcQqABAeFhA8gVDyE8rBjU6QgQIECAAAECBAgQINAbgYTySeFhb1aliUYuIDyMvEEjyutUeHj/3gPhl37t8cE0P/upq8Ktm9YP/v/Rt98Nd+7aHx574uDg87u3bgjXXXX5Esebbx0Jm7ftDs+9eHjw3x56YFu47JKLlr7+yONPhTt27h98fvWV68JdWzaEM05fnV63VUwgBoGEfsCMgUsNBAgQIECAAAEC1QgID6txdBYC8woID+cVbP71nQkPs+Aw+8gDw2HK4a/lQeFtm9YPAsI8WFx36cWDQPGll18Nn9+xL3xh+8Zw4flrw9PPHgr37T0Q9tx7SzjrzDWD/589QXXUOM23z4gECBAgQIAAAQIECBAgMI2A8HAaJccQqF9AeFi/cdUjdCI8zAK+Lz365MgdgVlYuP2efWHLzTcMwsDsYzhMzMLCXQ8+HHbcvnEQDhbDxOzYC847d2mnYjFMrLohzkeAAAECBAgQIECAAAEC1QsID6s3dUYCswgID2dRa/c1nQgPhy8rzjnzS4+LOwmzr2fHH3zmhUHY+Pyhw8t2Fg6Hi5tvunZwuXO+KzH7WvF8x46faLeDRidAoBcCC9me52zbsw8CBAjULJC935wM2T0mfBAgQKBmgZOh0febl18J4YGfPx6OHq15Xk5PgMBEgSw8/P7/rlmk01YtNjtgx0brRHg4anfg9h37wt6dtw3aNbyzMPu8GB4Wdy3mOxPz8PD6a65YugdiMTx888i7lS2JLBfwo3plnE5EoFMCqxYXwvET3iE61VSTIRCpwHtOWwzfOuaPo5G2R1kEOiXQ9M83b7yxKvzcvhPCw06tIpNJUeAzNy6Gj330eKP5x1lrPLdinrXSyfBw+NLj7/3YR5bdw3BUeDh8T8Ps68XwcNLOw3nwvZYAAQIECBAgQIAAAQIEmhFw2XIzzkYpCtgmVBRx2XJ63yWdCA+znYRfeeW1U56unO0Y/Mh3f6d7Hqa3LlVMgAABAgQIECBAgACBSgWEh5VyOhmBmQWEhzPTtfbCToSH2aXEm7beF3Zs3zi4vLj4UJMqn7Y86anOrXXRwAQIECBAgAABAgQIECAwUUB4aIEQiENAeBhHH8pU0YnwMJtwFhh++nP3Dub+oXPeP7jfYf505fwy5seeODj4+t1bNyw9PTn7PHsi8+Ztu8NzLx4efD1/2EoOOfxAlquvXDfyqc5l0B1LgAABAgQIECBAgAABAs0KCA+b9TYagXECwsP01kZnwsP06FVMgAABAgQIECBAgAABAk0JCA+bkjbOOIHs8YfZHRD7/iE8TG8FCA/T65mKCRAgQIAAAQIECBAgQKCkgPCwJJjDCdQkIDysCbbG0woPa8R1agIECBAgQIAAAQIECBCIQ0B4GEcfVEFAeJjeGhAeptczFRMgQIAAAQIECBAgQIBASQHhYUkwhxOoSUB4WBNsjacVHtaI69QECBAgQIAAAQIECBAgEIeA8DCOPqiCgPAwvTUgPEyvZyomQIAAAQIECBAgQIAAgZICwsOSYA4nUJOA8LAm2BpPKzysEdepCRAgQIAAAQIECEQj4DGf0bRCIe0ICA/bcTcqgaKA8DC9NSE8TK9nKiZAgAABAgQIECBAgACBkgLCw5JgDidQk4DwsCbYGk8rPKwR16kJECBAgAABAgQIECBAIA4B4WEcfVAFAeFhemsgmfDQVRbpLS4VEyBAgAABAgTaEvCzY1vyxiUQr4DwMN7eqKxfAsLD9PqdTHiYHq2KCfRQwG9qPWy6KRMgQIAAAQIE0hAQHqbRJ1V2X0B4mF6PhYfp9UzFBAgQIECAAAECBAgQIFBSQHhYEszhBGoSEB7WBFvjaYWHNeI6NQECBAgQIECAAAECBAjEISA8jKMPqiAgPExvDQgP0+uZigkQIECAAAECBAgQIECgpIDwsCSYwwnUJCA8rAm2xtMKD2vEdWoCBAgQIECAAAECBAgQiENAeBhHH1RBQHiY3hoQHqbXMxUTIECAAAECBAgQIECAQEkB4WFJMIcTqElAeFgTbI2nFR7WiOvUBAgQIECAAAECBAgQIBCHgPAwjj6ogoDwML01IDxMr2cqJkCAAAECBAgQIECAAIGSAsLDkmAOJ1CTgPBwTtiTIYSFOc9R8uXCw5JgDidQrUAL3/VzTCCtaueYqJd2T8Di7V5PzYgAAQIECJQUEB6WBHM4gZoEhIc1wdZ4WuFhjbhOTYAAAQIECBAgQIBA1QL+IlS1aF/OJzzsS6fNM3YB4WHsHTq1PuFhej1TMQECBAgQIECAAAECBAiUFBAelgRzOIGaBISHNcHWeFrhYY24Tk2AAAECBAgQIECAAAECcQgID+PogyoICA/TWwPCw/R6pmICBAgQIECAAAECBAgQKCkgPCwJ5nACNQkID2uCrfG0wsMacZ2aAAECBAgQIECAAAECBOIQEB7G0QdVEBAeprcG5g4Pj779brhz1/7w2BMHw4fOeX/Yu/O2sPacDwz+27pLLw7XXXV5eioqJkCAQGwC7g0fW0fUQ4AAAQIECCQmIDxMrGHK7ayA8DC91s4dHt6/90C44Lxzw9/8oXVh156Hw43X/XC48Py14elnD4UvPfpkuGvLhnDG6avTk1ExAQIEOirQag45afBWC+tos02LAAECBAgQWBIQHloMBOIQEB7G0YcyVcwVHr751pGw/Z59YcvNNwx2Gw6Hhy+9/GrY9eDDYcftG8NZZ64pU5NjCRAgQIAAAQIECBAgQIBApQLCw0o5nYzAzALCw5npWnthbeGhnYet9dTABAgQIECAAAECBAgQIFAQEB5aEgTiEBAextGHMlXMFR5mAz3y+FPh4DMvhO0/fWP42f2/Mbhs+ez3rQmbt+0O66+5opF7HmY7ILPxnnvx8NLc8/svZpdQD9+XMTvg7q0bltVVfP1DD2wLl11y0dK5sjnesXP/4POrr1znUuwyK8yxBAgQIECAAAECBAgQiEBAeBhBE2YtYSGEkN3ixkcnBISH6bVx7vAwm3K2y/DTn7t32eyLAVydNHn4d9um9ctCv3zM7L6M2cetm9aH4rF5sJg/3CW73PrzO/aFL2zfuHTvxvv2Hgh77r1lcPn18LnqnJNzEyBAgAABAgQIECBAgEB1AsLD6iydaYSAgHPqZSE8nJoqmgMrCQ/bns2k8HD4vozZLsTsYzgALN6bsRgm5g+EyZ8anQWlw2Fi23M3PgECBAgQIECAAAECBAisLCA8XNnIEQSaEBAeNqFc7RidCg/zy5aHL1ku7iTM+PJLrbMnQT9/6PApYWAeLm6+6dpw5679Id+VmL22eD47p6tdkM5GgMBogfF/yPSIYmuGAIFqBWycqNbT2QgQGC/Q9PvNV14+Ge7fcywcPaorBAi0KZCFh5/8/sVGS8jeb3zMLtCJ8LA4/SwcPPDok4NLjb/5x0dOeepzMTz80qNPLruPYTE8vP6aK5Yuhy6Gh994653Z9b2SAAECUwqcdtpiOHbsxJRHO4wAAQKzC6x+z6rw7reOz34CryRAgMCUAqtWLYTjx5vbjvGf//Oq8I9/8aTwcMr+OIxAXQKfvnExXHzRsXCyuW//8P4z31vXdHpx3rnCw/xy4e9a+8FTHiJSvBy4Sc3hS5WzcYfvYZh9XuXOwybnZSwCBAgQIECAAAECBAgQmE3AZcuzuXkVgaoFXLZctWj955s7PNx+z76w9twPhH/2L34nDD8kJZbwMHvyc1bjlptvGDwAJftwz8P6F5YRZhFw+eksal5DgAABAgQIECBAYBoB4eE0So4hUL+A8LB+46pHqCQ8zIK5LKTbvG33oL5xlwtXXXx+vuwhJtnHZZdcNPjf4Z2FZ5y+ellY6GnLdXXBeQkQIECAAAECBAgQIBCvgPAw3t6orF8CwsP0+l1ZeJjv6suCvE9/7t7wYz/6Q+HV174edty+MZx15ppaZbJdjpu23he+9vo3BuN84qMfHgSY+bj5E5Qfe+Lg4Ot3b90Q8qcnZ5/ngWL+wJXhHZR5GHnHzv2D11595bpTLtGudXJOToAAAQIECBAgQIAAgU4ItHuljfCwE4vIJDogIDxMr4mVh4cZQR7W/dGrbywL8dLjUTEBAgQIEOigQLu/u3UQ1JQIECBAIAUB4WEKXVJjHwSEh+l1ea7wML3pqpgAAQIEeiMgIOtNq02UAAECBAhMIyA8nEbJMQTqFxAe1m9c9QjCw6pFnY8AAQIECBAgQIAAAQIEohMQHkbXEgX1VEB4mF7jZwoP83sEfubHfiT88j/7VyG/V2Bx+sV7D6bHo+J4BGwhiqcXKiFAgAABAgQIECCQnoDwML2eqbibAsLD9Po6U3iY3jRVTIAAAQIECBAgQIAAAQJ9FhAe9rn75h6TgPAwpm5MV4vwcDonRxEgQIAAAQIECBAgQIBAwgLCw4Sbp/ROCQgP02un8DC9nqmYAAECBAgQIECAAAECBEoKCA9LgjmcQE0CwsOaYGs87dzh4f17D4TX3vhmuGvLhkGZd+7aHx574mD40DnvD3t33hYuPH9tjeU7NQECBAgQ6JaAO7x2q59mQ4AAAQLxCAgP4+mFSvotIDxMr/9zhYf5g1Nu27Q+XHbJReHpZw+FLz365CBIfP7Q4aX/f8bpq9OTUTEBAgQI/LmARMtqIECAAAECBBIXEB4m3kDld0ZAeJheK+cOD7ffsy9sufmGwQ7DbBdi9nHrpvXhpZdfDbsefDjsuH1jOOvMNenJqJgAAQIECBAgQIAAAQIEOiMgPOxMK01kksDCf70kNPvDf8QfwsOImzOmtLnCw6Nvvzu4TPn6a64IH/nu7wybt+0Ow7sQ79t7IOy59xbhYXrrQsUECBAgQIAAAQIECBDolIDwsFPtNJmEBYSH6TVvrvAwm262w3DT1vvC117/Rvjsp64a7DrMLmf+yW27wycvuWjwuQ8CBAgQIECAAAECBAgQINCmgPCwTX1jE/hzAeFheqth7vAwvSmrmAABAgQIECBAgAABAgT6JiA87FvHzTdWAeFhrJ0ZX5fwML2eqZgAAQIECBAgQIAAAQIESgoID0uCOZxATQLCw5pgazyt8LBGXKcmQIAAAQIECBAgQIAAgTgEhIdx9EEVBISH6a0B4WF6PVMxAQIECBAgQIAAAQIECJQUEB6WBHM4gZoEhIc1wdZ4WuFhjbhOTYAAAQIECBAg0KzAyRDCQrNDGo0AgUQEhIeJNEqZnRcQHqbXYuFhej1TMQECBAgQIECAAAECBAiUFBAelgRzOIGaBISHNcHWeNq5wsM33zoStt+zL2y5+YZw4flrayzTqQkQIECAAAECBAgQIECAwOwCwsPZ7bySQJUCwsMqNZs5l/CwGWejECBQoYBL0irEdCoCBAgQIECAQE8EhIc9abRpRi8gPIy+RacUOFd4mJ3t/r0Hwg9+8nvCZZdclN7sVUyAAAECBAi0J+AvAe3ZG5kAAQIdECj7z4jwsANNN4VOCAgP02vj3OHhSy+/Gr74yL8JWzbfEM44fXV6AiomQIAAAQIECBAgQIAAgc4LCA8732ITTERAeJhIo4bKnCs8zO55uHnb7vDci4dHzvwTH/1w2HPvLeGsM9ekJ6NiAgQIECBAgAABAgQIEOiMgPCw3VaW3SnabrVGr1NAeFinbj3nnis8rKckZyVAgAABAgQIECBAgAABAtUKCA+r9XQ2ArMKCA9nlWvvdcLD9uyNTIAAAQIECBAgQIAAAQINCQgPG4I2DIEVBISH6S2RucPDo2+/G+7ctT889sTB8KFz3h/27rwtrD3nA4P/tu7Si8N1V12enoqKCUQuYMt/5A1SHgECBAgQIECAQHQCwsPoWqKgngoID9Nr/NzhYfa05QvOOzf8zR9aF3bteTjceN0PhwvPXxuefvZQ+NKjT4a7tmzwIJX01oWKCRCoSEDQWxGk0xAgQIAAAQIE5hQQHs4J6OUEKhIQHlYE2eBp5goPswembL9nX9hy8w2D3YbD4WH2FOZdDz4cdty+0QNTGmyooQj0QUAg14cumyMBAgQIECBAoFqB+cLDhRBC9lOoDwIE5hUQHs4r2PzrawsP29p5mIWWm7beF26+6UeXLpkevrQ6I75764Zll1MXnxr90APbwmWXXLTUjUcefyrcsXP/4POrr1xnN2UV61T6U4WicxAgQIAAAQIECBAgMKXAfOHhlIM4jACBFQWEhysSRXfAXOFhNpssWDv4zAth+0/fGH52/28MLls++31rwuZtu8P6a674s5CumaQoDw6/9vo3lgWE2aXV2cetm9aHPCi8bdP6QUCYB4v5/Rmzc3x+x77whe0bly6/vm/vgbDn3lsGOyiHz9VMN5uxa2YuRiFAICWB3/rXx8Pzh/yFPaWeqbV7An/5AyH87f/ptLBmTffmls/oyJEQHvmXx8MbX/d+090um1kKAh+7aCFc9T+sSqHUmWsUHs5M54UEKhUQHlbK2cjJ5g4PsyqzXYaf/ty9ywou7t6rezb5JdQ/teFvhV898NtLD2sZvrQ6uxdj9jEcABYvry6Gifk9HfMHv2RzHQ4T656X8xMgQKAtgV99+Fh46st+mW/L37gEMoG/snYh3HrzaeEvdTw8vH/PsfDKV73fWPUE2hT4wXUL4aZPndZmCbWPLTysndgABKYSEB5OxRTVQZWEh23PaHg34ccv+vCyJz0XdxJmtea7JbOHuTx/6PApYWAeLm6+6dpTnho96nxtz9/4BAgQqENAeFiHqnMSKCcgPCzn5WgCBGYXEB7ObueVLQi4BWUL6NUNKTyszrKpMyUfHuY7Ba+/5oqxlyEXH9xSDA+LT4Uuhof5ubOmFMPDr7/1TlO9Mg4BAj0WOO20xXDs2InGBFYtLoR/8S8Xw+8dtBOoMXQDERghkIWHP/GZEFa/93hjPu95z6rwrW81N9677yyGfQ8t2HnYWIcNRGC0wA+sWwg/es2JcPx4c//2n7ZqIRxrcLyv/+dV4R//4slw9KhVQIBAmwKfvnExfPSiY+Fkc2834QNnvrfNKSc/9lzhYb7j78/vbdi8R/FhJ8MVZA9G+d6PfWTZPQyzr1e58/Bkk6u9eV4jEiAQkcDCQvYn1uY+7DxsztpIBMYJ2HlobRAg0JRAGzsPm/5d6it/dDLcv+e48LCpRWWc+gUS3YGZ7Tz85KXN/m7T9O9S9Te/2RHmCg+zUov3O/zsp64aPJikrY/iPQvd87CtThiXAIHUBYSHqXdQ/V0QEB52oYvmQCANgTbCw6Zl3POwaXHjERgt4LLl9FbG3OHh8JSLuwDbCBKL4WFWX9pPW05vUamYAIFuCAgPu9FHs0hbQHiYdv9UTyAlAeFhSt1SK4G0BYSH6fWv0vAwux/gpq33ha+9/o1TJJoKEkeFh/l/e+yJg4O6ssuZ86cnZ58XQ8/ik6Kzy5zv2Ll/8Nqrr1wXsgetnHH66vS6rWICBAiUEBAelsByKIGaBISHNcE6LQECpwgIDy0KAgSaEhAeNiVd3Thzh4fDwVpW1qiQMAvndvzMF8P2n74xnHXmmuqqdyYCBAgQqE1AeFgbrRMTmFpAeDg1lQMJEJhTQHg4J6CXEyAwtYDwcGqqaA6cKzyM4YEp0UgqhAABAh0TEB52rKGmk6SA8DDJtimaQJICwsMk26ZoAkkKCA/Ta9tc4WHp6WaP4W72gTqlS/QCAgQIEPi2gPDQSqhGINHHAFYz+bnPIjycm9AJCBCYUkB4OCWUwwgQmFtAeDg3YeMnaDY8bHx6BiRAgACBWQWEh7PKeR2B6gSEh9VZOhOBaAUi+RuL8DDaFaKwqgQi+V6rajopn0d4mF735g4PJz0k5RMf/XDYc+8t7nOY3rpQMQECBOw8tAYIRCAgPIygCUog0BMB4WFPGm2aBCIQEB5G0ISSJcwVHg4/2fh7P/aR8MVH/k3YsvmGwZOI7997IPzgJ78nXHbJRSVLcjgBAgQIxCBg52EMXVBD3wWEh31fAeZPoDkB4WFz1kYi0HcB4WF6K2Cu8DB7YMr2e/aFLTffMJj5rgcfDjtu3zjYafj0s4fClx59Mty1ZcMgTPRBgAABAmkJCA/T6pdquykgPOxmX82KQIwCwsMYu6ImAt0UEB6m19fKwsOz37cm7PiZL4btP33jIDzMLmceDhPTo1ExAQIE+i0gPOx3/80+DgHhYRx9UAWBPggID/vQZXMkEIeA8DCOPpSpYq7wcPiy5euuunxwqfIF550bsv//yONPhYPPvGDnYZluOJYAAQIRCQgPI2qGUnorIDzsbetNnEDjAsLDxskNSKC3AsLD9Fo/V3hYnG52GfPmbbvDcy8eDh865/1h787bwoXnr01PRcUECBAg4IEp1gCBCASEhxE0QQkEeiIgPOxJo02TQAQCwsMImlCyhErDw5JjO5wAAQIEIhaw8zDi5iitNwLCw9602kQJtC4gPGy9BQog0BsB4WF6ra4tPHTPw/QWg4oJECAwLCA8tB4ItC8gPGy/Byog0BcB4WFfOm2eBNoXEFWySxkAACAASURBVB6234OyFQgPy4o5ngABAj0REB72pNGmGbWA8DDq9iiOQKcEhIedaqfJEIhaQHgYdXtGFic8TK9nKiZAgEAjArWGhwshhJONTMMgBJIWEB4m3T7FE0hKQHiYVLsUSyBpAeFheu0THqbXMxUTIECgEYFaw8NGZmAQAukLCA/T76EZEEhFQHiYSqfUSSB9AeFhej0UHqbXMxUTIECgEQHhYSPMBiEwUUB4aIEQINCUgPCwKWnjECAgPExvDQgP0+uZigkQINCIgPCwEWaDEBAeHgnh/j3HwitfdS8D3w41CLhNxtSowsOpqRxIgMCcAsLDOQFbePlM4eGbbx0Jm7ftDs+9eHhiyZ/46IfDnntvCWeduaaFqRmyUoHs5/nshy8fBAj0RkB42JtWm2jEAnYeRtwcpRHomIDwsGMNNR0CEQsIDyNuzpjSZgoP05umigkQIECgrIDwsKyY4wlULyA8rN7UGQkQGC0gPLQyCBBoSkB42JR0deMID6uzdCYCBAh0SkB42Kl2mswMAjFsuhceztA4LyFAYCYB4eFMbF5EgMAMAsLDGdBafonwsOUGGJ4AAQKxCggPY+2MuvokIDzsU7fNlUC7AsLDdv2NTqBPAsLD9LotPEyvZyomQIBAIwLCw0aYDUJgooDw0NMufIsQaEpAeNiUtHEIEBAeprcGhIfp9UzFBAgQaERAeNgIs0EICA89bdl3AYEoBISHUbRBEQR6IdBKeBjD/WgS7q7wMOHmKZ0AAQJ1CggP69R1bgLTCdh5OJ2TowgQmF9AeDi/oTMQIDCdQCvh4XSlOWqMgPDQ0iBAgACBkQLCQwuDQPsCwsP2e6ACAn0RaCY8bHfrzx++fDLcv+dYOHq0L101TwJxCggP4+zLpKqEh+n1TMUECBBoREB42AizQQhMFBAeWiAECDQl0Ex42NRsRo8jPGzX3+gEcgHhYXprQXiYXs9UTIAAgUYEhIeNMBuEgPDQPQ99FxCIQkB4OHsb2t1POXvdXkmgLYFpwkPfV211Z/S4wsO4+qEaAgQIRCMgPIymFQrpsYCdhz1uvqkTaFhAeNgwuOEI9FhgmvCwxzxRTr0T4eGbbx0Jm7ftDs+9eHiA/ImPfjjsufeWcNaZawafH3373XDnrv3hsScODj6/e+uGcN1Vly81pPj6hx7YFi675KKlrz/y+FPhjp37B59ffeW6cNeWDeGM01dH2VBFESBAoCoB4WFVknGcx19v4+hD2SqEh2XFHE+AwKwCwsNZ5byOAIGyAsLDsmLtH9+J8PDpZw+FV159YykQzMK+g8+8sBTy3b/3wED61k3rQx4U3rZp/SAgzIPFdZdePHj9Sy+/Gj6/Y1/4wvaN4cLz14bs3PftPbAURg6fq/32qYAAAQL1CQgP67N1ZgLTCggPp5VyHAEC8woID+cV9HoCBKYVEB5OKxXPcZ0ID4ucw4Ff9rXt9+wLW26+YRAGZh/DAWAWFu568OGw4/aNg52KxTAxO/aC885dCiaLYWI8rVQJAQIEqhUQHlbr6WwEZhEQHs6i5jUECMwiIDycRc1rCBCYRUB4OItau6/pZHiYBX6vvfHNwc7DV1//+rKdhBn38M7E5w8dXrazcDhc3HzTtYPLnfNdidnXijsT222f0QkQIFCfgPCwPltnJjCtgPBwWinHESAwr4DwcF5BrydAYFoB4eG0UvEc16nwML834fA9D4s7C0eFh1969Mll9zHMdybm4eH111yxdA/EYnj45pF34+mmSggQ6KzAqsWFcPxEdte6Zj6y8R75PxfC7x2sc8yFEEKd52/GyigE6hTIwsOf/EwI7z3jRJ3DLDv3e05bDN861tx477y9GPb+cgivfNX7QWNNNhCBEQI/sG4hXPc/n2z0543FxRBONPd2E954Y1X4uX0nwtGjlgABAm0KfObGxfCxjx5v9DeBs9Z4bsU8PW88PGzihu3DlxZ/84+P1LrzsMlf5udptNcSIJC2wMLCQjh5stlfrL944Hh46svNjpl2l1RPoHqBLDz83E+uCmu+/Qy4Rj4WwkI42eCP83/yJyE88PPHhYeNdNcgBMYLZDsPf/zHVjVK1PTPNy+/cjLs3nO8t+FhE7+LN7qADJasQLbz8LLvyzYSNPeRbY7wMbtA4+Hh7KVO/8rsoSj5fQ7Pft8a9zycns6RBAgQWBJw2bLFQKB9AZctt98DFRDoi4DLlvvSafMk0L6Ay5bb70HZCjoRHmaXK5+39oNLlxZnnx949MmRT0j2tOWyS8TxBAj0VUB42NfOhxBcUR5N84WH0bRCIQQ6LyA87HyLTZBANALCw2haMXUhnQgPs/sQbtp6X/ja698YTHz4nofZ5/kTlB974uDg63dv3bD09OTs8zxQfO7Fw4OvP/TAtqUgMvs8v5di9v+vvnLdsvsjTi3tQAIECCQmIDxMrGHK7aSA8LCTbTUpAlEKCA+jbIuiCHRSQHiYXls7ER6mx65iAgQIxC8gPIy/RyrsvoDwsPs9NkMCsQgID2PphDoIdF9AeJhej4WH6fVMxQQIEGhEQHjYCLNBCEwUEB5aIAQINCUgPGxK2jgECAgP01sDwsP0eqZiAgQINCIgPGyE2SAEhIdHQrh/zzFPW/a9QKBlAeFhyw0wPIEeCQgP02u28DC9nqmYAAECjQgIDxthNggB4aHw0HcBgSgEhIdRtEERBHohIDxMr83Cw/R6pmICBAg0IiA8bITZIASEh8JD3wUEohAQHkbRBkUQ6IWA8DC9NgsP0+uZigkQINCIgPCwEWaDEBAeCg99FxCIQkB4GEUbFEGgFwLCw/TaLDxMr2cqJkCAQCMCwsNGmA1CQHgoPPRdQCAKAeFhFG1QBIFeCAgP02uz8DCFnp0MISykUKgaCRDokoDwsEvdNJdUBTxtOdXOqZtAegLCw/R6Vm/F2S+g2S+iPghULyA8rN607jMKD+sWdn4CBAgkKiA8TLRxvSm7H7/UCA97s6BNlEDrAsLD1lugAAK9ERAeptfqyMJDW+zSW0IqJkCgqwLCw6521rxSEhAeptQttRJIW0B4mHb/VE8gJQHhYUrd+natkYWH6QGqmAABAl0VEB52tbPmlZKA8DClbqmVQNoCwsO0+6d6AikJCA9T6pbwML1uqZgAAQINCggPG8Q2FIExAsJDS4MAgaYEhIdNSRuHAAHhYXprwM7D9HqmYgIECDQiIDxshNkgBCYKCA8tEAIEmhIQHjYlbRwCBISH6a0B4WF6PVMxAQIEGhEQHjbCbBACwsMjIdy/51h45aue6unbgUCbAsLDNvWNTaBfAsLD9PotPEyvZyomQIBAIwLCw0aYDUJAeFgqPOzHU7Z9WxBoQ0B42Ia6MQn0U0B4mF7fhYfp9UzFBAgQaERAeNgIs0EICA9LhYcWDAECdQkID+uSdV4CBIoCwsP01oTwML2eqZgAAQKNCAgPG2E2CAHhofDQdwGBKASEh1G0QREEeiEgPEyvzcLD9HqmYgIECDQiIDxshNkgBISHwsOovwuyO1FmF4v76L6A8LD7PTZDArEICA9j6cT0dXQwPPQjzvTtdyQBAgTGCwgPrQ4C7Qt42nL7PVABgb4ICA/70mnzJNC+gPCw/R6UraCD4WFZAscTIECAwCgB4aF1QaB9AeFh+z1QAYG+CAgPq+m0rSzVODpLtwWEh+n1V3gYac/8oxNpY5RFYF6BhL65hYfzNtvrCcwvIDyc39AZCBCYTkB4OJ2TowgQmF9AeDi/YdNnEB42LW48AgQIJCIgPEykUcrstIDwsNPtNTkCUQkID6Nqh2ISEEhoT0B0msLD6FqyYkHCwxWJHECAAIF+CggP+9l3s45LQHgYVz9UQ6DLAsLDLnfX3AjEJfD3fnxVWHfZYlxFqWaigPDQAiFAgACBkQLCQwuDQPsCwsP2e6ACAn0REB72pdPmSaB9ATsP2+9B2QqEh2XFHE+AAIGeCAgPe9Jo04xaQHgYdXsUR6BTAsLDTrXTZAhELSA8jLo9I4sTHqbXMxUTSFPATUGS65vwMLmWKbiDAsLDDjbVlAhEKiA8jLQxyiLQQQHhYXpNFR6m1zMVEyBAoBEB4WEjzAYhMFFAeGiBECDQlIDwsClp4xAgIDxMbw0ID9PrmYoJECDQiIDwsBFmgxAQHh4J4f49x8IrX822qPsgQKAtAeFhW/LGJdA/AeFhej3vRHj40suvhk1b7wtfe/0bgw584qMfDnvuvSWcdeaawedH33433Llrf3jsiYODz+/euiFcd9XlS916860jYfO23eG5Fw8P/ttDD2wLl11y0dLXH3n8qXDHzv2Dz6++cl24a8uGcMbpq9Prdq8rds1sr9tv8jMJCA9nYvMiApUK2HlYKaeTESAwQUB4aHkQINCUgPCwKenqxulEePj0s4fCK6++sRQI3r/3QHjtjW8uhXzZ59nHrZvWhzwovG3T+kFAmAeL6y69ePD6LIj8/I594QvbN4YLz18bsnPft/fAUhg5fK7q2uBMBAgQiE9AeBhfT1TUPwHhYf96bsYE2hIQHrYlb1wC/RMQHqbX806Eh0X24cAv+9r2e/aFLTffMAgDs4/hADALC3c9+HDYcfvGwU7FYpiYHXvBeecuBZPFMDG9lquYAAEC0wkID6dzchSBOgWEh3XqOjcBAsMCwkPrgQCBpgSEh01JVzdOJ8PD7DLjg8+8MNh5+OrrX1+2kzCjG/7684cOL9tZOBwubr7p2sHlzvmuxOxrxZ2J1bViujP9+/9wIvz275yY7mBHESBQi8Dq1SFce/WqcP5fWajl/LGcVHgYSyfU0WcB4WGfu2/uBJoVEB426200An0WEB6m1/3OhYfFcK+4s3BUePilR59cdh/DfGdiHh5ef80VS/dALJ7/rT95t9Gu/4cXV4X9/1R42Ci6wQgUBM44PYSf2rgYzj33eGM2i6sWw4kTzT1MYHFxIfz6b4bwewebG7MxTAMRSEggCw83fzaE089o7nvxtFWL4djx5n7WePvoQvj5/cEDUxJal0rtpsAPrFsIf+faEI43+fPGQmj055vXXl8Vfm7fiXD0aDd72JlZZX+fb+6fvc6wpTSRDTcuho9ffLzRNp/5Fz23Yp410qnwMH9wyo7tG8eGfaPCw+F7GmZfL4aHk3YevnusuR+us9r+3bMh/OI/aS6wmGdxeS2Brgpk4eE/+MlV4fzzujrDELKf2f6Pf34iPPVlP7l1t8tmloJAFh7+g02L4S/+xeaqbfp3tj/50xB+Zu8J4WFzLa5tJI+nq422kRNnOw9vvH6x0V/mG5nY0CB/9J9CeODnjwsPm4Y3HoGCwGf/7qpw6SXNsqw+bbHZATs2WrzhYcmfPkYFh1mvsgekdOmeh7//zImw71eFhx37PjSdxASy8PCWm08LHz7fZcuJtU65BJITcNlyci1TMIFkBVy2nGzrFE4gOQGXLSfXshBveFjCcqX7EHbpacvCwxILw6EEahIQHtYE67QECJwiIDy0KAgQaEpAeNiUtHEIEBAeprcGOhEeZg9AuWPn/lP0H3pg2+Dy5fwJyo89cXBwzN1bNyw9PTn7PNuduHnb7vDci4cHX89fl59w+PxXX7lu2f0Rm2658LBpceMROFVAeGhVECDQlIDwsClp4xAgIDy0BggQaEqg6vCw5IWrTU2zU+N0IjzsVEdWmIzwsE/dNtdYBYSHsXZGXQS6JyA87F5PzYhArALCw1g7oy4C3ROoOjzsnlB8MxIexteTiRUJDxNrmHI7KSA87GRbTYpAlALCwyjboigCnRQQHnayrSZFIEoB4WGUbZlYlPAwsZ4JDxNrmHI7KSA87GRbTYpAlALCwyjboigCnRQQHnayrSZFIEoB4WGUbREepteW8RULD7vUTXNJVUB4mGrn1E0gPQHhYXo9UzGBVAWEh6l2Tt0E0hMQHqbXMzsPE+uZ8DCxhim3kwLCw2611Q2Wu9XPrs1GeNi1jrY4n4UQQvaG54PAGAHhoaVBgEBTAsLDpqSrG0d4WJ1lI2cSHjbCbBACEwWEhxYIAQJNCQgPm5I2DgECwkNrgACBpgSEh01JVzeO8HAKy5h2pQgPp2iYQwjULCA8rBnY6QkQWBIQHloMBAg0JSA8bEraOAQICA/TWwPCw8R6JjxMrGHK7aSA8LCTbTUpAlEKCA+jbIuiCHRSQHjYybaaFIEoBYSHUbZlYlHCw8R6JjxMrGHK7aSA8LCTbTUpAlEKCA+jbIuiCHRSQHjYybaaFIEoBYSHUbZFeJheW8ZXLDzsUjfNJVUB4WGqnVM3gfQEhIfp9UzFBFIVEB6m2jl1E0hPQHiYXs/sPEysZ8LDxBqm3E4KCA872VaTIhClgPAwyrYoikAnBYSHnWyrSRGIUkB4GGVbJhYlPEysZ8LDxBqm3E4KCA872VaTIhClgPAwyrYoikAnBYSHnWyrSRGIUkB4GGNbJj8qWHgYY88m1CQ8TKxhyu2kgPCwk201KQJRCggPo2yLogh0UkB42Mm2mhSBKAWmCQ8nR1lRTqvTRQkPE2uv8DCxhim3kwLCw0621aQIRCkgPIyyLYoi0EkB4WEn22pSBKIUmCY8jLLwHhclPEys+cLDxBqm3E4KCA872VaTIhClgPAwyrYoikAnBYSHnWyrSRGIUkB4GGVbJhYlPEysZ8LDxBqm3E4KCA872VaTIhClgPAwyrYoikAnBYSHnWyrSRGIUkB4GGVbhIfptWV8xcLDLnXTXFIVaCU8bOGmH7/68LHw1JezgX0QINCWgPCwLXnjEuifgPCwfz03YwJtCQgP25KffVw7D2e3a+WVwsNW2A1KYJlAK+FhCz0QHraAbkgCBQHhoSVBgEBTAsLDpqSNQ4CA8DC9NSA8TKxnwsPEGqbcTgoIDzvZVpMiEKWA8DDKtiiKQCcFhIedbKtJEYhSQHgYZVsmFiU8TKxnwsPEGqbcTgoIDzvZVpMiEKWA8DDKtiiKQCcFhIedbKtJEYhSQHgYZVuEh+m1ZXzFwsMuddNcUhUQHqbaOXUTSE9AeJhez1RMIFUB4WGqnVM3gfQEhIfp9czOw8R6JjxMrGHK7aSA8LCTbTUpAlEKCA+jbIuiCJQQWAghpPHwMeFhibY6lACBuQSEh3PxtfJi4WEr7LMPKjyc3c4rCVQlIDysStJ5CBBYSUB4uJKQrxMgUJWA8LAqSechQGAlAeHhSkLxfV14GF9PJlYkPEysYcrtpIDwsJNtNSkCUQoID6Nsi6IIdFJAeNjJtpoUgSgFhIdRtmViUcLDxHomPEysYcrtpIDwsJNtNSkCUQoID6Nsi6IIdFJAeNjJtpoUgSgFhIdRtkV4mF5bxlcsPOxSN80lVQHhYaqdUzeB9ASEh+n1TMUEUhUQHqbaOXUTSE9AeJhez+w8TKxnwsPEGqbcTgoIDzvZVpMiEKWA8DDKtiiKQCcFhIedbKtJEYhSQHgYZVsmFiU8TKxnwsPEGqbcTgoIDzvZVpMiEKWA8DDKtiiKQCcFhIedbKtJEYhSQHgYZVv6Ex6++daRsP2efWHLzTeEC89fuzTxo2+/G+7ctT889sTBwX+7e+uGcN1Vly99PXvd5m27w3MvHh78t4ce2BYuu+Sipa8/8vhT4Y6d+wefX33lunDXlg3hjNNXt9Jt4WEr7AYlsExAeGhBECDQlIDwsClp4xAgIDy0BggQaEpAeNiUdHXjdGLn4XA4+KFz3h/27rxtWXh4/94DA7FbN60PeVB426b1g4Awf+26Sy8eBIovvfxq+PyOfeEL2zcOzvH0s4fCfXsPhD333hLOOnNNGD5XdW2Y/kzCw+mtHEmgLgHhYV2yzkuAQFFAeGhNECDQlIDwsClp40QjsBBCOBlNNb0qRHiYXrs7ER7m7KN2Ho76b8MBYBYW7nrw4bDj9o2DcLAYJmbHXnDeuUs7FYthYtMtFx42LW48AqcKCA+tCgIEmhIQHjYlbRwCPRMYEZoID3u2BkyXQIsCwsMW8WccuvPhYXEnYeaUXYZ88JkXBpcfP3/o8LKdhdnX83Bx803XDi53znclZl8bdb4Z7Wd6mfBwJjYvIlCpgPCwUk4nI0BggoDw0PIgQKApAeFhU9LGIUBAeJjeGuhFeDi8s3BUePilR59cdh/DYnh4/TVXLN0DsRgeHjl6rNGuP/f8Ytj/T483OqbBCHRNILs6IfuD+6wfWXj4Uz+xGNaube46h1ULC+H4yebGW1wI4Z//Rgi/e7C5MWfth9cR6LJAFh7e/PcWwhl/obnvxVWrFsLx482Nd/ToQtjziyfDK19tbswurxlzIzCrwA+sWwjX/60QTjT4rdj0zzevfW0h/MwvnAhHj86q5HUECFQhsOHHV4VPfPxEFaea+hxrzjht6mMdeKpAL8LD4XsYjgoPh+9pmH29zM7Dd95tNsj7d/9+IfzSP2l2TN84BAgsF8jCw3/wk6vCed/Z3E/XCwsL4WSD4eHCQgi/9usnw+9+ubk5WmfDAm7CYz18WyALD3/6JxbDd3xHg9+L2RtAg+83f/qnC+Fn953oSHjoe9f3broC2c7DT/2d7OeN5uawsLgQTjaYVr7y1YXwj/YeFx4212IjERgp8NkfXxW+73sbfLMJIbx39SrdmEOg8+Ghex7OsTq8lACBkQIuW7YwCBBoSsBly01JG4cAAZctWwMECDQl4LLlpqSrG6fz4WFG5WnL1S0YZyJAIAThoVVAYDqBeW8RMN0o3T5KeNjt/podgZgEhIcxdUMtBLotIDxMr7+dCA/zJyQ/9sTBpQ5cfeW6pfsYFr9+99YNS09Pzl6Q7U7cvG13eO7Fw4PXP/TAtqV7HGafZw9YuWPn/sHXhs/bRrs9MKUNdWMSWC4gPLQiCBBoSkB42JS0cQgQEB5aAwQINCUgPGxKurpxOhEeVscR/5mEh/H3SIXdFxAedr/HZkggFgHhYSydUAeB7gsID7vfYzMkEIuA8DCWTkxfh/BweqsojhQeRtEGRfRcQHjY8wVg+gQaFBAeNohtKAI9F+hWeDj6xhl/+PLJcP+eYx6Y0vO1bvrtCwgP2+9B2QpmDA/dxagsdFXHCw+rknSe2QU8SVJ4OPvq8UoCBMoJCA/LeTmaAIHZBboVHo52EB7Ovj68kkCVAsLDKjWbOdeM4WEzxRnlVAHhoVVBoH0B4WH7PVABgb4ICA/70mnzJNC+gPCw/R6ogEBfBISH6XVaeJhYz4SHiTVMuZ0UEB52sq0mRSBKAeFhlG1RFIFOCggPO9lWkyIQpYDwMMq2TCxKeJhYz4SHiTVMuZ0UEB52sq0mRSBKAeFhlG1RFIFOCggPO9lWkyIQpYDwMMq2CA/Ta8v4ioWHXeqmuaQqIDxMtXPqJpCegPAwvZ6pmECqAsLDVDunbgLpCQgP0+uZnYeJ9Ux4mFjDlNtJAeFhJ9tqUgSiFBAeRtkWRRHopIDwsJNtNSkCUQoID6Nsy8SihIeJ9Ux4mFjDlNtJAeFhJ9tqUgSiFBAeRtkWRRHopIDwsJNtNSkCUQoID6Nsi/AwvbaMr1h42KVumkuqAsLDVDunbgLpCQgP0+uZigmkKiA8TLVz6iaQnoDwML2e2XmYWM+Eh4k1TLmdFBAedrKtJkUgSgHhYZRtURSBTgoIDzvZVpMiEKVA++HhyRDCQpQ2sRYlPIy1M2PqEh4m1jDldlJAeNjJtpoUgSgFhIdRtkVRBDopIDzsZFtNikCUAu2Hh1GyRF1U8+GhgHeuBSE8nIvPiwlUIiA8rITRSQgQmEJAeDgFkkMIEKhEQHhYCaOTECAwhYDwcAqkyA5pPjyMDCC1coSHqXVMvV0UEB52savmRCBOAeFhnH1RFYEuCggPu9hVcyIQp4DwMM6+TKpKeNhiz2bZhCk8bLFhhibwZwLCQ0uBAIGmBISHTUkbhwAB4aE1QIBAUwLCw6akqxtHeFidZSNnEh42wmwQAhMFhIcWCAECTQkID5uSNg4BAsJDa4AAgaYEhIdNSVc3jvCwOstGziQ8bITZIASEhyGEX334WHjqy9keaR8ECLQlIDxsS964BPonIDzsX8/NmEBbAsLDtuRnH1d4OLtdK6+cJjyc5XLoViZjUAKJCth5mGjjlE0gQQHhYYJNUzKBRAWEh4k2TtkEEhQQHqbXtA6Eh/2KyqYJD9NbhiomkJaA8DCtfqmWQMoCwsOUu6d2AmkJCA/T6pdqCaQsIDxMr3sdCA/TQ5+nYuHhPHpeS6AaAeFhNY7OQoDAygLCw5WNHEGAQDUCwsNqHJ2FAIGVBYSHKxvFdoTwMLaOrFCP8DCxhim3kwLCw0621aQIRCkgPIyyLYoi0EkB4WEn22pSBKIUEB5G2ZaJRQkPE+uZ8DCxhim3kwLxh4fV3M7BA1M6uXxNKjEB4WFiDVMugYQFhIcJN0/pBBITEB4m1rAQgvAwsZ4JDxNrmHI7KRB/eFgNu/CwGkdnITCPgPBwHj2vJUCgjIDwsIyWY+cXWAghZH/w7tBHB6dUV3eEh3XJ1nde4WF9trWcWXhYC6uTEiglIDwsxeVgAgTmEBAezoHnpb0TqGbffe/YliYsPOxv782cQNMCwsOmxecfT3g4v2GjZxAeNsptMAIjBYSHFgYBAk0JCA+bkjYOAQLCQ2uAAIGmBISHTUlXN47wsDrLRs4kPGyE2SAEJgoIDy0QAgSaEhAeNiVtnE4LuJRwqvbGFB7WtYv0D18+Ge7fcywcPToViYMIEKhJQHhYE2yNpxUe1ohbx6mFh3WoOieBcgLCw3JejiZAYHYB4eHsdl5JgEA5gZjCw3KVT3+08HB6K0cSqFNAeFinbj3nFh7W41rbWYWHtdE6MYGpBYSHU1M5kACBOQWEh3MCejkBAlMLCA+npnIgAQJzCggP5wRs4eXCwynQH3n8qXDHzv2DI6++cl24a8uGcMbpq6d4ZfWHCA+rN3VGAmUFhIdlxRxPgMCsAsLDWeW8jgCBsgLCw7JiJmLIOgAAEm5JREFUjidAYFYB4eGscu29Tni4gv3Tzx4K9+09EPbce0s468w14f69BwavuHXT+la6Jjxshd2gBJYJCA8tiFYE3LOrFfa2B207PKzrvmPDrkeOhME9yF75ajaaDwIE2hIQHrYlb1wC/RMQHqbXc+HhCj3LwsILzjs3XHfV5YMji2Fi0y0XHjYtbjwCpwoID62KtASkjmn1a3m1bYeHTdgJD5tQNgaBlQWEhysbOYIAgWoEhIfVODZ5FuHhBO2jb78b7ty1P6y79OKl8PCll18Nn9+xL3xh+8Zw4flrm+zVYCzhYePkBiRwioDw0KIgQKApAeFhU9LGIUBAeGgNECDQlIDwsCnp6sYRHk4RHl5/zRXhsksuGhxZDA+//tY71XVjhTNle0e+8vJ7wu/82xONjWkgAgROFVi9OoSr/sZCOOvsY53lWbW4EP7vL68KL/xHlxF2tskmloTAX/7AQvgff/hkeM/q40nUO0uR33p3Mfxf/2YxvPF17zez+HkNgaoELv5vF8Jf+2vHw/Hj3f1e/ONvrgqP/esQ3m3uV7iq2uM8BDol8EN/fTFccMG3wskG324+cOZ7O2XY9GSEh1OEh5N2HjYZHja9OIxHgAABAgQIECDQgIC7CzSAbAgCBAgQ6LOA8HC+7gsPV/CL7Z6H87XbqwkQIECAAAECBAgQIECAAAECKQs08Ui3lH2qr114uIJpbE9brn4JOCMBAgQIECBAgAABAgQIECBAgACB0QLCwylWxiOPPxXu2Ll/cOTVV64Ld23ZEM44ffUUr3QIAQIEOiLgj3sdaaRpEEhMwHtPYg1TLgECBAgQINBFAeFhF7tqTo0JZJe1/9KvPb403kMPbFt6uE62a/XTn7t36WvF4Ln42ru3blj2VO9NW+8LX3v9G4PXf+KjHw577r0lnHXmmsbmZiACBOIRePOtI2Hztt3huRcPj3xPKH59+P1keBbFW3HkXxt+P4rr/UZyFM8qVEkfBfKfZYZ/vskeHjj8M8rw1zKj4Z9/iu8nw3+Qz44d917VR2tzJtAngey94CuvvBZu3bR+5LSPvv1uuHPXtzfvDG/cmfTzSvH9JXvtZz911WCM4vtWXD/r9Knz5pqygPAw5e6pvVWB7Jf1X374t8Lmm64d7EQtPok7+wfsvLUfHISJ+T+A537w7ME/YNnne37lN8Nnbvibg0Aw/wdtx/aNg+OzH7xfefWNpTAx+4fytTe+addrqx03OIH2BIrvCdn7y8FnXhi8J2Qf2Q/Y+cO9iu8n2deHf6Au/rI+fK7svaz4eXuzNjIBAm0KDIeAeUCY/6Hitk3rl35e2b5jX9i787Zw4flrR/4sNPxeNfyzT/Fcbc7V2AQINCMw/L6SB3vFkfPfmx574uCyq/5W+nll0s8vfrdqpr9G6baA8LDb/TW7BgVW+iF40j9o+T+Sw0/2Hi69eO/NBqdlKAIEIhQYfk/4f//wq+G+vQeW7U7O/uCQfRT/oj9q52HxWO83ETZcSQQaFsj+CLHrwYfD1r//qXD7jn0hDwuLP8sUf34p7iYq/mF1eBor/ezT8JQNR4BAgwKTdh7mP6tk5eR/fMj+uLnSzytl/vjpZ50Gm22ozggIDzvTShNpWyD7R2j4r+/Fesb9Mp8dN0/w2Pa8jU+AQPMCw7uRnz90+JTwcNwP0KPCw3yn4lU/9MlB2Dju0ubmZ2lEAgTaEBgO/M5+35rBLRPGhYdZfcM/3xR/1pn0882oXdJtzNeYBAg0LzAuPBx+Dyn+LLPSzyvFy5bH7WzMZlsmaGxex4gE4hQQHsbZF1UlJDB8D43ifX/yaaz0161JweKkv9onxKRUAgQqEMh/MB6+V8+oX87LhIf57p+3jvxp+L0/eM49Vivok1MQSFUgez/Zfs++sOXmGwaXIRffX0b9TFIMDy8479yl266Men8avkerex6mulLUTWA+gVHhYfG/jdvpPM3PK/n7zPprrlh6P8or9rvVfL3z6v4KCA/723szr1hg3F/Xp9mROO5+hv4qX3GTnI5ARwSKf5AoPqApm+aov7iPu2x5+Jf97If1A48+6SFNHVkrpkGgjEDxoQLDr83/QDrqoQR5CFhm56HLlst0xrEEuiUwKjwsPkwyn3H+0Mnsnqllfl4ZNYbfrbq1jsymWQHhYbPeRuu4QPEXc8FhxxtuegRaEijuDiqWkb0X/eAnv2fp6e/514vvUfkv79dfc8XSsf4i31JTDUsgQoGVbquSvYfs2vNwuPG6Hx7sVCxzz8Nsuis9cTVCEiURIFCBwDTf+6MeDlfm55VR70fZk+LzB1RWMA2nINArAeFhr9ptslUKZL9gP/G7z4Sf+PFrBqcd9cTk4kMMhsd3qXKV3XAuAt0WGH56e/4L97jdgZPu4zNu5+Hw7mc7D7u9lsyOQBmBlcLD4s8yxT8+DL8fvf3OO+GXH/6tsPmma0P28INJlxWWqdGxBAikJzBNePjrjz8Vfv+ZF8JdWzYM3jOG7/ecfT7888rp731v+PXH/m3421f/9WXvL/n9Wv1hNL01ouL4BISH8fVERYkI5Dt2Hnvi4FLFw/c8HLX1/kPnvD/s3XlbyG9A/tyLh5fNNt+W/1u/czDcsXP/KRLj7qmYCJkyCRCYUaB4KeHwPQ/zMDF/zxh1uXLxMsP8vSjbKVR8Lyuee8aSvYwAgQ4IjAoPh3++GXXPwuHbKBTfT4o/G7nnYQcWiSkQKCEw6jYr436/GXfPw/x3rzLvL6Nut5CV7XerEs1zaO8FhIe9XwJdBDgZQljo4sTMiQABAgQIECBAgAABAgQIECDQqIDwsFFug1UtICasWtT5CBAgQIAAAQIECBAgQIAAAQJ/LiA8tBoIECBAgAABAgQIECBAgAABAgQIEBgpIDy0MAgQIECAAAECBAgQIECAAAECBAgQEB5aAwQIECBAgAABAgQIECBAgAABAgQITC9g5+H0Vo4sCLjfoCVBgAABAgQIECBAgAABAgQIEOi2gPCw2/01OwIECBAgQIBAfAL+AhlfT1REgAABAgQIlBboy480wsPSS8MLCBAgQKAbAn35p74b3TILAgQIECBAgAABAgTaERAetuNuVAIECBAgQIAAAQIECBAgQIAAAQLRC4wND+3HiL53CiRAgAABAgQIECBAgAABAgQIECBQq4Cdh7XyOjkBAgQIEPDnOGuAAAECBAgQIECAAIF0BYSH6fZO5QQIECBAgAABAgQIECBAgAABAgRqFRAezsNrM8k8el5LgAABAgQIECBAIHIBP/BH3iDlESBAgEADAsLDBpANQYAAAQIECBAgQIAAAQIECBAgQCBFAeFhil1TMwECBAgQIECAAAECBAgQIECAAIEGBISHDSAbggABAgQIECBAgAABAgQIECBAgECKAsLDFLumZgIECBAgQKCXAm++dSRs3rY73LZpfbjskotC8fPYUGKvLzYv9RAgQIAAAQIEYhQQHsbYFTURIECAAAECBEYICA8tCwIECBAgQIAAgaYFhIdNixuPAAECBAgQIDCjgPBwRjgvI0CAAAECBAgQmFlAeDgznRcSIECAAAECBGYTeOnlV8OmrfeFr73+jcEJPvHRD4c9994SzjpzzdKlyM+9eHjwtauvXBfu2rIhnHH66lMuU57msuCnnz0U7tt7YHCp8/Yd+5bGfOiBbYNLn7OPRx5/Khx85oWlcbL/lr8urys/5nsuvjDs+NkvLqv7lx/+rfBLv/b42Ho/82M/En75n/2rkM/p7q0bwnVXXb6El89j0pxvvulHw7/8118Ojz1xcJnJbB3oyatOhhAWejJX0yRAgAABAgRqExAe1kbrxAQIECBAgACBUwXy4HDH9o1L4d1vP/kH4SPf/VfC2e9bs+yehtmr7997ILz2xjcHwd7b77xT+p6HWQj46c/duyxwy4LAA48+uRRYThse3rFzf8iDv6Nvvxvu3LV/EOYV/9u6Sy8ehIN5KJjNIw8hi/MfFYCOmvPXv/lW2LvztnDh+WstKwIECBAgQIAAgQYFhIcNYhuKQG0CdhbURuvEBAgQqFogC8ayj1s3rT/l1FmI95VXXlv2tSxs+/yOfeEL2zeeEi6W2XmYh3fZoMPnzMK4acPD4u7EUa8b/m/FsDOf8LBB2TlP1Q//Lp7ChGSqleMgAgQIECBAYISA8NCyIECAAAECBAg0JJDv1rv+miuWdh0OD52Favnlv8P//UPnvH+w6664MzHV8HA4YNzzK79Zas4NtcowBAgQIECAAAECfyYgPLQUCBAgQIAAAQINCUwTHmaljNqVmP33WR6YUrx3YXaetnceFsPDMnNuqFWGIUCAAAECBAj8/+3dMXITMRQGYM5CR0FNTwW5AFBmqLgBt+AIqXMD7kFBx1kYeUYe4xjvSyzLkt6XWl7pfU8Tk5/dFQHhoT1AgAABAgQIEOgvsPXY8vGjwYcrXCU8PH5s+Tk19++YGQkQIECAAAECuQXceZi7/6pfVMB7jRZtrLIIEFhCoB5gcnjacT0wpRRYTmG+e/9uf/dhuVuxPNp7//njrv5v33/sTk4uJyW3emy5rKmcxFwPJDl10MnW+w3LadDlZ+udh8dz1QNUojUvsQkUQYAAAQIECBCYSEB4OFGzLJUAAQIECBBYQ6AGiLWat29e708jrsHdr99/9sV+/XK3CxOvdedhDf3Kacrlp6zn/tOHVw+PP8+eyLwVKNYDUw5rqe9vPDw1+Tk1r7EDVEGAAAECBAgQmEdAeDhPr6yUAAECBAgQIECAAAECBAgQIECAQFcB4WFXbpMRIECAAAECBAgQIDCbgFfCzNYx6yVAgACBlgLCw5aarkWAAAECBAgQIECAAAECBAgQIEBgIQHh4ULNVAoBAgQIECBAgAABAgQIECBAgACBlgLCw5aarkWAAAECBAgQIECAAAECBAgQIEBgIQHh4ULNVAoBAgQIECBAgAABAgQIECBAYAQB74sdoQtt1nAiPNTeNrSuQoAAAQIECBDoLOCfcSFwTCEmgwgQIECAAAECOwF3HtoIBAgQIECAAAECBAgQIECAAAECBAicFBAe2hgECBAgQIAAAQIECBAgQIAAAQIECAgP7QECBAgQIECAAAECBAgQIECAAAECBOIC7jyMWxlJgAABAgQIECBAgAABAgQIECBAIJWA8DBVuxVLgAABAgQIECBAgAABAgQIECBAIC4gPIxbGUmAAAECKQScw5qizYokQIAAAQIECBAgQCAkIDwMMRlEgAABAgQIECBAgAABAgQIECBAIJ+A8DBfz1VMgAABAgQIECBAgAABAgQIECBAICQgPAwxGUSAAAECBAgQIECAAAECBAgQIEAgn4DwMF/PVUyAAAECBAgQIECAAAECBAgQIEAgJCA8DDEZRIAAAQIECBAgQIAAAQIECBAgQCCDwL+HSAoPM/RcjfMLOPx1/h6qgACBmwj49XkTdpMSIECAwJAC578VfWcO2TSLIjCEgPBwiDZYBAECBAgQIECAAAECBAgQIECAAIHxBISH4/XEiggQIECAAAECBAgQIHBGwD1itgcBAgRSCdz4177wMNVuUywBAgQIECBAgAABAgQIECBAgACBuIDwMG5lJAECBAgQIECAAAECBAgQIECAAIFUAsLDVO1WLAECBAgQIECAAAECBAgQIECAAIG4gPAwbmUkAQIEtgVu/C6K7QUaQYAAAQIECBAgQIAAAQIE4gLCw7iVkQQIECBAgACBNAL+LyRNqxVKgAABAgQIEDgrIDy0QQgQIECAAAECBAgQIECAAAECBAgQOCkgPLQxCBAgQIAAAQIECBAgQIAAAQIECBAQHtoDBAgQIECAAAECBJ4IeEbbpiBAgAABAgQI/FfAnYc2BwECfQX8gdbX22wECBAgQIAAAQIECBAgQOACAeHhBXg+SoAAAQIECBAgQIAAAQIECBAgQGBlAeHhyt1VGwECBAgQIECAAAECBAgQIECAAIELBISHF+D5KAECBAgQIECAAAECBAgQIECAAIGVBYSHK3dXbQQIECBAgAABAgQIECBAgEBeAe+cz9v7hpULDxtiuhQBAgReIjDk9/mQi3qJrs8QIECAQC8BXx29pM1DgAABAgT6CggP+3qbjQABAgQIECBAgAABAgQIECBAgMA0AsLDaVploQQIECBAgAABAgQIECBAgAABAgT6CggP+3qb7RoCnpG5hqprEiBAgAABAgQIEJhGwJ8E07TKQgkQmFBAeDhh0yyZAAECBAgQIECAAAECBAgQIECAQA8B4WEPZXMQIECAAAECBAgQIECAAAECBAgQmFDgL0f7l/SeyQmAAAAAAElFTkSuQmCC", - "text/html": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig = px.bar(x=cells, y=dimensions,\n", - " template=\"plotly_white\",\n", - " height=500,\n", - " width=600,\n", - " title=\"The dependence of the VAE layer size on the cell number\")\n", - "fig.update_xaxes(title=\"cell number\")\n", - "fig.update_yaxes(title=\"Layer size\")\n", - "\n", - "fig.show()" - ] - }, - { - "cell_type": "markdown", - "id": "4f75a6fb-d4e3-4188-ae70-28fe298e3882", - "metadata": {}, - "source": [ - "# PAS VAE dim choice" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "3f06a0df-c15a-45d8-a5d7-baf028d97820", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "error_y": { - "array": [ - 0.06080723721443479, - 0.10925925657540869, - 0.0670081222025483, - 0.07549622385577531, - 0.0629396887117361, - 0.0330016920577989, - 0.018056054598589104, - 0.0239023785042898, - 0.0314952822579857, - 0.008174455425378, - 0.0205641780740882, - 0.0121356772465019, - 0.0564421483495132 - ], - "arrayminus": [ - 0.06080723721443479, - 0.1092592565754088, - 0.06700812220254841, - 0.07549622385577519, - 0.0629396887117362, - 0.033001692057798904, - 0.018056054598589097, - 0.023902378504289896, - 0.031495282257985896, - 0.008174455425378, - 0.0205641780740881, - 0.012135677246501901, - 0.056442148349513 - ], - "symmetric": false, - "type": "data" - }, - "hovertemplate": "Layer size=%{x}
Silhouette score=%{y}", - "legendgroup": "", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "", - "offsetgroup": "", - "orientation": "v", - "showlegend": false, - "textposition": "auto", - "type": "bar", - "x": [ - "(64,)", - "(128,)", - "(16,)", - "(8,)", - "(32,)", - "(256,)", - "(2,)", - "(8, 4)", - "(4, 2)", - "(16, 8)", - "(64, 32)", - "(32, 16)", - "(128, 64)" - ], - "xaxis": "x", - "y": [ - -0.1860573371108728, - -0.1748437417971942, - -0.1224957077365197, - -0.115015741298486, - -0.1149869503441839, - -0.0439793202951313, - -0.0334142057963539, - -0.0093752811813049, - -0.0050562651932901, - 0.0020989780877017, - 0.0060312165490468, - 0.0097648913329334, - 0.0111558514881026 - ], - "yaxis": "y" - } - ], - "layout": { - "autosize": true, - "barmode": "relative", - "legend": { - "tracegroupgap": 0 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "white", - "showlakes": true, - "showland": true, - "subunitcolor": "#C8D4E3" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "white", - "polar": { - "angularaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - }, - "bgcolor": "white", - "radialaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "yaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "zaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "baxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "bgcolor": "white", - "caxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - } - } - }, - "title": { - "text": "VAE architecture choice for PBMC dataset" - }, - "xaxis": { - "anchor": "y", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.5, - 12.5 - ], - "title": { - "text": "Layer size" - }, - "type": "category" - }, - "yaxis": { - "anchor": "x", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.30364194271761513, - 0.08713694418262796 - ], - "title": { - "text": "Silhouette score" - }, - "type": "linear" - } - } - }, - "image/png": "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", - "text/html": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "error_y": { - "array": [ - 0.02724560937629969, - 0.026805609618007098, - 0.015184750858443896, - 0.01237057708445101, - 0.017931622685877807, - 0.024956910642183895, - 0.043813699045429005, - 0.09526175043557827, - 0.08644473599006239, - 0.04736585439574789, - 0.09886340639452001, - 0.0864474418988202, - 0.035184858640720074 - ], - "arrayminus": [ - 0.027245609376299815, - 0.026805609618007195, - 0.015184750858443993, - 0.012370577084450898, - 0.01793162268587789, - 0.024956910642183902, - 0.043813699045429, - 0.0952617504355783, - 0.0864447359900625, - 0.04736585439574778, - 0.0988634063945201, - 0.0864474418988202, - 0.03518485864072002 - ], - "symmetric": false, - "type": "data" - }, - "hovertemplate": "Layer size=%{x}
Silhouette score=%{y}", - "legendgroup": "", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "", - "offsetgroup": "", - "orientation": "v", - "showlegend": false, - "textposition": "auto", - "type": "bar", - "x": [ - "(64,)", - "(32,)", - "(16,)", - "(8,)", - "(128,)", - "(256,)", - "(2,)", - "(4, 2)", - "(8, 4)", - "(32, 16)", - "(128, 64)", - "(16, 8)", - "(64, 32)" - ], - "xaxis": "x", - "y": [ - -0.1109521000864953, - -0.1108641817339482, - -0.1103184557263525, - -0.1063497213733789, - -0.0868199445698857, - -0.0756306957762819, - -0.0440270298472186, - 0.2049123308701003, - 0.2241950862006382, - 0.2287535118896317, - 0.2539799854544641, - 0.2601236913285121, - 0.2992305571469267 - ], - "yaxis": "y" - } - ], - "layout": { - "autosize": true, - "barmode": "relative", - "legend": { - "tracegroupgap": 0 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "white", - "showlakes": true, - "showland": true, - "subunitcolor": "#C8D4E3" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "white", - "polar": { - "angularaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - }, - "bgcolor": "white", - "radialaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "yaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "zaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "baxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "bgcolor": "white", - "caxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - } - } - }, - "title": { - "text": "VAE architecture choice for COVID dataset" - }, - "xaxis": { - "anchor": "y", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.5, - 12.5 - ], - "title": { - "text": "Layer size" - }, - "type": "category" - }, - "yaxis": { - "anchor": "x", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.16547777064678285, - 0.38012345303297185 - ], - "title": { - "text": "Silhouette score" - }, - "type": "linear" - } - } - }, - "image/png": "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", - "text/html": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "error_y": { - "array": [ - 0.02531704339214258, - 0.020490760680993397, - 0.016391459341938697, - 0.059308981516719206, - 0.08367029282182009, - 0.0285831838112746, - 0.037115447361105405, - 0.060043875594555596, - 0.013173657459100797, - 0.011940436260437906, - 0.023972378454913, - 0.020951243333114402, - 0.0440337071425887 - ], - "arrayminus": [ - 0.02531704339214269, - 0.02049076068099351, - 0.016391459341938697, - 0.05930898151671929, - 0.0836702928218202, - 0.028583183811274504, - 0.03711544736110539, - 0.06004387559455569, - 0.013173657459100804, - 0.011940436260437899, - 0.0239723784549129, - 0.020951243333114298, - 0.04403370714258881 - ], - "symmetric": false, - "type": "data" - }, - "hovertemplate": "Layer size=%{x}
Silhouette score=%{y}", - "legendgroup": "", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "", - "offsetgroup": "", - "orientation": "v", - "showlegend": false, - "textposition": "auto", - "type": "bar", - "x": [ - "(128,)", - "(64,)", - "(16,)", - "(256,)", - "(32,)", - "(8,)", - "(2,)", - "(32, 16)", - "(4, 2)", - "(16, 8)", - "(8, 4)", - "(128, 64)", - "(64, 32)" - ], - "xaxis": "x", - "y": [ - -0.2294004009286419, - -0.2043308662277685, - -0.1855723575347153, - -0.1848551504532159, - -0.1451477004817231, - -0.1349750483388836, - -0.1192370150893362, - -0.0685220726007937, - -0.0543512733205854, - -0.0464939887641018, - -0.0272947531273504, - -0.0245967555192669, - -0.0227767586785934 - ], - "yaxis": "y" - } - ], - "layout": { - "autosize": true, - "barmode": "relative", - "legend": { - "tracegroupgap": 0 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "white", - "showlakes": true, - "showland": true, - "subunitcolor": "#C8D4E3" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "white", - "polar": { - "angularaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - }, - "bgcolor": "white", - "radialaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "yaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "zaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "baxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "bgcolor": "white", - "caxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - } - } - }, - "title": { - "text": "VAE architecture choice for Liver dataset" - }, - "xaxis": { - "anchor": "y", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.5, - 12.5 - ], - "title": { - "text": "Layer size" - }, - "type": "category" - }, - "yaxis": { - "anchor": "x", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.27004935503105015, - 0.03658885917426085 - ], - "title": { - "text": "Silhouette score" - }, - "type": "linear" - } - } - }, - "image/png": "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", - "text/html": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "error_y": { - "array": [ - 0.02602733401698589, - 0.0643683960659891, - 0.0175000548663726, - 0.013918335934749497, - 0.012796633904139695, - 0.012830444069214304, - 0.017243140035005704, - 0.013430800797110804, - 0.0100192086421911, - 0.022286939794699798, - 0.0193935291258324, - 0.0146640258270026, - 0.0050137279346074 - ], - "arrayminus": [ - 0.0260273340169858, - 0.0643683960659891, - 0.017500054866372593, - 0.013918335934749497, - 0.0127966339041398, - 0.012830444069214297, - 0.0172431400350058, - 0.013430800797110794, - 0.010019208642191003, - 0.0222869397946998, - 0.019393529125832396, - 0.0146640258270028, - 0.0050137279346076 - ], - "symmetric": false, - "type": "data" - }, - "hovertemplate": "Layer size=%{x}
Silhouette score=%{y}", - "legendgroup": "", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "", - "offsetgroup": "", - "orientation": "v", - "showlegend": false, - "textposition": "auto", - "type": "bar", - "x": [ - "(8,)", - "(4, 2)", - "(16,)", - "(128,)", - "(64, 32)", - "(64,)", - "(128, 64)", - "(32,)", - "(32, 16)", - "(8, 4)", - "(256,)", - "(16, 8)", - "(2,)" - ], - "xaxis": "x", - "y": [ - -0.0779434774902489, - -0.0698282331213938, - -0.0622769116761483, - -0.0465521795354829, - -0.0462963792571455, - -0.0462305510890479, - -0.0394281033832718, - -0.033005977329308, - -0.0314524477856689, - -0.0285357347918048, - -0.022680329217898, - -0.0122798415568094, - -0.002957705330638 - ], - "yaxis": "y" - } - ], - "layout": { - "autosize": true, - "barmode": "relative", - "legend": { - "tracegroupgap": 0 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "white", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "#C8D4E3", - "linecolor": "#C8D4E3", - "minorgridcolor": "#C8D4E3", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "white", - "showlakes": true, - "showland": true, - "subunitcolor": "#C8D4E3" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "white", - "polar": { - "angularaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - }, - "bgcolor": "white", - "radialaxis": { - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "yaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - }, - "zaxis": { - "backgroundcolor": "white", - "gridcolor": "#DFE8F3", - "gridwidth": 2, - "linecolor": "#EBF0F8", - "showbackground": true, - "ticks": "", - "zerolinecolor": "#EBF0F8" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "baxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - }, - "bgcolor": "white", - "caxis": { - "gridcolor": "#DFE8F3", - "linecolor": "#A2B1C6", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "#EBF0F8", - "linecolor": "#EBF0F8", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "#EBF0F8", - "zerolinewidth": 2 - } - } - }, - "title": { - "text": "VAE architecture choice for BM dataset" - }, - "xaxis": { - "anchor": "y", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.5, - 12.5 - ], - "title": { - "text": "Layer size" - }, - "type": "category" - }, - "yaxis": { - "anchor": "x", - "autorange": true, - "domain": [ - 0, - 1 - ], - "range": [ - -0.14178445215724825, - 0.00997200724005854 - ], - "title": { - "text": "Silhouette score" - }, - "type": "linear" - } - } - }, - "image/png": "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", - "text/html": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tissues = [\"PBMC\", \"COVID\", \"Liver\", \"BM\"]\n", - "for tissue in tissues:\n", - " df = pd.read_csv(f\"/mnt/pmanas/Ania/scrna-seq/results/{tissue}/pas_vae/param_choice_fix.csv\", index_col=0)\n", - " df.columns = [\"Layer size\", \"Silhouette score\", \"upper\", \"lower\", \"dir\"]\n", - " fig = px.bar(df, x=\"Layer size\", y=\"Silhouette score\", title=f\"VAE architecture choice for {tissue} dataset\", template=\"plotly_white\").update_traces(\n", - " error_y={\n", - " \"type\": \"data\",\n", - " \"symmetric\": False,\n", - " \"array\": df[\"upper\"] - df[\"Silhouette score\"],\n", - " \"arrayminus\": df[\"Silhouette score\"] - df[\"lower\"],\n", - " }\n", - " )\n", - " fig.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6b73d4dc-11a1-45e1-bb3e-4878eeea9134", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "enrich", - "language": "python", - "name": "enrich" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/pas-vae-eval.ipynb b/notebooks/pas-vae-eval.ipynb deleted file mode 100644 index 334845d..0000000 --- a/notebooks/pas-vae-eval.ipynb +++ /dev/null @@ -1,124 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "bd965a6d-9d15-4878-a46d-028cb5a3c507", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import os\n", - "import pandas as pd\n", - "import numpy as np\n", - "import plotly.express as px\n", - "from sklearn.metrics import silhouette_score\n", - "import scipy.stats as st " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "d2c053dc-a4e4-4d25-842c-fc883a78be70", - "metadata": {}, - "outputs": [], - "source": [ - "res_path = \"/mnt/pmanas/Ania/scrna-seq/results/\"" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "0e572aef-7c7a-4019-998f-a551d02248ac", - "metadata": {}, - "outputs": [], - "source": [ - "datasets = [\"BM\", \"COVID\", \"Liver\", \"PBMC\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cd183220-8372-41f7-9c6b-ecaf63ed6813", - "metadata": {}, - "outputs": [], - "source": [ - "for dataset in datasets:\n", - " true_labels = pd.read_csv(os.path.join(\"/mnt/pmanas/Ania/scrna-seq/data/\", dataset, \"true_labels.csv\"), index_col=0)\n", - " chosen_pathways = pd.read_csv(os.path.join(\"/mnt/pmanas/Ania/scrna-seq/data/\", dataset, \"chosen_genesets.csv\"), index_col=0)\n", - " labels = np.array(true_labels.CellType).T\n", - " vae_pas = res_path + dataset + \"/pas_vae/\"\n", - " vae_opts = [vae_pas + folder for folder in os.listdir(vae_pas) if os.path.isdir(vae_pas + folder)]\n", - " layer_params = {}\n", - " uncorr_files = {}\n", - " for vae_opt in vae_opts:\n", - " configs = sorted([os.path.join(vae_opt, file) for file in os.listdir(vae_opt) if file.endswith(\".txt\")])\n", - " for config in configs:\n", - " with open(config, \"r\") as f:\n", - " layer_param = f.readline()[:-1]\n", - " lp_list = []\n", - " unc_files = []\n", - " for i in range(10):\n", - " pas_vae_name = os.path.join(vae_opt, f'pas_trial{config.split(\".\")[0][-1]}_{i}.csv')\n", - " res = pd.read_csv(pas_vae_name, index_col=0)\n", - " res = res.loc[chosen_pathways.index, :]\n", - " if not res.isna().values.any():\n", - " lp_list.append(silhouette_score(res.T, labels))\n", - " unc_files.append(pas_vae_name)\n", - " if len(lp_list) > 2:\n", - " layer_params[layer_param] = lp_list\n", - " uncorr_files[layer_param] = unc_files\n", - " means = []\n", - " upper = []\n", - " lower = []\n", - " best_file = []\n", - " for key, data in layer_params.items():\n", - " means.append(sum(data)/len(data))\n", - " best_file.append(uncorr_files[key][np.argmax(np.array(data))])\n", - " interval = st.t.interval(alpha=0.95, \n", - " df=len(data)-1, \n", - " loc=np.mean(data), \n", - " scale=st.sem(data))\n", - " lower.append(interval[0])\n", - " upper.append(interval[1])\n", - " results = pd.DataFrame([[key for key, _ in layer_params.items()], means, upper, lower, best_file]).T\n", - " results = results.sort_values(by=[1])\n", - " results.to_csv(f\"/mnt/pmanas/Ania/scrna-seq/results/{dataset}/pas_vae/param_choice_fix.csv\")\n", - "\n", - " res = pd.read_csv(results.iloc[-1, -1], index_col=0)\n", - " res = res.loc[chosen_pathways.index, :]\n", - " res.to_csv(f\"/mnt/pmanas/Ania/scrna-seq/results/{dataset}/seurat/vae.csv\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "762202aa-bba7-493a-9dad-6b984172b0c4", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "enrich", - "language": "python", - "name": "enrich" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/poetry.lock b/poetry.lock index dd185c7..d98d581 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,35 +1,10 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "absl-py" -version = "2.1.0" -description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." -optional = false -python-versions = ">=3.7" -files = [ - {file = "absl-py-2.1.0.tar.gz", hash = "sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff"}, - {file = "absl_py-2.1.0-py3-none-any.whl", hash = "sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308"}, -] - -[[package]] -name = "astunparse" -version = "1.6.3" -description = "An AST unparser for Python" -optional = false -python-versions = "*" -files = [ - {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, - {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, -] - -[package.dependencies] -six = ">=1.6.1,<2.0" -wheel = ">=0.23.0,<1.0" +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. [[package]] name = "black" version = "23.12.1" description = "The uncompromising code formatter." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -72,136 +47,16 @@ d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] -[[package]] -name = "cachetools" -version = "5.3.3" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, - {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, -] - -[[package]] -name = "certifi" -version = "2024.2.2" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, -] - [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -211,6 +66,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -222,6 +78,7 @@ files = [ name = "contourpy" version = "1.1.1" description = "Python library for calculating contours of 2D quadrilateral grids" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -293,6 +150,7 @@ test-no-images = ["pytest", "pytest-cov", "wurlitzer"] name = "cycler" version = "0.12.1" description = "Composable style cycles" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -306,78 +164,80 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.3.0" description = "Backport of PEP 654 (exception groups)" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, + {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + [package.extras] test = ["pytest (>=6)"] -[[package]] -name = "flatbuffers" -version = "24.3.25" -description = "The FlatBuffers serialization format for Python" -optional = false -python-versions = "*" -files = [ - {file = "flatbuffers-24.3.25-py2.py3-none-any.whl", hash = "sha256:8dbdec58f935f3765e4f7f3cf635ac3a77f83568138d6a2311f524ec96364812"}, - {file = "flatbuffers-24.3.25.tar.gz", hash = "sha256:de2ec5b203f21441716617f38443e0a8ebf3d25bf0d9c0bb0ce68fa00ad546a4"}, -] - [[package]] name = "fonttools" -version = "4.51.0" +version = "4.57.0" description = "Tools to manipulate font files" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.51.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:84d7751f4468dd8cdd03ddada18b8b0857a5beec80bce9f435742abc9a851a74"}, - {file = "fonttools-4.51.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8b4850fa2ef2cfbc1d1f689bc159ef0f45d8d83298c1425838095bf53ef46308"}, - {file = "fonttools-4.51.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5b48a1121117047d82695d276c2af2ee3a24ffe0f502ed581acc2673ecf1037"}, - {file = "fonttools-4.51.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:180194c7fe60c989bb627d7ed5011f2bef1c4d36ecf3ec64daec8302f1ae0716"}, - {file = "fonttools-4.51.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:96a48e137c36be55e68845fc4284533bda2980f8d6f835e26bca79d7e2006438"}, - {file = "fonttools-4.51.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:806e7912c32a657fa39d2d6eb1d3012d35f841387c8fc6cf349ed70b7c340039"}, - {file = "fonttools-4.51.0-cp310-cp310-win32.whl", hash = "sha256:32b17504696f605e9e960647c5f64b35704782a502cc26a37b800b4d69ff3c77"}, - {file = "fonttools-4.51.0-cp310-cp310-win_amd64.whl", hash = "sha256:c7e91abdfae1b5c9e3a543f48ce96013f9a08c6c9668f1e6be0beabf0a569c1b"}, - {file = "fonttools-4.51.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a8feca65bab31479d795b0d16c9a9852902e3a3c0630678efb0b2b7941ea9c74"}, - {file = "fonttools-4.51.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ac27f436e8af7779f0bb4d5425aa3535270494d3bc5459ed27de3f03151e4c2"}, - {file = "fonttools-4.51.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e19bd9e9964a09cd2433a4b100ca7f34e34731e0758e13ba9a1ed6e5468cc0f"}, - {file = "fonttools-4.51.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2b92381f37b39ba2fc98c3a45a9d6383bfc9916a87d66ccb6553f7bdd129097"}, - {file = "fonttools-4.51.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5f6bc991d1610f5c3bbe997b0233cbc234b8e82fa99fc0b2932dc1ca5e5afec0"}, - {file = "fonttools-4.51.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9696fe9f3f0c32e9a321d5268208a7cc9205a52f99b89479d1b035ed54c923f1"}, - {file = "fonttools-4.51.0-cp311-cp311-win32.whl", hash = "sha256:3bee3f3bd9fa1d5ee616ccfd13b27ca605c2b4270e45715bd2883e9504735034"}, - {file = "fonttools-4.51.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f08c901d3866a8905363619e3741c33f0a83a680d92a9f0e575985c2634fcc1"}, - {file = "fonttools-4.51.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4060acc2bfa2d8e98117828a238889f13b6f69d59f4f2d5857eece5277b829ba"}, - {file = "fonttools-4.51.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1250e818b5f8a679ad79660855528120a8f0288f8f30ec88b83db51515411fcc"}, - {file = "fonttools-4.51.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76f1777d8b3386479ffb4a282e74318e730014d86ce60f016908d9801af9ca2a"}, - {file = "fonttools-4.51.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b5ad456813d93b9c4b7ee55302208db2b45324315129d85275c01f5cb7e61a2"}, - {file = "fonttools-4.51.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:68b3fb7775a923be73e739f92f7e8a72725fd333eab24834041365d2278c3671"}, - {file = "fonttools-4.51.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8e2f1a4499e3b5ee82c19b5ee57f0294673125c65b0a1ff3764ea1f9db2f9ef5"}, - {file = "fonttools-4.51.0-cp312-cp312-win32.whl", hash = "sha256:278e50f6b003c6aed19bae2242b364e575bcb16304b53f2b64f6551b9c000e15"}, - {file = "fonttools-4.51.0-cp312-cp312-win_amd64.whl", hash = "sha256:b3c61423f22165541b9403ee39874dcae84cd57a9078b82e1dce8cb06b07fa2e"}, - {file = "fonttools-4.51.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1621ee57da887c17312acc4b0e7ac30d3a4fb0fec6174b2e3754a74c26bbed1e"}, - {file = "fonttools-4.51.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d9298be7a05bb4801f558522adbe2feea1b0b103d5294ebf24a92dd49b78e5"}, - {file = "fonttools-4.51.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee1af4be1c5afe4c96ca23badd368d8dc75f611887fb0c0dac9f71ee5d6f110e"}, - {file = "fonttools-4.51.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c18b49adc721a7d0b8dfe7c3130c89b8704baf599fb396396d07d4aa69b824a1"}, - {file = "fonttools-4.51.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:de7c29bdbdd35811f14493ffd2534b88f0ce1b9065316433b22d63ca1cd21f14"}, - {file = "fonttools-4.51.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cadf4e12a608ef1d13e039864f484c8a968840afa0258b0b843a0556497ea9ed"}, - {file = "fonttools-4.51.0-cp38-cp38-win32.whl", hash = "sha256:aefa011207ed36cd280babfaa8510b8176f1a77261833e895a9d96e57e44802f"}, - {file = "fonttools-4.51.0-cp38-cp38-win_amd64.whl", hash = "sha256:865a58b6e60b0938874af0968cd0553bcd88e0b2cb6e588727117bd099eef836"}, - {file = "fonttools-4.51.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:60a3409c9112aec02d5fb546f557bca6efa773dcb32ac147c6baf5f742e6258b"}, - {file = "fonttools-4.51.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f7e89853d8bea103c8e3514b9f9dc86b5b4120afb4583b57eb10dfa5afbe0936"}, - {file = "fonttools-4.51.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56fc244f2585d6c00b9bcc59e6593e646cf095a96fe68d62cd4da53dd1287b55"}, - {file = "fonttools-4.51.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d145976194a5242fdd22df18a1b451481a88071feadf251221af110ca8f00ce"}, - {file = "fonttools-4.51.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5b8cab0c137ca229433570151b5c1fc6af212680b58b15abd797dcdd9dd5051"}, - {file = "fonttools-4.51.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:54dcf21a2f2d06ded676e3c3f9f74b2bafded3a8ff12f0983160b13e9f2fb4a7"}, - {file = "fonttools-4.51.0-cp39-cp39-win32.whl", hash = "sha256:0118ef998a0699a96c7b28457f15546815015a2710a1b23a7bf6c1be60c01636"}, - {file = "fonttools-4.51.0-cp39-cp39-win_amd64.whl", hash = "sha256:599bdb75e220241cedc6faebfafedd7670335d2e29620d207dd0378a4e9ccc5a"}, - {file = "fonttools-4.51.0-py3-none-any.whl", hash = "sha256:15c94eeef6b095831067f72c825eb0e2d48bb4cea0647c1b05c981ecba2bf39f"}, - {file = "fonttools-4.51.0.tar.gz", hash = "sha256:dc0673361331566d7a663d7ce0f6fdcbfbdc1f59c6e3ed1165ad7202ca183c68"}, + {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:babe8d1eb059a53e560e7bf29f8e8f4accc8b6cfb9b5fd10e485bde77e71ef41"}, + {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:81aa97669cd726349eb7bd43ca540cf418b279ee3caba5e2e295fb4e8f841c02"}, + {file = "fonttools-4.57.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0e9618630edd1910ad4f07f60d77c184b2f572c8ee43305ea3265675cbbfe7e"}, + {file = "fonttools-4.57.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34687a5d21f1d688d7d8d416cb4c5b9c87fca8a1797ec0d74b9fdebfa55c09ab"}, + {file = "fonttools-4.57.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69ab81b66ebaa8d430ba56c7a5f9abe0183afefd3a2d6e483060343398b13fb1"}, + {file = "fonttools-4.57.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d639397de852f2ccfb3134b152c741406752640a266d9c1365b0f23d7b88077f"}, + {file = "fonttools-4.57.0-cp310-cp310-win32.whl", hash = "sha256:cc066cb98b912f525ae901a24cd381a656f024f76203bc85f78fcc9e66ae5aec"}, + {file = "fonttools-4.57.0-cp310-cp310-win_amd64.whl", hash = "sha256:7a64edd3ff6a7f711a15bd70b4458611fb240176ec11ad8845ccbab4fe6745db"}, + {file = "fonttools-4.57.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3871349303bdec958360eedb619169a779956503ffb4543bb3e6211e09b647c4"}, + {file = "fonttools-4.57.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c59375e85126b15a90fcba3443eaac58f3073ba091f02410eaa286da9ad80ed8"}, + {file = "fonttools-4.57.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967b65232e104f4b0f6370a62eb33089e00024f2ce143aecbf9755649421c683"}, + {file = "fonttools-4.57.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39acf68abdfc74e19de7485f8f7396fa4d2418efea239b7061d6ed6a2510c746"}, + {file = "fonttools-4.57.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d077f909f2343daf4495ba22bb0e23b62886e8ec7c109ee8234bdbd678cf344"}, + {file = "fonttools-4.57.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:46370ac47a1e91895d40e9ad48effbe8e9d9db1a4b80888095bc00e7beaa042f"}, + {file = "fonttools-4.57.0-cp311-cp311-win32.whl", hash = "sha256:ca2aed95855506b7ae94e8f1f6217b7673c929e4f4f1217bcaa236253055cb36"}, + {file = "fonttools-4.57.0-cp311-cp311-win_amd64.whl", hash = "sha256:17168a4670bbe3775f3f3f72d23ee786bd965395381dfbb70111e25e81505b9d"}, + {file = "fonttools-4.57.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:889e45e976c74abc7256d3064aa7c1295aa283c6bb19810b9f8b604dfe5c7f31"}, + {file = "fonttools-4.57.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0425c2e052a5f1516c94e5855dbda706ae5a768631e9fcc34e57d074d1b65b92"}, + {file = "fonttools-4.57.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44c26a311be2ac130f40a96769264809d3b0cb297518669db437d1cc82974888"}, + {file = "fonttools-4.57.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c41ba992df5b8d680b89fd84c6a1f2aca2b9f1ae8a67400c8930cd4ea115f6"}, + {file = "fonttools-4.57.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea1e9e43ca56b0c12440a7c689b1350066595bebcaa83baad05b8b2675129d98"}, + {file = "fonttools-4.57.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84fd56c78d431606332a0627c16e2a63d243d0d8b05521257d77c6529abe14d8"}, + {file = "fonttools-4.57.0-cp312-cp312-win32.whl", hash = "sha256:f4376819c1c778d59e0a31db5dc6ede854e9edf28bbfa5b756604727f7f800ac"}, + {file = "fonttools-4.57.0-cp312-cp312-win_amd64.whl", hash = "sha256:57e30241524879ea10cdf79c737037221f77cc126a8cdc8ff2c94d4a522504b9"}, + {file = "fonttools-4.57.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:408ce299696012d503b714778d89aa476f032414ae57e57b42e4b92363e0b8ef"}, + {file = "fonttools-4.57.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bbceffc80aa02d9e8b99f2a7491ed8c4a783b2fc4020119dc405ca14fb5c758c"}, + {file = "fonttools-4.57.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f022601f3ee9e1f6658ed6d184ce27fa5216cee5b82d279e0f0bde5deebece72"}, + {file = "fonttools-4.57.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dea5893b58d4637ffa925536462ba626f8a1b9ffbe2f5c272cdf2c6ebadb817"}, + {file = "fonttools-4.57.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dff02c5c8423a657c550b48231d0a48d7e2b2e131088e55983cfe74ccc2c7cc9"}, + {file = "fonttools-4.57.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:767604f244dc17c68d3e2dbf98e038d11a18abc078f2d0f84b6c24571d9c0b13"}, + {file = "fonttools-4.57.0-cp313-cp313-win32.whl", hash = "sha256:8e2e12d0d862f43d51e5afb8b9751c77e6bec7d2dc00aad80641364e9df5b199"}, + {file = "fonttools-4.57.0-cp313-cp313-win_amd64.whl", hash = "sha256:f1d6bc9c23356908db712d282acb3eebd4ae5ec6d8b696aa40342b1d84f8e9e3"}, + {file = "fonttools-4.57.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d57b4e23ebbe985125d3f0cabbf286efa191ab60bbadb9326091050d88e8213"}, + {file = "fonttools-4.57.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:579ba873d7f2a96f78b2e11028f7472146ae181cae0e4d814a37a09e93d5c5cc"}, + {file = "fonttools-4.57.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e3e1ec10c29bae0ea826b61f265ec5c858c5ba2ce2e69a71a62f285cf8e4595"}, + {file = "fonttools-4.57.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1968f2a2003c97c4ce6308dc2498d5fd4364ad309900930aa5a503c9851aec8"}, + {file = "fonttools-4.57.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:aff40f8ac6763d05c2c8f6d240c6dac4bb92640a86d9b0c3f3fff4404f34095c"}, + {file = "fonttools-4.57.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d07f1b64008e39fceae7aa99e38df8385d7d24a474a8c9872645c4397b674481"}, + {file = "fonttools-4.57.0-cp38-cp38-win32.whl", hash = "sha256:51d8482e96b28fb28aa8e50b5706f3cee06de85cbe2dce80dbd1917ae22ec5a6"}, + {file = "fonttools-4.57.0-cp38-cp38-win_amd64.whl", hash = "sha256:03290e818782e7edb159474144fca11e36a8ed6663d1fcbd5268eb550594fd8e"}, + {file = "fonttools-4.57.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7339e6a3283e4b0ade99cade51e97cde3d54cd6d1c3744459e886b66d630c8b3"}, + {file = "fonttools-4.57.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:05efceb2cb5f6ec92a4180fcb7a64aa8d3385fd49cfbbe459350229d1974f0b1"}, + {file = "fonttools-4.57.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a97bb05eb24637714a04dee85bdf0ad1941df64fe3b802ee4ac1c284a5f97b7c"}, + {file = "fonttools-4.57.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:541cb48191a19ceb1a2a4b90c1fcebd22a1ff7491010d3cf840dd3a68aebd654"}, + {file = "fonttools-4.57.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cdef9a056c222d0479a1fdb721430f9efd68268014c54e8166133d2643cb05d9"}, + {file = "fonttools-4.57.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3cf97236b192a50a4bf200dc5ba405aa78d4f537a2c6e4c624bb60466d5b03bd"}, + {file = "fonttools-4.57.0-cp39-cp39-win32.whl", hash = "sha256:e952c684274a7714b3160f57ec1d78309f955c6335c04433f07d36c5eb27b1f9"}, + {file = "fonttools-4.57.0-cp39-cp39-win_amd64.whl", hash = "sha256:a2a722c0e4bfd9966a11ff55c895c817158fcce1b2b6700205a376403b546ad9"}, + {file = "fonttools-4.57.0-py3-none-any.whl", hash = "sha256:3122c604a675513c68bd24c6a8f9091f1c2376d18e8f5fe5a101746c81b3e98f"}, + {file = "fonttools-4.57.0.tar.gz", hash = "sha256:727ece10e065be2f9dd239d15dd5d60a66e17eac11aea47d447f9f03fdbc42de"}, ] [package.extras] @@ -398,6 +258,7 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "future" version = "1.0.0" description = "Clean single-source support for Python 3 and 2" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -405,191 +266,11 @@ files = [ {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, ] -[[package]] -name = "gast" -version = "0.4.0" -description = "Python AST that abstracts the underlying Python version" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "gast-0.4.0-py3-none-any.whl", hash = "sha256:b7adcdd5adbebf1adf17378da5ba3f543684dbec47b1cda1f3997e573cd542c4"}, - {file = "gast-0.4.0.tar.gz", hash = "sha256:40feb7b8b8434785585ab224d1568b857edb18297e5a3047f1ba012bc83b42c1"}, -] - -[[package]] -name = "google-auth" -version = "2.29.0" -description = "Google Authentication Library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "google-auth-2.29.0.tar.gz", hash = "sha256:672dff332d073227550ffc7457868ac4218d6c500b155fe6cc17d2b13602c360"}, - {file = "google_auth-2.29.0-py2.py3-none-any.whl", hash = "sha256:d452ad095688cd52bae0ad6fafe027f6a6d6f560e810fec20914e17a09526415"}, -] - -[package.dependencies] -cachetools = ">=2.0.0,<6.0" -pyasn1-modules = ">=0.2.1" -rsa = ">=3.1.4,<5" - -[package.extras] -aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] -enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] -pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] -reauth = ["pyu2f (>=0.1.5)"] -requests = ["requests (>=2.20.0,<3.0.0.dev0)"] - -[[package]] -name = "google-auth-oauthlib" -version = "1.0.0" -description = "Google Authentication Library" -optional = false -python-versions = ">=3.6" -files = [ - {file = "google-auth-oauthlib-1.0.0.tar.gz", hash = "sha256:e375064964820b47221a7e1b7ee1fd77051b6323c3f9e3e19785f78ab67ecfc5"}, - {file = "google_auth_oauthlib-1.0.0-py2.py3-none-any.whl", hash = "sha256:95880ca704928c300f48194d1770cf5b1462835b6e49db61445a520f793fd5fb"}, -] - -[package.dependencies] -google-auth = ">=2.15.0" -requests-oauthlib = ">=0.7.0" - -[package.extras] -tool = ["click (>=6.0.0)"] - -[[package]] -name = "google-pasta" -version = "0.2.0" -description = "pasta is an AST-based Python refactoring library" -optional = false -python-versions = "*" -files = [ - {file = "google-pasta-0.2.0.tar.gz", hash = "sha256:c9f2c8dfc8f96d0d5808299920721be30c9eec37f2389f28904f454565c8a16e"}, - {file = "google_pasta-0.2.0-py2-none-any.whl", hash = "sha256:4612951da876b1a10fe3960d7226f0c7682cf901e16ac06e473b267a5afa8954"}, - {file = "google_pasta-0.2.0-py3-none-any.whl", hash = "sha256:b32482794a366b5366a32c92a9a9201b107821889935a02b3e51f6b432ea84ed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "grpcio" -version = "1.62.1" -description = "HTTP/2-based RPC framework" -optional = false -python-versions = ">=3.7" -files = [ - {file = "grpcio-1.62.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:179bee6f5ed7b5f618844f760b6acf7e910988de77a4f75b95bbfaa8106f3c1e"}, - {file = "grpcio-1.62.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:48611e4fa010e823ba2de8fd3f77c1322dd60cb0d180dc6630a7e157b205f7ea"}, - {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:b2a0e71b0a2158aa4bce48be9f8f9eb45cbd17c78c7443616d00abbe2a509f6d"}, - {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbe80577c7880911d3ad65e5ecc997416c98f354efeba2f8d0f9112a67ed65a5"}, - {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f6c693d446964e3292425e1d16e21a97a48ba9172f2d0df9d7b640acb99243"}, - {file = "grpcio-1.62.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:77c339403db5a20ef4fed02e4d1a9a3d9866bf9c0afc77a42234677313ea22f3"}, - {file = "grpcio-1.62.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b5a4ea906db7dec694098435d84bf2854fe158eb3cd51e1107e571246d4d1d70"}, - {file = "grpcio-1.62.1-cp310-cp310-win32.whl", hash = "sha256:4187201a53f8561c015bc745b81a1b2d278967b8de35f3399b84b0695e281d5f"}, - {file = "grpcio-1.62.1-cp310-cp310-win_amd64.whl", hash = "sha256:844d1f3fb11bd1ed362d3fdc495d0770cfab75761836193af166fee113421d66"}, - {file = "grpcio-1.62.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:833379943d1728a005e44103f17ecd73d058d37d95783eb8f0b28ddc1f54d7b2"}, - {file = "grpcio-1.62.1-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:c7fcc6a32e7b7b58f5a7d27530669337a5d587d4066060bcb9dee7a8c833dfb7"}, - {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:fa7d28eb4d50b7cbe75bb8b45ed0da9a1dc5b219a0af59449676a29c2eed9698"}, - {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48f7135c3de2f298b833be8b4ae20cafe37091634e91f61f5a7eb3d61ec6f660"}, - {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71f11fd63365ade276c9d4a7b7df5c136f9030e3457107e1791b3737a9b9ed6a"}, - {file = "grpcio-1.62.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4b49fd8fe9f9ac23b78437da94c54aa7e9996fbb220bac024a67469ce5d0825f"}, - {file = "grpcio-1.62.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:482ae2ae78679ba9ed5752099b32e5fe580443b4f798e1b71df412abf43375db"}, - {file = "grpcio-1.62.1-cp311-cp311-win32.whl", hash = "sha256:1faa02530b6c7426404372515fe5ddf66e199c2ee613f88f025c6f3bd816450c"}, - {file = "grpcio-1.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bd90b8c395f39bc82a5fb32a0173e220e3f401ff697840f4003e15b96d1befc"}, - {file = "grpcio-1.62.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:b134d5d71b4e0837fff574c00e49176051a1c532d26c052a1e43231f252d813b"}, - {file = "grpcio-1.62.1-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d1f6c96573dc09d50dbcbd91dbf71d5cf97640c9427c32584010fbbd4c0e0037"}, - {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:359f821d4578f80f41909b9ee9b76fb249a21035a061a327f91c953493782c31"}, - {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a485f0c2010c696be269184bdb5ae72781344cb4e60db976c59d84dd6354fac9"}, - {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b50b09b4dc01767163d67e1532f948264167cd27f49e9377e3556c3cba1268e1"}, - {file = "grpcio-1.62.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3227c667dccbe38f2c4d943238b887bac588d97c104815aecc62d2fd976e014b"}, - {file = "grpcio-1.62.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3952b581eb121324853ce2b191dae08badb75cd493cb4e0243368aa9e61cfd41"}, - {file = "grpcio-1.62.1-cp312-cp312-win32.whl", hash = "sha256:83a17b303425104d6329c10eb34bba186ffa67161e63fa6cdae7776ff76df73f"}, - {file = "grpcio-1.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:6696ffe440333a19d8d128e88d440f91fb92c75a80ce4b44d55800e656a3ef1d"}, - {file = "grpcio-1.62.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:e3393b0823f938253370ebef033c9fd23d27f3eae8eb9a8f6264900c7ea3fb5a"}, - {file = "grpcio-1.62.1-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:83e7ccb85a74beaeae2634f10eb858a0ed1a63081172649ff4261f929bacfd22"}, - {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:882020c87999d54667a284c7ddf065b359bd00251fcd70279ac486776dbf84ec"}, - {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a10383035e864f386fe096fed5c47d27a2bf7173c56a6e26cffaaa5a361addb1"}, - {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:960edebedc6b9ada1ef58e1c71156f28689978188cd8cff3b646b57288a927d9"}, - {file = "grpcio-1.62.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:23e2e04b83f347d0aadde0c9b616f4726c3d76db04b438fd3904b289a725267f"}, - {file = "grpcio-1.62.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:978121758711916d34fe57c1f75b79cdfc73952f1481bb9583399331682d36f7"}, - {file = "grpcio-1.62.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9084086190cc6d628f282e5615f987288b95457292e969b9205e45b442276407"}, - {file = "grpcio-1.62.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:22bccdd7b23c420a27fd28540fb5dcbc97dc6be105f7698cb0e7d7a420d0e362"}, - {file = "grpcio-1.62.1-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:8999bf1b57172dbc7c3e4bb3c732658e918f5c333b2942243f10d0d653953ba9"}, - {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:d9e52558b8b8c2f4ac05ac86344a7417ccdd2b460a59616de49eb6933b07a0bd"}, - {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1714e7bc935780bc3de1b3fcbc7674209adf5208ff825799d579ffd6cd0bd505"}, - {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8842ccbd8c0e253c1f189088228f9b433f7a93b7196b9e5b6f87dba393f5d5d"}, - {file = "grpcio-1.62.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f1e7b36bdff50103af95a80923bf1853f6823dd62f2d2a2524b66ed74103e49"}, - {file = "grpcio-1.62.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bba97b8e8883a8038606480d6b6772289f4c907f6ba780fa1f7b7da7dfd76f06"}, - {file = "grpcio-1.62.1-cp38-cp38-win32.whl", hash = "sha256:a7f615270fe534548112a74e790cd9d4f5509d744dd718cd442bf016626c22e4"}, - {file = "grpcio-1.62.1-cp38-cp38-win_amd64.whl", hash = "sha256:e6c8c8693df718c5ecbc7babb12c69a4e3677fd11de8886f05ab22d4e6b1c43b"}, - {file = "grpcio-1.62.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:73db2dc1b201d20ab7083e7041946910bb991e7e9761a0394bbc3c2632326483"}, - {file = "grpcio-1.62.1-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:407b26b7f7bbd4f4751dbc9767a1f0716f9fe72d3d7e96bb3ccfc4aace07c8de"}, - {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:f8de7c8cef9261a2d0a62edf2ccea3d741a523c6b8a6477a340a1f2e417658de"}, - {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd5c8a1af40ec305d001c60236308a67e25419003e9bb3ebfab5695a8d0b369"}, - {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0477cb31da67846a33b1a75c611f88bfbcd427fe17701b6317aefceee1b96f"}, - {file = "grpcio-1.62.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:60dcd824df166ba266ee0cfaf35a31406cd16ef602b49f5d4dfb21f014b0dedd"}, - {file = "grpcio-1.62.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:973c49086cabab773525f6077f95e5a993bfc03ba8fc32e32f2c279497780585"}, - {file = "grpcio-1.62.1-cp39-cp39-win32.whl", hash = "sha256:12859468e8918d3bd243d213cd6fd6ab07208195dc140763c00dfe901ce1e1b4"}, - {file = "grpcio-1.62.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7209117bbeebdfa5d898205cc55153a51285757902dd73c47de498ad4d11332"}, - {file = "grpcio-1.62.1.tar.gz", hash = "sha256:6c455e008fa86d9e9a9d85bb76da4277c0d7d9668a3bfa70dbe86e9f3c759947"}, -] - -[package.extras] -protobuf = ["grpcio-tools (>=1.62.1)"] - -[[package]] -name = "h5py" -version = "3.10.0" -description = "Read and write HDF5 files from Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "h5py-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b963fb772964fc1d1563c57e4e2e874022ce11f75ddc6df1a626f42bd49ab99f"}, - {file = "h5py-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:012ab448590e3c4f5a8dd0f3533255bc57f80629bf7c5054cf4c87b30085063c"}, - {file = "h5py-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:781a24263c1270a62cd67be59f293e62b76acfcc207afa6384961762bb88ea03"}, - {file = "h5py-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f42e6c30698b520f0295d70157c4e202a9e402406f50dc08f5a7bc416b24e52d"}, - {file = "h5py-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:93dd840bd675787fc0b016f7a05fc6efe37312a08849d9dd4053fd0377b1357f"}, - {file = "h5py-3.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2381e98af081b6df7f6db300cd88f88e740649d77736e4b53db522d8874bf2dc"}, - {file = "h5py-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:667fe23ab33d5a8a6b77970b229e14ae3bb84e4ea3382cc08567a02e1499eedd"}, - {file = "h5py-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90286b79abd085e4e65e07c1bd7ee65a0f15818ea107f44b175d2dfe1a4674b7"}, - {file = "h5py-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c013d2e79c00f28ffd0cc24e68665ea03ae9069e167087b2adb5727d2736a52"}, - {file = "h5py-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:92273ce69ae4983dadb898fd4d3bea5eb90820df953b401282ee69ad648df684"}, - {file = "h5py-3.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c97d03f87f215e7759a354460fb4b0d0f27001450b18b23e556e7856a0b21c3"}, - {file = "h5py-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86df4c2de68257b8539a18646ceccdcf2c1ce6b1768ada16c8dcfb489eafae20"}, - {file = "h5py-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9ab36be991119a3ff32d0c7cbe5faf9b8d2375b5278b2aea64effbeba66039"}, - {file = "h5py-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:2c8e4fda19eb769e9a678592e67eaec3a2f069f7570c82d2da909c077aa94339"}, - {file = "h5py-3.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:492305a074327e8d2513011fa9fffeb54ecb28a04ca4c4227d7e1e9616d35641"}, - {file = "h5py-3.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9450464b458cca2c86252b624279115dcaa7260a40d3cb1594bf2b410a2bd1a3"}, - {file = "h5py-3.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd6f6d1384a9f491732cee233b99cd4bfd6e838a8815cc86722f9d2ee64032af"}, - {file = "h5py-3.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3074ec45d3dc6e178c6f96834cf8108bf4a60ccb5ab044e16909580352010a97"}, - {file = "h5py-3.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:212bb997a91e6a895ce5e2f365ba764debeaef5d2dca5c6fb7098d66607adf99"}, - {file = "h5py-3.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5dfc65ac21fa2f630323c92453cadbe8d4f504726ec42f6a56cf80c2f90d6c52"}, - {file = "h5py-3.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d4682b94fd36ab217352be438abd44c8f357c5449b8995e63886b431d260f3d3"}, - {file = "h5py-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aece0e2e1ed2aab076c41802e50a0c3e5ef8816d60ece39107d68717d4559824"}, - {file = "h5py-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43a61b2c2ad65b1fabc28802d133eed34debcc2c8b420cb213d3d4ef4d3e2229"}, - {file = "h5py-3.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:ae2f0201c950059676455daf92700eeb57dcf5caaf71b9e1328e6e6593601770"}, - {file = "h5py-3.10.0.tar.gz", hash = "sha256:d93adc48ceeb33347eb24a634fb787efc7ae4644e6ea4ba733d099605045c049"}, -] - -[package.dependencies] -numpy = ">=1.17.3" - -[[package]] -name = "idna" -version = "3.6" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, -] - [[package]] name = "importlib-metadata" version = "6.11.0" description = "Read metadata from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -607,277 +288,180 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs [[package]] name = "importlib-resources" -version = "6.4.0" +version = "6.4.5" description = "Read resources from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, - {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, + {file = "importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717"}, + {file = "importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] +type = ["pytest-mypy"] [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, ] [[package]] name = "joblib" -version = "1.4.0" +version = "1.4.2" description = "Lightweight pipelining with Python functions" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "joblib-1.4.0-py3-none-any.whl", hash = "sha256:42942470d4062537be4d54c83511186da1fc14ba354961a2114da91efa9a4ed7"}, - {file = "joblib-1.4.0.tar.gz", hash = "sha256:1eb0dc091919cd384490de890cb5dfd538410a6d4b3b54eef09fb8c50b409b1c"}, -] - -[[package]] -name = "keras" -version = "2.13.1" -description = "Deep learning for humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "keras-2.13.1-py3-none-any.whl", hash = "sha256:5ce5f706f779fa7330e63632f327b75ce38144a120376b2ae1917c00fa6136af"}, - {file = "keras-2.13.1.tar.gz", hash = "sha256:5df12cc241a015a11b65ddb452c0eeb2744fce21d9b54ba48db87492568ccc68"}, + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, ] [[package]] name = "kiwisolver" -version = "1.4.5" +version = "1.4.7" description = "A fast implementation of the Cassowary constraint solver" -optional = false -python-versions = ">=3.7" -files = [ - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, - {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, -] - -[[package]] -name = "libclang" -version = "18.1.1" -description = "Clang Python Bindings, mirrored from the official LLVM repo: https://github.com/llvm/llvm-project/tree/main/clang/bindings/python, to make the installation process easier." -optional = false -python-versions = "*" -files = [ - {file = "libclang-18.1.1-py2.py3-none-macosx_10_9_x86_64.whl", hash = "sha256:6f14c3f194704e5d09769108f03185fce7acaf1d1ae4bbb2f30a72c2400cb7c5"}, - {file = "libclang-18.1.1-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:83ce5045d101b669ac38e6da8e58765f12da2d3aafb3b9b98d88b286a60964d8"}, - {file = "libclang-18.1.1-py2.py3-none-manylinux2010_x86_64.whl", hash = "sha256:c533091d8a3bbf7460a00cb6c1a71da93bffe148f172c7d03b1c31fbf8aa2a0b"}, - {file = "libclang-18.1.1-py2.py3-none-manylinux2014_aarch64.whl", hash = "sha256:54dda940a4a0491a9d1532bf071ea3ef26e6dbaf03b5000ed94dd7174e8f9592"}, - {file = "libclang-18.1.1-py2.py3-none-manylinux2014_armv7l.whl", hash = "sha256:cf4a99b05376513717ab5d82a0db832c56ccea4fd61a69dbb7bccf2dfb207dbe"}, - {file = "libclang-18.1.1-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:69f8eb8f65c279e765ffd28aaa7e9e364c776c17618af8bff22a8df58677ff4f"}, - {file = "libclang-18.1.1-py2.py3-none-win_amd64.whl", hash = "sha256:4dd2d3b82fab35e2bf9ca717d7b63ac990a3519c7e312f19fa8e86dcc712f7fb"}, - {file = "libclang-18.1.1-py2.py3-none-win_arm64.whl", hash = "sha256:3f0e1f49f04d3cd198985fea0511576b0aee16f9ff0e0f0cad7f9c57ec3c20e8"}, - {file = "libclang-18.1.1.tar.gz", hash = "sha256:a1214966d08d73d971287fc3ead8dfaf82eb07fb197680d8b3859dbbbbf78250"}, -] - -[[package]] -name = "markdown" -version = "3.6" -description = "Python implementation of John Gruber's Markdown." +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, - {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] -testing = ["coverage", "pyyaml"] - -[[package]] -name = "markupsafe" -version = "2.1.5" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5d5abf8f8ec1f4e22882273c423e16cae834c36856cac348cfbfa68e01c40f3a"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aeb3531b196ef6f11776c21674dba836aeea9d5bd1cf630f869e3d90b16cfade"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7d755065e4e866a8086c9bdada157133ff466476a2ad7861828e17b6026e22c"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08471d4d86cbaec61f86b217dd938a83d85e03785f51121e791a6e6689a3be95"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bbfcb7165ce3d54a3dfbe731e470f65739c4c1f85bb1018ee912bae139e263b"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d34eb8494bea691a1a450141ebb5385e4b69d38bb8403b5146ad279f4b30fa3"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9242795d174daa40105c1d86aba618e8eab7bf96ba8c3ee614da8302a9f95503"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a0f64a48bb81af7450e641e3fe0b0394d7381e342805479178b3d335d60ca7cf"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8e045731a5416357638d1700927529e2b8ab304811671f665b225f8bf8d8f933"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4322872d5772cae7369f8351da1edf255a604ea7087fe295411397d0cfd9655e"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e1631290ee9271dffe3062d2634c3ecac02c83890ada077d225e081aca8aab89"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:edcfc407e4eb17e037bca59be0e85a2031a2ac87e4fed26d3e9df88b4165f92d"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4d05d81ecb47d11e7f8932bd8b61b720bf0b41199358f3f5e36d38e28f0532c5"}, + {file = "kiwisolver-1.4.7-cp38-cp38-win32.whl", hash = "sha256:b38ac83d5f04b15e515fd86f312479d950d05ce2368d5413d46c088dda7de90a"}, + {file = "kiwisolver-1.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:d83db7cde68459fc803052a55ace60bea2bae361fc3b7a6d5da07e11954e4b09"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f9362ecfca44c863569d3d3c033dbe8ba452ff8eed6f6b5806382741a1334bd"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8df2eb9b2bac43ef8b082e06f750350fbbaf2887534a5be97f6cf07b19d9583"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f32d6edbc638cde7652bd690c3e728b25332acbadd7cad670cc4a02558d9c417"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2e6c39bd7b9372b0be21456caab138e8e69cc0fc1190a9dfa92bd45a1e6e904"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dda56c24d869b1193fcc763f1284b9126550eaf84b88bbc7256e15028f19188a"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79849239c39b5e1fd906556c474d9b0439ea6792b637511f3fe3a41158d89ca8"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e3bc157fed2a4c02ec468de4ecd12a6e22818d4f09cde2c31ee3226ffbefab2"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3da53da805b71e41053dc670f9a820d1157aae77b6b944e08024d17bcd51ef88"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8705f17dfeb43139a692298cb6637ee2e59c0194538153e83e9ee0c75c2eddde"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:82a5c2f4b87c26bb1a0ef3d16b5c4753434633b83d365cc0ddf2770c93829e3c"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce8be0466f4c0d585cdb6c1e2ed07232221df101a4c6f28821d2aa754ca2d9e2"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:409afdfe1e2e90e6ee7fc896f3df9a7fec8e793e58bfa0d052c8a82f99c37abb"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b9c3f4ee0b9a439d2415012bd1b1cc2df59e4d6a9939f4d669241d30b414327"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win32.whl", hash = "sha256:a79ae34384df2b615eefca647a2873842ac3b596418032bef9a7283675962644"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:cf0438b42121a66a3a667de17e779330fc0f20b0d97d59d2f2121e182b0505e4"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:764202cc7e70f767dab49e8df52c7455e8de0df5d858fa801a11aa0d882ccf3f"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bfa1acfa0c54932d5607e19a2c24646fb4c1ae2694437789129cf099789a3b00"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:eee3ea935c3d227d49b4eb85660ff631556841f6e567f0f7bda972df6c2c9935"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f3160309af4396e0ed04db259c3ccbfdc3621b5559b5453075e5de555e1f3a1b"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a17f6a29cf8935e587cc8a4dbfc8368c55edc645283db0ce9801016f83526c2d"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10849fb2c1ecbfae45a693c070e0320a91b35dd4bcf58172c023b994283a124d"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ac542bf38a8a4be2dc6b15248d36315ccc65f0743f7b1a76688ffb6b5129a5c2"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b01aac285f91ca889c800042c35ad3b239e704b150cfd3382adfc9dcc780e39"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48be928f59a1f5c8207154f935334d374e79f2b5d212826307d072595ad76a2e"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f37cfe618a117e50d8c240555331160d73d0411422b59b5ee217843d7b693608"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599b5c873c63a1f6ed7eead644a8a380cfbdf5db91dcb6f85707aaab213b1674"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:801fa7802e5cfabe3ab0c81a34c323a319b097dfb5004be950482d882f3d7225"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0c6c43471bc764fad4bc99c5c2d6d16a676b1abf844ca7c8702bdae92df01ee0"}, + {file = "kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60"}, ] [[package]] name = "matplotlib" version = "3.7.5" description = "Python plotting package" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -944,56 +528,59 @@ python-dateutil = ">=2.7" [[package]] name = "mypy-extensions" -version = "1.0.0" +version = "1.1.0" description = "Type system extensions for programs checked with the mypy type checker." +category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, ] [[package]] name = "numpy" -version = "1.24.3" +version = "1.24.4" description = "Fundamental package for array computing in Python" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, - {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"}, - {file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"}, - {file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"}, - {file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"}, - {file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"}, - {file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"}, - {file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"}, - {file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"}, - {file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, - {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, + {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, + {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, + {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, + {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, + {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, + {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, + {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, + {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, + {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, ] [[package]] name = "numpy-indexed" version = "0.3.7" description = "This package contains functionality for indexed operations on numpy ndarrays, providing efficient vectorized functionality such as grouping and set operations." +category = "main" optional = false python-versions = "*" files = [ @@ -1004,55 +591,23 @@ files = [ future = "*" numpy = "*" -[[package]] -name = "oauthlib" -version = "3.2.2" -description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -optional = false -python-versions = ">=3.6" -files = [ - {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, - {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, -] - -[package.extras] -rsa = ["cryptography (>=3.0.0)"] -signals = ["blinker (>=1.4.0)"] -signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] - -[[package]] -name = "opt-einsum" -version = "3.3.0" -description = "Optimizing numpys einsum function" -optional = false -python-versions = ">=3.5" -files = [ - {file = "opt_einsum-3.3.0-py3-none-any.whl", hash = "sha256:2455e59e3947d3c275477df7f5205b30635e266fe6dc300e3d9f9646bfcea147"}, - {file = "opt_einsum-3.3.0.tar.gz", hash = "sha256:59f6475f77bbc37dcf7cd748519c0ec60722e91e63ca114e68821c0c54a46549"}, -] - -[package.dependencies] -numpy = ">=1.7" - -[package.extras] -docs = ["numpydoc", "sphinx (==1.2.3)", "sphinx-rtd-theme", "sphinxcontrib-napoleon"] -tests = ["pytest", "pytest-cov", "pytest-pep8"] - [[package]] name = "packaging" -version = "24.0" +version = "25.0" description = "Core utilities for Python packages" +category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] [[package]] name = "pandas" version = "2.0.3" description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1086,7 +641,7 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, ] python-dateutil = ">=2.8.2" @@ -1120,6 +675,7 @@ xml = ["lxml (>=4.6.3)"] name = "parameterized" version = "0.9.0" description = "Parameterized testing with any Python test framework" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1134,6 +690,7 @@ dev = ["jinja2"] name = "pathspec" version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1143,102 +700,114 @@ files = [ [[package]] name = "patsy" -version = "0.5.6" +version = "1.0.1" description = "A Python package for describing statistical models and for building design matrices." +category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "patsy-0.5.6-py2.py3-none-any.whl", hash = "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6"}, - {file = "patsy-0.5.6.tar.gz", hash = "sha256:95c6d47a7222535f84bff7f63d7303f2e297747a598db89cf5c67f0c0c7d2cdb"}, + {file = "patsy-1.0.1-py2.py3-none-any.whl", hash = "sha256:751fb38f9e97e62312e921a1954b81e1bb2bcda4f5eeabaf94db251ee791509c"}, + {file = "patsy-1.0.1.tar.gz", hash = "sha256:e786a9391eec818c054e359b737bbce692f051aee4c661f4141cc88fb459c0c4"}, ] [package.dependencies] numpy = ">=1.4" -six = "*" [package.extras] test = ["pytest", "pytest-cov", "scipy"] [[package]] name = "pillow" -version = "10.3.0" +version = "10.4.0" description = "Python Imaging Library (Fork)" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -1247,28 +816,31 @@ xmp = ["defusedxml"] [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "plotly" -version = "5.20.0" +version = "5.24.1" description = "An open-source, interactive data visualization library for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "plotly-5.20.0-py3-none-any.whl", hash = "sha256:837a9c8aa90f2c0a2f0d747b82544d014dc2a2bdde967b5bb1da25b53932d1a9"}, - {file = "plotly-5.20.0.tar.gz", hash = "sha256:bf901c805d22032cfa534b2ff7c5aa6b0659e037f19ec1e0cca7f585918b5c89"}, + {file = "plotly-5.24.1-py3-none-any.whl", hash = "sha256:f67073a1e637eb0dc3e46324d9d51e2fe76e9727c892dde64ddf1e1b51f29089"}, + {file = "plotly-5.24.1.tar.gz", hash = "sha256:dbc8ac8339d248a4bcc36e08a5659bacfe1b079390b8953533f4eb22169b4bae"}, ] [package.dependencies] @@ -1277,73 +849,30 @@ tenacity = ">=6.2.0" [[package]] name = "pluggy" -version = "1.4.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "protobuf" -version = "4.25.3" -description = "" -optional = false -python-versions = ">=3.8" -files = [ - {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, - {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, - {file = "protobuf-4.25.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c"}, - {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019"}, - {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d"}, - {file = "protobuf-4.25.3-cp38-cp38-win32.whl", hash = "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2"}, - {file = "protobuf-4.25.3-cp38-cp38-win_amd64.whl", hash = "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4"}, - {file = "protobuf-4.25.3-cp39-cp39-win32.whl", hash = "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4"}, - {file = "protobuf-4.25.3-cp39-cp39-win_amd64.whl", hash = "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c"}, - {file = "protobuf-4.25.3-py3-none-any.whl", hash = "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9"}, - {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, -] - -[[package]] -name = "pyasn1" -version = "0.6.0" -description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyasn1-0.6.0-py2.py3-none-any.whl", hash = "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473"}, - {file = "pyasn1-0.6.0.tar.gz", hash = "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c"}, -] - -[[package]] -name = "pyasn1-modules" -version = "0.4.0" -description = "A collection of ASN.1-based protocols modules" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyasn1_modules-0.4.0-py3-none-any.whl", hash = "sha256:be04f15b66c206eed667e0bb5ab27e2b1855ea54a842e5037738099e8ca4ae0b"}, - {file = "pyasn1_modules-0.4.0.tar.gz", hash = "sha256:831dbcea1b177b28c9baddf4c6d1013c24c3accd14a1873fffaa6a2e905f17b6"}, -] - -[package.dependencies] -pyasn1 = ">=0.4.6,<0.7.0" - [[package]] name = "pyparsing" -version = "3.1.2" +version = "3.1.4" description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "main" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, ] [package.extras] @@ -1353,6 +882,7 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pytest" version = "7.4.4" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1375,6 +905,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -1387,72 +918,21 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2024.1" +version = "2025.2" description = "World timezone definitions, modern and historical" +category = "main" optional = false python-versions = "*" files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-oauthlib" -version = "2.0.0" -description = "OAuthlib authentication support for Requests." -optional = false -python-versions = ">=3.4" -files = [ - {file = "requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"}, - {file = "requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36"}, + {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"}, + {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"}, ] -[package.dependencies] -oauthlib = ">=3.0.0" -requests = ">=2.0.0" - -[package.extras] -rsa = ["oauthlib[signedtoken] (>=3.0.0)"] - -[[package]] -name = "rsa" -version = "4.9" -description = "Pure-Python RSA implementation" -optional = false -python-versions = ">=3.6,<4" -files = [ - {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, - {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, -] - -[package.dependencies] -pyasn1 = ">=0.1.3" - [[package]] name = "scikit-learn" version = "1.3.2" description = "A set of python modules for machine learning and data mining" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1500,6 +980,7 @@ tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc ( name = "scipy" version = "1.10.1" description = "Fundamental algorithms for scientific computing in Python" +category = "main" optional = false python-versions = "<3.12,>=3.8" files = [ @@ -1538,6 +1019,7 @@ test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeo name = "seaborn" version = "0.12.2" description = "Statistical data visualization" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1557,35 +1039,42 @@ stats = ["scipy (>=1.3)", "statsmodels (>=0.10)"] [[package]] name = "setuptools" -version = "69.2.0" +version = "75.3.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, - {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, + {file = "setuptools-75.3.2-py3-none-any.whl", hash = "sha256:90ab613b6583fc02d5369cbca13ea26ea0e182d1df2d943ee9cbe81d4c61add9"}, + {file = "setuptools-75.3.2.tar.gz", hash = "sha256:3c1383e1038b68556a382c1e8ded8887cd20141b0eb5708a6c8d277de49364f5"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "ruff (<=0.7.1)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12.0,<1.13.0)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] name = "statsmodels" version = "0.14.1" description = "Statistical computations and models for Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1637,367 +1126,141 @@ docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "n [[package]] name = "tenacity" -version = "8.2.3" +version = "9.0.0" description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tenacity-8.2.3-py3-none-any.whl", hash = "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c"}, - {file = "tenacity-8.2.3.tar.gz", hash = "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a"}, -] - -[package.extras] -doc = ["reno", "sphinx", "tornado (>=4.5)"] - -[[package]] -name = "tensorboard" -version = "2.13.0" -description = "TensorBoard lets you watch Tensors Flow" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "tensorboard-2.13.0-py3-none-any.whl", hash = "sha256:ab69961ebddbddc83f5fa2ff9233572bdad5b883778c35e4fe94bf1798bd8481"}, -] - -[package.dependencies] -absl-py = ">=0.4" -google-auth = ">=1.6.3,<3" -google-auth-oauthlib = ">=0.5,<1.1" -grpcio = ">=1.48.2" -markdown = ">=2.6.8" -numpy = ">=1.12.0" -protobuf = ">=3.19.6" -requests = ">=2.21.0,<3" -setuptools = ">=41.0.0" -tensorboard-data-server = ">=0.7.0,<0.8.0" -werkzeug = ">=1.0.1" -wheel = ">=0.26" - -[[package]] -name = "tensorboard-data-server" -version = "0.7.2" -description = "Fast data loading for TensorBoard" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tensorboard_data_server-0.7.2-py3-none-any.whl", hash = "sha256:7e0610d205889588983836ec05dc098e80f97b7e7bbff7e994ebb78f578d0ddb"}, - {file = "tensorboard_data_server-0.7.2-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:9fe5d24221b29625dbc7328b0436ca7fc1c23de4acf4d272f1180856e32f9f60"}, - {file = "tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl", hash = "sha256:ef687163c24185ae9754ed5650eb5bc4d84ff257aabdc33f0cc6f74d8ba54530"}, -] - -[[package]] -name = "tensorflow" -version = "2.13.1" -description = "TensorFlow is an open source machine learning framework for everyone." -optional = false -python-versions = ">=3.8" -files = [ - {file = "tensorflow-2.13.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:17b9a82d69abc487ebad503d61acd11fb24f3b0105be669b5319e55f90f0ca21"}, - {file = "tensorflow-2.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f2935ea4bdf37c1840f4d6ed1ddbb4990dc5ae68e1bc8bba4587bac413195c2f"}, - {file = "tensorflow-2.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dd6555e9248bace921a311ff05d88239a6b7e96bcd024c5df4c2eaeb1678ac3"}, - {file = "tensorflow-2.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cd54d7cf979de0e407db182eea27dbed37361af5c329c2dbf71c486be3e432b"}, - {file = "tensorflow-2.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2ab5efb2d0e888a1f65539f495744aaab542ae5e36ed33e50e98cf8b9f088c2c"}, - {file = "tensorflow-2.13.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:dbd7c5c427dacdea1ce2dce29b9a7b3c7409d314fa6f413b7fe58ed5635af754"}, - {file = "tensorflow-2.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:a3e1e42dd286adf0fd91cf68a405a30a21a2c8c09b9515b91faa5704a09ff803"}, - {file = "tensorflow-2.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf37fa1b434568b8c853ffdeeff9e477237495d2f2bbdb0eac61a6bcac779e8"}, - {file = "tensorflow-2.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2f109daa5d0cbabb3df5fdebcde0ca895d891e18d03e08cb6742c96a6be7012"}, - {file = "tensorflow-2.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:c23ebcaa2131062a9bf6fe2634aef8c95f9c043b2dc814bc2f8765ba7a4e3612"}, - {file = "tensorflow-2.13.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:56f35d88c419d59ed5e2823f1c69d794c8f28b77f3aed5300e454e7513a6228e"}, - {file = "tensorflow-2.13.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:89959a3a31f17c3a0099d7e3c48b20a02eb01f3c1dbf96c6cc5fbf84a623e176"}, - {file = "tensorflow-2.13.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e42cdf625125c9ef99d29310774617990915cd046125ef5e9624799659a7d3e8"}, - {file = "tensorflow-2.13.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:deb204fc8c98ceff81f0f776ffb5172e1a6892143c7bfee90a865e9d5e4bbee2"}, - {file = "tensorflow-2.13.1-cp38-cp38-win_amd64.whl", hash = "sha256:46024ba77aaf5c0b578aadf0c75320e539e135ddfe731a1ee241b039c332e565"}, - {file = "tensorflow-2.13.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:fbb68c8ea407f515393ef50bd8ccbbc01914cc76f39e2ca18c238a3189230f71"}, - {file = "tensorflow-2.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:69add96604b9a4e8e8e00505953478027964445d8eb8d7541538ef38159b7f27"}, - {file = "tensorflow-2.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bf992bf62cf628f5ff57694312037885ba8cc7b8b0d51b3d772e350a717d2d0"}, - {file = "tensorflow-2.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04538df649aa0be5050695cdb0c8f2c26e6122ca04c7c1e4471b23c0d6c490cf"}, - {file = "tensorflow-2.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:884dbafa213f8bea7869977f88bfb404051b65aa17dc7927ff4bfe47e3fc839b"}, -] - -[package.dependencies] -absl-py = ">=1.0.0" -astunparse = ">=1.6.0" -flatbuffers = ">=23.1.21" -gast = ">=0.2.1,<=0.4.0" -google-pasta = ">=0.1.1" -grpcio = ">=1.24.3,<2.0" -h5py = ">=2.9.0" -keras = ">=2.13.1,<2.14" -libclang = ">=13.0.0" -numpy = ">=1.22,<=1.24.3" -opt-einsum = ">=2.3.2" -packaging = "*" -protobuf = ">=3.20.3,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" -setuptools = "*" -six = ">=1.12.0" -tensorboard = ">=2.13,<2.14" -tensorflow-estimator = ">=2.13.0,<2.14" -tensorflow-io-gcs-filesystem = {version = ">=0.23.1", markers = "platform_machine != \"arm64\" or platform_system != \"Darwin\""} -termcolor = ">=1.1.0" -typing-extensions = ">=3.6.6,<4.6.0" -wrapt = ">=1.11.0" - -[[package]] -name = "tensorflow-estimator" -version = "2.13.0" -description = "TensorFlow Estimator." -optional = false -python-versions = ">=3.7" -files = [ - {file = "tensorflow_estimator-2.13.0-py2.py3-none-any.whl", hash = "sha256:6f868284eaa654ae3aa7cacdbef2175d0909df9fcf11374f5166f8bf475952aa"}, -] - -[[package]] -name = "tensorflow-io-gcs-filesystem" -version = "0.33.0" -description = "TensorFlow IO" -optional = false -python-versions = ">=3.7, <3.12" -files = [ - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:2dd49262831ee20f03fd3f5d2c679e7111cd1575e0ad60f60b5632f2da555bfc"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e1d833f6856aec465652c0d7a75a7c28cf83b132b8351ba0c4df4e05136c403"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8295a65fd4fa731b06b31fab223e3ba11369430537169934a17f7bcc07dfef76"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:58f953665620725c842de8f4074c14779bf11d9081e4d0d8f2b75145de9ee20a"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ac69d8ba4d27435a5e199248b3a3befc19e65d86a97a52a19ee1f43195f51207"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c793e313e9cfed6caa328ec1a162844006a4bc016ba1d116813d7541938a9"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:99c063f766fdb431d555f17fa185979195abb0477445f054fe16567bfd340fd7"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cfa1df21535f7c945041fda99da2940a56b67d86e20aa2ac8cde3d371bc08659"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8d3ddd86a0f7cf4d35f2401d5b28d574d0f296b4e4349c69c671f7b83fc6ce8f"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4657f92dcc2474adc773bf69b836818b416c22cfadaac05b9b64f2a53f3009ee"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcf4fc3a44f75b7dccb7b40ca709872bf7f0e812522f82aa7881ecdc0d86af48"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:68db367697353184667bbd94faf53a58e7b695acb905f23da1e8ccad8bd6b451"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a57e64cd5d22085f9b475df9d12086a894eb8861524970c8839a2ec315841a20"}, - {file = "tensorflow_io_gcs_filesystem-0.33.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7916ca0accdd259c3fbee1b1f0816d61d6e8a639aa5bc1d4cdfbaf63b344623"}, + {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"}, + {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"}, ] [package.extras] -tensorflow = ["tensorflow (>=2.13.0,<2.14.0)"] -tensorflow-aarch64 = ["tensorflow-aarch64 (>=2.13.0,<2.14.0)"] -tensorflow-cpu = ["tensorflow-cpu (>=2.13.0,<2.14.0)"] -tensorflow-gpu = ["tensorflow-gpu (>=2.13.0,<2.14.0)"] -tensorflow-rocm = ["tensorflow-rocm (>=2.13.0,<2.14.0)"] - -[[package]] -name = "termcolor" -version = "2.4.0" -description = "ANSI color formatting for output in terminal" -optional = false -python-versions = ">=3.8" -files = [ - {file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"}, - {file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"}, -] - -[package.extras] -tests = ["pytest", "pytest-cov"] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "threadpoolctl" -version = "3.4.0" +version = "3.5.0" description = "threadpoolctl" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "threadpoolctl-3.4.0-py3-none-any.whl", hash = "sha256:8f4c689a65b23e5ed825c8436a92b818aac005e0f3715f6a1664d7c7ee29d262"}, - {file = "threadpoolctl-3.4.0.tar.gz", hash = "sha256:f11b491a03661d6dd7ef692dd422ab34185d982466c49c8f98c8f716b5c93196"}, + {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, + {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, ] [[package]] name = "tomli" -version = "2.0.1" +version = "2.2.1" description = "A lil' TOML parser" +category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] name = "tqdm" -version = "4.66.2" +version = "4.67.1" description = "Fast, Extensible Progress Meter" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, - {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] [[package]] name = "typing-extensions" -version = "4.5.0" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.13.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, - {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, + {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, + {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, ] [[package]] name = "tzdata" -version = "2024.1" +version = "2025.2" description = "Provider of IANA time zone data" +category = "main" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, - {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, -] - -[[package]] -name = "urllib3" -version = "2.2.1" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "werkzeug" -version = "3.0.2" -description = "The comprehensive WSGI web application library." -optional = false -python-versions = ">=3.8" -files = [ - {file = "werkzeug-3.0.2-py3-none-any.whl", hash = "sha256:3aac3f5da756f93030740bc235d3e09449efcf65f2f55e3602e1d851b8f48795"}, - {file = "werkzeug-3.0.2.tar.gz", hash = "sha256:e39b645a6ac92822588e7b39a692e7828724ceae0b0d702ef96701f90e70128d"}, -] - -[package.dependencies] -MarkupSafe = ">=2.1.1" - -[package.extras] -watchdog = ["watchdog (>=2.3)"] - -[[package]] -name = "wheel" -version = "0.43.0" -description = "A built-package format for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "wheel-0.43.0-py3-none-any.whl", hash = "sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81"}, - {file = "wheel-0.43.0.tar.gz", hash = "sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85"}, -] - -[package.extras] -test = ["pytest (>=6.0.0)", "setuptools (>=65)"] - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, + {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, ] [[package]] name = "zipp" -version = "3.18.1" +version = "3.20.2" description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, - {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, + {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, + {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.12" -content-hash = "220b5fb4306b0ee7de879d0addd873d5b416cb46404dab6a0103a7e0b6deea22" +content-hash = "54083971f587b9db5b1862d90d89ae5ba9da41021b755b4923a1867f394491fe" diff --git a/polyaxongit.yaml b/polyaxongit.yaml index f3d9fd0..ea8fb7a 100644 --- a/polyaxongit.yaml +++ b/polyaxongit.yaml @@ -1 +1 @@ -{"git":{"url":"https:\/\/github.com\/amrukwa\/enrichment-auc"},"connection":"repo"} \ No newline at end of file +{"git":{"url":"https:\/\/github.com\/ZAEDPolSl\/pyFUNCellA"},"connection":"repo"} \ No newline at end of file diff --git a/pyfuncella/GMMdecomp.py b/pyfuncella/GMMdecomp.py new file mode 100644 index 0000000..7de988c --- /dev/null +++ b/pyfuncella/GMMdecomp.py @@ -0,0 +1,475 @@ +""" +GMM Decomposition using R's dpGMM package through process execution. + +This module provides a Python wrapper for the GMMdecomp function +originally implemented in R using the dpGMM package. +""" + +import numpy as np +import pandas as pd +from typing import Dict, Any, Union, Optional, Callable + +from .utils.r_executor import execute_r_code, check_r_available, RProcessError + + +def _check_r_available() -> bool: + """Check if R is available (backward compatibility for tests).""" + return check_r_available() + + +def _check_dpgmm_installed() -> bool: + """Check if dpGMM package is installed in R.""" + if not check_r_available(): + return False + try: + result = execute_r_code( + """ + tryCatch({ + library(dpGMM) + success <- TRUE + }, error = function(e) { + success <- FALSE + }) + success + """ + ) + return result.get("success", False) + except Exception: + return False + + +def _install_dpgmm() -> bool: + """Attempt to install dpGMM package in R.""" + if not check_r_available(): + return False + + try: + result = execute_r_code( + """ + # Try to install dpGMM from GitHub + if (!require("devtools", quietly = TRUE)) { + install.packages("devtools", repos='https://cloud.r-project.org/') + } + + devtools::install_github("ZAEDPolSl/dpGMM") + + # Verify installation + library(dpGMM) + installation_success <- TRUE + """ + ) + return result.get("success", False) and result.get( + "installation_success", False + ) + except Exception: + return False + + +def _create_simple_result(pathway_data, multiply): + """Create a simple result for constant or near-constant data.""" + mean_value = np.mean(pathway_data) + std_value = np.std(pathway_data) + + # Scale back if multiply was used + if multiply: + scaling_factor = 10 + mean_value = mean_value / scaling_factor + std_value = std_value / scaling_factor + + return { + "model": { + "alpha": np.array([1.0]), + "mu": np.array([mean_value]), + "sigma": np.array([std_value]), + }, + "thresholds": np.array([]), # No thresholds for single component + "IC_value": 0.0 if std_value == 0 else None, + "converged": True, + } + + +def _is_constant_data(pathway_data): + """Check if pathway data is constant or near-constant.""" + return len(np.unique(pathway_data)) == 1 or np.std(pathway_data) < 1e-10 + + +def _validate_inputs(X, K, multiply, IC, parallel, verbose): + """Validate input parameters for GMMdecomp.""" + # Input validation + if not isinstance(X, (pd.DataFrame, np.ndarray)): + raise ValueError("X must be a pandas DataFrame or numpy array") + + if not isinstance(K, int) or K <= 0: + raise ValueError("K must be a positive integer") + + if not isinstance(multiply, bool): + raise ValueError("multiply must be a boolean value") + + IC_options = ["AIC", "AICc", "BIC", "ICL-BIC", "LR"] + if IC not in IC_options: + raise ValueError(f"IC must be one of {IC_options}") + + if not isinstance(parallel, bool): + raise ValueError("parallel must be a boolean value") + + if not isinstance(verbose, bool): + raise ValueError("verbose must be a boolean value") + + +def _prepare_data(X, multiply, verbose): + """Prepare and validate data for GMM decomposition.""" + # Convert input to DataFrame if needed + if isinstance(X, np.ndarray): + if X.size == 0: + raise ValueError("Input data X cannot be empty") + X = pd.DataFrame( + X, + index=[f"pathway_{i}" for i in range(X.shape[0])], + columns=[f"sample_{i}" for i in range(X.shape[1])], + ) + elif isinstance(X, pd.DataFrame): + if X.empty: + raise ValueError("Input data X cannot be empty") + + # Convert to numeric and handle missing values + X_numeric = X.select_dtypes(include=[np.number]).copy() + if X_numeric.empty: + raise ValueError("No numeric columns found in input data") + + # Apply scaling if requested + if multiply: + X_for_r = X_numeric * 10 + else: + X_for_r = X_numeric.copy() + + return X_for_r + + +def _process_constant_pathways(X_for_r, multiply, verbose): + """Process pathways with constant data and identify non-constant ones.""" + results = {} + non_constant_pathways = [] + + if verbose: + print("Preprocessing pathways for constant data...") + + for pathway_name in X_for_r.index: + pathway_data = X_for_r.loc[pathway_name].values.astype(float) + + if _is_constant_data(pathway_data): + results[pathway_name] = _create_simple_result(pathway_data, multiply) + if verbose: + print( + f"Pathway {pathway_name}: Constant data detected, using simple result" + ) + else: + non_constant_pathways.append(pathway_name) + + return results, non_constant_pathways + + +def _process_single_pathway_gmm(pathway_name, X_for_r, K, IC, multiply, verbose): + """Process a single pathway through GMM decomposition.""" + # Get single pathway data + single_pathway_data = X_for_r.loc[[pathway_name]] + + # Prepare data for R (single pathway) + data_inputs = { + "X_data": single_pathway_data, + "K_param": K, + "IC_param": IC, + "verbose_param": False, # Reduce R verbosity for individual pathways + } + + try: + # Execute R code for single pathway + result = execute_r_code(_get_gmm_r_code(), data_inputs) + + if not result.get("success", False): + if verbose: + print(f"Warning: GMM failed for pathway {pathway_name}") + return _create_failed_result() + + # Extract and process results for this pathway + gmm_results = result.get("gmm_results", {}) + + if pathway_name in gmm_results: + pathway_result = gmm_results[pathway_name] + if isinstance(pathway_result, dict) and pathway_result.get( + "success", False + ): + # Process successful result + return _process_single_pathway_result(pathway_result, multiply) + else: + # Handle failed pathway + return _create_failed_result() + else: + return _create_failed_result() + + except Exception as e: + if verbose: + print(f"Error processing pathway {pathway_name}: {str(e)}") + return _create_failed_result() + + +def GMMdecomp( + X: Union[pd.DataFrame, np.ndarray], + K: int = 10, + multiply: bool = True, + IC: str = "BIC", + parallel: bool = False, + verbose: bool = True, + progress_callback: Optional[Callable] = None, +) -> Dict[str, Any]: + """ + Perform Gaussian Mixture Model (GMM) decomposition on pathway enrichment scores. + + This function reduces pathway-level data to probabilistic components, which can + help detect multimodal activity patterns in gene sets. + + Parameters + ---------- + X : pd.DataFrame or np.ndarray + Data enrichment scores (rows: pathways, columns: samples). + If numpy array, row names will be generated automatically. + K : int, default=10 + Maximum number of components for GMM decomposition. + multiply : bool, default=True + Whether to scale values by 10 before fitting GMM. + IC : str, default="BIC" + Information criterion to use for model selection. + Options: "AIC", "AICc", "BIC", "ICL-BIC", "LR". + parallel : bool, default=False + Whether to perform decomposition in parallel. + Note: Parallel execution is not yet implemented. + verbose : bool, default=True + Whether to show progress messages. + progress_callback : callable, optional + Optional callback function for progress reporting. + Should accept (current, total, message) parameters. + + Returns + ------- + dict + Dictionary of GMM decomposition results for each pathway. + Keys are pathway names, values are dictionaries containing: + - 'model': Fitted GMM model parameters (mixture weights, means, and standard deviations) + - 'thresholds': Array of decision thresholds calculated by the model + - Other diagnostics from dpGMM package + + Raises + ------ + RuntimeError + If R or dpGMM package is not available. + ValueError + If input parameters are invalid. + """ + + # Check R availability first with informative error message + if not check_r_available(): + raise RuntimeError( + "R is not available. GMM decomposition requires R with the dpGMM package.\n" + "Please ensure:\n" + "1. R is installed and accessible from your PATH\n" + "2. Install R dependencies by running: Rscript setup_docker_compatible_renv.R\n" + "3. Or manually install required packages: BiocManager::install('GSVA'); " + "remotes::install_github('ZAEDPolSl/dpGMM')" + ) + + # Validate inputs + _validate_inputs(X, K, multiply, IC, parallel, verbose) + + # Check dpGMM availability + if not _check_dpgmm_installed(): + if verbose: + print("dpGMM package not found. Attempting to install...") + if not _install_dpgmm(): + raise RuntimeError( + "Failed to install dpGMM package. " + "Please install it manually by running: Rscript setup_docker_compatible_renv.R\n" + "Or use: remotes::install_github('ZAEDPolSl/dpGMM')" + ) + + # Prepare data + X_for_r = _prepare_data(X, multiply, verbose) + + # Process constant pathways and identify non-constant ones + results, non_constant_pathways = _process_constant_pathways( + X_for_r, multiply, verbose + ) + + # If all pathways were constant, return results + if not non_constant_pathways: + if verbose: + print("All pathways contain constant data. Returning simple results.") + return results + + if verbose: + print( + f"Processing {len(non_constant_pathways)} non-constant pathways through R..." + ) + + # Process pathways individually to avoid timeout and provide progress updates + if progress_callback: + progress_callback( + 0, len(non_constant_pathways), "Starting GMM decomposition..." + ) + + for i, pathway_name in enumerate(non_constant_pathways): + if progress_callback: + progress_callback( + i, len(non_constant_pathways), f"Processing {pathway_name}" + ) + + if verbose: + print( + f"Processing pathway {i+1}/{len(non_constant_pathways)}: {pathway_name}" + ) + + # Process this pathway + results[pathway_name] = _process_single_pathway_gmm( + pathway_name, X_for_r, K, IC, multiply, verbose + ) + + if progress_callback: + progress_callback( + len(non_constant_pathways), + len(non_constant_pathways), + "GMM decomposition completed", + ) + + if verbose: + successful_pathways = sum(1 for r in results.values() if r.get("K", 0) > 0) + print( + f"GMM decomposition completed: {successful_pathways}/{len(results)} pathways successful" + ) + + return results + + +def _get_gmm_r_code(): + """Get the R code for GMM decomposition from separate file.""" + import os + + script_dir = os.path.dirname(os.path.abspath(__file__)) + r_script_path = os.path.join(script_dir, "gmm_decomposition.R") + + # Read the R script content + with open(r_script_path, "r") as f: + return f.read() + + +def _process_single_pathway_result(pathway_result, multiply): + """Process a single pathway result from R.""" + + # Helper function to handle NA values from R + def _clean_r_value(value): + """Convert R values, handling NA strings.""" + if isinstance(value, str) and value.upper() in ["NA", "NAN", "NULL"]: + return np.nan + elif isinstance(value, (list, tuple)): + return [_clean_r_value(v) for v in value] + else: + return value + + # Convert the flat structure from R to nested structure expected by tests + alpha = _clean_r_value(pathway_result.get("alpha", [])) + mu = _clean_r_value(pathway_result.get("mu", [])) + sigma = _clean_r_value(pathway_result.get("sigma", [])) + threshold = _clean_r_value(pathway_result.get("threshold", [])) + + # Convert scalars to arrays for consistency + if np.isscalar(alpha): + alpha = [alpha] + if np.isscalar(mu): + mu = [mu] + if np.isscalar(sigma): + sigma = [sigma] + if np.isscalar(threshold): + threshold = [threshold] + + # Filter out NaN values and handle empty results + alpha = ( + [a for a in alpha if not (isinstance(a, float) and np.isnan(a))] + if isinstance(alpha, (list, tuple)) + else ([alpha] if not (isinstance(alpha, float) and np.isnan(alpha)) else []) + ) + mu = ( + [m for m in mu if not (isinstance(m, float) and np.isnan(m))] + if isinstance(mu, (list, tuple)) + else ([mu] if not (isinstance(mu, float) and np.isnan(mu)) else []) + ) + sigma = ( + [s for s in sigma if not (isinstance(s, float) and np.isnan(s))] + if isinstance(sigma, (list, tuple)) + else ([sigma] if not (isinstance(sigma, float) and np.isnan(sigma)) else []) + ) + threshold = ( + [t for t in threshold if not (isinstance(t, float) and np.isnan(t))] + if isinstance(threshold, (list, tuple)) + else ( + [threshold] + if not (isinstance(threshold, float) and np.isnan(threshold)) + else [] + ) + ) + + # If we have no valid values, return a failed result + if not alpha or not mu or not sigma or not threshold: + return _create_failed_result() + + # Unscale values if multiply=True was used + if multiply: + # Use exact arithmetic to avoid floating point precision issues + scaling_factor = 10 + mu = [ + m / scaling_factor if isinstance(m, (int, float)) and not np.isnan(m) else m + for m in mu + ] + sigma = [ + s / scaling_factor if isinstance(s, (int, float)) and not np.isnan(s) else s + for s in sigma + ] + threshold = [ + t / scaling_factor if isinstance(t, (int, float)) and not np.isnan(t) else t + for t in threshold + ] + + return { + "model": { + "alpha": np.array(alpha), + "mu": np.array(mu), + "sigma": np.array(sigma), + }, + "thresholds": np.array(threshold), + "K": pathway_result.get("K", 1), + "IC": pathway_result.get("IC", 0.0), + "loglik": pathway_result.get("loglik", 0.0), + "cluster": np.array(pathway_result.get("cluster", [])), + } + + +def _create_failed_result(): + """Create a failed result structure.""" + return { + "model": { + "alpha": np.array([]), + "mu": np.array([]), + "sigma": np.array([]), + }, + "thresholds": np.array([]), + "K": 0, + "IC": float("inf"), + "loglik": float("-inf"), + "cluster": np.array([]), + } + + +# Legacy function for backwards compatibility +def gmm_decomposition_parallel(*args, **kwargs): + """ + Legacy function name for backwards compatibility. + Calls GMMdecomp with parallel=True by default. + """ + kwargs.setdefault("parallel", True) + return GMMdecomp(*args, **kwargs) diff --git a/pyfuncella/__init__.py b/pyfuncella/__init__.py new file mode 100644 index 0000000..a108ff8 --- /dev/null +++ b/pyfuncella/__init__.py @@ -0,0 +1,34 @@ +import importlib.resources +import pandas as pd +import json + + +def load_pathways(kind: str): + """ + Load pathway information or data. + + Parameters + ---------- + kind : str + Either "info" (returns CSV as DataFrame) or "data" (returns JSON as dict) + + Returns + ------- + pd.DataFrame | dict + """ + if kind == "info": + filename = "pathway_info.csv" + with importlib.resources.files(__package__ + ".data").joinpath(filename).open( + "r", encoding="utf-8" + ) as f: + return pd.read_csv(f) + + elif kind == "data": + filename = "pathways.json" + with importlib.resources.files(__package__ + ".data").joinpath(filename).open( + "r", encoding="utf-8" + ) as f: + return json.load(f) + + else: + raise ValueError("kind must be either 'info' or 'data'") diff --git a/pyfuncella/aucell_threshold.R b/pyfuncella/aucell_threshold.R new file mode 100644 index 0000000..f056732 --- /dev/null +++ b/pyfuncella/aucell_threshold.R @@ -0,0 +1,32 @@ +# AUCell Threshold Calculation Script +# This script calculates AUCell thresholds for a single pathway +# +# Expected inputs: +# - pathway_scores: Single pathway data as a DataFrame row +# +# Output: +# - aucell_results: Threshold value for the pathway + +# Load required libraries +suppressMessages({ + library(AUCell) +}) + +# Get the single pathway data +pathway_data <- pathway_scores + +# Convert to matrix and ensure proper format +pathway_matrix <- as.matrix(pathway_data) + +# Use the exact same approach as FUNCellA +# Note: Using ::: operator to access internal AUCell function that provides +# the specific thresholding algorithm required for compatibility with FUNCellA +# AUCell:::.auc_assignmnetThreshold_v6(as.matrix(df_path[i,]),plotHist = F)$selected +result_obj <- AUCell:::.auc_assignmnetThreshold_v6(pathway_matrix, plotHist = FALSE) + +# Extract the selected threshold +if (!is.null(result_obj) && !is.null(result_obj$selected)) { + aucell_results <- result_obj$selected +} else { + aucell_results <- result_obj +} diff --git a/pyfuncella/data/pathways_info.csv b/pyfuncella/data/pathways_info.csv new file mode 100644 index 0000000..cd4e492 --- /dev/null +++ b/pyfuncella/data/pathways_info.csv @@ -0,0 +1,46 @@ +"ID","Title","DataBase" +"CM00016","Epithelial cell","CellMarker" +"CM00026","Mesenchymal stem cell","CellMarker" +"CM00028","Monocyte","CellMarker" +"CM00032","Natural killer cell","CellMarker" +"CM00003","B cell","CellMarker" +"CM00001","Adipose-derived stem cell","CellMarker" +"CM00042","Regulatory T (Treg) cell","CellMarker" +"CM00013","Endothelial cell","CellMarker" +"CM00046","T cell","CellMarker" +"CM00011","Dendritic cell","CellMarker" +"CM00035","Neutrophil","CellMarker" +"CM00014","Endothelial progenitor cell","CellMarker" +"CM00027","Mesenchymal stromal cell","CellMarker" +"CM00009","CD4+ T cell","CellMarker" +"CM00019","Hematopoietic cell","CellMarker" +"CM00010","CD8+ T cell","CellMarker" +"CM00039","Platelet","CellMarker" +"CM00047","T helper cell","CellMarker" +"CM00038","Plasmacytoid dendritic cell","CellMarker" +"CM00017","Fibroblast","CellMarker" +"CM00023","Macrophage","CellMarker" +"CM00036","Pericyte","CellMarker" +"CM00020","Hematopoietic stem cell","CellMarker" +"CM00040","Pluripotent stem cell","CellMarker" +"CM00015","Eosinophil","CellMarker" +"CM00037","Plasma cell","CellMarker" +"CM00006","Beta cell","CellMarker" +"CM00030","Myoepithelial cell","CellMarker" +"CM00033","Neural stem cell","CellMarker" +"CM00018","Germ cell","CellMarker" +"CM00022","M2 macrophage","CellMarker" +"CM00021","Hepatocyte","CellMarker" +"CM00029","Muscle satellite cell","CellMarker" +"CM00025","Megakaryocyte","CellMarker" +"CM00004","Basal cell","CellMarker" +"CM00007","Cancer stem cell","CellMarker" +"CM00005","Basophil","CellMarker" +"CM00034","Neuron","CellMarker" +"CM00008","Cardiomyocyte","CellMarker" +"CM00012","Embryonic stem cell","CellMarker" +"CM00002","Astrocyte","CellMarker" +"CM00043","Sertoli cell","CellMarker" +"CM00045","Stromal cell","CellMarker" +"CM00031","Myofibroblast","CellMarker" +"CM00024","Mast cell","CellMarker" diff --git a/pyfuncella/gene2path.py b/pyfuncella/gene2path.py new file mode 100644 index 0000000..fedef19 --- /dev/null +++ b/pyfuncella/gene2path.py @@ -0,0 +1,248 @@ +""" +Transform Gene-level Data to Pathway-level Scores Using Single-Sample Methods + +This module provides a comprehensive function similar to FUNCellA's gene2path.R +for reducing gene-level data to pathway-level activity scores using various +single-sample pathway enrichment methods with filtering capabilities. +""" + +import numpy as np +import pandas as pd +from typing import Dict, List, Optional, Union, Literal +import warnings + +# Import your existing metrics +from pyfuncella.metrics.mean import MEAN +from pyfuncella.metrics.bina import BINA +from pyfuncella.metrics.cerno import AUC +from pyfuncella.metrics.aucell import AUCELL +from pyfuncella.metrics.jasmine import JASMINE +from pyfuncella.metrics.z import Z as ZSCORE +from pyfuncella.metrics.gsea import SSGSEA + +# Import preprocessing functions +from pyfuncella.preprocess.filter import ( + filter as variance_filter, + filter_coverage, + filter_size, +) + + +def _validate_inputs(data, genesets, method): + """Validate input parameters for gene2path.""" + if data is None or len(data) == 0: + raise ValueError("No data provided") + + if genesets is None or len(genesets) == 0: + raise ValueError("No pathway list provided") + + valid_methods = [ + "CERNO", + "MEAN", + "BINA", + "AUCELL", + "JASMINE", + "ZSCORE", + "SSGSEA", + ] + if method not in valid_methods: + raise ValueError(f"Method must be one of {valid_methods}") + + +def _prepare_data_and_genes(data, genes): + """Prepare data array and gene names from input.""" + if isinstance(data, pd.DataFrame): + if genes is None: + genes = list(data.index) + data_array = data.values + sample_names = list(data.columns) + else: + data_array = np.array(data) + if genes is None: + genes = [f"Gene_{i}" for i in range(data_array.shape[0])] + sample_names = [f"Sample_{i}" for i in range(data_array.shape[1])] + + if len(genes) != data_array.shape[0]: + raise ValueError("Number of genes must match number of rows in data") + + return data_array, genes, sample_names + + +def _apply_variance_filtering(data, data_array, genes, variance_filter_threshold): + """Apply variance filtering to the data if requested.""" + if variance_filter_threshold is None: + return data_array, genes + + print(f"Applying variance filtering (keep top {variance_filter_threshold:.2%})") + + if isinstance(data, pd.DataFrame): + try: + filtered_data = variance_filter(data, leave_best=variance_filter_threshold) + if isinstance(filtered_data, pd.DataFrame): + data_array = filtered_data.values + genes = list(filtered_data.index) + else: + raise ValueError("Unexpected return type from variance filter") + except Exception as e: + print(f"Warning: Variance filtering failed: {e}") + print("Continuing without variance filtering...") + else: + # Use enhanced filter function for numpy arrays + try: + filtered_result = variance_filter( + data_array, leave_best=variance_filter_threshold, genes=genes + ) + if isinstance(filtered_result, tuple) and len(filtered_result) == 2: + data_array, genes = filtered_result + else: + raise ValueError("Unexpected return type from variance filter") + except Exception as e: + print(f"Warning: Variance filtering failed: {e}") + print("Continuing without variance filtering...") + + if genes is not None: + print(f"After variance filtering: {len(genes)} genes") + + return data_array, genes + + +def _apply_pathway_filtering(genesets, genes, filt_min, filt_max, filt_cov): + """Apply pathway filtering based on size and coverage.""" + # Filter pathways by size (filt_min, filt_max) + if filt_min > 0 or filt_max < float("inf"): + genesets = filter_size(genesets, min_size=filt_min, max_size=filt_max) + + # Filter pathways by coverage (filt_cov) + if filt_cov > 0: + genesets = filter_coverage(genesets, genes, min_coverage=filt_cov) + + return genesets + + +def _calculate_pathway_scores( + method, genesets, data_array, genes, aucell_threshold, type +): + """Calculate pathway scores using the specified method.""" + print(f"Calculating {method} scores...") + + if method == "CERNO": + scores = AUC(genesets, data_array, genes) # Use existing AUC function + elif method == "MEAN": + scores = MEAN(genesets, data_array, genes) + elif method == "BINA": + scores = BINA(genesets, data_array, genes) + elif method == "AUCELL": + scores = AUCELL(genesets, data_array, genes, aucell_threshold) + elif method == "JASMINE": + scores = JASMINE(genesets, data_array, genes, effect_size=type) + elif method == "ZSCORE": + pval, qval, z = ZSCORE(genesets, data_array, genes) + scores = z # Use z-scores as the primary result + elif method == "SSGSEA": + scores = SSGSEA(genesets, data_array, genes) + else: + raise ValueError(f"Method {method} not implemented") + + return scores + + +def gene2path( + data: Union[np.ndarray, pd.DataFrame], + genesets: Dict[str, List[str]], + genes: Optional[List[str]] = None, + method: Literal[ + "CERNO", "MEAN", "BINA", "AUCELL", "JASMINE", "ZSCORE", "SSGSEA" + ] = "CERNO", + filt_cov: float = 0, + filt_min: int = 15, + filt_max: int = 500, + aucell_threshold: float = 0.05, + variance_filter_threshold: Optional[float] = None, + type: Literal["oddsratio", "likelihood"] = "oddsratio", +) -> pd.DataFrame: + """ + Transform gene-level data to pathway-level scores using single-sample methods. + + This function reduces gene-level data to pathway-level activity scores using a variety of + single-sample pathway enrichment methods. It supports filtering pathways based on coverage + and size, similar to FUNCellA's gene2path function. + + Args: + data: Gene expression matrix with genes as rows and samples as columns + genesets: Dictionary mapping pathway names to lists of gene identifiers + genes: List of gene names (if None, uses data index if DataFrame or creates range) + method: Single-sample enrichment method to use + filt_cov: Minimum fraction of pathway genes that must be present in data (0-1) + filt_min: Minimum number of genes a pathway must have + filt_max: Maximum number of genes a pathway can have + aucell_threshold: Threshold parameter for AUCELL method (fraction of top genes to consider) + variance_filter_threshold: If provided, filter genes by variance (keep top fraction) + type: Type of effect size adjustment for JASMINE method ("oddsratio" or "likelihood") + + Returns: + DataFrame with pathways as rows and samples as columns containing pathway activity scores + + Methods: + - CERNO: Non-parametric method based on gene expression ranks using Mann-Whitney U statistic + - MEAN: Simple mean expression of pathway genes per sample + - BINA: Binary scoring based on proportion of expressed genes with logit transformation + - AUCELL: Area Under the Curve method for gene set enrichment + - JASMINE: Dropout-aware method for single-cell data with effect size adjustment + Uses 'type' parameter to specify effect size method (oddsratio or likelihood) + - ZSCORE: Z-score based method using Stouffer integration + - SSGSEA: Single-sample Gene Set Enrichment Analysis (requires R) + + Example: + >>> import pandas as pd + >>> import numpy as np + >>> # Create example data + >>> data = pd.DataFrame(np.random.randn(1000, 50)) # 1000 genes, 50 samples + >>> data.index = [f"Gene_{i}" for i in range(1000)] + >>> genesets = { + ... "Pathway1": [f"Gene_{i}" for i in range(0, 20)], + ... "Pathway2": [f"Gene_{i}" for i in range(10, 30)] + ... } + >>> scores = gene2path(data, genesets, method="CERNO") + """ + + # Input validation + _validate_inputs(data, genesets, method) + + # Convert to numpy array if needed and get gene names + data_array, genes, sample_names = _prepare_data_and_genes(data, genes) + + print(f"Starting gene2path transformation using {method} method") + print(f"Input data: {data_array.shape[0]} genes x {data_array.shape[1]} samples") + print(f"Input pathways: {len(genesets)}") + + # Apply variance filtering if requested + data_array, genes = _apply_variance_filtering( + data, data_array, genes, variance_filter_threshold + ) + + # Ensure genes is not None for the rest of the function + if genes is None: + raise ValueError("Gene names are required for filtering operations") + + # Filter pathways + genesets = _apply_pathway_filtering(genesets, genes, filt_min, filt_max, filt_cov) + + print(f"Final pathways for analysis: {len(genesets)}") + + if len(genesets) == 0: + warnings.warn("No pathways remain after filtering") + return pd.DataFrame() + + # Calculate pathway scores based on method + scores = _calculate_pathway_scores( + method, genesets, data_array, genes, aucell_threshold, type + ) + + # Create result DataFrame + pathway_names = list(genesets.keys()) + result_df = pd.DataFrame(scores, index=pathway_names, columns=sample_names) + + print(f"{method} scores calculated successfully") + print(f"Output: {result_df.shape[0]} pathways x {result_df.shape[1]} samples") + + return result_df diff --git a/pyfuncella/gmm_decomposition.R b/pyfuncella/gmm_decomposition.R new file mode 100644 index 0000000..42bf50f --- /dev/null +++ b/pyfuncella/gmm_decomposition.R @@ -0,0 +1,90 @@ +# GMM Decomposition Script +# This script performs Gaussian Mixture Model decomposition for pathway analysis +# +# Expected inputs: +# - X_data: Single pathway expression data as DataFrame row +# - K_param: Maximum number of components +# - IC_param: Information criterion ("AIC", "AICc", "BIC", "ICL-BIC", "LR") +# - verbose_param: Whether to show verbose output +# +# Output: +# - gmm_results: List containing decomposition results for each pathway + +# Load required libraries +library(dpGMM) +library(jsonlite) + +# Get parameters +K <- K_param +IC <- IC_param +X <- X_data +verbose_flag <- verbose_param + +# GMM options setup +opt <- dpGMM::GMM_1D_opts +opt$max_iter <- 1000 +opt$KS <- K +opt$plot <- FALSE +opt$quick_stop <- FALSE +opt$SW <- 0.05 +opt$sigmas.dev <- 0 +opt$IC <- IC + +# Helper function for row calculation that extracts serializable components +row_multiple <- function(row) { + tmp <- as.numeric(row) + result <- dpGMM::runGMM(tmp, opts = opt) + + # Extract key components that can be serialized based on runGMM structure + serializable_result <- list( + K = result$KS, # Number of components + IC = result[[IC]], # Information criterion value + loglik = result$logLik, # Log-likelihood + threshold = result$threshold, # The thresholds we need! + cluster = as.vector(result$cluster), # Cluster assignments + mu = result$model$mu, # Component means + sigma = result$model$sigma, # Component standard deviations + alpha = result$model$alpha, # Component weights (not lambda) + success = TRUE + ) + + # Handle potential NULL values + if (is.null(serializable_result$mu)) serializable_result$mu <- numeric(0) + if (is.null(serializable_result$sigma)) serializable_result$sigma <- numeric(0) + if (is.null(serializable_result$alpha)) serializable_result$alpha <- numeric(0) + if (is.null(serializable_result$threshold)) serializable_result$threshold <- numeric(0) + if (is.null(serializable_result$cluster)) serializable_result$cluster <- integer(0) + + serializable_result +} + +# GMM Calculation for each row (should be just one row now) +results_list <- list() +total_rows <- nrow(X) + +for (i in seq_len(total_rows)) { + tryCatch( + { + row_result <- row_multiple(X[i, ]) + results_list[[rownames(X)[i]]] <- row_result + }, + error = function(e) { + if (verbose_flag) { + cat("Warning: Failed to process pathway", rownames(X)[i], ":", e$message, "\n") + } + results_list[[rownames(X)[i]]] <- list(error = e$message, success = FALSE) + } + ) +} + +# Use jsonlite to properly serialize the results +tryCatch( + { + # Prepare final results using the expected variable name + gmm_results <- results_list + }, + error = function(e) { + cat("Error serializing results:", e$message, "\n") + gmm_results <- list(error = "Serialization failed", details = e$message) + } +) diff --git a/enrichment_auc/metrics/__init__.py b/pyfuncella/metrics/__init__.py similarity index 100% rename from enrichment_auc/metrics/__init__.py rename to pyfuncella/metrics/__init__.py diff --git a/enrichment_auc/metrics/aucell.py b/pyfuncella/metrics/aucell.py similarity index 93% rename from enrichment_auc/metrics/aucell.py rename to pyfuncella/metrics/aucell.py index bffdcdd..f9d3156 100644 --- a/enrichment_auc/metrics/aucell.py +++ b/pyfuncella/metrics/aucell.py @@ -1,7 +1,7 @@ import numpy as np from tqdm import tqdm -from enrichment_auc.metrics.rank import rank_genes +from pyfuncella.metrics.rank import rank_genes def _aucell( @@ -33,7 +33,7 @@ def _aucell( return aucell -def AUCELL(genesets, data, genes, thr=0.25): +def AUCELL(genesets, data, genes, thr=0.05): data = rank_genes(data, ordinal=True) aucell = np.zeros((len(genesets), data.shape[1])) N_tot = len(genes) diff --git a/enrichment_auc/metrics/ratio.py b/pyfuncella/metrics/bina.py similarity index 78% rename from enrichment_auc/metrics/ratio.py rename to pyfuncella/metrics/bina.py index f4bde9c..e87927c 100644 --- a/enrichment_auc/metrics/ratio.py +++ b/pyfuncella/metrics/bina.py @@ -12,10 +12,13 @@ def _ratio(geneset, data, genes, gs_name=""): return gs_expression -def RATIO(genesets, data, genes): +def BINA(genesets, data, genes): res = np.empty((len(genesets), data.shape[1])) for i, (gs_name, geneset_genes) in tqdm( enumerate(genesets.items()), total=len(genesets) ): res[i] = _ratio(geneset_genes, data, genes, gs_name) - return res + + # Calculate BINA: log((DR + 0.1) / (1 - DR + 0.1)) + bina_scores = np.log((res + 0.1) / (1 - res + 0.1)) + return bina_scores diff --git a/enrichment_auc/metrics/cerno.py b/pyfuncella/metrics/cerno.py similarity index 97% rename from enrichment_auc/metrics/cerno.py rename to pyfuncella/metrics/cerno.py index 34ec7ba..8795d57 100644 --- a/enrichment_auc/metrics/cerno.py +++ b/pyfuncella/metrics/cerno.py @@ -3,7 +3,7 @@ from statsmodels.stats.multitest import multipletests from tqdm import tqdm -from enrichment_auc.metrics.rank import rank_genes +from pyfuncella.metrics.rank import rank_genes def _fisher( diff --git a/pyfuncella/metrics/gsea.py b/pyfuncella/metrics/gsea.py new file mode 100644 index 0000000..0e221d9 --- /dev/null +++ b/pyfuncella/metrics/gsea.py @@ -0,0 +1,167 @@ +import pandas as pd +import numpy as np +from typing import Optional, Dict, Any, Union +from ..utils.r_executor import execute_r_code, check_r_available, RProcessError + + +def _check_gsva_installed() -> bool: + """Check if GSVA package is installed in R.""" + if not check_r_available(): + return False + try: + result = execute_r_code( + """ + tryCatch({ + library(GSVA) + success <- TRUE + }, error = function(e) { + success <- FALSE + }) + success + """ + ) + return result.get("success", False) + except Exception as e: + return False + + +def _run_analysis(genesets, data, genes, method, progress_callback=None): + """ + Run GSVA/SSGSEA analysis using R executor pattern. + + Parameters + ---------- + genesets : dict + Dictionary mapping pathway names to lists of gene names + data : array-like + Gene expression data (genes x samples) + genes : list + List of gene names corresponding to data rows + method : str + Method to use ('gsva' or 'ssgsea') + + Returns + ------- + numpy.ndarray + Pathway enrichment scores (pathways x samples) + """ + + # Note: GSVA availability is verified during container build + # Skip the runtime check to avoid false negatives in different execution contexts + + # Convert data to DataFrame + df = pd.DataFrame(data, index=genes) + + # Prepare data for R + data_inputs = {"gene_expr": df, "genesets": genesets, "method_param": method} + + # Get the path to the R script and read it + import os + + script_dir = os.path.dirname(os.path.abspath(__file__)) + r_script_path = os.path.join(script_dir, "gsva_analysis.R") + + # Read the R script content + with open(r_script_path, "r") as f: + r_code = f.read() + + try: + result = execute_r_code(r_code, data_inputs) + + if not result.get("success", False): + raise RProcessError(f"{method.upper()} analysis failed in R") + + # Extract results - try different keys where results might be stored + gsva_results = result.get("gsva_results") + + # If gsva_results is None, try other possible keys + if gsva_results is None: + for possible_key in ["scores", "samples", "pathways", "data", "results"]: + if possible_key in result: + gsva_results = {possible_key: result[possible_key]} + break + + if gsva_results is None or not isinstance(gsva_results, dict): + raise RProcessError(f"No results returned from {method.upper()} analysis") + + # Check for errors + if "error" in gsva_results: + raise RProcessError( + f"{method.upper()} analysis failed: {gsva_results['error']}" + ) + + # Extract structured results + scores = gsva_results.get("scores", {}) + samples = gsva_results.get("samples", []) + pathways = gsva_results.get("pathways", []) + + # Reconstruct DataFrame + try: + # Create DataFrame with pathways as rows and samples as columns + data_matrix = [] + pathway_names = [] + + for pathway in pathways: + if pathway in scores: + data_matrix.append(scores[pathway]) + pathway_names.append(pathway) + + if not data_matrix: + raise RProcessError( + f"No pathway scores found in {method.upper()} results" + ) + + results_df = pd.DataFrame(data_matrix, index=pathway_names, columns=samples) + + return results_df.values # Return numpy array instead of DataFrame + + except Exception as e: + # If all else fails, let's see what we actually got + raise RProcessError( + f"Cannot convert {method.upper()} results to DataFrame: {str(e)}" + ) + + except Exception as e: + raise RProcessError(f"{method.upper()} analysis failed: {str(e)}") + + +def GSVA(genesets, data, genes): + """ + Run GSVA analysis using R executor pattern. + + Parameters + ---------- + genesets : dict + Dictionary mapping pathway names to lists of gene names + data : array-like + Gene expression data (genes x samples) + genes : list + List of gene names corresponding to data rows + + Returns + ------- + numpy.ndarray + GSVA enrichment scores (pathways x samples) + """ + return _run_analysis(genesets, data, genes, "gsva", None) + + +def SSGSEA(genesets, data, genes): + """ + Run ssGSEA analysis using R executor pattern. + + Parameters + ---------- + genesets : dict + Dictionary mapping pathway names to lists of gene names + data : array-like + Gene expression data (genes x samples) + genes : list + List of gene names corresponding to data rows + + Returns + ------- + numpy.ndarray + ssGSEA enrichment scores (pathways x samples) + """ + return _run_analysis(genesets, data, genes, "ssgsea", None) diff --git a/pyfuncella/metrics/gsva_analysis.R b/pyfuncella/metrics/gsva_analysis.R new file mode 100644 index 0000000..d1c8d75 --- /dev/null +++ b/pyfuncella/metrics/gsva_analysis.R @@ -0,0 +1,76 @@ +# GSVA/SSGSEA Analysis Script +# This script runs GSVA or SSGSEA analysis using the modern GSVA interface +# +# Expected inputs: +# - gene_expr: Gene expression matrix (genes x samples) +# - genesets: Named list of gene sets +# - method_param: Analysis method ("gsva" or "ssgsea") +# +# Output: +# - gsva_results: List containing scores, samples, and pathways + +# Load required libraries +suppressMessages({ + library(methods) + library(stats) + library(utils) + library(GSVA) +}) + +# Get parameters +gene_expression <- gene_expr +pathways <- genesets +analysis_method <- method_param + +# Initialize result variable +gsva_results <- list(error = "Initialization failed") + +# Run GSVA/SSGSEA analysis +tryCatch( + { + # Use the new GSVA interface with method-specific parameter objects + if (analysis_method == "ssgsea") { + # For ssGSEA, use ssgseaParam + param <- ssgseaParam( + expr = as.matrix(gene_expression), + geneSets = pathways + ) + results <- gsva(param) + } else if (analysis_method == "gsva") { + # For GSVA, use gsvaParam + param <- gsvaParam( + expr = as.matrix(gene_expression), + geneSets = pathways, + kcdf = "Gaussian" + ) + results <- gsva(param) + } else { + stop(paste("Unsupported method:", analysis_method)) + } + + # Convert results matrix to list format for JSON serialization + # Each row (pathway) becomes a named list element + results_list <- list() + for (i in seq_len(nrow(results))) { + pathway_name <- rownames(results)[i] + pathway_scores <- as.numeric(results[i, ]) + results_list[[pathway_name]] <- pathway_scores + } + + # Also include column names for proper reconstruction + sample_names <- colnames(results) + + # Create the final result structure and assign to the expected variable name + gsva_results <- list( + scores = results_list, + samples = sample_names, + pathways = rownames(results) + ) + }, + error = function(e) { + gsva_results <<- list(error = paste("GSVA error:", e$message)) + } +) + +# Ensure gsva_results is the final result variable that gets returned +gsva_results diff --git a/pyfuncella/metrics/jasmine.py b/pyfuncella/metrics/jasmine.py new file mode 100644 index 0000000..f5862da --- /dev/null +++ b/pyfuncella/metrics/jasmine.py @@ -0,0 +1,217 @@ +import numpy as np +from tqdm import tqdm +from scipy.stats.mstats import rankdata + + +def dropout(data): + ma_data = np.ma.masked_equal(data, 0) + return ma_data + + +def rank_genes(masked_data): + ranks = np.zeros(masked_data.data.shape) + N = np.count_nonzero(masked_data.mask == 0, axis=0) + good_idx = np.where(N != 0) + ranks[:, good_idx] = rankdata(masked_data[:, good_idx], axis=0, use_missing=False) + ranks = np.ma.masked_array(ranks, masked_data.mask) + return ranks + + +def calc_odds_ratio(data, geneset_genes, genes): + """ + Calculate odds ratio for each sample, assessing the enrichment + of a pathway by comparing the presence (non-zero expression) of genes + in the pathway versus those not in the pathway. + + Parameters: + ----------- + data : np.ndarray + Gene expression matrix with genes as rows and samples as columns + geneset_genes : list + List of gene names in the geneset + genes : list + List of all gene names + + Returns: + -------- + np.ndarray + Odds ratios for each sample + """ + # Get indices of genes in and not in the geneset + sig_gene_indices = [i for i, gene in enumerate(genes) if gene in geneset_genes] + non_sig_gene_indices = [ + i for i, gene in enumerate(genes) if gene not in geneset_genes + ] + + if len(sig_gene_indices) == 0: + return np.zeros(data.shape[1]) + + # Count expressed genes (non-zero) for signature and non-signature genes + sig_genes_exp = np.sum(data[sig_gene_indices, :] != 0, axis=0) + non_sig_genes_exp = np.sum(data[non_sig_gene_indices, :] != 0, axis=0) + + # Count non-expressed genes with pseudocount to prevent division by zero + sig_genes_ne = np.maximum(len(sig_gene_indices) - sig_genes_exp, 1) + non_sig_genes_ne = np.maximum(len(non_sig_gene_indices) - non_sig_genes_exp, 1) + + # Calculate odds ratio with protection against division by zero + denominator = sig_genes_ne * non_sig_genes_exp + denominator = np.maximum(denominator, 1e-10) # Avoid division by zero + or_values = (sig_genes_exp * non_sig_genes_ne) / denominator + + return or_values + + +def calc_likelihood(data, geneset_genes, genes): + """ + Calculate likelihood ratio for each sample, comparing the expression + of genes in the provided gene set against non-pathway genes. + + Parameters: + ----------- + data : np.ndarray + Gene expression matrix with genes as rows and samples as columns + geneset_genes : list + List of gene names in the geneset + genes : list + List of all gene names + + Returns: + -------- + np.ndarray + Likelihood ratios for each sample + """ + # Get indices of genes in and not in the geneset + sig_gene_indices = [i for i, gene in enumerate(genes) if gene in geneset_genes] + non_sig_gene_indices = [ + i for i, gene in enumerate(genes) if gene not in geneset_genes + ] + + if len(sig_gene_indices) == 0: + return np.zeros(data.shape[1]) + + # Count expressed genes (non-zero) for signature and non-signature genes + sig_genes_exp = np.sum(data[sig_gene_indices, :] != 0, axis=0) + non_sig_genes_exp = np.sum(data[non_sig_gene_indices, :] != 0, axis=0) + + # Count non-expressed genes with pseudocount to prevent division by zero + sig_genes_ne = np.maximum(len(sig_gene_indices) - sig_genes_exp, 1) + non_sig_genes_ne = np.maximum(len(non_sig_gene_indices) - non_sig_genes_exp, 1) + + # Calculate likelihood ratio + lr1 = sig_genes_exp * (non_sig_genes_exp + non_sig_genes_ne) + lr2 = non_sig_genes_exp * (sig_genes_exp + sig_genes_ne) + + # Avoid division by zero + lr2 = np.maximum(lr2, 1e-10) + lr_values = lr1 / lr2 + + return lr_values + + +def scale_minmax(x): + """ + Apply min-max normalization to scale values to range [0, 1]. + + Parameters: + ----------- + x : np.ndarray + Input array to normalize + + Returns: + -------- + np.ndarray + Min-max normalized array + """ + x = np.asarray(x) + if np.isnan(x).all(): + return np.zeros_like(x) + + x_range = np.max(x) - np.min(x) + if x_range == 0 or np.isnan(x_range): + return np.zeros_like(x) + + x_scaled = (x - np.min(x)) / x_range + return x_scaled + + +def _jasmine(geneset, ranks, genes, data=None, effect_size="oddsratio", gs_name=""): + genes_in_ds = [gene in geneset for gene in genes] + # find the number of nonzero genes for each cell + N = np.count_nonzero(ranks.mask == 0, axis=0) + + # Calculate ranking component (RM) - dropout-aware ranking + ranking_scores = ranks[genes_in_ds, :].mean(axis=0) / N + ranking_scores = ranking_scores.filled(0) + + # If data is provided, calculate and combine with effect size component (ES) + if data is not None: + # Calculate effect size component + if effect_size == "oddsratio": + effect_scores = calc_odds_ratio(data, geneset, genes) + elif effect_size == "likelihood": + effect_scores = calc_likelihood(data, geneset, genes) + else: + effect_scores = np.zeros(data.shape[1]) + + # Normalize both components with min-max scaling + ranking_scores_norm = scale_minmax(ranking_scores) + effect_scores_norm = scale_minmax(effect_scores) + + # Combine ranking and effect size (if effect size is valid) + if np.isnan(effect_scores_norm).all(): + final_scores = ranking_scores_norm + else: + final_scores = (ranking_scores_norm + effect_scores_norm) / 2 + + return final_scores + else: + # Return only ranking scores for backward compatibility (original method) + return ranking_scores + + +def JASMINE(genesets, data, genes, use_effect_size=True, effect_size="oddsratio"): + """ + Calculate JASMINE pathway enrichment scores. + + Parameters: + ----------- + genesets : dict + Dictionary mapping geneset names to lists of gene names + data : np.ndarray + Gene expression matrix with genes as rows and samples as columns + genes : list + List of all gene names + use_effect_size : bool, default=True + Whether to use effect size component (FUNCellA-style implementation) + effect_size : str, default="oddsratio" + Effect size method: "oddsratio" or "likelihood" + + Returns: + -------- + np.ndarray + JASMINE scores with shape (n_genesets, n_samples) + """ + jasmine = np.empty((len(genesets), data.shape[1])) + masked_data = dropout(data) + ranks = rank_genes(masked_data) + + for i, (gs_name, geneset_genes) in tqdm( + enumerate(genesets.items()), total=len(genesets) + ): + if use_effect_size: + # Use enhanced method with effect size + jasmine[i] = _jasmine( + geneset_genes, ranks, genes, data, effect_size, gs_name + ) + else: + # Use original method + jasmine[i] = _jasmine(geneset_genes, ranks, genes, gs_name=gs_name) + + # Apply final normalization only for original method + if not use_effect_size: + # standardize the results for each geneset using min-max scaling + for i in range(jasmine.shape[0]): + jasmine[i] = scale_minmax(jasmine[i]) + + return jasmine diff --git a/enrichment_auc/metrics/mean.py b/pyfuncella/metrics/mean.py similarity index 100% rename from enrichment_auc/metrics/mean.py rename to pyfuncella/metrics/mean.py diff --git a/enrichment_auc/metrics/rank.py b/pyfuncella/metrics/rank.py similarity index 100% rename from enrichment_auc/metrics/rank.py rename to pyfuncella/metrics/rank.py diff --git a/enrichment_auc/metrics/svd.py b/pyfuncella/metrics/svd.py similarity index 100% rename from enrichment_auc/metrics/svd.py rename to pyfuncella/metrics/svd.py diff --git a/enrichment_auc/metrics/vision.py b/pyfuncella/metrics/vision.py similarity index 100% rename from enrichment_auc/metrics/vision.py rename to pyfuncella/metrics/vision.py diff --git a/enrichment_auc/metrics/z.py b/pyfuncella/metrics/z.py similarity index 100% rename from enrichment_auc/metrics/z.py rename to pyfuncella/metrics/z.py diff --git a/enrichment_auc/normalize/__init__.py b/pyfuncella/normalize/__init__.py similarity index 100% rename from enrichment_auc/normalize/__init__.py rename to pyfuncella/normalize/__init__.py diff --git a/enrichment_auc/normalize/freeman_tukey.py b/pyfuncella/normalize/freeman_tukey.py similarity index 100% rename from enrichment_auc/normalize/freeman_tukey.py rename to pyfuncella/normalize/freeman_tukey.py diff --git a/enrichment_auc/plot/__init__.py b/pyfuncella/plot/__init__.py similarity index 100% rename from enrichment_auc/plot/__init__.py rename to pyfuncella/plot/__init__.py diff --git a/enrichment_auc/plot/legend_handler.py b/pyfuncella/plot/legend_handler.py similarity index 100% rename from enrichment_auc/plot/legend_handler.py rename to pyfuncella/plot/legend_handler.py diff --git a/pyfuncella/plot/plot_distributed_data.py b/pyfuncella/plot/plot_distributed_data.py new file mode 100644 index 0000000..49ba187 --- /dev/null +++ b/pyfuncella/plot/plot_distributed_data.py @@ -0,0 +1,133 @@ +import plotly.graph_objects as go +import pandas as pd +import numpy as np +from scipy.stats import norm + + +def plot_pas_distribution(pas_scores, pas_method, pathway_name, threshold, gmm=None): + """ + Plot PAS score distribution for a pathway, with threshold and optional GMM components. + + Parameters + ---------- + pas_scores : array-like + PAS scores for cells. + pas_method : str + Name of PAS method (for axis label). + pathway_name : str + Name of pathway (for plot title). + threshold : float + Threshold value for significance. + gmm : dict, optional + GMM parameters from GMMdecomp (dict with keys 'alpha', 'mu', 'sigma'). + If provided, overlays GMM components as dashed lines. + + Notes + ----- + - For GMM overlay, pass the 'model' dict from GMMdecomp output for the pathway: + e.g. gmm = results[pathway]['model'] + """ + + pas_scores = np.asarray(pas_scores) + labels = (pas_scores > threshold).astype(int) + df = pd.DataFrame({"value": pas_scores, "label": labels}) + + # Histogram with density normalization + hist = go.Histogram( + x=df["value"], + marker_color="lightgrey", + opacity=0.75, + nbinsx=30, + histnorm="probability density", # Normalize to density + showlegend=False, + ) + + # Rugs + rug0 = go.Scatter( + x=df[df["label"] == 0]["value"], + y=[-1] * sum(df["label"] == 0), + mode="markers", + marker=dict(color="blue", size=5), + name="Non significant", + legendgroup="significance", + showlegend=True, + hoverinfo="x", + ) + rug1 = go.Scatter( + x=df[df["label"] == 1]["value"], + y=[-1] * sum(df["label"] == 1), + mode="markers", + marker=dict(color="red", size=5), + name="Significant", + legendgroup="significance", + showlegend=True, + hoverinfo="x", + ) + + fig = go.Figure(data=[hist, rug0, rug1]) + + # Calculate density histogram stats for y-axis scaling + counts, bin_edges = np.histogram(df["value"], bins=30, density=True) + hist_ymax = counts.max() + + # Overlay GMM if provided (from GMMdecomp) + if gmm is not None and isinstance(gmm, dict): + # Limit x-range to actual data range + data_min, data_max = df["value"].min(), df["value"].max() + x = np.linspace(data_min, data_max, 1000) + alpha = np.asarray(gmm.get("alpha", [])) + mu = np.asarray(gmm.get("mu", [])) + sigma = np.asarray(gmm.get("sigma", [])) + n_comp = len(alpha) + for i in range(n_comp): + pdf = alpha[i] * norm.pdf(x, mu[i], sigma[i]) + fig.add_trace( + go.Scatter( + x=x, + y=pdf, + mode="lines", + line=dict(width=2, dash="dot"), + name=f"GMM comp. {i+1}", + legendgroup="gmm", + ) + ) + + # Add threshold line + fig.add_shape( + type="line", + x0=threshold, + x1=threshold, + y0=0, + y1=hist_ymax, + xref="x", + yref="y", + line=dict(color="black", width=2, dash="dash"), + ) + + # Add threshold label + fig.add_annotation( + x=threshold, + y=hist_ymax / 2, + text=f"thr = {threshold:.2f}", + showarrow=False, + ax=2, + yanchor="bottom", + font=dict(color="black"), + ) + + # Clean style and adjust legend position + fig.update_layout( + title=pathway_name, + xaxis_title=pas_method, + yaxis_title="Density", + template="simple_white", + font=dict(family="Arial", size=14), + bargap=0.05, + legend=dict(title="", orientation="h", x=0.5, xanchor="center", y=1.15), + margin=dict(l=40, r=30, t=50, b=40), + ) + + # Extend y-axis to show rugs + fig.update_yaxes(range=[-2, None]) + + return fig diff --git a/pyfuncella/plot/plot_scatter_flow.py b/pyfuncella/plot/plot_scatter_flow.py new file mode 100644 index 0000000..95a8e3e --- /dev/null +++ b/pyfuncella/plot/plot_scatter_flow.py @@ -0,0 +1,146 @@ +import plotly.graph_objects as go +from plotly.subplots import make_subplots +import plotly.colors as pc +import numpy as np +import pandas as pd + + +def scatterplot_subplots( + x, + y, + continuous_labels=None, + binary_labels=None, + ranked_labels=None, + title="Pathway name", + pas_method="PAS name", +): + has_continuous = continuous_labels is not None + has_binary = binary_labels is not None + has_ranked = ranked_labels is not None + + plots = [] + if has_continuous: + plots.append("continuous") + if has_binary: + plots.append("binary") + if has_ranked: + plots.append("ranked") + + rows = len(plots) + cols = 1 + + title_map = { + "continuous": "PAS values", + "binary": "Significance", + "ranked": "Groups", + } + subplot_titles = [title_map[p] for p in plots] + specs = [[{}] for _ in plots] + + fig = make_subplots( + rows=rows, + cols=cols, + specs=specs, + subplot_titles=subplot_titles, + vertical_spacing=0.12, + ) + + current_row = 1 + + if has_continuous: + fig.add_trace( + go.Scatter( + x=x, + y=y, + mode="markers", + customdata=continuous_labels, + hovertemplate="%{fullData.name}
" + + "x: %{x}
" + + "y: %{y}
" + + f"{pas_method}: %{{customdata:.3f}}
" + + "", + marker=dict( + color=continuous_labels, + colorscale="Viridis", + size=8, + showscale=True, + colorbar=dict( + title=pas_method, + thickness=15, + len=0.3, # Shortened colorbar length + y=1.0, + yanchor="top", + x=1.07, # Position right side + ), + ), + showlegend=False, # No legend entry for continuous; colorbar used + ), + row=current_row, + col=1, + ) + current_row += 1 + + if has_binary: + binary_df = pd.DataFrame({"x": x, "y": y, "label": binary_labels}) + for label, color, name in zip( + [0, 1], ["blue", "red"], ["Non significant", "Significant"] + ): + subset = binary_df[binary_df["label"] == label] + fig.add_trace( + go.Scatter( + x=subset["x"], + y=subset["y"], + mode="markers", + marker=dict(color=color, size=8), + name=name, + legendgroup="binary", + showlegend=True, + ), + row=current_row, + col=1, + ) + current_row += 1 + + if has_ranked: + ranked_df = pd.DataFrame({"x": x, "y": y, "label": ranked_labels}) + unique_ranks = sorted(np.unique(ranked_labels)) + color_cycle = ( + pc.qualitative.Plotly + * ((len(unique_ranks) // len(pc.qualitative.Plotly)) + 1) + )[: len(unique_ranks)] + for i, rank in enumerate(unique_ranks): + subset = ranked_df[ranked_df["label"] == rank] + fig.add_trace( + go.Scatter( + x=subset["x"], + y=subset["y"], + mode="markers", + marker=dict(color=color_cycle[i], size=8), + name=f"Group {rank}", + legendgroup="ranked", + showlegend=True, + ), + row=current_row, + col=1, + ) + current_row += 1 + + fig.update_layout( + height=400 * rows, + width=750, + title_text=title, + title_x=0.02, + margin=dict(l=80, r=230), # room on right for colorbar+legend + legend=dict( + yanchor="top", + y=0.65, # Legend below the colorbar (colorbar y=1 with length=0.3) + xanchor="left", + x=1.07, # Align horizontally with colorbar + tracegroupgap=350, # vertical gap between legend groups + font=dict(size=12), + bgcolor="rgba(0,0,0,0)", # transparent background + borderwidth=0, # no border + ), + ) + + return fig diff --git a/enrichment_auc/preprocess/__init__.py b/pyfuncella/preprocess/__init__.py similarity index 100% rename from enrichment_auc/preprocess/__init__.py rename to pyfuncella/preprocess/__init__.py diff --git a/enrichment_auc/preprocess/clean_geneset.py b/pyfuncella/preprocess/clean_geneset.py similarity index 100% rename from enrichment_auc/preprocess/clean_geneset.py rename to pyfuncella/preprocess/clean_geneset.py diff --git a/enrichment_auc/preprocess/entrez2genes.py b/pyfuncella/preprocess/entrez2genes.py similarity index 100% rename from enrichment_auc/preprocess/entrez2genes.py rename to pyfuncella/preprocess/entrez2genes.py diff --git a/pyfuncella/preprocess/filter.py b/pyfuncella/preprocess/filter.py new file mode 100644 index 0000000..352e37e --- /dev/null +++ b/pyfuncella/preprocess/filter.py @@ -0,0 +1,156 @@ +import sys +from typing import Union, List, Optional + +import numpy as np +import pandas as pd + + +def filter( + cells: Union[pd.DataFrame, np.ndarray], + leave_best: float = 0.25, + genes: Optional[List[str]] = None, +) -> Union[pd.DataFrame, tuple]: + """ + Filter genes by variance, keeping the most variable ones. + + Args: + cells: Gene expression data (DataFrame or numpy array) + leave_best: Fraction of genes to keep (0-1) + genes: Gene names (required if cells is numpy array) + + Returns: + If input is DataFrame: filtered DataFrame + If input is numpy array: tuple of (filtered_array, filtered_gene_names) + """ + leave_best = max(0, min(leave_best, 1)) + + if isinstance(cells, pd.DataFrame): + # Original DataFrame logic + cells.dropna(inplace=True) + vars = np.var(cells, axis=1) + vars = vars[vars != 0] + vars = vars.sort_values() + cells = cells.loc[vars[int((1 - leave_best) * vars.shape[0]) :].index] + return cells + + elif isinstance(cells, np.ndarray): + # Numpy array logic + if genes is None: + raise ValueError("Gene names must be provided when filtering numpy arrays") + + if len(genes) != cells.shape[0]: + raise ValueError("Number of genes must match number of rows in data") + + # Calculate variances + variances = np.var(cells, axis=1) + + # Remove genes with zero variance + non_zero_mask = variances != 0 + cells_filtered = cells[non_zero_mask, :] + genes_filtered = [genes[i] for i in range(len(genes)) if non_zero_mask[i]] + variances_filtered = variances[non_zero_mask] + + # Sort by variance and keep top fraction + n_keep = int(leave_best * len(variances_filtered)) + if n_keep == 0: + n_keep = 1 # Keep at least one gene + + # Get indices of top variable genes + top_indices = np.argsort(variances_filtered)[-n_keep:] + + # Filter data and genes + final_data = cells_filtered[top_indices, :] + final_genes = [genes_filtered[i] for i in top_indices] + + return final_data, final_genes + + else: + raise ValueError("Input must be pandas DataFrame or numpy array") + + +def filter_coverage( + genesets: dict, + genes: List[str], + min_coverage: float = 0.0, +) -> dict: + """ + Filter pathways by gene coverage in expression data. + + Args: + genesets: Dictionary of pathway name -> list of genes + genes: List of gene names available in the dataset + min_coverage: Minimum fraction of pathway genes that must be present in data (0-1) + + Returns: + Filtered genesets dictionary + """ + if min_coverage <= 0: + return genesets + + print(f"PATHWAY COVERAGE FILTRATION (min_coverage={min_coverage})") + + filtered_genesets = {} + removed_count = 0 + + for pathway_name, pathway_genes in genesets.items(): + # Check how many pathway genes are present in the data + genes_present = [gene for gene in pathway_genes if gene in genes] + coverage = ( + len(genes_present) / len(pathway_genes) if len(pathway_genes) > 0 else 0 + ) + + if coverage >= min_coverage: + filtered_genesets[pathway_name] = pathway_genes + else: + removed_count += 1 + + print(f"In total removed: {removed_count} pathways") + return filtered_genesets + + +def filter_size( + genesets: dict, + min_size: int = 15, + max_size: int = 500, +) -> dict: + """ + Filter pathways by size (number of genes). + + Args: + genesets: Dictionary of pathway name -> list of genes + min_size: Minimum number of genes a pathway must have + max_size: Maximum number of genes a pathway can have + + Returns: + Filtered genesets dictionary + """ + print(f"PATHWAY SIZE FILTRATION (min_size={min_size}, max_size={max_size})") + + filtered_genesets = {} + removed_count = 0 + + for pathway_name, pathway_genes in genesets.items(): + pathway_size = len(pathway_genes) + + if min_size <= pathway_size <= max_size: + filtered_genesets[pathway_name] = pathway_genes + else: + removed_count += 1 + + print(f"In total removed: {removed_count} pathways") + return filtered_genesets + + +if __name__ == "__main__": + folder = sys.argv[1] + datatype = sys.argv[2] + path = sys.argv[3] + infile = path + folder + "/" + datatype + "_data.csv" + outfile = path + folder + "/" + datatype + "_filtered_data.csv" + cells = pd.read_csv(infile, index_col=0) + filtered_cells = filter(cells) + # Since we're reading a CSV, the result will always be a DataFrame + if isinstance(filtered_cells, pd.DataFrame): + filtered_cells.to_csv(outfile) + else: + raise ValueError("Unexpected return type from filter function") diff --git a/pyfuncella/thr_AUCell.py b/pyfuncella/thr_AUCell.py new file mode 100644 index 0000000..a9fbc4e --- /dev/null +++ b/pyfuncella/thr_AUCell.py @@ -0,0 +1,197 @@ +import numpy as np +import pandas as pd +from typing import Optional, Callable, Union, Dict, Any +from pyfuncella.utils.progress_callbacks import get_progress_callback +from .utils.r_executor import execute_r_code, check_r_available, RProcessError + + +def _check_aucell_installed() -> bool: + """Check if AUCell package is installed in R.""" + if not check_r_available(): + return False + try: + result = execute_r_code( + """ + tryCatch({ + library(AUCell) + success <- TRUE + }, error = function(e) { + success <- FALSE + }) + success + """ + ) + return result.get("success", False) + except Exception: + return False + + +def thr_AUCell( + df_path, + pathway_names=None, + sample_names=None, + progress_callback: Optional[Callable] = None, +): + """ + Calculate activity thresholds for pathways using AUCell's thresholding algorithm. + + Automatically normalizes data to [0,1] range if values are outside this range, + calculates thresholds on normalized data, then rescales thresholds back to + original data range. + + Parameters + ---------- + df_path : pd.DataFrame or np.ndarray + Pathway activity scores (rows: pathways, columns: samples). + pathway_names : list, optional + Names for pathways (rows). Used if df_path is numpy array. + sample_names : list, optional + Names for samples (columns). Used if df_path is numpy array. + progress_callback : callable, optional + Optional callback function for progress reporting. + Should accept (current, total, message) parameters. + + Returns + ------- + dict + Dictionary mapping pathway names to threshold activity score. + Thresholds are in the original data scale. + """ + if not check_r_available(): + raise RuntimeError( + "R is not available. AUCell thresholding requires R with the AUCell package.\n" + "Please ensure:\n" + "1. R is installed and accessible from your PATH\n" + "2. Install R dependencies by running: Rscript setup_docker_compatible_renv.R\n" + "3. Or manually install AUCell: BiocManager::install('AUCell')" + ) + + if not _check_aucell_installed(): + raise RuntimeError( + "AUCell package is not installed in R.\n" + "Please install it by running: Rscript setup_docker_compatible_renv.R\n" + "Or manually: BiocManager::install('AUCell')" + ) + + # Convert input to DataFrame if needed + if isinstance(df_path, np.ndarray): + n_pathways, n_samples = df_path.shape + if pathway_names is None: + pathway_names = [f"pathway_{i}" for i in range(n_pathways)] + if sample_names is None: + sample_names = [f"sample_{i}" for i in range(n_samples)] + sample_names = [f"sample_{i}" for i in range(n_samples)] + df = pd.DataFrame(df_path, index=pathway_names, columns=sample_names) + else: + df = df_path.copy() + if df.index is None or not hasattr(df.index, "size") or df.index.size == 0: + df = df.copy() + df.index = pd.Index([f"pathway_{i}" for i in range(df.shape[0])]) + + # Check if normalization is needed and store per-pathway scaling info + pathway_scaling_info = {} + df_normalized = df.copy() + + for pathway_name in df.index: + pathway_data = df.loc[pathway_name] + data_min = np.min(pathway_data) + data_max = np.max(pathway_data) + + # Check if this pathway needs normalization + if data_min < 0 or data_max > 1: + # Store scaling info for this pathway + original_range = data_max - data_min + if original_range == 0: + # Handle constant values - no normalization needed + pathway_scaling_info[pathway_name] = None + else: + pathway_scaling_info[pathway_name] = { + "min": data_min, + "max": data_max, + "range": original_range, + } + # Normalize this pathway to [0, 1] + df_normalized.loc[pathway_name] = ( + pathway_data - data_min + ) / original_range + else: + # No normalization needed for this pathway + pathway_scaling_info[pathway_name] = None + + # Count how many pathways needed normalization + normalized_count = sum( + 1 for info in pathway_scaling_info.values() if info is not None + ) + total_pathways = len(df.index) + + if progress_callback: + if normalized_count > 0: + progress_callback( + 0, + len(df), + f"Normalized {normalized_count}/{total_pathways} pathways to [0, 1] range", + ) + else: + progress_callback(0, len(df), "All pathways already in [0, 1] range") + + # Get the path to the R script and read it + import os + + script_dir = os.path.dirname(os.path.abspath(__file__)) + r_script_path = os.path.join(script_dir, "aucell_threshold.R") + + # Read the R script content + with open(r_script_path, "r") as f: + r_code = f.read() + + try: + if progress_callback: + progress_callback( + 0, len(df_normalized), "Starting AUCell threshold calculation" + ) + + thresholds = {} + + # Process each pathway individually for proper progress reporting + for i, (pathway_name, pathway_data) in enumerate(df_normalized.iterrows()): + if progress_callback: + progress_callback(i, len(df_normalized), f"Processing {pathway_name}") + + # Prepare single pathway data for R + pathway_df = pd.DataFrame([pathway_data], index=[pathway_name]) + data_inputs = {"pathway_scores": pathway_df} + + # Execute R code for this pathway + result = execute_r_code(r_code, data_inputs) + + if result.get("success", False): + threshold_value = result.get("aucell_results") + if threshold_value is not None: + # Rescale threshold back to original data range if normalization was applied + scaling_info = pathway_scaling_info[pathway_name] + if scaling_info is not None: + # Rescale: threshold_original = threshold_normalized * range + min + threshold_value = ( + threshold_value * scaling_info["range"] + + scaling_info["min"] + ) + thresholds[pathway_name] = threshold_value + else: + print(f"Warning: Failed to calculate threshold for {pathway_name}") + + if progress_callback: + if normalized_count > 0: + progress_callback( + len(df), + len(df), + f"AUCell completed ({normalized_count} pathways rescaled to original ranges)", + ) + else: + progress_callback( + len(df), len(df), "AUCell threshold calculation completed" + ) + + return thresholds + + except Exception as e: + raise RProcessError(f"AUCell threshold calculation failed: {str(e)}") diff --git a/pyfuncella/thr_GMM.py b/pyfuncella/thr_GMM.py new file mode 100644 index 0000000..bab3c87 --- /dev/null +++ b/pyfuncella/thr_GMM.py @@ -0,0 +1,100 @@ +import numpy as np +from typing import Optional, Callable +from pyfuncella.utils.kmeans_search import km_search +from pyfuncella.utils.progress_callbacks import get_progress_callback + + +def thr_GMM(gmms, progress_callback: Optional[Callable] = None): + """ + Calculate thresholds for pathway activity based on GMMs. + + Parameters + ---------- + gmms : dict + Dictionary of GMM results, one per pathway. Each value must have: + - 'thresholds': numeric vector of GMM thresholds + - 'model': dict with 'mu', 'sigma', 'alpha' (component params) + progress_callback : callable, optional + Optional callback function for progress reporting. + Should accept (current, total, message) parameters. + + Returns + ------- + dict + Dictionary with keys as pathway names, values as dicts: + - 'Kmeans_thr': threshold chosen via k-means (or fallback) + - 'Top1_thr': maximum original threshold + - 'All_thr': all thresholds (after NA removal) + """ + results = {} + pathway_names = list(gmms.keys()) + total_pathways = len(pathway_names) + + progress_cb = get_progress_callback( + progress_callback, + description="Calculating thresholds", + unit="pathway", + verbose=True, + ) + + for i, name in enumerate(pathway_names): + progress_cb(i + 1, total_pathways, f"threshold {name}") + results[name] = _process_pathway_threshold(gmms[name]) + + return results + + +def _process_pathway_threshold(gmm): + """Process threshold calculation for a single pathway.""" + # Handle both old format (thresholds array) and new format (single threshold) + thrs = gmm.get("thresholds") # Old format for backward compatibility + single_thr = gmm.get("threshold") # New format from GMMdecomp + + if thrs is not None: + # Old format: multiple thresholds as array + thrs = np.asarray(thrs, dtype=float) + valid_mask = ~np.isnan(thrs) + thrs_clean = thrs[valid_mask] + elif single_thr is not None: + # New format: single threshold from GMMdecomp + if np.isnan(single_thr) or np.isinf(single_thr): + thrs_clean = np.array([]) + else: + thrs_clean = np.array([float(single_thr)]) + else: + # No thresholds available + thrs_clean = np.array([]) + + model = gmm.get("model", {}) + + # Top1 threshold: max of cleaned thresholds, fallback to nan if empty + Top1_thr = np.nanmax(thrs_clean) if thrs_clean.size > 0 else float("nan") + All_thr = thrs_clean.tolist() + + # Prepare params for k-means threshold + mu = np.asarray(model.get("mu", [])) + sigma = np.asarray(model.get("sigma", [])) + alpha = np.asarray(model.get("alpha", [])) + + # Kmeans threshold logic + if thrs_clean.size > 0: + n_components = mu.size + if thrs_clean.size == 1 and n_components == 2: + Kmeans_thr = thrs_clean[0] + elif thrs_clean.size != n_components - 1: + Kmeans_thr = Top1_thr + else: + # Build a GMM result dict for km_search + gmm_for_kmeans = { + "model": {"mu": mu, "sigma": sigma, "alpha": alpha}, + "thresholds": thrs_clean, + } + Kmeans_thr = km_search(gmm_for_kmeans) + else: + Kmeans_thr = float("-inf") + + return { + "Kmeans_thr": Kmeans_thr, + "Top1_thr": Top1_thr, + "All_thr": All_thr, + } diff --git a/pyfuncella/thr_KM.py b/pyfuncella/thr_KM.py new file mode 100644 index 0000000..7883809 --- /dev/null +++ b/pyfuncella/thr_KM.py @@ -0,0 +1,138 @@ +""" +Thresholding pathway activity scores using k-means clustering. +Based on the FUNCellA R package thr_KM.R implementation. +""" + +from typing import Optional, Union, Callable + +import numpy as np +import pandas as pd +from sklearn.cluster import KMeans + +from pyfuncella.utils.optimize_clusters import find_optimal_clusters +from pyfuncella.utils.progress_callbacks import get_progress_callback + + +def thr_KM( + df_path: Union[np.ndarray, pd.DataFrame], + K: int = 10, + random_state: Optional[int] = 42, + verbose: bool = True, + progress_callback: Optional[Callable] = None, +) -> Union[np.ndarray, pd.DataFrame]: + """ + Threshold pathway activity scores using k-means clustering. + + This function applies k-means clustering to threshold pathway activity scores + for each pathway (row) individually. The optimal number of clusters is + estimated using the silhouette method. Samples belonging to the cluster + with the highest mean activity are marked as active (1); all others are + marked inactive (0). + + Parameters + ---------- + df_path : numpy.ndarray or pandas.DataFrame + A numeric matrix or DataFrame of pathway activity scores, + where rows correspond to pathways and columns to samples. + K : int, default=10 + Maximum number of clusters to consider when estimating the optimal + number of clusters using the silhouette method. + random_state : int, optional, default=42 + Random state for reproducible k-means clustering. + verbose : bool, default=True + Whether to print progress information. + Returns + ------- + numpy.ndarray or pandas.DataFrame + A binary matrix of the same dimensions as df_path, where + values are 1 for samples in the most active cluster per pathway, + and 0 otherwise. Returns the same type as the input. + """ + # Input validation + if not isinstance(df_path, (np.ndarray, pd.DataFrame)): + raise TypeError("df_path must be a numpy array or pandas DataFrame") + + if K < 2: + raise ValueError("K must be at least 2") + + # Convert to numpy array for processing + is_dataframe = isinstance(df_path, pd.DataFrame) + if is_dataframe: + values = df_path.values + index = df_path.index + columns = df_path.columns + else: + values = df_path + + n_pathways, n_samples = values.shape + + if n_samples < 2: + raise ValueError("Need at least 2 samples for clustering") + + # Initialize result matrices + result = np.zeros_like(values, dtype=int) + cluster_assignments = np.zeros_like(values, dtype=int) + + # Process each pathway (row) with progress reporting + progress_cb = get_progress_callback( + progress_callback, + description="Processing pathways", + unit="pathway", + verbose=verbose, + ) + + for i in range(n_pathways): + progress_cb(i + 1, n_pathways, f"pathway {i + 1}") + + # Get pathway activity scores for current pathway + sample_values = values[i, :] + + if len(np.unique(sample_values)) == 1: + result[i, :] = 1 + cluster_assignments[i, :] = 0 + continue + + if n_samples < K: + max_k = n_samples + else: + max_k = K + + # Find optimal number of clusters using silhouette analysis + kmeans_model = KMeans(random_state=random_state, n_init=10) + param_name = "n_clusters" + best_k = find_optimal_clusters(sample_values, max_k, kmeans_model, param_name) + + # Perform k-means clustering with optimal k + if best_k == 1: + # Only one cluster, mark all as active + result[i, :] = 1 + cluster_assignments[i, :] = 0 + else: + kmeans = KMeans(n_clusters=best_k, random_state=random_state, n_init=10) + sample_matrix = sample_values.reshape(-1, 1) + cluster_labels = kmeans.fit_predict(sample_matrix) + + # Sort clusters by mean activity and relabel + cluster_centers = kmeans.cluster_centers_.flatten() + sorted_idx = np.argsort(cluster_centers) + relabel_map = {old: new for new, old in enumerate(sorted_idx)} + relabeled_clusters = np.vectorize(lambda x: relabel_map[x])(cluster_labels) + cluster_assignments[i, :] = relabeled_clusters + + # Find the cluster with the highest mean activity (now the last label) + most_active_cluster = best_k - 1 + result[i, relabeled_clusters == most_active_cluster] = 1 + + if is_dataframe: + # Create DataFrame with binary and cluster columns + binary_df = pd.DataFrame(result, index=index, columns=columns) + cluster_df = pd.DataFrame(cluster_assignments, index=index, columns=columns) + # Suffix columns for clarity + binary_df.columns = [f"{col}_binary" for col in binary_df.columns] + cluster_df.columns = [f"{col}_cluster" for col in cluster_df.columns] + combined_df = pd.concat([binary_df, cluster_df], axis=1) + return combined_df + else: + # For ndarray, concatenate binary and cluster assignments along columns + combined = np.concatenate([result, cluster_assignments], axis=1) + return combined diff --git a/pyfuncella/utils/__init__.py b/pyfuncella/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyfuncella/utils/kmeans_search.py b/pyfuncella/utils/kmeans_search.py new file mode 100644 index 0000000..dfd8eec --- /dev/null +++ b/pyfuncella/utils/kmeans_search.py @@ -0,0 +1,90 @@ +import numpy as np +from sklearn.cluster import KMeans +from .optimize_clusters import find_optimal_clusters + + +def last_consecutive_true(row): + """ + Finds the indices of the last run of consecutive True values in a boolean array. + Returns None if no True values exist. + """ + row = np.asarray(row, dtype=bool) + if not np.any(row): + return None + # Find transitions from False to True and True to False + diff = np.diff(np.concatenate(([0], row.astype(int), [0]))) + starts = np.where(diff == 1)[0] + ends = np.where(diff == -1)[0] + if starts.size == 0: + return None + # Last run is from starts[-1] to ends[-1]-1 + return list(range(starts[-1], ends[-1])) + + +def km_search(gmm_result): + """ + Chooses the most appropriate threshold from a GMMdecomp output dict by k-means clustering on the GMM components' parameters. + + Parameters + ---------- + gmm_result : dict + Output dictionary from GMMdecomp for a single pathway, must contain keys: + - 'model': dict with 'mu', 'alpha', 'sigma' (all np.ndarray) + - 'thresholds': np.ndarray (thresholds between components, len = len(mu) - 1) + + Returns + ------- + float + Selected threshold. + """ + model = gmm_result.get("model", {}) + mu = np.asarray(model.get("mu", [])) + sigma = np.asarray(model.get("sigma", [])) + alpha = np.asarray(model.get("alpha", [])) + thrs = np.asarray(gmm_result.get("thresholds", [])) + if mu.size == 0 or sigma.size == 0 or alpha.size == 0 or thrs.size == 0: + return float("nan") + params = np.column_stack([mu, sigma, alpha]) + n_components = params.shape[0] + if n_components <= 2 or thrs.size == 0: + return np.nanmax(thrs) if thrs.size > 0 else float("nan") + + # Standardize columns only if needed (vectorized) + params_std = params.copy() + col_means = np.mean(params, axis=0) + col_stds = np.std(params, axis=0) + 1e-10 + for col in range(params.shape[1]): + if np.unique(params[:, col]).size > 1: + params_std[:, col] = (params[:, col] - col_means[col]) / col_stds[col] + + # Find optimal clusters using silhouette analysis + max_k = min(5, n_components) + optimal_k = find_optimal_clusters( + params_std, max_k, KMeans(), n_clusters_param="n_clusters" + ) + kmeans = KMeans(n_clusters=optimal_k, n_init=10, random_state=0) + cluster_labels = kmeans.fit_predict(params_std) + # Use mean column to find strongest cluster + mean_col = params_std[:, 0] + cluster_means = np.array( + [mean_col[cluster_labels == k].mean() for k in range(optimal_k)] + ) + best_cluster = np.argmax(cluster_means) + ord = cluster_labels == best_cluster + + # Edge case: every component is its own cluster + if optimal_k == n_components or not np.any(ord): + return np.nanmax(thrs) + + # If final component is not in target cluster, fallback + if not ord[-1]: + return np.nanmax(thrs) + + # Use last_consecutive_true to find last run of TRUEs + last_run = last_consecutive_true(ord) + if not last_run or last_run[0] == 0: + return np.nanmax(thrs) + idx = last_run[0] - 1 + if idx < 0 or idx >= thrs.size: + return np.nanmax(thrs) + return np.nanmin(thrs[: idx + 1]) diff --git a/pyfuncella/utils/optimize_clusters.py b/pyfuncella/utils/optimize_clusters.py new file mode 100644 index 0000000..de4f7cb --- /dev/null +++ b/pyfuncella/utils/optimize_clusters.py @@ -0,0 +1,92 @@ +from typing import Any + +import numpy as np +from sklearn.metrics import silhouette_score + + +def find_optimal_clusters( + values: np.ndarray, max_k: int, model: Any, n_clusters_param: str = "n_clusters" +) -> int: + """ + Find the optimal number of clusters using silhouette analysis. + + Parameters + ---------- + values : numpy.ndarray + 1D array of values to cluster. + max_k : int + Maximum number of clusters to consider. + model : Any + Pre-configured clustering model instance. The model should support + fit_predict() and have a parameter for number of clusters. + Most sklearn clustering models inherit from BaseEstimator and ClusterMixin. + n_clusters_param : str, default='n_clusters' + The name of the parameter that controls the number of clusters in the model. + Common values: 'n_clusters' (KMeans, AgglomerativeClustering), + 'n_components' (GaussianMixture). + + Returns + ------- + int + Optimal number of clusters. + """ + if len(np.unique(values)) == 1: + return 1 + + if max_k == 1: + return 1 + + # Limit max_k to the number of unique values + n_unique = len(np.unique(values)) + max_k = min(max_k, n_unique) + + if max_k == 1: + return 1 + + sample_matrix = values.reshape(-1, 1) + silhouette_scores = [] + + # Try different numbers of clusters from 2 to max_k + k_range = range(2, max_k + 1) + + for k in k_range: + try: + # Create a copy of the model with the specific number of clusters + # Most sklearn clustering models inherit from BaseEstimator and have get_params() + if hasattr(model, "get_params") and callable(getattr(model, "get_params")): + model_params = model.get_params() + model_params[n_clusters_param] = k + # Create new instance of the same class + clustering_model = model.__class__(**model_params) + else: + # Fallback: create a new instance and try to set the parameter + clustering_model = model.__class__() + if hasattr(clustering_model, n_clusters_param): + setattr(clustering_model, n_clusters_param, k) + else: + # If the parameter doesn't exist, skip this iteration + silhouette_scores.append(-1) + continue + + cluster_labels = clustering_model.fit_predict(sample_matrix) + + # Calculate silhouette score + if len(np.unique(cluster_labels)) > 1: # Need at least 2 clusters + score = silhouette_score(sample_matrix, cluster_labels) + silhouette_scores.append(score) + else: + silhouette_scores.append(-1) # Invalid score + + except Exception: + # If clustering fails for this k, assign a low score + silhouette_scores.append(-1) + + if not silhouette_scores or all(score <= 0 for score in silhouette_scores): + # If no valid silhouette scores, default to 2 clusters + return 2 + + # Find k with the highest silhouette score + best_idx = np.argmax(silhouette_scores) + optimal_k = k_range[best_idx] + + return optimal_k diff --git a/pyfuncella/utils/progress_callbacks.py b/pyfuncella/utils/progress_callbacks.py new file mode 100644 index 0000000..e288c2f --- /dev/null +++ b/pyfuncella/utils/progress_callbacks.py @@ -0,0 +1,82 @@ +""" +Progress callback utilities for command line and web interfaces. +""" + +from typing import Optional, Callable +from tqdm import tqdm + + +def create_tqdm_callback( + description: str = "Processing", unit: str = "item", verbose: bool = True +) -> Callable: + """ + Create a progress callback that uses tqdm for command line progress display. + + Parameters + ---------- + description : str + Description to show in the progress bar + unit : str + Unit name for the progress bar (e.g., 'pathway', 'sample') + verbose : bool + Whether to show the progress bar + + Returns + ------- + callable + Progress callback function that accepts (current, total, message) parameters + """ + pbar = None + + def callback(current: int, total: int, message: str = ""): + nonlocal pbar + + if pbar is None: + pbar = tqdm( + total=total, + desc=description, + unit=unit, + disable=not verbose, + ) + + pbar.update(current - pbar.n) # Update to current position + + if message: + pbar.set_postfix_str(message) + + if current >= total: + pbar.close() + pbar = None + + return callback + + +def get_progress_callback( + progress_callback: Optional[Callable] = None, + description: str = "Processing", + unit: str = "item", + verbose: bool = True, +) -> Callable: + """ + Get appropriate progress callback - either provided one or create tqdm fallback. + + Parameters + ---------- + progress_callback : callable, optional + Optional progress callback function + description : str + Description for fallback tqdm progress bar + unit : str + Unit for fallback tqdm progress bar + verbose : bool + Whether to show fallback progress bar + + Returns + ------- + callable + Progress callback function + """ + if progress_callback is not None: + return progress_callback + else: + return create_tqdm_callback(description, unit, verbose) diff --git a/pyfuncella/utils/r_executor.py b/pyfuncella/utils/r_executor.py new file mode 100644 index 0000000..70dacd5 --- /dev/null +++ b/pyfuncella/utils/r_executor.py @@ -0,0 +1,459 @@ +""" +Process-based R execution for Streamlit compatibility. + +This module provides a process-isolated way to run R code, avoiding the +threading issues that plague rpy2 in Streamlit environments. +""" + +import json +import subprocess +import tempfile +import os +from pathlib import Path +from typing import Any, Dict, Optional +import logging +import pandas as pd +import numpy as np + +logger = logging.getLogger(__name__) + + +class RProcessError(Exception): + """Raised when R process execution fails.""" + + pass + + +class RProcessExecutor: + """Execute R code in isolated processes to avoid threading issues.""" + + def __init__(self, r_libs_path: Optional[str] = None): + """ + Initialize R process executor. + + Args: + r_libs_path: Optional path to R libraries directory + """ + # Detect renv environment + renv_activate = Path("renv/activate.R") + if renv_activate.exists(): + # Use renv library path + # renv library is usually at renv/library// + # We'll try to find the first subdir under renv/library + renv_lib_root = Path("renv/library") + renv_lib_path = None + if renv_lib_root.exists(): + for subdir in renv_lib_root.iterdir(): + if subdir.is_dir(): + # Use the first platform subdir (e.g., 'macos', 'linux', etc.) + for rver in subdir.iterdir(): + if rver.is_dir(): + renv_lib_path = str(rver) + break + if renv_lib_path: + break + self.using_renv = True + self.renv_lib_path = renv_lib_path + self.r_libs_path = ( + renv_lib_path + or r_libs_path + or os.environ.get("R_LIBS_USER", "/usr/local/lib/R/site-library") + ) + else: + self.using_renv = False + self.renv_lib_path = None + self.r_libs_path = r_libs_path or os.environ.get( + "R_LIBS_USER", "/usr/local/lib/R/site-library" + ) + + def execute_r_script( + self, r_code: str, data_inputs: Optional[Dict[str, Any]] = None + ) -> Dict[str, Any]: + """ + Execute R code in a separate process using file-based communication. + + Args: + r_code: R code to execute + data_inputs: Dictionary of Python objects to pass to R + + Returns: + Dictionary containing results and metadata + + Raises: + RProcessError: If R execution fails + """ + with tempfile.TemporaryDirectory() as temp_dir: + temp_path = Path(temp_dir) + + try: + # Save input data using simple file formats + if data_inputs: + self._save_input_data(data_inputs, temp_path) + + # Create R script file + r_script = self._create_r_script(r_code, temp_path, bool(data_inputs)) + script_path = temp_path / "script.R" + + with open(script_path, "w") as f: + f.write(r_script) + + # Execute R script using simple subprocess call (like GSEA module) + env = os.environ.copy() + env["R_LIBS_USER"] = self.r_libs_path + if self.using_renv: + # Activate renv by sourcing renv/activate.R in the R script (handled below) + # Do not disable renv + env.pop("RENV_CONFIG_AUTOLOADER_ENABLED", None) + env.pop("RENV_PROJECT", None) + else: + # Disable renv for this session to avoid conflicts + env["RENV_CONFIG_AUTOLOADER_ENABLED"] = "FALSE" + env["RENV_PROJECT"] = "" + + cmd = [ + "Rscript", + "--no-restore", + "--no-save", + str(script_path), + str(temp_path), + ] + + result = subprocess.run( + cmd, + capture_output=True, + text=True, + env=env, + timeout=900, # 15 minute timeout + ) + + if result.returncode != 0: + error_msg = ( + f"R process failed with return code {result.returncode}\n" + ) + error_msg += f"STDOUT: {result.stdout}\n" + error_msg += f"STDERR: {result.stderr}" + raise RProcessError(error_msg) + + # Read results using simple file reading + results = self._load_output_data(temp_path, result.stdout) + + return results + + except subprocess.TimeoutExpired: + raise RProcessError("R process timed out after 15 minutes") + except Exception as e: + raise RProcessError(f"Failed to execute R process: {str(e)}") + + def _save_input_data(self, data_inputs: Dict[str, Any], temp_path: Path): + """Save input data to files that R can read (following GSEA pattern).""" + + for key, value in data_inputs.items(): + if isinstance(value, pd.DataFrame): + # Save DataFrame as CSV (like GSEA module) + csv_path = temp_path / f"{key}.csv" + value.to_csv(csv_path, index=True) + + elif isinstance(value, pd.Series): + # Save Series as CSV + csv_path = temp_path / f"{key}.csv" + value.to_csv(csv_path, header=True) + + elif isinstance(value, np.ndarray): + # Save numpy array as CSV + csv_path = temp_path / f"{key}.csv" + pd.DataFrame(value).to_csv(csv_path, index=False) + + elif isinstance(value, (dict, list)): + # Save as JSON (like GSEA module) + json_path = temp_path / f"{key}.json" + with open(json_path, "w") as f: + json.dump(value, f) + else: + # Save simple values as JSON + json_path = temp_path / f"{key}.json" + with open(json_path, "w") as f: + json.dump(value, f) + + def _load_output_data(self, temp_path: Path, stdout: str) -> Dict[str, Any]: + """Load output data from R execution (following GSEA pattern).""" + + results = {"success": True, "stdout": stdout} + + # Look for results.json (main output) + results_json = temp_path / "results.json" + if results_json.exists(): + try: + with open(results_json, "r") as f: + output_data = json.load(f) + results.update(output_data) + except Exception as e: + logger.warning(f"Failed to load results JSON: {e}") + + # Look for results.csv (alternative output format) + results_csv = temp_path / "results.csv" + if results_csv.exists(): + try: + results["results_data"] = pd.read_csv(results_csv, index_col=0) + except Exception as e: + logger.warning(f"Failed to load results CSV: {e}") + + return results + + def _create_r_script( + self, user_code: str, temp_path: Path, has_inputs: bool + ) -> str: + """Create R script following the GSEA module pattern.""" + + script_parts = [ + "# R script generated for process-based execution", + "# Following pattern from GSEA module", + "", + "# Get working directory from command line", + "args <- commandArgs(trailingOnly=TRUE)", + "if (length(args) > 0) {", + " work_dir <- args[1]", + "} else {", + f" work_dir <- '{temp_path}'", + "}", + "", + ] + # If using renv, source renv/activate.R + if self.using_renv: + script_parts.append("# Activate renv if present") + script_parts.append( + "if (file.exists('renv/activate.R')) source('renv/activate.R')" + ) + # Add both renv and global lib paths + if self.renv_lib_path: + script_parts.append( + f".libPaths(c('{self.renv_lib_path}', .libPaths()))" + ) + else: + script_parts.append(f".libPaths(c('{self.r_libs_path}', .libPaths()))") + else: + script_parts.append(f".libPaths(c('{self.r_libs_path}', .libPaths()))") + script_parts.extend( + [ + "", + "# Main execution with error handling", + "tryCatch({", + "", + ] + ) + + if has_inputs: + script_parts.extend( + [ + " # Load input data (following GSEA pattern)", + " input_files <- list.files(work_dir, pattern='\\\\.(csv|json)$', full.names=TRUE)", + " ", + " for (input_file in input_files) {", + " file_name <- basename(input_file)", + " var_name <- gsub('\\\\.(csv|json)$', '', file_name)", + " ", + " if (grepl('\\\\.csv$', input_file)) {", + " # Load CSV data", + " tryCatch({", + " df <- read.csv(input_file, row.names=1, header=TRUE, check.names=FALSE)", + " assign(var_name, df, envir=.GlobalEnv)", + " cat('Loaded CSV:', var_name, 'with dimensions:', nrow(df), 'x', ncol(df), '\\n')", + " }, error = function(e) {", + " cat('Warning: Could not load CSV file:', input_file, '\\n')", + " })", + " } else if (grepl('\\\\.json$', input_file)) {", + " # Load JSON data (prefer jsonlite)", + " tryCatch({", + " if (require('jsonlite', quietly=TRUE)) {", + " data <- jsonlite::fromJSON(input_file)", + " } else if (require('rjson', quietly=TRUE)) {", + " data <- rjson::fromJSON(file=input_file)", + " } else {", + " cat('Warning: No JSON library available\\n')", + " next", + " }", + " assign(var_name, data, envir=.GlobalEnv)", + " cat('Loaded JSON:', var_name, '\\n')", + " }, error = function(e) {", + " cat('Warning: Could not load JSON file:', input_file, '\\n')", + " })", + " }", + " }", + " ", + ] + ) + + script_parts.extend( + [ + " # User R code starts here", + " " + user_code.replace("\n", "\n "), # Indent user code + " ", + " # Save results (following GSEA pattern)", + " output_file <- file.path(work_dir, 'results.json')", + " ", + " # Collect results from environment", + " results_list <- list(success = TRUE)", + " ", + " # Look for common result variable names", + " result_vars <- c('gmm_results', 'aucell_results', 'gsva_results', 'test_result', 'package_results')", + " for (var_name in result_vars) {", + " if (exists(var_name)) {", + " # Try to safely convert complex R objects to JSON-serializable format", + " obj <- get(var_name)", + " tryCatch({", + " # Test if object can be serialized to JSON (prefer jsonlite)", + " if (require('jsonlite', quietly=TRUE)) {", + " test_json <- jsonlite::toJSON(obj, auto_unbox=TRUE)", + " results_list[[var_name]] <- obj", + " } else if (require('rjson', quietly=TRUE)) {", + " test_json <- rjson::toJSON(obj)", + " results_list[[var_name]] <- obj", + " }", + " }, error = function(e) {", + " cat('Warning: Cannot serialize', var_name, 'to JSON, creating summary\\n')", + " # Create a simplified version for complex objects", + " if (is.list(obj)) {", + " # For lists, try to extract basic information", + " summary_obj <- list()", + " summary_obj$type <- 'complex_list'", + " summary_obj$length <- length(obj)", + " summary_obj$names <- names(obj)", + " # Try to include simple elements", + " for (name in names(obj)) {", + " tryCatch({", + " element <- obj[[name]]", + " if (is.numeric(element) || is.character(element) || is.logical(element)) {", + " summary_obj[[name]] <- element", + " }", + " }, error = function(e2) { })", + " }", + " results_list[[var_name]] <- summary_obj", + " } else {", + " results_list[[var_name]] <- list(error = 'complex_object_not_serializable')", + " }", + " })", + " }", + " }", + " ", + " # Write results to JSON (prefer jsonlite)", + " tryCatch({", + " if (require('jsonlite', quietly=TRUE)) {", + " jsonlite::write_json(results_list, output_file, auto_unbox=TRUE, pretty=TRUE)", + " } else if (require('rjson', quietly=TRUE)) {", + " write(rjson::toJSON(results_list), output_file)", + " } else {", + " cat('Warning: No JSON library available for output\\n')", + " }", + " }, error = function(e) {", + " cat('Warning: Could not save JSON results:', e$message, '\\n')", + " })", + " ", + " cat('R script completed successfully\\n')", + "", + "}, error = function(e) {", + " cat('Error in R execution:', e$message, '\\n')", + " quit(status=1)", + "})", + ] + ) + + return "\n".join(script_parts) + + def check_r_availability(self) -> Dict[str, Any]: + """ + Check if R is available and working properly. + + Returns: + Dictionary with availability status and details + """ + try: + result = self.execute_r_script( + """ + # Basic R availability test + r_version <- R.version.string + r_libs <- .libPaths() + + # Check for essential packages + essential_packages <- c('AUCell', 'GSVA', 'dpGMM') + package_status <- sapply(essential_packages, function(pkg) { + require(pkg, quietly=TRUE, character.only=TRUE) + }) + + # Simple calculation test + test_calculation <- 2 + 2 + + cat('R version:', r_version, '\\n') + cat('Test calculation (2+2):', test_calculation, '\\n') + cat('Available packages:', names(package_status[package_status]), '\\n') + + test_result <- list( + r_version = r_version, + r_libs = r_libs, + packages_available = package_status, + test_calculation = test_calculation + ) + """ + ) + + if result.get("success"): + return { + "available": True, + "details": result, + "message": "R is available and working", + } + else: + return { + "available": False, + "details": result, + "message": "R execution failed", + } + + except Exception as e: + return { + "available": False, + "details": {"error": str(e)}, + "message": f"R availability check failed: {str(e)}", + } + + +# Global executor instance +_executor = None + + +def get_r_executor() -> RProcessExecutor: + """Get or create the global R executor instance.""" + global _executor + if _executor is None: + _executor = RProcessExecutor() + return _executor + + +def execute_r_code( + r_code: str, data_inputs: Optional[Dict[str, Any]] = None +) -> Dict[str, Any]: + """ + Convenience function to execute R code. + + Args: + r_code: R code to execute + data_inputs: Optional dictionary of Python objects to pass to R + + Returns: + Dictionary containing results + """ + executor = get_r_executor() + return executor.execute_r_script(r_code, data_inputs) + + +def check_r_available() -> bool: + """ + Quick check if R is available. + + Returns: + True if R is available and working + """ + try: + executor = get_r_executor() + result = executor.check_r_availability() + return result.get("available", False) + except Exception: + return False diff --git a/pyproject.toml b/pyproject.toml index 04287bc..916abbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] -name = "enrichment_auc" +name = "pyfuncella" version = "0.1.0" -description = "" +description = "Python implementation of Functional Cell Analysis (FUNCellA) for single-sample pathway enrichment analysis" authors = ["amrukwa "] license = "Apache-2.0" readme = "README.md" @@ -11,9 +11,9 @@ generate-setup-file = true [tool.poetry.dependencies] python = ">=3.8,<3.12" -setuptools = ">=67.7.2" +setuptools = ">=68.0.0" importlib-metadata = "^6.6.0" -numpy = "^1.24.3" +numpy = ">=1.24.3,<2.0.0" pandas = "^2.0.1" scipy = "^1.8" scikit-learn = "^1.2.2" @@ -22,11 +22,6 @@ seaborn = "^0.12.2" tqdm = "^4.65.0" statsmodels = "^0.14.0" matplotlib = "^3.7.1" -tensorflow = "^2.13.0" -tensorflow-io-gcs-filesystem = "^0.33.0" -keras = "^2.13.1" - -[tool.poetry.dev-dependencies] [tool.poetry.group.dev.dependencies] pytest = "^7.3.1" @@ -39,3 +34,6 @@ requires = ["poetry-core>=1.0.0", "numpy>=1.24.3", "setuptools"] build-backend = "poetry.core.masonry.api" + +[tool.setuptools.package-data] +"my_package.data" = ["*.csv", "*.json"] \ No newline at end of file diff --git a/renv.lock b/renv.lock index baee585..6a34dc4 100644 --- a/renv.lock +++ b/renv.lock @@ -1,1053 +1,6664 @@ { "R": { - "Version": "4.3.3", + "Version": "4.4.2", "Repositories": [ + { + "Name": "BioCsoft", + "URL": "https://bioconductor.org/packages/3.20/bioc" + }, + { + "Name": "BioCann", + "URL": "https://bioconductor.org/packages/3.20/data/annotation" + }, + { + "Name": "BioCexp", + "URL": "https://bioconductor.org/packages/3.20/data/experiment" + }, + { + "Name": "BioCworkflows", + "URL": "https://bioconductor.org/packages/3.20/workflows" + }, + { + "Name": "BioCbooks", + "URL": "https://bioconductor.org/packages/3.20/books" + }, { "Name": "CRAN", - "URL": "https://packagemanager.posit.co/cran/latest" + "URL": "https://cloud.r-project.org" } ] }, "Bioconductor": { - "Version": "3.18" + "Version": "3.20" }, "Packages": { + "AUCell": { + "Package": "AUCell", + "Version": "1.28.0", + "Source": "Bioconductor", + "Type": "Package", + "Title": "AUCell: Analysis of 'gene set' activity in single-cell RNA-seq data (e.g. identify cells with specific gene signatures)", + "Date": "2024-03-09", + "Author": "Sara Aibar, Stein Aerts. Laboratory of Computational Biology. VIB-KU Leuven Center for Brain & Disease Research. Leuven, Belgium.", + "Maintainer": "Gert Hulselmans ", + "Description": "AUCell allows to identify cells with active gene sets (e.g. signatures, gene modules...) in single-cell RNA-seq data. AUCell uses the \"Area Under the Curve\" (AUC) to calculate whether a critical subset of the input gene set is enriched within the expressed genes for each cell. The distribution of AUC scores across all the cells allows exploring the relative expression of the signature. Since the scoring method is ranking-based, AUCell is independent of the gene expression units and the normalization procedure. In addition, since the cells are evaluated individually, it can easily be applied to bigger datasets, subsetting the expression matrix if needed.", + "URL": "http://scenic.aertslab.org", + "Imports": [ + "DelayedArray", + "DelayedMatrixStats", + "data.table", + "graphics", + "grDevices", + "GSEABase", + "Matrix", + "methods", + "mixtools", + "R.utils", + "stats", + "SummarizedExperiment", + "BiocGenerics", + "utils" + ], + "Enhances": [ + "doMC", + "doRNG", + "doParallel", + "foreach" + ], + "Suggests": [ + "Biobase", + "BiocStyle", + "doSNOW", + "dynamicTreeCut", + "DT", + "GEOquery", + "knitr", + "NMF", + "plyr", + "R2HTML", + "rmarkdown", + "reshape2", + "plotly", + "Rtsne", + "testthat", + "zoo" + ], + "License": "GPL-3", + "biocViews": "SingleCell, GeneSetEnrichment, Transcriptomics, Transcription, GeneExpression, WorkflowStep, Normalization", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.2.0", + "git_url": "https://git.bioconductor.org/packages/AUCell", + "git_branch": "RELEASE_3_20", + "git_last_commit": "52a1d2b", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no" + }, "AnnotationDbi": { "Package": "AnnotationDbi", - "Version": "1.64.1", + "Version": "1.68.0", "Source": "Bioconductor", - "Requirements": [ - "Biobase", - "BiocGenerics", + "Title": "Manipulation of SQLite-based annotations in Bioconductor", + "Description": "Implements a user-friendly interface for querying SQLite-based annotation data packages.", + "biocViews": "Annotation, Microarray, Sequencing, GenomeAnnotation", + "URL": "https://bioconductor.org/packages/AnnotationDbi", + "Video": "https://www.youtube.com/watch?v=8qvGNTVz3Ik", + "BugReports": "https://github.com/Bioconductor/AnnotationDbi/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Author": "Hervé Pagès, Marc Carlson, Seth Falcon, Nianhua Li", + "Maintainer": "Bioconductor Package Maintainer ", + "Depends": [ + "R (>= 2.7.0)", + "methods", + "stats4", + "BiocGenerics (>= 0.29.2)", + "Biobase (>= 1.17.0)", + "IRanges" + ], + "Imports": [ "DBI", - "IRanges", - "KEGGREST", - "R", "RSQLite", - "S4Vectors", - "methods", + "S4Vectors (>= 0.9.25)", "stats", - "stats4" + "KEGGREST" ], - "Hash": "27587689922e22f60ec9ad0182a0a825" + "Suggests": [ + "utils", + "hgu95av2.db", + "GO.db", + "org.Sc.sgd.db", + "org.At.tair.db", + "RUnit", + "TxDb.Hsapiens.UCSC.hg19.knownGene", + "org.Hs.eg.db", + "reactome.db", + "AnnotationForge", + "graph", + "EnsDb.Hsapiens.v75", + "BiocStyle", + "knitr" + ], + "VignetteBuilder": "knitr", + "Collate": "00RTobjs.R AllGenerics.R AllClasses.R unlist2.R utils.R SQL.R FlatBimap.R AnnDbObj-lowAPI.R Bimap.R GOTerms.R BimapFormatting.R Bimap-envirAPI.R flatten.R methods-AnnotationDb.R methods-SQLiteConnection.R methods-geneCentricDbs.R methods-geneCentricDbs-keys.R methods-ReactomeDb.R methods-OrthologyDb.R loadDb.R createAnnObjs-utils.R createAnnObjs.NCBIORG_DBs.R createAnnObjs.NCBICHIP_DBs.R createAnnObjs.ORGANISM_DB.R createAnnObjs.YEASTCHIP_DB.R createAnnObjs.COELICOLOR_DB.R createAnnObjs.ARABIDOPSISCHIP_DB.R createAnnObjs.MALARIA_DB.R createAnnObjs.YEAST_DB.R createAnnObjs.YEASTNCBI_DB.R createAnnObjs.ARABIDOPSIS_DB.R createAnnObjs.GO_DB.R createAnnObjs.KEGG_DB.R createAnnObjs.PFAM_DB.R AnnDbPkg-templates-common.R AnnDbPkg-checker.R print.probetable.R makeMap.R inpIDMapper.R test_AnnotationDbi_package.R", + "git_url": "https://git.bioconductor.org/packages/AnnotationDbi", + "git_branch": "RELEASE_3_20", + "git_last_commit": "6a2aa33", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no" }, "BH": { "Package": "BH", - "Version": "1.84.0-0", + "Version": "1.87.0-1", "Source": "Repository", - "Repository": "RSPM", - "Hash": "a8235afbcd6316e6e91433ea47661013" + "Type": "Package", + "Title": "Boost C++ Header Files", + "Date": "2024-12-17", + "Authors@R": "c(person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"John W.\", \"Emerson\", role = \"aut\"), person(\"Michael J.\", \"Kane\", role = \"aut\", comment = c(ORCID = \"0000-0003-1899-6662\")))", + "Description": "Boost provides free peer-reviewed portable C++ source libraries. A large part of Boost is provided as C++ template code which is resolved entirely at compile-time without linking. This package aims to provide the most useful subset of Boost libraries for template use among CRAN packages. By placing these libraries in this package, we offer a more efficient distribution system for CRAN as replication of this code in the sources of other packages is avoided. As of release 1.84.0-0, the following Boost libraries are included: 'accumulators' 'algorithm' 'align' 'any' 'atomic' 'beast' 'bimap' 'bind' 'circular_buffer' 'compute' 'concept' 'config' 'container' 'date_time' 'detail' 'dynamic_bitset' 'exception' 'flyweight' 'foreach' 'functional' 'fusion' 'geometry' 'graph' 'heap' 'icl' 'integer' 'interprocess' 'intrusive' 'io' 'iostreams' 'iterator' 'lambda2' 'math' 'move' 'mp11' 'mpl' 'multiprecision' 'numeric' 'pending' 'phoenix' 'polygon' 'preprocessor' 'process' 'propery_tree' 'qvm' 'random' 'range' 'scope_exit' 'smart_ptr' 'sort' 'spirit' 'tuple' 'type_traits' 'typeof' 'unordered' 'url' 'utility' 'uuid'.", + "License": "BSL-1.0", + "URL": "https://github.com/eddelbuettel/bh, https://dirk.eddelbuettel.com/code/bh.html", + "BugReports": "https://github.com/eddelbuettel/bh/issues", + "NeedsCompilation": "no", + "Author": "Dirk Eddelbuettel [aut, cre] (), John W. Emerson [aut], Michael J. Kane [aut] ()", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "CRAN" }, "Biobase": { "Package": "Biobase", - "Version": "2.62.0", + "Version": "2.66.0", "Source": "Bioconductor", - "Requirements": [ - "BiocGenerics", - "R", - "methods", + "Title": "Biobase: Base functions for Bioconductor", + "Description": "Functions that are needed by many other packages or which replace R functions.", + "biocViews": "Infrastructure", + "URL": "https://bioconductor.org/packages/Biobase", + "BugReports": "https://github.com/Bioconductor/Biobase/issues", + "License": "Artistic-2.0", + "Authors@R": "c( person(\"R.\", \"Gentleman\", role=\"aut\"), person(\"V.\", \"Carey\", role = \"aut\"), person(\"M.\", \"Morgan\", role=\"aut\"), person(\"S.\", \"Falcon\", role=\"aut\"), person(\"Haleema\", \"Khan\", role = \"ctb\", comment = \"'esApply' and 'BiobaseDevelopment' vignette translation from Sweave to Rmarkdown / HTML\" ), person(\"Bioconductor Package Maintainer\", role = \"cre\", email = \"maintainer@bioconductor.org\" ))", + "Suggests": [ + "tools", + "tkWidgets", + "ALL", + "RUnit", + "golubEsets", + "BiocStyle", + "knitr", + "limma" + ], + "Depends": [ + "R (>= 2.10)", + "BiocGenerics (>= 0.27.1)", "utils" ], - "Hash": "38252a34e82d3ff6bb46b4e2252d2dce" + "Imports": [ + "methods" + ], + "VignetteBuilder": "knitr", + "LazyLoad": "yes", + "Collate": "tools.R strings.R environment.R vignettes.R packages.R AllGenerics.R VersionsClass.R VersionedClasses.R methods-VersionsNull.R methods-VersionedClass.R DataClasses.R methods-aggregator.R methods-container.R methods-MIAxE.R methods-MIAME.R methods-AssayData.R methods-AnnotatedDataFrame.R methods-eSet.R methods-ExpressionSet.R methods-MultiSet.R methods-SnpSet.R methods-NChannelSet.R anyMissing.R rowOp-methods.R updateObjectTo.R methods-ScalarObject.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/Biobase", + "git_branch": "RELEASE_3_20", + "git_last_commit": "2cd604f", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "R. Gentleman [aut], V. Carey [aut], M. Morgan [aut], S. Falcon [aut], Haleema Khan [ctb] ('esApply' and 'BiobaseDevelopment' vignette translation from Sweave to Rmarkdown / HTML), Bioconductor Package Maintainer [cre]", + "Maintainer": "Bioconductor Package Maintainer " + }, + "BiocFileCache": { + "Package": "BiocFileCache", + "Version": "2.14.0", + "Source": "Bioconductor", + "Title": "Manage Files Across Sessions", + "Authors@R": "c(person(\"Lori\", \"Shepherd\", email = \"lori.shepherd@roswellpark.org\", role = c(\"aut\", \"cre\")), person(\"Martin\", \"Morgan\", email = \"martin.morgan@roswellpark.org\", role = \"aut\"))", + "Description": "This package creates a persistent on-disk cache of files that the user can add, update, and retrieve. It is useful for managing resources (such as custom Txdb objects) that are costly or difficult to create, web resources, and data files used across sessions.", + "Depends": [ + "R (>= 3.4.0)", + "dbplyr (>= 1.0.0)" + ], + "Imports": [ + "methods", + "stats", + "utils", + "dplyr", + "RSQLite", + "DBI", + "filelock", + "curl", + "httr" + ], + "BugReports": "https://github.com/Bioconductor/BiocFileCache/issues", + "DevelopmentURL": "https://github.com/Bioconductor/BiocFileCache", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "biocViews": "DataImport", + "VignetteBuilder": "knitr", + "Suggests": [ + "testthat", + "knitr", + "BiocStyle", + "rmarkdown", + "rtracklayer" + ], + "git_url": "https://git.bioconductor.org/packages/BiocFileCache", + "git_branch": "RELEASE_3_20", + "git_last_commit": "66862c5", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Lori Shepherd [aut, cre], Martin Morgan [aut]", + "Maintainer": "Lori Shepherd " }, "BiocGenerics": { "Package": "BiocGenerics", - "Version": "0.48.1", + "Version": "0.52.0", "Source": "Bioconductor", - "Requirements": [ - "R", + "Title": "S4 generic functions used in Bioconductor", + "Description": "The package defines many S4 generic functions used in Bioconductor.", + "biocViews": "Infrastructure", + "URL": "https://bioconductor.org/packages/BiocGenerics", + "BugReports": "https://github.com/Bioconductor/BiocGenerics/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Author": "The Bioconductor Dev Team", + "Maintainer": "Hervé Pagès ", + "Depends": [ + "R (>= 4.0.0)", + "methods", + "utils", "graphics", + "stats" + ], + "Imports": [ "methods", - "stats", - "utils" + "utils", + "graphics", + "stats" + ], + "Suggests": [ + "Biobase", + "S4Vectors", + "IRanges", + "S4Arrays", + "SparseArray", + "DelayedArray", + "HDF5Array", + "GenomicRanges", + "pwalign", + "Rsamtools", + "AnnotationDbi", + "affy", + "affyPLM", + "DESeq2", + "flowClust", + "MSnbase", + "annotate", + "RUnit" ], - "Hash": "e34278c65d7dffcc08f737bf0944ca9a" + "Collate": "S3-classes-as-S4-classes.R utils.R normarg-utils.R replaceSlots.R aperm.R append.R as.data.frame.R as.list.R as.vector.R cbind.R do.call.R duplicated.R eval.R Extremes.R format.R funprog.R get.R grep.R is.unsorted.R lapply.R mapply.R match.R mean.R nrow.R order.R paste.R rank.R rep.R row_colnames.R saveRDS.R sets.R sort.R start.R subset.R t.R table.R tapply.R unique.R unlist.R unsplit.R relist.R var.R which.R which.min.R boxplot.R image.R density.R IQR.R mad.R residuals.R weights.R xtabs.R annotation.R combine.R containsOutOfMemoryData.R dbconn.R dge.R dims.R fileName.R normalize.R Ontology.R organism_species.R path.R plotMA.R plotPCA.R score.R strand.R toTable.R type.R updateObject.R testPackage.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/BiocGenerics", + "git_branch": "RELEASE_3_20", + "git_last_commit": "1422115", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no" }, "BiocManager": { "Package": "BiocManager", - "Version": "1.30.22", + "Version": "1.30.26", "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ + "Title": "Access the Bioconductor Project Package Repository", + "Description": "A convenient tool to install and update Bioconductor packages.", + "Authors@R": "c( person(\"Martin\", \"Morgan\", email = \"martin.morgan@roswellpark.org\", role = \"aut\", comment = c(ORCID = \"0000-0002-5874-8148\")), person(\"Marcel\", \"Ramos\", email = \"marcel.ramos@sph.cuny.edu\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-3242-0582\")))", + "Imports": [ "utils" ], - "Hash": "d57e43105a1aa9cb54fdb4629725acb1" + "Suggests": [ + "BiocVersion", + "BiocStyle", + "remotes", + "rmarkdown", + "testthat", + "withr", + "curl", + "knitr" + ], + "URL": "https://bioconductor.github.io/BiocManager/", + "BugReports": "https://github.com/Bioconductor/BiocManager/issues", + "VignetteBuilder": "knitr", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Martin Morgan [aut] (ORCID: ), Marcel Ramos [aut, cre] (ORCID: )", + "Maintainer": "Marcel Ramos ", + "Repository": "https://packagemanager.posit.co/cran/latest" }, "BiocParallel": { "Package": "BiocParallel", - "Version": "1.36.0", + "Version": "1.40.2", "Source": "Bioconductor", - "Requirements": [ - "BH", - "R", - "codetools", - "cpp11", - "futile.logger", + "Type": "Package", + "Title": "Bioconductor facilities for parallel evaluation", + "Authors@R": "c( person(\"Martin\", \"Morgan\", email = \"mtmorgan.bioc@gmail.com\", role=c(\"aut\", \"cre\")), person(\"Jiefei\", \"Wang\", role = \"aut\"), person(\"Valerie\", \"Obenchain\", role=\"aut\"), person(\"Michel\", \"Lang\", email=\"michellang@gmail.com\", role=\"aut\"), person(\"Ryan\", \"Thompson\", email=\"rct@thompsonclan.org\", role=\"aut\"), person(\"Nitesh\", \"Turaga\", role=\"aut\"), person(\"Aaron\", \"Lun\", role = \"ctb\"), person(\"Henrik\", \"Bengtsson\", role = \"ctb\"), person(\"Madelyn\", \"Carlson\", role = \"ctb\", comment = \"Translated 'Random Numbers' vignette from Sweave to RMarkdown / HTML.\" ), person(\"Phylis\", \"Atieno\", role = \"ctb\", comment = \"Translated 'Introduction to BiocParallel' vignette from Sweave to Rmarkdown / HTML.\" ), person( \"Sergio\", \"Oller\", role = \"ctb\", comment = c( \"Improved bpmapply() efficiency.\", \"ORCID\" = \"0000-0002-8994-1549\" ) ))", + "Description": "This package provides modified versions and novel implementation of functions for parallel evaluation, tailored to use with Bioconductor objects.", + "URL": "https://github.com/Bioconductor/BiocParallel", + "BugReports": "https://github.com/Bioconductor/BiocParallel/issues", + "biocViews": "Infrastructure", + "License": "GPL-2 | GPL-3", + "SystemRequirements": "C++11", + "Depends": [ "methods", + "R (>= 3.5.0)" + ], + "Imports": [ + "stats", + "utils", + "futile.logger", "parallel", "snow", - "stats", - "utils" + "codetools" + ], + "Suggests": [ + "BiocGenerics", + "tools", + "foreach", + "BBmisc", + "doParallel", + "GenomicRanges", + "RNAseqData.HNRNPC.bam.chr14", + "TxDb.Hsapiens.UCSC.hg19.knownGene", + "VariantAnnotation", + "Rsamtools", + "GenomicAlignments", + "ShortRead", + "RUnit", + "BiocStyle", + "knitr", + "batchtools", + "data.table" + ], + "Enhances": [ + "Rmpi" + ], + "Collate": "AllGenerics.R DeveloperInterface.R prototype.R bploop.R ErrorHandling.R log.R bpbackend-methods.R bpisup-methods.R bplapply-methods.R bpiterate-methods.R bpstart-methods.R bpstop-methods.R BiocParallelParam-class.R bpmapply-methods.R bpschedule-methods.R bpvec-methods.R bpvectorize-methods.R bpworkers-methods.R bpaggregate-methods.R bpvalidate.R SnowParam-class.R MulticoreParam-class.R TransientMulticoreParam-class.R register.R SerialParam-class.R DoparParam-class.R SnowParam-utils.R BatchtoolsParam-class.R progress.R ipcmutex.R worker-number.R utilities.R rng.R bpinit.R reducer.R worker.R bpoptions.R cpp11.R BiocParallel-defunct.R", + "LinkingTo": [ + "BH", + "cpp11" ], - "Hash": "6d1689ee8b65614ba6ef4012a67b663a" + "VignetteBuilder": "knitr", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "yes", + "Author": "Martin Morgan [aut, cre], Jiefei Wang [aut], Valerie Obenchain [aut], Michel Lang [aut], Ryan Thompson [aut], Nitesh Turaga [aut], Aaron Lun [ctb], Henrik Bengtsson [ctb], Madelyn Carlson [ctb] (Translated 'Random Numbers' vignette from Sweave to RMarkdown / HTML.), Phylis Atieno [ctb] (Translated 'Introduction to BiocParallel' vignette from Sweave to Rmarkdown / HTML.), Sergio Oller [ctb] (Improved bpmapply() efficiency., )", + "Maintainer": "Martin Morgan " }, "BiocSingular": { "Package": "BiocSingular", - "Version": "1.18.0", + "Version": "1.22.0", "Source": "Bioconductor", - "Requirements": [ + "Date": "2024-09-21", + "Title": "Singular Value Decomposition for Bioconductor Packages", + "Authors@R": "c(person(\"Aaron\", \"Lun\", role=c(\"aut\", \"cre\", \"cph\"), email=\"infinite.monkeys.with.keyboards@gmail.com\"))", + "Imports": [ "BiocGenerics", - "BiocParallel", - "DelayedArray", - "Matrix", - "Rcpp", "S4Vectors", + "Matrix", + "methods", + "utils", + "DelayedArray", + "BiocParallel", "ScaledMatrix", - "beachmat", "irlba", - "methods", "rsvd", - "utils" + "Rcpp", + "beachmat (>= 2.21.1)" + ], + "Suggests": [ + "testthat", + "BiocStyle", + "knitr", + "rmarkdown", + "ResidualMatrix" ], - "Hash": "bed2b7ea3b0b0b31387d1d80286abb97" + "biocViews": "Software, DimensionReduction, PrincipalComponent", + "Description": "Implements exact and approximate methods for singular value decomposition and principal components analysis, in a framework that allows them to be easily switched within Bioconductor packages or workflows. Where possible, parallelization is achieved using the BiocParallel framework.", + "License": "GPL-3", + "LinkingTo": [ + "Rcpp", + "beachmat", + "assorthead" + ], + "VignetteBuilder": "knitr", + "SystemRequirements": "C++17", + "RoxygenNote": "7.2.3", + "BugReports": "https://github.com/LTLA/BiocSingular/issues", + "URL": "https://github.com/LTLA/BiocSingular", + "git_url": "https://git.bioconductor.org/packages/BiocSingular", + "git_branch": "RELEASE_3_20", + "git_last_commit": "aa0f642", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Aaron Lun [aut, cre, cph]", + "Maintainer": "Aaron Lun " }, "BiocVersion": { "Package": "BiocVersion", - "Version": "3.18.1", + "Version": "3.20.0", "Source": "Bioconductor", - "Requirements": [ - "R" + "Title": "Set the appropriate version of Bioconductor packages", + "Description": "This package provides repository information for the appropriate version of Bioconductor.", + "Authors@R": "c( person(\"Martin\", \"Morgan\", email = \"martin.morgan@roswellpark.org\", role = \"aut\"), person(\"Marcel\", \"Ramos\", email = \"marcel.ramos@roswellpark.org\", role = \"ctb\"), person(\"Bioconductor\", \"Package Maintainer\", email = \"maintainer@bioconductor.org\", role = c(\"ctb\", \"cre\")))", + "biocViews": "Infrastructure", + "Depends": [ + "R (>= 4.4.0)" ], - "Hash": "2ecaed86684f5fae76ed5530f9d29c4a" + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "RoxygenNote": "6.0.1", + "git_url": "https://git.bioconductor.org/packages/BiocVersion", + "git_branch": "devel", + "git_last_commit": "43c716a", + "git_last_commit_date": "2024-04-30", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Martin Morgan [aut], Marcel Ramos [ctb], Bioconductor Package Maintainer [ctb, cre]", + "Maintainer": "Bioconductor Package Maintainer " }, "Biostrings": { "Package": "Biostrings", - "Version": "2.70.3", + "Version": "2.74.1", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Requirements": [ - "BiocGenerics", - "GenomeInfoDb", - "IRanges", - "R", - "S4Vectors", - "XVector", - "crayon", - "grDevices", - "graphics", + "Title": "Efficient manipulation of biological strings", + "Description": "Memory efficient string containers, string matching algorithms, and other utilities, for fast manipulation of large biological sequences or sets of sequences.", + "biocViews": "SequenceMatching, Alignment, Sequencing, Genetics, DataImport, DataRepresentation, Infrastructure", + "URL": "https://bioconductor.org/packages/Biostrings", + "BugReports": "https://github.com/Bioconductor/Biostrings/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\"), person(\"Patrick\", \"Aboyoun\", role=\"aut\"), person(\"Robert\", \"Gentleman\", role=\"aut\"), person(\"Saikat\", \"DebRoy\", role=\"aut\"), person(\"Vince\", \"Carey\", role=\"ctb\"), person(\"Nicolas\", \"Delhomme\", role=\"ctb\"), person(\"Felix\", \"Ernst\", role=\"ctb\"), person(\"Wolfgang\", \"Huber\", role=\"ctb\", comment=\"'matchprobes' vignette\"), person(\"Beryl\", \"Kanali\", role=\"ctb\", comment=\"Converted 'MultipleAlignments' vignette from Sweave to RMarkdown\"), person(\"Haleema\", \"Khan\", role=\"ctb\", comment=\"Converted 'matchprobes' vignette from Sweave to RMarkdown\"), person(\"Aidan\", \"Lakshman\", role=\"ctb\"), person(\"Kieran\", \"O'Neill\", role=\"ctb\"), person(\"Valerie\", \"Obenchain\", role=\"ctb\"), person(\"Marcel\", \"Ramos\", role=\"ctb\"), person(\"Albert\", \"Vill\", role=\"ctb\"), person(\"Jen\", \"Wokaty\", role=\"ctb\", comment=\"Converted 'matchprobes' vignette from Sweave to RMarkdown\"), person(\"Erik\", \"Wright\", role=\"ctb\"))", + "Depends": [ + "R (>= 4.0.0)", + "BiocGenerics (>= 0.37.0)", + "S4Vectors (>= 0.27.12)", + "IRanges (>= 2.31.2)", + "XVector (>= 0.37.1)", + "GenomeInfoDb" + ], + "Imports": [ "methods", + "utils", + "grDevices", "stats", - "utils" + "crayon" + ], + "LinkingTo": [ + "S4Vectors", + "IRanges", + "XVector" + ], + "Suggests": [ + "graphics", + "pwalign", + "BSgenome (>= 1.13.14)", + "BSgenome.Celegans.UCSC.ce2 (>= 1.3.11)", + "BSgenome.Dmelanogaster.UCSC.dm3 (>= 1.3.11)", + "BSgenome.Hsapiens.UCSC.hg18", + "drosophila2probe", + "hgu95av2probe", + "hgu133aprobe", + "GenomicFeatures (>= 1.3.14)", + "hgu95av2cdf", + "affy (>= 1.41.3)", + "affydata (>= 1.11.5)", + "RUnit", + "BiocStyle", + "knitr", + "testthat (>= 3.0.0)", + "covr" ], - "Hash": "86ffa781f132f54e9c963a13fd6cf9fc" + "VignetteBuilder": "knitr", + "Collate": "utils.R IUPAC_CODE_MAP.R AMINO_ACID_CODE.R GENETIC_CODE.R XStringCodec-class.R seqtype.R coloring.R XString-class.R XStringSet-class.R XStringSet-comparison.R XStringViews-class.R MaskedXString-class.R XStringSetList-class.R seqinfo-methods.R xscat.R XStringSet-io.R letter.R getSeq.R letterFrequency.R dinucleotideFrequencyTest.R chartr.R reverseComplement.R translate.R toComplex.R replaceAt.R replaceLetterAt.R injectHardMask.R padAndClip.R strsplit-methods.R misc.R SparseList-class.R MIndex-class.R lowlevel-matching.R match-utils.R matchPattern.R maskMotif.R matchLRPatterns.R trimLRPatterns.R matchProbePair.R matchPWM.R findPalindromes.R PDict-class.R matchPDict.R XStringPartialMatches-class.R XStringQuality-class.R QualityScaledXStringSet.R pmatchPattern.R needwunsQS.R MultipleAlignment.R matchprobes.R moved_to_pwalign.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/Biostrings", + "git_branch": "RELEASE_3_20", + "git_last_commit": "b5de574", + "git_last_commit_date": "2024-12-14", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Hervé Pagès [aut, cre], Patrick Aboyoun [aut], Robert Gentleman [aut], Saikat DebRoy [aut], Vince Carey [ctb], Nicolas Delhomme [ctb], Felix Ernst [ctb], Wolfgang Huber [ctb] ('matchprobes' vignette), Beryl Kanali [ctb] (Converted 'MultipleAlignments' vignette from Sweave to RMarkdown), Haleema Khan [ctb] (Converted 'matchprobes' vignette from Sweave to RMarkdown), Aidan Lakshman [ctb], Kieran O'Neill [ctb], Valerie Obenchain [ctb], Marcel Ramos [ctb], Albert Vill [ctb], Jen Wokaty [ctb] (Converted 'matchprobes' vignette from Sweave to RMarkdown), Erik Wright [ctb]", + "Maintainer": "Hervé Pagès " }, "DBI": { "Package": "DBI", - "Version": "1.2.2", + "Version": "1.2.3", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "methods" + "Title": "R Database Interface", + "Date": "2024-06-02", + "Authors@R": "c( person(\"R Special Interest Group on Databases (R-SIG-DB)\", role = \"aut\"), person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Kirill\", \"Müller\", , \"kirill@cynkra.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-1416-3412\")), person(\"R Consortium\", role = \"fnd\") )", + "Description": "A database interface definition for communication between R and relational database management systems. All classes in this package are virtual and need to be extended by the various R/DBMS implementations.", + "License": "LGPL (>= 2.1)", + "URL": "https://dbi.r-dbi.org, https://github.com/r-dbi/DBI", + "BugReports": "https://github.com/r-dbi/DBI/issues", + "Depends": [ + "methods", + "R (>= 3.0.0)" + ], + "Suggests": [ + "arrow", + "blob", + "covr", + "DBItest", + "dbplyr", + "downlit", + "dplyr", + "glue", + "hms", + "knitr", + "magrittr", + "nanoarrow (>= 0.3.0.1)", + "RMariaDB", + "rmarkdown", + "rprojroot", + "RSQLite (>= 1.1-2)", + "testthat (>= 3.0.0)", + "vctrs", + "xml2" ], - "Hash": "164809cd72e1d5160b4cb3aa57f510fe" + "VignetteBuilder": "knitr", + "Config/autostyle/scope": "line_breaks", + "Config/autostyle/strict": "false", + "Config/Needs/check": "r-dbi/DBItest", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Config/Needs/website": "r-dbi/DBItest, r-dbi/dbitemplate, adbi, AzureKusto, bigrquery, DatabaseConnector, dittodb, duckdb, implyr, lazysf, odbc, pool, RAthena, IMSMWU/RClickhouse, RH2, RJDBC, RMariaDB, RMySQL, RPostgres, RPostgreSQL, RPresto, RSQLite, sergeant, sparklyr, withr", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "R Special Interest Group on Databases (R-SIG-DB) [aut], Hadley Wickham [aut], Kirill Müller [aut, cre] (), R Consortium [fnd]", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" }, "DelayedArray": { "Package": "DelayedArray", - "Version": "0.28.0", + "Version": "0.32.0", "Source": "Bioconductor", - "Requirements": [ - "BiocGenerics", - "IRanges", - "Matrix", - "MatrixGenerics", - "R", - "S4Arrays", - "S4Vectors", - "SparseArray", + "Title": "A unified framework for working transparently with on-disk and in-memory array-like datasets", + "Description": "Wrapping an array-like object (typically an on-disk object) in a DelayedArray object allows one to perform common array operations on it without loading the object in memory. In order to reduce memory usage and optimize performance, operations on the object are either delayed or executed using a block processing mechanism. Note that this also works on in-memory array-like objects like DataFrame objects (typically with Rle columns), Matrix objects, ordinary arrays and, data frames.", + "biocViews": "Infrastructure, DataRepresentation, Annotation, GenomeAnnotation", + "URL": "https://bioconductor.org/packages/DelayedArray", + "BugReports": "https://github.com/Bioconductor/DelayedArray/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\"), person(\"Aaron\", \"Lun\", role=\"ctb\", email=\"infinite.monkeys.with.keyboards@gmail.com\"), person(\"Peter\", \"Hickey\", role=\"ctb\", email=\"peter.hickey@gmail.com\"))", + "Maintainer": "Hervé Pagès ", + "Depends": [ + "R (>= 4.0.0)", "methods", - "stats", - "stats4" + "stats4", + "Matrix", + "BiocGenerics (>= 0.51.3)", + "MatrixGenerics (>= 1.1.3)", + "S4Vectors (>= 0.27.2)", + "IRanges (>= 2.17.3)", + "S4Arrays (>= 1.5.4)", + "SparseArray (>= 1.5.42)" + ], + "Imports": [ + "stats" + ], + "LinkingTo": [ + "S4Vectors" + ], + "Suggests": [ + "BiocParallel", + "HDF5Array (>= 1.17.12)", + "genefilter", + "SummarizedExperiment", + "airway", + "lobstr", + "DelayedMatrixStats", + "knitr", + "rmarkdown", + "BiocStyle", + "RUnit" ], - "Hash": "0e5c84e543a3d04ce64c6f60ed46d7eb" + "VignetteBuilder": "knitr", + "Collate": "compress_atomic_vector.R SparseArraySeed-class.R SparseArraySeed-utils.R read_sparse_block.R makeCappedVolumeBox.R AutoBlock-global-settings.R AutoGrid.R blockApply.R DelayedOp-class.R DelayedSubset-class.R DelayedAperm-class.R DelayedUnaryIsoOpStack-class.R DelayedUnaryIsoOpWithArgs-class.R DelayedSubassign-class.R DelayedSetDimnames-class.R DelayedNaryIsoOp-class.R DelayedAbind-class.R showtree.R simplify.R DelayedArray-class.R DelayedArray-subsetting.R chunkGrid.R RealizationSink-class.R realize.R DelayedArray-utils.R DelayedArray-stats.R matrixStats-methods.R DelayedMatrix-rowsum.R DelayedMatrix-mult.R ConstantArray-class.R RleArraySeed-class.R RleArray-class.R compat.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/DelayedArray", + "git_branch": "RELEASE_3_20", + "git_last_commit": "980c34e", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Hervé Pagès [aut, cre], Aaron Lun [ctb], Peter Hickey [ctb]" }, "DelayedMatrixStats": { "Package": "DelayedMatrixStats", - "Version": "1.24.0", + "Version": "1.28.1", "Source": "Bioconductor", - "Requirements": [ - "DelayedArray", - "IRanges", - "Matrix", - "MatrixGenerics", - "S4Vectors", + "Type": "Package", + "Title": "Functions that Apply to Rows and Columns of 'DelayedMatrix' Objects", + "Date": "2025-01-09", + "Authors@R": "c(person(\"Peter\", \"Hickey\", role = c(\"aut\", \"cre\"), email = \"peter.hickey@gmail.com\", comment = c(ORCID = \"0000-0002-8153-6258\")), person(\"Hervé\", \"Pagès\", role = \"ctb\", email = \"hpages.on.github@gmail.com\"), person(\"Aaron\", \"Lun\", role = \"ctb\", email = \"infinite.monkeys.with.keyboards@gmail.com\"))", + "Description": "A port of the 'matrixStats' API for use with DelayedMatrix objects from the 'DelayedArray' package. High-performing functions operating on rows and columns of DelayedMatrix objects, e.g. col / rowMedians(), col / rowRanks(), and col / rowSds(). Functions optimized per data type and for subsetted calculations such that both memory usage and processing time is minimized.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Roxygen": "list(markdown = TRUE)", + "RoxygenNote": "7.3.2", + "Depends": [ + "MatrixGenerics (>= 1.15.1)", + "DelayedArray (>= 0.31.7)" + ], + "Imports": [ "methods", - "sparseMatrixStats" + "sparseMatrixStats (>= 1.13.2)", + "Matrix (>= 1.5-0)", + "S4Vectors (>= 0.17.5)", + "IRanges (>= 2.25.10)", + "SparseArray (>= 1.5.19)" + ], + "Suggests": [ + "testthat", + "knitr", + "rmarkdown", + "BiocStyle", + "microbenchmark", + "profmem", + "HDF5Array", + "matrixStats (>= 1.0.0)" + ], + "VignetteBuilder": "knitr", + "URL": "https://github.com/PeteHaitch/DelayedMatrixStats", + "BugReports": "https://github.com/PeteHaitch/DelayedMatrixStats/issues", + "biocViews": "Infrastructure, DataRepresentation, Software", + "git_url": "https://git.bioconductor.org/packages/DelayedMatrixStats", + "git_branch": "RELEASE_3_20", + "git_last_commit": "7915324", + "git_last_commit_date": "2025-01-08", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Peter Hickey [aut, cre] (), Hervé Pagès [ctb], Aaron Lun [ctb]", + "Maintainer": "Peter Hickey " + }, + "Deriv": { + "Package": "Deriv", + "Version": "4.2.0", + "Source": "Repository", + "Type": "Package", + "Title": "Symbolic Differentiation", + "Date": "2025-06-20", + "Authors@R": "c(person(given=\"Andrew\", family=\"Clausen\", role=\"aut\"), person(given=\"Serguei\", family=\"Sokol\", role=c(\"aut\", \"cre\"), email=\"sokol@insa-toulouse.fr\", comment = c(ORCID = \"0000-0002-5674-3327\")), person(given=\"Andreas\", family=\"Rappold\", role=\"ctb\", email=\"arappold@gmx.at\"))", + "Description": "R-based solution for symbolic differentiation. It admits user-defined function as well as function substitution in arguments of functions to be differentiated. Some symbolic simplification is part of the work.", + "License": "GPL (>= 3)", + "Suggests": [ + "testthat (>= 0.11.0)" ], - "Hash": "71c2d178d33f9d91999f67dc2d53b747" + "BugReports": "https://github.com/sgsokol/Deriv/issues", + "RoxygenNote": "7.3.1", + "Imports": [ + "methods" + ], + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Andrew Clausen [aut], Serguei Sokol [aut, cre] (ORCID: ), Andreas Rappold [ctb]", + "Maintainer": "Serguei Sokol ", + "Repository": "CRAN" + }, + "Formula": { + "Package": "Formula", + "Version": "1.2-5", + "Source": "Repository", + "Date": "2023-02-23", + "Title": "Extended Model Formulas", + "Description": "Infrastructure for extended formulas with multiple parts on the right-hand side and/or multiple responses on the left-hand side (see ).", + "Authors@R": "c(person(given = \"Achim\", family = \"Zeileis\", role = c(\"aut\", \"cre\"), email = \"Achim.Zeileis@R-project.org\", comment = c(ORCID = \"0000-0003-0918-3766\")), person(given = \"Yves\", family = \"Croissant\", role = \"aut\", email = \"Yves.Croissant@univ-reunion.fr\"))", + "Depends": [ + "R (>= 2.0.0)", + "stats" + ], + "License": "GPL-2 | GPL-3", + "NeedsCompilation": "no", + "Author": "Achim Zeileis [aut, cre] (), Yves Croissant [aut]", + "Maintainer": "Achim Zeileis ", + "Repository": "CRAN" }, "GSEABase": { "Package": "GSEABase", - "Version": "1.64.0", + "Version": "1.68.0", "Source": "Bioconductor", - "Requirements": [ + "Type": "Package", + "Title": "Gene set enrichment data structures and methods", + "Authors@R": "c( person(\"Martin\", \"Morgan\", role = \"aut\"), person(\"Seth\", \"Falcon\", role = \"aut\"), person(\"Robert\", \"Gentleman\", role = \"aut\"), person(\"Paul\", \"Villafuerte\", role = \"ctb\", comment = \"'GSEABase' vignette translation from Sweave to Rmarkdown / HTML\"), person(\"Bioconductor Package Maintainer\", role = \"cre\", email = \"maintainer@bioconductor.org\" ))", + "Description": "This package provides classes and methods to support Gene Set Enrichment Analysis (GSEA).", + "License": "Artistic-2.0", + "Depends": [ + "R (>= 2.6.0)", + "BiocGenerics (>= 0.13.8)", + "Biobase (>= 2.17.8)", + "annotate (>= 1.45.3)", + "methods", + "graph (>= 1.37.2)" + ], + "Suggests": [ + "hgu95av2.db", + "GO.db", + "org.Hs.eg.db", + "Rgraphviz", + "ReportingTools", + "testthat", + "BiocStyle", + "knitr", + "RUnit" + ], + "Imports": [ "AnnotationDbi", - "Biobase", - "BiocGenerics", - "R", - "XML", - "annotate", - "graph", - "methods" + "XML" ], - "Hash": "96e2adf800dc97758f8c5a36b98d8fef" + "LazyLoad": "yes", + "Collate": "utilities.R AAA.R AllClasses.R AllGenerics.R getObjects.R methods-CollectionType.R methods-ExpressionSet.R methods-GeneColorSet.R methods-GeneIdentifierType.R methods-GeneSet.R methods-GeneSetCollection.R methods-OBOCollection.R", + "VignetteBuilder": "knitr", + "biocViews": "GeneExpression, GeneSetEnrichment, GraphAndNetwork, GO, KEGG", + "git_url": "https://git.bioconductor.org/packages/GSEABase", + "git_branch": "RELEASE_3_20", + "git_last_commit": "3766175", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Martin Morgan [aut], Seth Falcon [aut], Robert Gentleman [aut], Paul Villafuerte [ctb] ('GSEABase' vignette translation from Sweave to Rmarkdown / HTML), Bioconductor Package Maintainer [cre]", + "Maintainer": "Bioconductor Package Maintainer " }, "GSVA": { "Package": "GSVA", - "Version": "1.50.2", + "Version": "2.0.7", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Requirements": [ + "Title": "Gene Set Variation Analysis for Microarray and RNA-Seq Data", + "Authors@R": "c(person(\"Robert\", \"Castelo\", role=c(\"aut\", \"cre\"), email=\"robert.castelo@upf.edu\"), person(\"Justin\", \"Guinney\", role=\"aut\", email=\"jguinney@gmail.com\"), person(\"Alexey\", \"Sergushichev\", role=\"ctb\", email=\"alsergbox@gmail.com\"), person(\"Pablo Sebastian\", \"Rodriguez\", role=\"ctb\", email=\"pablo.rodriguez.bio2@gmail.com\"), person(\"Axel\", \"Klenk\", role=\"ctb\", email=\"axelvolker.klenk@upf.edu\"))", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "methods", + "stats", + "utils", + "graphics", + "S4Vectors", + "IRanges", "Biobase", + "SummarizedExperiment", + "GSEABase", + "Matrix (>= 1.5-0)", + "parallel", "BiocParallel", - "BiocSingular", + "SingleCellExperiment", + "SpatialExperiment", + "sparseMatrixStats", "DelayedArray", "DelayedMatrixStats", - "GSEABase", "HDF5Array", - "IRanges", - "Matrix", - "R", - "S4Vectors", - "SingleCellExperiment", - "SummarizedExperiment", - "graphics", - "methods", - "parallel", - "sparseMatrixStats", - "stats", - "utils" + "BiocSingular", + "cli" + ], + "Suggests": [ + "BiocGenerics", + "RUnit", + "BiocStyle", + "knitr", + "rmarkdown", + "limma", + "RColorBrewer", + "org.Hs.eg.db", + "genefilter", + "edgeR", + "GSVAdata", + "shiny", + "shinydashboard", + "ggplot2", + "data.table", + "plotly", + "future", + "promises", + "shinybusy", + "shinyjs" + ], + "LinkingTo": [ + "cli" ], - "Hash": "787e1f2eb10588e83be85b0abe78c5d1" + "Description": "Gene Set Variation Analysis (GSVA) is a non-parametric, unsupervised method for estimating variation of gene set enrichment through the samples of a expression data set. GSVA performs a change in coordinate systems, transforming the data from a gene by sample matrix to a gene-set by sample matrix, thereby allowing the evaluation of pathway enrichment for each sample. This new matrix of GSVA enrichment scores facilitates applying standard analytical methods like functional enrichment, survival analysis, clustering, CNV-pathway analysis or cross-tissue pathway analysis, in a pathway-centric manner.", + "License": "GPL (>= 2)", + "VignetteBuilder": "knitr", + "URL": "https://github.com/rcastelo/GSVA", + "BugReports": "https://github.com/rcastelo/GSVA/issues", + "Encoding": "UTF-8", + "biocViews": "FunctionalGenomics, Microarray, RNASeq, Pathways, GeneSetEnrichment", + "Roxygen": "list(markdown = TRUE)", + "RoxygenNote": "7.3.2", + "git_url": "https://git.bioconductor.org/packages/GSVA", + "git_branch": "RELEASE_3_20", + "git_last_commit": "b63c3a0", + "git_last_commit_date": "2025-03-21", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Robert Castelo [aut, cre], Justin Guinney [aut], Alexey Sergushichev [ctb], Pablo Sebastian Rodriguez [ctb], Axel Klenk [ctb]", + "Maintainer": "Robert Castelo " }, "GenomeInfoDb": { "Package": "GenomeInfoDb", - "Version": "1.38.8", + "Version": "1.42.3", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Requirements": [ - "BiocGenerics", - "GenomeInfoDbData", - "IRanges", - "R", - "RCurl", - "S4Vectors", + "Title": "Utilities for manipulating chromosome names, including modifying them to follow a particular naming style", + "Description": "Contains data and functions that define and allow translation between different chromosome sequence naming conventions (e.g., \"chr1\" versus \"1\"), including a function that attempts to place sequence names in their natural, rather than lexicographic, order.", + "biocViews": "Genetics, DataRepresentation, Annotation, GenomeAnnotation", + "URL": "https://bioconductor.org/packages/GenomeInfoDb", + "Video": "http://youtu.be/wdEjCYSXa7w", + "BugReports": "https://github.com/Bioconductor/GenomeInfoDb/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Sonali\", \"Arora\", role=\"aut\"), person(\"Martin\", \"Morgan\", role=\"aut\"), person(\"Marc\", \"Carlson\", role=\"aut\"), person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\"), person(\"Prisca Chidimma\", \"Maduka\", role=\"ctb\"), person(\"Atuhurira Kirabo\", \"Kakopo\", role=\"ctb\"), person(\"Haleema\", \"Khan\", role=\"ctb\", comment=\"vignette translation from Sweave to Rmarkdown / HTML\"), person(\"Emmanuel Chigozie\", \"Elendu\", role=\"ctb\"))", + "Depends": [ + "R (>= 4.0.0)", "methods", + "BiocGenerics (>= 0.37.0)", + "S4Vectors (>= 0.25.12)", + "IRanges (>= 2.13.12)" + ], + "Imports": [ "stats", "stats4", - "utils" + "utils", + "UCSC.utils", + "GenomeInfoDbData" + ], + "Suggests": [ + "R.utils", + "data.table", + "GenomicRanges", + "Rsamtools", + "GenomicAlignments", + "GenomicFeatures", + "BSgenome", + "TxDb.Dmelanogaster.UCSC.dm3.ensGene", + "BSgenome.Scerevisiae.UCSC.sacCer2", + "BSgenome.Celegans.UCSC.ce2", + "BSgenome.Hsapiens.NCBI.GRCh38", + "RUnit", + "BiocStyle", + "knitr" ], - "Hash": "155053909d2831bfac154a1118151d6b" + "VignetteBuilder": "knitr", + "Collate": "utils.R fetch_table_dump_from_Ensembl_FTP.R list_ftp_dir.R rankSeqlevels.R NCBI-utils.R UCSC-utils.R Ensembl-utils.R getChromInfoFromNCBI.R getChromInfoFromUCSC.R getChromInfoFromEnsembl.R loadTaxonomyDb.R mapGenomeBuilds.R seqinfo.R Seqinfo-class.R seqlevelsStyle.R seqlevels-wrappers.R GenomeDescription-class.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/GenomeInfoDb", + "git_branch": "RELEASE_3_20", + "git_last_commit": "2f182bf", + "git_last_commit_date": "2025-01-23", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Sonali Arora [aut], Martin Morgan [aut], Marc Carlson [aut], Hervé Pagès [aut, cre], Prisca Chidimma Maduka [ctb], Atuhurira Kirabo Kakopo [ctb], Haleema Khan [ctb] (vignette translation from Sweave to Rmarkdown / HTML), Emmanuel Chigozie Elendu [ctb]", + "Maintainer": "Hervé Pagès " }, "GenomeInfoDbData": { "Package": "GenomeInfoDbData", - "Version": "1.2.11", + "Version": "1.2.13", "Source": "Bioconductor", - "Requirements": [ - "R" + "Title": "Species and taxonomy ID look up tables used by GenomeInfoDb", + "Description": "Files for mapping between NCBI taxonomy ID and species. Used by functions in the GenomeInfoDb package.", + "Author": "Bioconductor Core Team", + "Maintainer": "Bioconductor Maintainer ", + "Depends": [ + "R (>= 3.5.0)" ], - "Hash": "10f32956181d1d46bd8402c93ac193e8" + "biocViews": "AnnotationData, Organism", + "License": "Artistic-2.0", + "NeedsCompilation": "no" }, "GenomicRanges": { "Package": "GenomicRanges", - "Version": "1.54.1", + "Version": "1.58.0", "Source": "Bioconductor", - "Requirements": [ - "BiocGenerics", - "GenomeInfoDb", - "IRanges", - "R", - "S4Vectors", - "XVector", + "Title": "Representation and manipulation of genomic intervals", + "Description": "The ability to efficiently represent and manipulate genomic annotations and alignments is playing a central role when it comes to analyzing high-throughput sequencing data (a.k.a. NGS data). The GenomicRanges package defines general purpose containers for storing and manipulating genomic intervals and variables defined along a genome. More specialized containers for representing and manipulating short alignments against a reference genome, or a matrix-like summarization of an experiment, are defined in the GenomicAlignments and SummarizedExperiment packages, respectively. Both packages build on top of the GenomicRanges infrastructure.", + "biocViews": "Genetics, Infrastructure, DataRepresentation, Sequencing, Annotation, GenomeAnnotation, Coverage", + "URL": "https://bioconductor.org/packages/GenomicRanges", + "BugReports": "https://github.com/Bioconductor/GenomicRanges/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Patrick\", \"Aboyoun\", role=\"aut\"), person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\"), person(\"Michael\", \"Lawrence\", role=\"aut\"), person(\"Sonali\", \"Arora\", role=\"ctb\"), person(\"Martin\", \"Morgan\", role=\"ctb\"), person(\"Kayla\", \"Morrell\", role=\"ctb\"), person(\"Valerie\", \"Obenchain\", role=\"ctb\"), person(\"Marcel\", \"Ramos\", role=\"ctb\"), person(\"Lori\", \"Shepherd\", role=\"ctb\"), person(\"Dan\", \"Tenenbaum\", role=\"ctb\"), person(\"Daniel\", \"van Twisk\", role=\"ctb\"))", + "Depends": [ + "R (>= 4.0.0)", "methods", - "stats", "stats4", - "utils" + "BiocGenerics (>= 0.37.0)", + "S4Vectors (>= 0.27.12)", + "IRanges (>= 2.37.1)", + "GenomeInfoDb (>= 1.15.2)" + ], + "Imports": [ + "utils", + "stats", + "XVector (>= 0.29.2)" + ], + "LinkingTo": [ + "S4Vectors", + "IRanges" ], - "Hash": "7e0c1399af35369312d9c399454374e8" + "Suggests": [ + "Matrix", + "Biobase", + "AnnotationDbi", + "annotate", + "Biostrings (>= 2.25.3)", + "SummarizedExperiment (>= 0.1.5)", + "Rsamtools (>= 1.13.53)", + "GenomicAlignments", + "rtracklayer", + "BSgenome", + "GenomicFeatures", + "txdbmaker", + "Gviz", + "VariantAnnotation", + "AnnotationHub", + "DESeq2", + "DEXSeq", + "edgeR", + "KEGGgraph", + "RNAseqData.HNRNPC.bam.chr14", + "pasillaBamSubset", + "KEGGREST", + "hgu95av2.db", + "hgu95av2probe", + "BSgenome.Scerevisiae.UCSC.sacCer2", + "BSgenome.Hsapiens.UCSC.hg38", + "BSgenome.Mmusculus.UCSC.mm10", + "TxDb.Athaliana.BioMart.plantsmart22", + "TxDb.Dmelanogaster.UCSC.dm3.ensGene", + "TxDb.Hsapiens.UCSC.hg38.knownGene", + "TxDb.Mmusculus.UCSC.mm10.knownGene", + "RUnit", + "digest", + "knitr", + "rmarkdown", + "BiocStyle" + ], + "VignetteBuilder": "knitr", + "Collate": "normarg-utils.R utils.R phicoef.R transcript-utils.R constraint.R strand-utils.R genomic-range-squeezers.R GenomicRanges-class.R GenomicRanges-comparison.R GRanges-class.R GPos-class.R GRangesFactor-class.R DelegatingGenomicRanges-class.R GNCList-class.R GenomicRangesList-class.R GRangesList-class.R makeGRangesFromDataFrame.R makeGRangesListFromDataFrame.R RangedData-methods.R findOverlaps-methods.R intra-range-methods.R inter-range-methods.R coverage-methods.R setops-methods.R subtract-methods.R nearest-methods.R absoluteRanges.R tileGenome.R tile-methods.R genomicvars.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/GenomicRanges", + "git_branch": "RELEASE_3_20", + "git_last_commit": "31ad89c", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Patrick Aboyoun [aut], Hervé Pagès [aut, cre], Michael Lawrence [aut], Sonali Arora [ctb], Martin Morgan [ctb], Kayla Morrell [ctb], Valerie Obenchain [ctb], Marcel Ramos [ctb], Lori Shepherd [ctb], Dan Tenenbaum [ctb], Daniel van Twisk [ctb]", + "Maintainer": "Hervé Pagès " }, "HDF5Array": { "Package": "HDF5Array", - "Version": "1.30.1", + "Version": "1.34.0", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Requirements": [ - "BiocGenerics", - "DelayedArray", - "IRanges", - "Matrix", - "R", - "Rhdf5lib", - "S4Arrays", - "S4Vectors", + "Title": "HDF5 datasets as array-like objects in R", + "Description": "The HDF5Array package is an HDF5 backend for DelayedArray objects. It implements the HDF5Array, H5SparseMatrix, H5ADMatrix, and TENxMatrix classes, 4 convenient and memory-efficient array-like containers for representing and manipulating either: (1) a conventional (a.k.a. dense) HDF5 dataset, (2) an HDF5 sparse matrix (stored in CSR/CSC/Yale format), (3) the central matrix of an h5ad file (or any matrix in the /layers group), or (4) a 10x Genomics sparse matrix. All these containers are DelayedArray extensions and thus support all operations (delayed or block-processed) supported by DelayedArray objects.", + "biocViews": "Infrastructure, DataRepresentation, DataImport, Sequencing, RNASeq, Coverage, Annotation, GenomeAnnotation, SingleCell, ImmunoOncology", + "URL": "https://bioconductor.org/packages/HDF5Array", + "BugReports": "https://github.com/Bioconductor/HDF5Array/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Author": "Hervé Pagès", + "Maintainer": "Hervé Pagès ", + "Depends": [ + "R (>= 3.4)", "methods", - "rhdf5", - "rhdf5filters", + "SparseArray (>= 1.5.42)", + "DelayedArray (>= 0.31.8)", + "rhdf5 (>= 2.31.6)" + ], + "Imports": [ + "utils", "stats", "tools", - "utils" + "Matrix", + "rhdf5filters", + "BiocGenerics (>= 0.51.2)", + "S4Vectors", + "IRanges", + "S4Arrays (>= 1.1.1)" + ], + "LinkingTo": [ + "S4Vectors (>= 0.27.13)", + "Rhdf5lib" + ], + "SystemRequirements": "GNU make", + "Suggests": [ + "BiocParallel", + "GenomicRanges", + "SummarizedExperiment (>= 1.15.1)", + "h5vcData", + "ExperimentHub", + "TENxBrainData", + "zellkonverter", + "GenomicFeatures", + "RUnit", + "SingleCellExperiment", + "DelayedMatrixStats", + "genefilter" ], - "Hash": "9b8deb4fd34fa439c16c829457d1968f" + "Collate": "utils.R H5File-class.R h5ls.R h5utils.R H5DSetDescriptor-class.R h5dimscales.R uaselection.R h5mread.R h5mread_from_reshaped.R h5writeDimnames.R h5summarize.R HDF5ArraySeed-class.R HDF5Array-class.R ReshapedHDF5ArraySeed-class.R ReshapedHDF5Array-class.R dump-management.R writeHDF5Array.R saveHDF5SummarizedExperiment.R H5SparseMatrixSeed-class.R H5SparseMatrix-class.R H5ADMatrixSeed-class.R H5ADMatrix-class.R TENxMatrixSeed-class.R TENxMatrix-class.R writeTENxMatrix.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/HDF5Array", + "git_branch": "RELEASE_3_20", + "git_last_commit": "dab3921", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes" }, "IRanges": { "Package": "IRanges", - "Version": "2.36.0", + "Version": "2.40.1", "Source": "Bioconductor", - "Requirements": [ - "BiocGenerics", - "R", - "S4Vectors", + "Title": "Foundation of integer range manipulation in Bioconductor", + "Description": "Provides efficient low-level and highly reusable S4 classes for storing, manipulating and aggregating over annotated ranges of integers. Implements an algebra of range operations, including efficient algorithms for finding overlaps and nearest neighbors. Defines efficient list-like classes for storing, transforming and aggregating large grouped data, i.e., collections of atomic vectors and DataFrames.", + "biocViews": "Infrastructure, DataRepresentation", + "URL": "https://bioconductor.org/packages/IRanges", + "BugReports": "https://github.com/Bioconductor/IRanges/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\"), person(\"Patrick\", \"Aboyoun\", role=\"aut\"), person(\"Michael\", \"Lawrence\", role=\"aut\"))", + "Depends": [ + "R (>= 4.0.0)", "methods", + "utils", "stats", - "stats4", - "utils" + "BiocGenerics (>= 0.39.2)", + "S4Vectors (>= 0.43.2)" + ], + "Imports": [ + "stats4" + ], + "LinkingTo": [ + "S4Vectors" ], - "Hash": "f98500eeb93e8a66ad65be955a848595" + "Suggests": [ + "XVector", + "GenomicRanges", + "Rsamtools", + "GenomicAlignments", + "GenomicFeatures", + "BSgenome.Celegans.UCSC.ce2", + "pasillaBamSubset", + "RUnit", + "BiocStyle" + ], + "Collate": "range-squeezers.R Vector-class-leftovers.R DataFrameList-class.R DataFrameList-utils.R AtomicList-class.R AtomicList-utils.R Ranges-and-RangesList-classes.R IPosRanges-class.R IPosRanges-comparison.R IntegerRangesList-class.R IRanges-class.R IRanges-constructor.R IRanges-utils.R Rle-class-leftovers.R IPos-class.R subsetting-utils.R Grouping-class.R Views-class.R RleViews-class.R RleViews-utils.R extractList.R seqapply.R multisplit.R SimpleGrouping-class.R IRangesList-class.R IPosList-class.R ViewsList-class.R RleViewsList-class.R RleViewsList-utils.R RangedSelection-class.R MaskCollection-class.R read.Mask.R CompressedList-class.R CompressedList-comparison.R CompressedHitsList-class.R CompressedDataFrameList-class.R CompressedAtomicList-class.R CompressedGrouping-class.R CompressedRangesList-class.R Hits-class-leftovers.R NCList-class.R findOverlaps-methods.R windows-methods.R intra-range-methods.R inter-range-methods.R reverse-methods.R coverage-methods.R cvg-methods.R slice-methods.R setops-methods.R nearest-methods.R cbind-Rle-methods.R tile-methods.R extractListFragments.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/IRanges", + "git_branch": "RELEASE_3_20", + "git_last_commit": "535f07e", + "git_last_commit_date": "2024-12-02", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Hervé Pagès [aut, cre], Patrick Aboyoun [aut], Michael Lawrence [aut]", + "Maintainer": "Hervé Pagès " }, "KEGGREST": { "Package": "KEGGREST", - "Version": "1.42.0", + "Version": "1.46.0", "Source": "Bioconductor", - "Requirements": [ - "Biostrings", - "R", - "httr", + "Title": "Client-side REST access to the Kyoto Encyclopedia of Genes and Genomes (KEGG)", + "Authors@R": "c( person(\"Dan\", \"Tenenbaum\", role = \"aut\"), person(\"Bioconductor Package\", \"Maintainer\", role = c(\"aut\", \"cre\"), email = \"maintainer@bioconductor.org\"), person(\"Martin\", \"Morgan\", role = \"ctb\"), person(\"Kozo\", \"Nishida\", role = \"ctb\"), person(\"Marcel\", \"Ramos\", role = \"ctb\"), person(\"Kristina\", \"Riemer\", role = \"ctb\"), person(\"Lori\", \"Shepherd\", role = \"ctb\"), person(\"Jeremy\", \"Volkening\", role = \"ctb\") )", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ "methods", - "png" + "httr", + "png", + "Biostrings" + ], + "Suggests": [ + "RUnit", + "BiocGenerics", + "BiocStyle", + "knitr", + "markdown" + ], + "Description": "A package that provides a client interface to the Kyoto Encyclopedia of Genes and Genomes (KEGG) REST API. Only for academic use by academic users belonging to academic institutions (see ). Note that KEGGREST is based on KEGGSOAP by J. Zhang, R. Gentleman, and Marc Carlson, and KEGG (python package) by Aurelien Mazurie.", + "URL": "https://bioconductor.org/packages/KEGGREST", + "BugReports": "https://github.com/Bioconductor/KEGGREST/issues", + "License": "Artistic-2.0", + "VignetteBuilder": "knitr", + "biocViews": "Annotation, Pathways, ThirdPartyClient, KEGG", + "RoxygenNote": "7.1.1", + "Date": "2024-06-17", + "git_url": "https://git.bioconductor.org/packages/KEGGREST", + "git_branch": "RELEASE_3_20", + "git_last_commit": "b34820c", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Dan Tenenbaum [aut], Bioconductor Package Maintainer [aut, cre], Martin Morgan [ctb], Kozo Nishida [ctb], Marcel Ramos [ctb], Kristina Riemer [ctb], Lori Shepherd [ctb], Jeremy Volkening [ctb]", + "Maintainer": "Bioconductor Package Maintainer " + }, + "MASS": { + "Package": "MASS", + "Version": "7.3-65", + "Source": "Repository", + "Priority": "recommended", + "Date": "2025-02-19", + "Revision": "$Rev: 3681 $", + "Depends": [ + "R (>= 4.4.0)", + "grDevices", + "graphics", + "stats", + "utils" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "lattice", + "nlme", + "nnet", + "survival" ], - "Hash": "8d6e9f4dce69aec9c588c27ae79be08e" + "Authors@R": "c(person(\"Brian\", \"Ripley\", role = c(\"aut\", \"cre\", \"cph\"), email = \"Brian.Ripley@R-project.org\"), person(\"Bill\", \"Venables\", role = c(\"aut\", \"cph\")), person(c(\"Douglas\", \"M.\"), \"Bates\", role = \"ctb\"), person(\"Kurt\", \"Hornik\", role = \"trl\", comment = \"partial port ca 1998\"), person(\"Albrecht\", \"Gebhardt\", role = \"trl\", comment = \"partial port ca 1998\"), person(\"David\", \"Firth\", role = \"ctb\", comment = \"support functions for polr\"))", + "Description": "Functions and datasets to support Venables and Ripley, \"Modern Applied Statistics with S\" (4th edition, 2002).", + "Title": "Support Functions and Datasets for Venables and Ripley's MASS", + "LazyData": "yes", + "ByteCompile": "yes", + "License": "GPL-2 | GPL-3", + "URL": "http://www.stats.ox.ac.uk/pub/MASS4/", + "Contact": "", + "NeedsCompilation": "yes", + "Author": "Brian Ripley [aut, cre, cph], Bill Venables [aut, cph], Douglas M. Bates [ctb], Kurt Hornik [trl] (partial port ca 1998), Albrecht Gebhardt [trl] (partial port ca 1998), David Firth [ctb] (support functions for polr)", + "Maintainer": "Brian Ripley ", + "Repository": "CRAN" }, "Matrix": { "Package": "Matrix", - "Version": "1.6-5", + "Version": "1.7-3", "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R", + "VersionNote": "do also bump src/version.h, inst/include/Matrix/version.h", + "Date": "2025-03-05", + "Priority": "recommended", + "Title": "Sparse and Dense Matrix Classes and Methods", + "Description": "A rich hierarchy of sparse and dense matrix classes, including general, symmetric, triangular, and diagonal matrices with numeric, logical, or pattern entries. Efficient methods for operating on such matrices, often wrapping the 'BLAS', 'LAPACK', and 'SuiteSparse' libraries.", + "License": "GPL (>= 2) | file LICENCE", + "URL": "https://Matrix.R-forge.R-project.org", + "BugReports": "https://R-forge.R-project.org/tracker/?atid=294&group_id=61", + "Contact": "Matrix-authors@R-project.org", + "Authors@R": "c(person(\"Douglas\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Martin\", \"Maechler\", role = c(\"aut\", \"cre\"), email = \"mmaechler+Matrix@gmail.com\", comment = c(ORCID = \"0000-0002-8685-9910\")), person(\"Mikael\", \"Jagan\", role = \"aut\", comment = c(ORCID = \"0000-0002-3542-2938\")), person(\"Timothy A.\", \"Davis\", role = \"ctb\", comment = c(ORCID = \"0000-0001-7614-6899\", \"SuiteSparse libraries\", \"collaborators listed in dir(system.file(\\\"doc\\\", \\\"SuiteSparse\\\", package=\\\"Matrix\\\"), pattern=\\\"License\\\", full.names=TRUE, recursive=TRUE)\")), person(\"George\", \"Karypis\", role = \"ctb\", comment = c(ORCID = \"0000-0003-2753-1437\", \"METIS library\", \"Copyright: Regents of the University of Minnesota\")), person(\"Jason\", \"Riedy\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4345-4200\", \"GNU Octave's condest() and onenormest()\", \"Copyright: Regents of the University of California\")), person(\"Jens\", \"Oehlschlägel\", role = \"ctb\", comment = \"initial nearPD()\"), person(\"R Core Team\", role = \"ctb\", comment = c(ROR = \"02zz1nj61\", \"base R's matrix implementation\")))", + "Depends": [ + "R (>= 4.4)", + "methods" + ], + "Imports": [ "grDevices", "graphics", "grid", "lattice", - "methods", "stats", "utils" ], - "Hash": "8c7115cd3a0e048bda2a7cd110549f7a" + "Suggests": [ + "MASS", + "datasets", + "sfsmisc", + "tools" + ], + "Enhances": [ + "SparseM", + "graph" + ], + "LazyData": "no", + "LazyDataNote": "not possible, since we use data/*.R and our S4 classes", + "BuildResaveData": "no", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Douglas Bates [aut] (), Martin Maechler [aut, cre] (), Mikael Jagan [aut] (), Timothy A. Davis [ctb] (, SuiteSparse libraries, collaborators listed in dir(system.file(\"doc\", \"SuiteSparse\", package=\"Matrix\"), pattern=\"License\", full.names=TRUE, recursive=TRUE)), George Karypis [ctb] (, METIS library, Copyright: Regents of the University of Minnesota), Jason Riedy [ctb] (, GNU Octave's condest() and onenormest(), Copyright: Regents of the University of California), Jens Oehlschlägel [ctb] (initial nearPD()), R Core Team [ctb] (02zz1nj61, base R's matrix implementation)", + "Maintainer": "Martin Maechler ", + "Repository": "CRAN" }, "MatrixGenerics": { "Package": "MatrixGenerics", - "Version": "1.14.0", + "Version": "1.18.1", "Source": "Bioconductor", - "Requirements": [ - "matrixStats", + "Title": "S4 Generic Summary Statistic Functions that Operate on Matrix-Like Objects", + "Description": "S4 generic functions modeled after the 'matrixStats' API for alternative matrix implementations. Packages with alternative matrix implementation can depend on this package and implement the generic functions that are defined here for a useful set of row and column summary statistics. Other package developers can import this package and handle a different matrix implementations without worrying about incompatibilities.", + "biocViews": "Infrastructure, Software", + "URL": "https://bioconductor.org/packages/MatrixGenerics", + "BugReports": "https://github.com/Bioconductor/MatrixGenerics/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c(person(\"Constantin\", \"Ahlmann-Eltze\", email = \"artjom31415@googlemail.com\", role = c(\"aut\"), comment = c(ORCID = \"0000-0002-3762-068X\")), person(\"Peter\", \"Hickey\", role = c(\"aut\", \"cre\"), email = \"peter.hickey@gmail.com\", comment = c(ORCID = \"0000-0002-8153-6258\")), person(\"Hervé\", \"Pagès\", email = \"hpages.on.github@gmail.com\", role = \"aut\"))", + "Depends": [ + "matrixStats (>= 1.4.1)" + ], + "Imports": [ "methods" ], - "Hash": "088cd2077b5619fcb7b373b1a45174e7" + "Suggests": [ + "Matrix", + "sparseMatrixStats", + "SparseArray", + "DelayedArray", + "DelayedMatrixStats", + "SummarizedExperiment", + "testthat (>= 2.1.0)" + ], + "RoxygenNote": "7.3.2", + "Roxygen": "list(markdown = TRUE, old_usage = TRUE)", + "Collate": "'MatrixGenerics-package.R' 'rowAlls.R' 'rowAnyNAs.R' 'rowAnys.R' 'rowAvgsPerColSet.R' 'rowCollapse.R' 'rowCounts.R' 'rowCummaxs.R' 'rowCummins.R' 'rowCumprods.R' 'rowCumsums.R' 'rowDiffs.R' 'rowIQRDiffs.R' 'rowIQRs.R' 'rowLogSumExps.R' 'rowMadDiffs.R' 'rowMads.R' 'rowMaxs.R' 'rowMeans.R' 'rowMeans2.R' 'rowMedians.R' 'rowMins.R' 'rowOrderStats.R' 'rowProds.R' 'rowQuantiles.R' 'rowRanges.R' 'rowRanks.R' 'rowSdDiffs.R' 'rowSds.R' 'rowSums.R' 'rowSums2.R' 'rowTabulates.R' 'rowVarDiffs.R' 'rowVars.R' 'rowWeightedMads.R' 'rowWeightedMeans.R' 'rowWeightedMedians.R' 'rowWeightedSds.R' 'rowWeightedVars.R'", + "git_url": "https://git.bioconductor.org/packages/MatrixGenerics", + "git_branch": "RELEASE_3_20", + "git_last_commit": "5fb4445", + "git_last_commit_date": "2025-01-08", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Constantin Ahlmann-Eltze [aut] (), Peter Hickey [aut, cre] (), Hervé Pagès [aut]", + "Maintainer": "Peter Hickey " + }, + "MatrixModels": { + "Package": "MatrixModels", + "Version": "0.5-4", + "Source": "Repository", + "VersionNote": "Released 0.5-3 on 2023-11-06", + "Date": "2025-03-25", + "Title": "Modelling with Sparse and Dense Matrices", + "Contact": "Matrix-authors@R-project.org", + "Authors@R": "c( person(\"Douglas\", \"Bates\", role = \"aut\", email = \"bates@stat.wisc.edu\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Martin\", \"Maechler\", role = c(\"aut\", \"cre\"), email = \"mmaechler+Matrix@gmail.com\", comment = c(ORCID = \"0000-0002-8685-9910\")))", + "Description": "Generalized Linear Modelling with sparse and dense 'Matrix' matrices, using modular prediction and response module classes.", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "stats", + "methods", + "Matrix (>= 1.6-0)", + "Matrix(< 1.8-0)" + ], + "ImportsNote": "_not_yet_stats4", + "Encoding": "UTF-8", + "LazyLoad": "yes", + "License": "GPL (>= 2)", + "URL": "https://Matrix.R-forge.R-project.org/, https://r-forge.r-project.org/R/?group_id=61", + "BugReports": "https://R-forge.R-project.org/tracker/?func=add&atid=294&group_id=61", + "NeedsCompilation": "no", + "Author": "Douglas Bates [aut] (), Martin Maechler [aut, cre] ()", + "Maintainer": "Martin Maechler ", + "Repository": "CRAN" + }, + "R.methodsS3": { + "Package": "R.methodsS3", + "Version": "1.8.2", + "Source": "Repository", + "Depends": [ + "R (>= 2.13.0)" + ], + "Imports": [ + "utils" + ], + "Suggests": [ + "codetools" + ], + "Title": "S3 Methods Simplified", + "Authors@R": "c(person(\"Henrik\", \"Bengtsson\", role=c(\"aut\", \"cre\", \"cph\"), email = \"henrikb@braju.com\"))", + "Author": "Henrik Bengtsson [aut, cre, cph]", + "Maintainer": "Henrik Bengtsson ", + "Description": "Methods that simplify the setup of S3 generic functions and S3 methods. Major effort has been made in making definition of methods as simple as possible with a minimum of maintenance for package developers. For example, generic functions are created automatically, if missing, and naming conflict are automatically solved, if possible. The method setMethodS3() is a good start for those who in the future may want to migrate to S4. This is a cross-platform package implemented in pure R that generates standard S3 methods.", + "License": "LGPL (>= 2.1)", + "LazyLoad": "TRUE", + "URL": "https://github.com/HenrikBengtsson/R.methodsS3", + "BugReports": "https://github.com/HenrikBengtsson/R.methodsS3/issues", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "R.oo": { + "Package": "R.oo", + "Version": "1.27.1", + "Source": "Repository", + "Depends": [ + "R (>= 2.13.0)", + "R.methodsS3 (>= 1.8.2)" + ], + "Imports": [ + "methods", + "utils" + ], + "Suggests": [ + "tools" + ], + "Title": "R Object-Oriented Programming with or without References", + "Authors@R": "c(person(\"Henrik\", \"Bengtsson\", role=c(\"aut\", \"cre\", \"cph\"), email = \"henrikb@braju.com\"))", + "Author": "Henrik Bengtsson [aut, cre, cph]", + "Maintainer": "Henrik Bengtsson ", + "Description": "Methods and classes for object-oriented programming in R with or without references. Large effort has been made on making definition of methods as simple as possible with a minimum of maintenance for package developers. The package has been developed since 2001 and is now considered very stable. This is a cross-platform package implemented in pure R that defines standard S3 classes without any tricks.", + "License": "LGPL (>= 2.1)", + "LazyLoad": "TRUE", + "URL": "https://henrikbengtsson.github.io/R.oo/, https://github.com/HenrikBengtsson/R.oo", + "BugReports": "https://github.com/HenrikBengtsson/R.oo/issues", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "R.utils": { + "Package": "R.utils", + "Version": "2.13.0", + "Source": "Repository", + "Depends": [ + "R (>= 2.14.0)", + "R.oo" + ], + "Imports": [ + "methods", + "utils", + "tools", + "R.methodsS3" + ], + "Suggests": [ + "datasets", + "digest (>= 0.6.10)" + ], + "Title": "Various Programming Utilities", + "Authors@R": "c(person(\"Henrik\", \"Bengtsson\", role=c(\"aut\", \"cre\", \"cph\"), email = \"henrikb@braju.com\"))", + "Author": "Henrik Bengtsson [aut, cre, cph]", + "Maintainer": "Henrik Bengtsson ", + "Description": "Utility functions useful when programming and developing R packages.", + "License": "LGPL (>= 2.1)", + "LazyLoad": "TRUE", + "URL": "https://henrikbengtsson.github.io/R.utils/, https://github.com/HenrikBengtsson/R.utils", + "BugReports": "https://github.com/HenrikBengtsson/R.utils/issues", + "NeedsCompilation": "no", + "Repository": "CRAN" }, "R6": { "Package": "R6", - "Version": "2.5.1", + "Version": "2.6.1", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Title": "Encapsulated Classes with Reference Semantics", + "Authors@R": "c( person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Creates classes with reference semantics, similar to R's built-in reference classes. Compared to reference classes, R6 classes are simpler and lighter-weight, and they are not built on S4 classes so they do not require the methods package. These classes allow public and private members, and they support inheritance, even when the classes are defined in different packages.", + "License": "MIT + file LICENSE", + "URL": "https://r6.r-lib.org, https://github.com/r-lib/R6", + "BugReports": "https://github.com/r-lib/R6/issues", + "Depends": [ + "R (>= 3.6)" ], - "Hash": "470851b6d5d0ac559e9d01bb352b4021" + "Suggests": [ + "lobstr", + "testthat (>= 3.0.0)" + ], + "Config/Needs/website": "tidyverse/tidytemplate, ggplot2, microbenchmark, scales", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" }, - "RCurl": { - "Package": "RCurl", - "Version": "1.98-1.14", + "RColorBrewer": { + "Package": "RColorBrewer", + "Version": "1.1-3", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "bitops", - "methods" + "Date": "2022-04-03", + "Title": "ColorBrewer Palettes", + "Authors@R": "c(person(given = \"Erich\", family = \"Neuwirth\", role = c(\"aut\", \"cre\"), email = \"erich.neuwirth@univie.ac.at\"))", + "Author": "Erich Neuwirth [aut, cre]", + "Maintainer": "Erich Neuwirth ", + "Depends": [ + "R (>= 2.0.0)" ], - "Hash": "47f648d288079d0c696804ad4e55197e" + "Description": "Provides color schemes for maps (and other graphics) designed by Cynthia Brewer as described at http://colorbrewer2.org.", + "License": "Apache License 2.0", + "NeedsCompilation": "no", + "Repository": "CRAN" }, "RSQLite": { "Package": "RSQLite", - "Version": "2.3.6", + "Version": "2.4.1", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "DBI", - "R", + "Title": "SQLite Interface for R", + "Date": "2025-06-08", + "Authors@R": "c( person(\"Kirill\", \"Müller\", , \"kirill@cynkra.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-1416-3412\")), person(\"Hadley\", \"Wickham\", role = \"aut\"), person(c(\"David\", \"A.\"), \"James\", role = \"aut\"), person(\"Seth\", \"Falcon\", role = \"aut\"), person(\"D. Richard\", \"Hipp\", role = \"ctb\", comment = \"for the included SQLite sources\"), person(\"Dan\", \"Kennedy\", role = \"ctb\", comment = \"for the included SQLite sources\"), person(\"Joe\", \"Mistachkin\", role = \"ctb\", comment = \"for the included SQLite sources\"), person(, \"SQLite Authors\", role = \"ctb\", comment = \"for the included SQLite sources\"), person(\"Liam\", \"Healy\", role = \"ctb\", comment = \"for the included SQLite sources\"), person(\"R Consortium\", role = \"fnd\"), person(, \"RStudio\", role = \"cph\") )", + "Description": "Embeds the SQLite database engine in R and provides an interface compliant with the DBI package. The source for the SQLite engine and for various extensions in a recent version is included. System libraries will never be consulted because this package relies on static linking for the plugins it includes; this also ensures a consistent experience across all installations.", + "License": "LGPL (>= 2.1)", + "URL": "https://rsqlite.r-dbi.org, https://github.com/r-dbi/RSQLite", + "BugReports": "https://github.com/r-dbi/RSQLite/issues", + "Depends": [ + "R (>= 3.1.0)" + ], + "Imports": [ "bit64", - "blob", - "cpp11", + "blob (>= 1.2.0)", + "DBI (>= 1.2.0)", "memoise", "methods", "pkgconfig", - "plogr", "rlang" ], - "Hash": "ae4a925e0f6bb1b7e5fa96b739c5221a" + "Suggests": [ + "callr", + "cli", + "DBItest (>= 1.8.0)", + "decor", + "gert", + "gh", + "hms", + "knitr", + "magrittr", + "rmarkdown", + "rvest", + "testthat (>= 3.0.0)", + "withr", + "xml2" + ], + "LinkingTo": [ + "plogr (>= 0.2.0)", + "cpp11 (>= 0.4.0)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "r-dbi/dbitemplate", + "Config/autostyle/scope": "line_breaks", + "Config/autostyle/strict": "false", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2.9000", + "Collate": "'SQLiteConnection.R' 'SQLKeywords_SQLiteConnection.R' 'SQLiteDriver.R' 'SQLite.R' 'SQLiteResult.R' 'coerce.R' 'compatRowNames.R' 'copy.R' 'cpp11.R' 'datasetsDb.R' 'dbAppendTable_SQLiteConnection.R' 'dbBeginTransaction.R' 'dbBegin_SQLiteConnection.R' 'dbBind_SQLiteResult.R' 'dbClearResult_SQLiteResult.R' 'dbColumnInfo_SQLiteResult.R' 'dbCommit_SQLiteConnection.R' 'dbConnect_SQLiteConnection.R' 'dbConnect_SQLiteDriver.R' 'dbDataType_SQLiteConnection.R' 'dbDataType_SQLiteDriver.R' 'dbDisconnect_SQLiteConnection.R' 'dbExistsTable_SQLiteConnection_Id.R' 'dbExistsTable_SQLiteConnection_character.R' 'dbFetch_SQLiteResult.R' 'dbGetException_SQLiteConnection.R' 'dbGetInfo_SQLiteConnection.R' 'dbGetInfo_SQLiteDriver.R' 'dbGetPreparedQuery.R' 'dbGetPreparedQuery_SQLiteConnection_character_data.frame.R' 'dbGetRowCount_SQLiteResult.R' 'dbGetRowsAffected_SQLiteResult.R' 'dbGetStatement_SQLiteResult.R' 'dbHasCompleted_SQLiteResult.R' 'dbIsValid_SQLiteConnection.R' 'dbIsValid_SQLiteDriver.R' 'dbIsValid_SQLiteResult.R' 'dbListResults_SQLiteConnection.R' 'dbListTables_SQLiteConnection.R' 'dbQuoteIdentifier_SQLiteConnection_SQL.R' 'dbQuoteIdentifier_SQLiteConnection_character.R' 'dbReadTable_SQLiteConnection_character.R' 'dbRemoveTable_SQLiteConnection_character.R' 'dbRollback_SQLiteConnection.R' 'dbSendPreparedQuery.R' 'dbSendPreparedQuery_SQLiteConnection_character_data.frame.R' 'dbSendQuery_SQLiteConnection_character.R' 'dbUnloadDriver_SQLiteDriver.R' 'dbUnquoteIdentifier_SQLiteConnection_SQL.R' 'dbWriteTable_SQLiteConnection_character_character.R' 'dbWriteTable_SQLiteConnection_character_data.frame.R' 'db_bind.R' 'deprecated.R' 'export.R' 'fetch_SQLiteResult.R' 'import-standalone-check_suggested.R' 'import-standalone-purrr.R' 'initExtension.R' 'initRegExp.R' 'isSQLKeyword_SQLiteConnection_character.R' 'make.db.names_SQLiteConnection_character.R' 'pkgconfig.R' 'show_SQLiteConnection.R' 'sqlData_SQLiteConnection.R' 'table.R' 'transactions.R' 'utils.R' 'version.R' 'zzz.R'", + "NeedsCompilation": "yes", + "Author": "Kirill Müller [aut, cre] (ORCID: ), Hadley Wickham [aut], David A. James [aut], Seth Falcon [aut], D. Richard Hipp [ctb] (for the included SQLite sources), Dan Kennedy [ctb] (for the included SQLite sources), Joe Mistachkin [ctb] (for the included SQLite sources), SQLite Authors [ctb] (for the included SQLite sources), Liam Healy [ctb] (for the included SQLite sources), R Consortium [fnd], RStudio [cph]", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" }, "Rcpp": { "Package": "Rcpp", - "Version": "1.0.12", + "Version": "1.1.0", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ + "Title": "Seamless R and C++ Integration", + "Date": "2025-07-01", + "Authors@R": "c(person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Romain\", \"Francois\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"JJ\", \"Allaire\", role = \"aut\", comment = c(ORCID = \"0000-0003-0174-9868\")), person(\"Kevin\", \"Ushey\", role = \"aut\", comment = c(ORCID = \"0000-0003-2880-7407\")), person(\"Qiang\", \"Kou\", role = \"aut\", comment = c(ORCID = \"0000-0001-6786-5453\")), person(\"Nathan\", \"Russell\", role = \"aut\"), person(\"Iñaki\", \"Ucar\", role = \"aut\", comment = c(ORCID = \"0000-0001-6403-5550\")), person(\"Doug\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"John\", \"Chambers\", role = \"aut\"))", + "Description": "The 'Rcpp' package provides R functions as well as C++ classes which offer a seamless integration of R and C++. Many R data types and objects can be mapped back and forth to C++ equivalents which facilitates both writing of new code as well as easier integration of third-party libraries. Documentation about 'Rcpp' is provided by several vignettes included in this package, via the 'Rcpp Gallery' site at , the paper by Eddelbuettel and Francois (2011, ), the book by Eddelbuettel (2013, ) and the paper by Eddelbuettel and Balamuta (2018, ); see 'citation(\"Rcpp\")' for details.", + "Imports": [ "methods", "utils" ], - "Hash": "5ea2700d21e038ace58269ecdbeb9ec0" + "Suggests": [ + "tinytest", + "inline", + "rbenchmark", + "pkgKitten (>= 0.1.2)" + ], + "URL": "https://www.rcpp.org, https://dirk.eddelbuettel.com/code/rcpp.html, https://github.com/RcppCore/Rcpp", + "License": "GPL (>= 2)", + "BugReports": "https://github.com/RcppCore/Rcpp/issues", + "MailingList": "rcpp-devel@lists.r-forge.r-project.org", + "RoxygenNote": "6.1.1", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Dirk Eddelbuettel [aut, cre] (ORCID: ), Romain Francois [aut] (ORCID: ), JJ Allaire [aut] (ORCID: ), Kevin Ushey [aut] (ORCID: ), Qiang Kou [aut] (ORCID: ), Nathan Russell [aut], Iñaki Ucar [aut] (ORCID: ), Doug Bates [aut] (ORCID: ), John Chambers [aut]", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "CRAN" + }, + "RcppEigen": { + "Package": "RcppEigen", + "Version": "0.3.4.0.2", + "Source": "Repository", + "Type": "Package", + "Title": "'Rcpp' Integration for the 'Eigen' Templated Linear Algebra Library", + "Date": "2024-08-23", + "Authors@R": "c(person(\"Doug\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Romain\", \"Francois\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Yixuan\", \"Qiu\", role = \"aut\", comment = c(ORCID = \"0000-0003-0109-6692\")), person(\"Authors of\", \"Eigen\", role = \"cph\", comment = \"Authorship and copyright in included Eigen library as detailed in inst/COPYRIGHTS\"))", + "Copyright": "See the file COPYRIGHTS for various Eigen copyright details", + "Description": "R and 'Eigen' integration using 'Rcpp'. 'Eigen' is a C++ template library for linear algebra: matrices, vectors, numerical solvers and related algorithms. It supports dense and sparse matrices on integer, floating point and complex numbers, decompositions of such matrices, and solutions of linear systems. Its performance on many algorithms is comparable with some of the best implementations based on 'Lapack' and level-3 'BLAS'. The 'RcppEigen' package includes the header files from the 'Eigen' C++ template library. Thus users do not need to install 'Eigen' itself in order to use 'RcppEigen'. Since version 3.1.1, 'Eigen' is licensed under the Mozilla Public License (version 2); earlier version were licensed under the GNU LGPL version 3 or later. 'RcppEigen' (the 'Rcpp' bindings/bridge to 'Eigen') is licensed under the GNU GPL version 2 or later, as is the rest of 'Rcpp'.", + "License": "GPL (>= 2) | file LICENSE", + "LazyLoad": "yes", + "Depends": [ + "R (>= 3.6.0)" + ], + "LinkingTo": [ + "Rcpp" + ], + "Imports": [ + "Rcpp (>= 0.11.0)", + "stats", + "utils" + ], + "Suggests": [ + "Matrix", + "inline", + "tinytest", + "pkgKitten", + "microbenchmark" + ], + "URL": "https://github.com/RcppCore/RcppEigen, https://dirk.eddelbuettel.com/code/rcpp.eigen.html", + "BugReports": "https://github.com/RcppCore/RcppEigen/issues", + "NeedsCompilation": "yes", + "Author": "Doug Bates [aut] (), Dirk Eddelbuettel [aut, cre] (), Romain Francois [aut] (), Yixuan Qiu [aut] (), Authors of Eigen [cph] (Authorship and copyright in included Eigen library as detailed in inst/COPYRIGHTS)", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "CRAN" + }, + "Rdpack": { + "Package": "Rdpack", + "Version": "2.6.4", + "Source": "Repository", + "Type": "Package", + "Title": "Update and Manipulate Rd Documentation Objects", + "Authors@R": "c( person(given = c(\"Georgi\", \"N.\"), family = \"Boshnakov\", role = c(\"aut\", \"cre\"), email = \"georgi.boshnakov@manchester.ac.uk\", comment = c(ORCID = \"0000-0003-2839-346X\")), person(given = \"Duncan\", family = \"Murdoch\", role = \"ctb\", email = \"murdoch.duncan@gmail.com\") )", + "Description": "Functions for manipulation of R documentation objects, including functions reprompt() and ereprompt() for updating 'Rd' documentation for functions, methods and classes; 'Rd' macros for citations and import of references from 'bibtex' files for use in 'Rd' files and 'roxygen2' comments; 'Rd' macros for evaluating and inserting snippets of 'R' code and the results of its evaluation or creating graphics on the fly; and many functions for manipulation of references and Rd files.", + "URL": "https://geobosh.github.io/Rdpack/ (doc), https://github.com/GeoBosh/Rdpack (devel)", + "BugReports": "https://github.com/GeoBosh/Rdpack/issues", + "Depends": [ + "R (>= 2.15.0)", + "methods" + ], + "Imports": [ + "tools", + "utils", + "rbibutils (>= 1.3)" + ], + "Suggests": [ + "grDevices", + "testthat", + "rstudioapi", + "rprojroot", + "gbRd" + ], + "License": "GPL (>= 2)", + "LazyLoad": "yes", + "RoxygenNote": "7.1.1", + "NeedsCompilation": "no", + "Author": "Georgi N. Boshnakov [aut, cre] (), Duncan Murdoch [ctb]", + "Maintainer": "Georgi N. Boshnakov ", + "Repository": "CRAN" }, "Rhdf5lib": { "Package": "Rhdf5lib", - "Version": "1.24.2", + "Version": "1.28.0", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Requirements": [ - "R" + "Type": "Package", + "Title": "hdf5 library as an R package", + "Authors@R": "c( person( \"Mike\", \"Smith\", role=c(\"ctb\", \"cre\"), email = \"grimbough@gmail.com\", comment = c(ORCID = \"0000-0002-7800-3848\") ), person( given = \"The HDF Group\", role = \"cph\" ))", + "Description": "Provides C and C++ hdf5 libraries.", + "License": "Artistic-2.0", + "Copyright": "src/hdf5/COPYING", + "LazyLoad": "true", + "VignetteBuilder": "knitr", + "Depends": [ + "R (>= 4.2.0)" + ], + "Suggests": [ + "BiocStyle", + "knitr", + "rmarkdown", + "tinytest", + "mockery" ], - "Hash": "3cf103db29d75af0221d71946509a30c" + "URL": "https://github.com/grimbough/Rhdf5lib", + "BugReports": "https://github.com/grimbough/Rhdf5lib", + "SystemRequirements": "GNU make", + "Encoding": "UTF-8", + "biocViews": "Infrastructure", + "RoxygenNote": "7.1.2", + "git_url": "https://git.bioconductor.org/packages/Rhdf5lib", + "git_branch": "RELEASE_3_20", + "git_last_commit": "f37cb76", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Mike Smith [ctb, cre] (), The HDF Group [cph]", + "Maintainer": "Mike Smith " }, "S4Arrays": { "Package": "S4Arrays", - "Version": "1.2.1", + "Version": "1.6.0", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Requirements": [ - "BiocGenerics", - "IRanges", + "Title": "Foundation of array-like containers in Bioconductor", + "Description": "The S4Arrays package defines the Array virtual class to be extended by other S4 classes that wish to implement a container with an array-like semantic. It also provides: (1) low-level functionality meant to help the developer of such container to implement basic operations like display, subsetting, or coercion of their array-like objects to an ordinary matrix or array, and (2) a framework that facilitates block processing of array-like objects (typically on-disk objects).", + "biocViews": "Infrastructure, DataRepresentation", + "URL": "https://bioconductor.org/packages/S4Arrays", + "BugReports": "https://github.com/Bioconductor/S4Arrays/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\"), person(\"Jacques\", \"Serizay\", role=\"ctb\"))", + "Depends": [ + "R (>= 4.3.0)", + "methods", "Matrix", - "R", - "S4Vectors", "abind", - "crayon", - "methods", - "stats" + "BiocGenerics (>= 0.45.2)", + "S4Vectors", + "IRanges" + ], + "Imports": [ + "stats", + "crayon" + ], + "LinkingTo": [ + "S4Vectors" ], - "Hash": "3213a9826adb8f48e51af1e7b30fa568" + "Suggests": [ + "BiocParallel", + "SparseArray (>= 0.0.4)", + "DelayedArray", + "testthat", + "knitr", + "rmarkdown", + "BiocStyle" + ], + "VignetteBuilder": "knitr", + "Collate": "utils.R rowsum.R abind.R aperm2.R array_selection.R Nindex-utils.R Array-class.R dim-tuning-utils.R Array-subsetting.R Array-subassignment.R ArrayGrid-class.R mapToGrid.R extract_array.R type.R is_sparse.R read_block.R write_block.R show-utils.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/S4Arrays", + "git_branch": "RELEASE_3_20", + "git_last_commit": "e100af0", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Hervé Pagès [aut, cre], Jacques Serizay [ctb]", + "Maintainer": "Hervé Pagès " }, "S4Vectors": { "Package": "S4Vectors", - "Version": "0.40.2", + "Version": "0.44.0", "Source": "Bioconductor", - "Requirements": [ - "BiocGenerics", - "R", + "Title": "Foundation of vector-like and list-like containers in Bioconductor", + "Description": "The S4Vectors package defines the Vector and List virtual classes and a set of generic functions that extend the semantic of ordinary vectors and lists in R. Package developers can easily implement vector-like or list-like objects as concrete subclasses of Vector or List. In addition, a few low-level concrete subclasses of general interest (e.g. DataFrame, Rle, Factor, and Hits) are implemented in the S4Vectors package itself (many more are implemented in the IRanges package and in other Bioconductor infrastructure packages).", + "biocViews": "Infrastructure, DataRepresentation", + "URL": "https://bioconductor.org/packages/S4Vectors", + "BugReports": "https://github.com/Bioconductor/S4Vectors/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\"), person(\"Michael\", \"Lawrence\", role=\"aut\"), person(\"Patrick\", \"Aboyoun\", role=\"aut\"), person(\"Aaron\", \"Lun\", role=\"ctb\"), person(\"Beryl\", \"Kanali\", role=\"ctb\", comment=\"Converted vignettes from Sweave to RMarkdown\"))", + "Depends": [ + "R (>= 4.0.0)", "methods", + "utils", "stats", "stats4", - "utils" + "BiocGenerics (>= 0.37.0)" + ], + "Suggests": [ + "IRanges", + "GenomicRanges", + "SummarizedExperiment", + "Matrix", + "DelayedArray", + "ShortRead", + "graph", + "data.table", + "RUnit", + "BiocStyle", + "knitr" ], - "Hash": "1716e201f81ced0f456dd5ec85fe20f8" + "VignetteBuilder": "knitr", + "Collate": "S4-utils.R show-utils.R utils.R normarg-utils.R bindROWS.R LLint-class.R isSorted.R subsetting-utils.R vector-utils.R integer-utils.R character-utils.R raw-utils.R eval-utils.R map_ranges_to_runs.R RectangularData-class.R Annotated-class.R DataFrame_OR_NULL-class.R Vector-class.R Vector-comparison.R Vector-setops.R Vector-merge.R Hits-class.R Hits-comparison.R Hits-setops.R Rle-class.R Rle-utils.R Factor-class.R List-class.R List-comparison.R splitAsList.R List-utils.R SimpleList-class.R HitsList-class.R DataFrame-class.R DataFrame-combine.R DataFrame-comparison.R DataFrame-utils.R DataFrameFactor-class.R TransposedDataFrame-class.R Pairs-class.R FilterRules-class.R stack-methods.R expand-methods.R aggregate-methods.R shiftApply-methods.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/S4Vectors", + "git_branch": "RELEASE_3_20", + "git_last_commit": "79c3948", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Hervé Pagès [aut, cre], Michael Lawrence [aut], Patrick Aboyoun [aut], Aaron Lun [ctb], Beryl Kanali [ctb] (Converted vignettes from Sweave to RMarkdown)", + "Maintainer": "Hervé Pagès " }, "ScaledMatrix": { "Package": "ScaledMatrix", - "Version": "1.10.0", + "Version": "1.14.0", "Source": "Bioconductor", - "Requirements": [ - "DelayedArray", + "Date": "2024-02-29", + "Title": "Creating a DelayedMatrix of Scaled and Centered Values", + "Authors@R": "person(\"Aaron\", \"Lun\", role=c(\"aut\", \"cre\", \"cph\"), email=\"infinite.monkeys.with.keyboards@gmail.com\")", + "Imports": [ + "methods", "Matrix", "S4Vectors", - "methods" + "DelayedArray" + ], + "Suggests": [ + "testthat", + "BiocStyle", + "knitr", + "rmarkdown", + "BiocSingular", + "DelayedMatrixStats" ], - "Hash": "ecab4b44d12fc7642a7161f71f3397b5" + "biocViews": "Software, DataRepresentation", + "Description": "Provides delayed computation of a matrix of scaled and centered values. The result is equivalent to using the scale() function but avoids explicit realization of a dense matrix during block processing. This permits greater efficiency in common operations, most notably matrix multiplication.", + "License": "GPL-3", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.3.1", + "BugReports": "https://github.com/LTLA/ScaledMatrix/issues", + "URL": "https://github.com/LTLA/ScaledMatrix", + "git_url": "https://git.bioconductor.org/packages/ScaledMatrix", + "git_branch": "RELEASE_3_20", + "git_last_commit": "3fdccbc", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Aaron Lun [aut, cre, cph]", + "Maintainer": "Aaron Lun " }, "SingleCellExperiment": { "Package": "SingleCellExperiment", - "Version": "1.24.0", + "Version": "1.28.1", "Source": "Bioconductor", - "Requirements": [ - "BiocGenerics", - "DelayedArray", - "GenomicRanges", - "S4Vectors", - "SummarizedExperiment", + "Date": "2024-11-08", + "Title": "S4 Classes for Single Cell Data", + "Authors@R": "c( person(\"Aaron\", \"Lun\", role=c(\"aut\", \"cph\"), email=\"infinite.monkeys.with.keyboards@gmail.com\"), person(\"Davide\",\"Risso\", role=c(\"aut\",\"cre\", \"cph\"), email=\"risso.davide@gmail.com\"), person(\"Keegan\", \"Korthauer\", role=\"ctb\"), person(\"Kevin\", \"Rue-Albrecht\", role=\"ctb\"), person(\"Luke\", \"Zappia\", role = \"ctb\", comment = c(ORCID = \"0000-0001-7744-8565\", github = \"lazappi\")))", + "Depends": [ + "SummarizedExperiment" + ], + "Imports": [ "methods", + "utils", "stats", - "utils" + "S4Vectors", + "BiocGenerics", + "GenomicRanges", + "DelayedArray" + ], + "Suggests": [ + "testthat", + "BiocStyle", + "knitr", + "rmarkdown", + "Matrix", + "scRNAseq (>= 2.9.1)", + "Rtsne" ], - "Hash": "e21b3571ce76eb4dfe6bf7900960aa6a" + "biocViews": "ImmunoOncology, DataRepresentation, DataImport, Infrastructure, SingleCell", + "Description": "Defines a S4 class for storing data from single-cell experiments. This includes specialized methods to store and retrieve spike-in information, dimensionality reduction coordinates and size factors for each cell, along with the usual metadata for genes and libraries.", + "License": "GPL-3", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.3.1", + "git_url": "https://git.bioconductor.org/packages/SingleCellExperiment", + "git_branch": "RELEASE_3_20", + "git_last_commit": "f3e30fb", + "git_last_commit_date": "2024-11-08", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Aaron Lun [aut, cph], Davide Risso [aut, cre, cph], Keegan Korthauer [ctb], Kevin Rue-Albrecht [ctb], Luke Zappia [ctb] (, lazappi)", + "Maintainer": "Davide Risso " }, "SparseArray": { "Package": "SparseArray", - "Version": "1.2.4", + "Version": "1.6.2", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Requirements": [ - "BiocGenerics", - "IRanges", + "Title": "High-performance sparse data representation and manipulation in R", + "Description": "The SparseArray package provides array-like containers for efficient in-memory representation of multidimensional sparse data in R (arrays and matrices). The package defines the SparseArray virtual class and two concrete subclasses: COO_SparseArray and SVT_SparseArray. Each subclass uses its own internal representation of the nonzero multidimensional data: the \"COO layout\" and the \"SVT layout\", respectively. SVT_SparseArray objects mimic as much as possible the behavior of ordinary matrix and array objects in base R. In particular, they suppport most of the \"standard matrix and array API\" defined in base R and in the matrixStats package from CRAN.", + "biocViews": "Infrastructure, DataRepresentation", + "URL": "https://bioconductor.org/packages/SparseArray", + "BugReports": "https://github.com/Bioconductor/SparseArray/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\", comment=c(ORCID=\"0009-0002-8272-4522\")), person(\"Vince\", \"Carey\", role=\"fnd\", email=\"stvjc@channing.harvard.edu\", comment=c(ORCID=\"0000-0003-4046-0063\")), person(\"Rafael A.\", \"Irizarry\", role=\"fnd\", email=\"rafa@ds.harvard.edu\", comment=c(ORCID=\"0000-0002-3944-4309\")), person(\"Jacques\", \"Serizay\", role=\"ctb\", comment=c(ORCID=\"0000-0002-4295-0624\")))", + "Depends": [ + "R (>= 4.3.0)", + "methods", "Matrix", - "MatrixGenerics", - "R", - "S4Arrays", - "S4Vectors", - "XVector", + "BiocGenerics (>= 0.43.1)", + "MatrixGenerics (>= 1.11.1)", + "S4Vectors (>= 0.43.2)", + "S4Arrays (>= 1.5.11)" + ], + "Imports": [ + "utils", + "stats", "matrixStats", + "IRanges", + "XVector" + ], + "LinkingTo": [ + "S4Vectors", + "IRanges", + "XVector" + ], + "Suggests": [ + "HDF5Array", + "ExperimentHub", + "testthat", + "knitr", + "rmarkdown", + "BiocStyle" + ], + "VignetteBuilder": "knitr", + "Collate": "utils.R options.R OPBufTree.R thread-control.R sparseMatrix-utils.R is_nonzero.R SparseArray-class.R COO_SparseArray-class.R SVT_SparseArray-class.R extract_sparse_array.R read_block_as_sparse.R SparseArray-dim-tuning.R SparseArray-aperm.R SparseArray-subsetting.R SparseArray-subassignment.R SparseArray-abind.R SparseArray-summarization.R SparseArray-Arith-methods.R SparseArray-Compare-methods.R SparseArray-Logic-methods.R SparseArray-Math-methods.R SparseArray-Complex-methods.R SparseArray-misc-methods.R SparseArray-matrixStats.R rowsum-methods.R SparseMatrix-mult.R randomSparseArray.R readSparseCSV.R is_nonna.R NaArray-class.R NaArray-aperm.R NaArray-subsetting.R NaArray-subassignment.R NaArray-abind.R NaArray-summarization.R NaArray-Arith-methods.R NaArray-Compare-methods.R NaArray-Logic-methods.R NaArray-Math-methods.R NaArray-misc-methods.R NaArray-matrixStats.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/SparseArray", + "git_branch": "RELEASE_3_20", + "git_last_commit": "89a7e4b", + "git_last_commit_date": "2025-02-18", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Hervé Pagès [aut, cre] (), Vince Carey [fnd] (), Rafael A. Irizarry [fnd] (), Jacques Serizay [ctb] ()", + "Maintainer": "Hervé Pagès " + }, + "SparseM": { + "Package": "SparseM", + "Version": "1.84-2", + "Source": "Repository", + "Authors@R": "c( person(\"Roger\", \"Koenker\", role = c(\"cre\",\"aut\"), email = \"rkoenker@uiuc.edu\"), person(c(\"Pin\", \"Tian\"), \"Ng\", role = c(\"ctb\"), comment = \"Contributions to Sparse QR code\", email = \"pin.ng@nau.edu\") , person(\"Yousef\", \"Saad\", role = c(\"ctb\"), comment = \"author of sparskit2\") , person(\"Ben\", \"Shaby\", role = c(\"ctb\"), comment = \"author of chol2csr\") , person(\"Martin\", \"Maechler\", role = \"ctb\", comment = c(\"chol() tweaks; S4\", ORCID = \"0000-0002-8685-9910\")) )", + "Maintainer": "Roger Koenker ", + "Depends": [ + "R (>= 2.15)", + "methods" + ], + "Imports": [ + "graphics", + "stats", + "utils" + ], + "VignetteBuilder": "knitr", + "Suggests": [ + "knitr" + ], + "Description": "Some basic linear algebra functionality for sparse matrices is provided: including Cholesky decomposition and backsolving as well as standard R subsetting and Kronecker products.", + "License": "GPL (>= 2)", + "Title": "Sparse Linear Algebra", + "URL": "http://www.econ.uiuc.edu/~roger/research/sparse/sparse.html", + "NeedsCompilation": "yes", + "Author": "Roger Koenker [cre, aut], Pin Tian Ng [ctb] (Contributions to Sparse QR code), Yousef Saad [ctb] (author of sparskit2), Ben Shaby [ctb] (author of chol2csr), Martin Maechler [ctb] (chol() tweaks; S4, )", + "Repository": "CRAN" + }, + "SpatialExperiment": { + "Package": "SpatialExperiment", + "Version": "1.16.0", + "Source": "Bioconductor", + "Title": "S4 Class for Spatially Resolved -omics Data", + "Description": "Defines an S4 class for storing data from spatial -omics experiments. The class extends SingleCellExperiment to support storage and retrieval of additional information from spot-based and molecule-based platforms, including spatial coordinates, images, and image metadata. A specialized constructor function is included for data from the 10x Genomics Visium platform.", + "Authors@R": "c( person(\"Dario\", \"Righelli\", role=c(\"aut\", \"cre\"), email=\"dario.righelli@gmail.com\"), person(\"Davide\", \"Risso\", role=c(\"aut\"), email=\"risso.davide@gmail.com\"), person(\"Helena L.\", \"Crowell\", role=c(\"aut\"), email=\"helena.crowell@uzh.ch\"), person(\"Lukas M.\", \"Weber\", role=c(\"aut\"), email=\"lukas.weber.edu@gmail.com\"), person(\"Nicholas J.\", \"Eagles\", role=c(\"ctb\"), email=\"nickeagles77@gmail.com\"))", + "URL": "https://github.com/drighelli/SpatialExperiment", + "BugReports": "https://github.com/drighelli/SpatialExperiment/issues", + "License": "GPL-3", + "Encoding": "UTF-8", + "biocViews": "DataRepresentation, DataImport, Infrastructure, ImmunoOncology, GeneExpression, Transcriptomics, SingleCell, Spatial", + "Depends": [ "methods", - "stats" + "SingleCellExperiment" + ], + "Imports": [ + "rjson", + "grDevices", + "magick", + "utils", + "S4Vectors", + "SummarizedExperiment", + "BiocGenerics", + "BiocFileCache" + ], + "Suggests": [ + "knitr", + "rmarkdown", + "testthat", + "BiocStyle", + "BumpyMatrix", + "DropletUtils" ], - "Hash": "391092e7b81373ab624bd6471cebccd4" + "VignetteBuilder": "knitr", + "RoxygenNote": "7.2.3", + "git_url": "https://git.bioconductor.org/packages/SpatialExperiment", + "git_branch": "RELEASE_3_20", + "git_last_commit": "8798cb0", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Dario Righelli [aut, cre], Davide Risso [aut], Helena L. Crowell [aut], Lukas M. Weber [aut], Nicholas J. Eagles [ctb]", + "Maintainer": "Dario Righelli " }, "SummarizedExperiment": { "Package": "SummarizedExperiment", - "Version": "1.32.0", + "Version": "1.36.0", "Source": "Bioconductor", - "Requirements": [ - "Biobase", - "BiocGenerics", - "DelayedArray", - "GenomeInfoDb", - "GenomicRanges", - "IRanges", - "Matrix", - "MatrixGenerics", - "R", - "S4Arrays", - "S4Vectors", + "Title": "A container (S4 class) for matrix-like assays", + "Description": "The SummarizedExperiment container contains one or more assays, each represented by a matrix-like object of numeric or other mode. The rows typically represent genomic ranges of interest and the columns represent samples.", + "biocViews": "Genetics, Infrastructure, Sequencing, Annotation, Coverage, GenomeAnnotation", + "URL": "https://bioconductor.org/packages/SummarizedExperiment", + "BugReports": "https://github.com/Bioconductor/SummarizedExperiment/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "c( person(\"Martin\", \"Morgan\", role=\"aut\"), person(\"Valerie\", \"Obenchain\", role=\"aut\"), person(\"Jim\", \"Hester\", role=\"aut\"), person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\"))", + "Depends": [ + "R (>= 4.0.0)", "methods", + "MatrixGenerics (>= 1.1.3)", + "GenomicRanges (>= 1.55.2)", + "Biobase" + ], + "Imports": [ + "utils", "stats", "tools", - "utils" + "Matrix", + "BiocGenerics (>= 0.51.3)", + "S4Vectors (>= 0.33.7)", + "IRanges (>= 2.23.9)", + "GenomeInfoDb (>= 1.13.1)", + "S4Arrays (>= 1.1.1)", + "DelayedArray (>= 0.31.12)" + ], + "Suggests": [ + "jsonlite", + "rhdf5", + "HDF5Array (>= 1.7.5)", + "annotate", + "AnnotationDbi", + "GenomicFeatures", + "SparseArray", + "SingleCellExperiment", + "TxDb.Hsapiens.UCSC.hg19.knownGene", + "hgu95av2.db", + "airway (>= 1.15.1)", + "BiocStyle", + "knitr", + "rmarkdown", + "RUnit", + "testthat", + "digest" + ], + "VignetteBuilder": "knitr", + "Collate": "Assays-class.R SummarizedExperiment-class.R RangedSummarizedExperiment-class.R intra-range-methods.R inter-range-methods.R coverage-methods.R combine-methods.R findOverlaps-methods.R nearest-methods.R makeSummarizedExperimentFromExpressionSet.R makeSummarizedExperimentFromDataFrame.R makeSummarizedExperimentFromLoom.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/SummarizedExperiment", + "git_branch": "RELEASE_3_20", + "git_last_commit": "c84e08a", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Martin Morgan [aut], Valerie Obenchain [aut], Jim Hester [aut], Hervé Pagès [aut, cre]", + "Maintainer": "Hervé Pagès " + }, + "UCSC.utils": { + "Package": "UCSC.utils", + "Version": "1.2.0", + "Source": "Bioconductor", + "Title": "Low-level utilities to retrieve data from the UCSC Genome Browser", + "Description": "A set of low-level utilities to retrieve data from the UCSC Genome Browser. Most functions in the package access the data via the UCSC REST API but some of them query the UCSC MySQL server directly. Note that the primary purpose of the package is to support higher-level functionalities implemented in downstream packages like GenomeInfoDb or txdbmaker.", + "biocViews": "Infrastructure, GenomeAssembly, Annotation, GenomeAnnotation, DataImport", + "URL": "https://bioconductor.org/packages/UCSC.utils", + "BugReports": "https://github.com/Bioconductor/UCSC.utils/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Authors@R": "person(\"Hervé\", \"Pagès\", role=c(\"aut\", \"cre\"), email=\"hpages.on.github@gmail.com\")", + "Imports": [ + "methods", + "stats", + "httr", + "jsonlite", + "S4Vectors" + ], + "Suggests": [ + "DBI", + "RMariaDB", + "GenomeInfoDb", + "testthat", + "knitr", + "rmarkdown", + "BiocStyle" ], - "Hash": "caee529bf9710ff6fe1776612fcaa266" + "VignetteBuilder": "knitr", + "Collate": "00utils.R UCSC.api.url.R REST_API.R list_UCSC_genomes.R get_UCSC_chrom_sizes.R list_UCSC_tracks.R fetch_UCSC_track_data.R UCSC_dbselect.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/UCSC.utils", + "git_branch": "RELEASE_3_20", + "git_last_commit": "d77d73e", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Hervé Pagès [aut, cre]", + "Maintainer": "Hervé Pagès " }, "XML": { "Package": "XML", - "Version": "3.99-0.16.1", + "Version": "3.99-0.18", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", + "Authors@R": "c(person(\"CRAN Team\", role = c('ctb', 'cre'), email = \"CRAN@r-project.org\", comment = \"de facto maintainer since 2013\"), person(\"Duncan\", \"Temple Lang\", role = c(\"aut\"), email = \"duncan@r-project.org\", comment = c(ORCID = \"0000-0003-0159-1546\")), person(\"Tomas\", \"Kalibera\", role = \"ctb\"))", + "Title": "Tools for Parsing and Generating XML Within R and S-Plus", + "Depends": [ + "R (>= 4.0.0)", "methods", "utils" ], - "Hash": "da3098169c887914551b607c66fe2a28" + "Suggests": [ + "bitops", + "RCurl" + ], + "SystemRequirements": "libxml2 (>= 2.6.3)", + "Description": "Many approaches for both reading and creating XML (and HTML) documents (including DTDs), both local and accessible via HTTP or FTP. Also offers access to an 'XPath' \"interpreter\".", + "URL": "https://www.omegahat.net/RSXML/", + "License": "BSD_3_clause + file LICENSE", + "Collate": "AAA.R DTD.R DTDClasses.R DTDRef.R SAXMethods.R XMLClasses.R applyDOM.R assignChild.R catalog.R createNode.R dynSupports.R error.R flatTree.R nodeAccessors.R parseDTD.R schema.R summary.R tangle.R toString.R tree.R version.R xmlErrorEnums.R xmlEventHandler.R xmlEventParse.R xmlHandler.R xmlInternalSource.R xmlOutputDOM.R xmlNodes.R xmlOutputBuffer.R xmlTree.R xmlTreeParse.R htmlParse.R hashTree.R zzz.R supports.R parser.R libxmlFeatures.R xmlString.R saveXML.R namespaces.R readHTMLTable.R reflection.R xmlToDataFrame.R bitList.R compare.R encoding.R fixNS.R xmlRoot.R serialize.R xmlMemoryMgmt.R keyValueDB.R solrDocs.R XMLRErrorInfo.R xincludes.R namespaceHandlers.R tangle1.R htmlLinks.R htmlLists.R getDependencies.R getRelativeURL.R xmlIncludes.R simplifyPath.R", + "NeedsCompilation": "yes", + "Author": "CRAN Team [ctb, cre] (de facto maintainer since 2013), Duncan Temple Lang [aut] (), Tomas Kalibera [ctb]", + "Maintainer": "CRAN Team ", + "Repository": "CRAN" }, "XVector": { "Package": "XVector", - "Version": "0.42.0", + "Version": "0.46.0", "Source": "Bioconductor", - "Requirements": [ - "BiocGenerics", - "IRanges", - "R", - "S4Vectors", + "Title": "Foundation of external vector representation and manipulation in Bioconductor", + "Description": "Provides memory efficient S4 classes for storing sequences \"externally\" (e.g. behind an R external pointer, or on disk).", + "biocViews": "Infrastructure, DataRepresentation", + "URL": "https://bioconductor.org/packages/XVector", + "BugReports": "https://github.com/Bioconductor/XVector/issues", + "License": "Artistic-2.0", + "Encoding": "UTF-8", + "Author": "Hervé Pagès and Patrick Aboyoun", + "Maintainer": "Hervé Pagès ", + "Depends": [ + "R (>= 4.0.0)", + "methods", + "BiocGenerics (>= 0.37.0)", + "S4Vectors (>= 0.27.12)", + "IRanges (>= 2.23.9)" + ], + "Imports": [ "methods", - "tools", "utils", - "zlibbioc" + "tools", + "zlibbioc", + "BiocGenerics", + "S4Vectors", + "IRanges" + ], + "LinkingTo": [ + "S4Vectors", + "IRanges" + ], + "Suggests": [ + "Biostrings", + "drosophila2probe", + "RUnit" ], - "Hash": "65c0b6bca03f88758f86ef0aa18c4873" + "Collate": "io-utils.R RDS-random-access.R SharedVector-class.R SharedRaw-class.R SharedInteger-class.R SharedDouble-class.R XVector-class.R XRaw-class.R XInteger-class.R XDouble-class.R XVectorList-class.R XRawList-class.R XRawList-comparison.R XIntegerViews-class.R XDoubleViews-class.R OnDiskRaw-class.R RdaCollection-class.R RdsCollection-class.R intra-range-methods.R compact-methods.R reverse-methods.R slice-methods.R view-summarization-methods.R updateObject-methods.R zzz.R", + "git_url": "https://git.bioconductor.org/packages/XVector", + "git_branch": "RELEASE_3_20", + "git_last_commit": "1c8f81d", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes" }, "abind": { "Package": "abind", - "Version": "1.4-5", + "Version": "1.4-8", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", + "Date": "2024-09-08", + "Title": "Combine Multidimensional Arrays", + "Authors@R": "c(person(\"Tony\", \"Plate\", email = \"tplate@acm.org\", role = c(\"aut\", \"cre\")), person(\"Richard\", \"Heiberger\", role = c(\"aut\")))", + "Maintainer": "Tony Plate ", + "Description": "Combine multidimensional arrays into a single array. This is a generalization of 'cbind' and 'rbind'. Works with vectors, matrices, and higher-dimensional arrays (aka tensors). Also provides functions 'adrop', 'asub', and 'afill' for manipulating, extracting and replacing data in arrays.", + "Depends": [ + "R (>= 1.5.0)" + ], + "Imports": [ "methods", "utils" ], - "Hash": "4f57884290cc75ab22f4af9e9d4ca862" + "License": "MIT + file LICENSE", + "NeedsCompilation": "no", + "Author": "Tony Plate [aut, cre], Richard Heiberger [aut]", + "Repository": "CRAN" }, "annotate": { "Package": "annotate", - "Version": "1.80.0", + "Version": "1.84.0", "Source": "Bioconductor", - "Requirements": [ - "AnnotationDbi", + "Title": "Annotation for microarrays", + "Author": "R. Gentleman", + "Authors@R": "c( person(\"Jeff\", \"Gentry\", role = \"aut\"), person(\"Kritika\", \"Verma\", role = \"ctb\", comment = \"Converted chromLOC vignette from Sweave to RMarkdown / HTML.\"), person(\"Manvi\", \"Yaduvanshi\", role = \"ctb\", comment = \"Converted useDataPkgs vignette from Sweave to RMarkdown / HTML.\"), person(\"Bioconductor Package Maintainer\", email = \"maintainer@bioconductor.org\", role = \"cre\"))", + "Description": "Using R enviroments for annotation.", + "Depends": [ + "R (>= 2.10)", + "AnnotationDbi (>= 1.27.5)", + "XML" + ], + "Imports": [ "Biobase", - "BiocGenerics", "DBI", - "R", - "XML", + "xtable", "graphics", - "httr", - "methods", - "stats", "utils", - "xtable" + "stats", + "methods", + "BiocGenerics (>= 0.13.8)", + "httr" + ], + "Suggests": [ + "hgu95av2.db", + "genefilter", + "Biostrings (>= 2.25.10)", + "IRanges", + "rae230a.db", + "rae230aprobe", + "tkWidgets", + "GO.db", + "org.Hs.eg.db", + "org.Mm.eg.db", + "humanCHRLOC", + "Rgraphviz", + "RUnit", + "BiocStyle", + "knitr" ], - "Hash": "08359e5ce909c14a936ec1f9712ca830" + "VignetteBuilder": "knitr", + "License": "Artistic-2.0", + "LazyLoad": "yes", + "Collate": "AllGenerics.R ACCNUMStats.R Amat.R AnnMaps.R chromLocation.R compatipleVersions.R findNeighbors.R getData.R getPMInfo.R getSeq4ACC.R GOhelpers.R homoData.R html.R isValidKey.R LL2homology.R pmid2MIAME.R probesByLL.R pubMedAbst.R query.R readGEOAnn.R serializeEnv.R blastSequences.R zzz.R test_annotate_package.R", + "biocViews": "Annotation, Pathways, GO", + "git_url": "https://git.bioconductor.org/packages/annotate", + "git_branch": "RELEASE_3_20", + "git_last_commit": "6188ffb", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Maintainer": "Bioconductor Package Maintainer " }, "askpass": { "Package": "askpass", - "Version": "1.2.0", + "Version": "1.2.1", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "sys" + "Type": "Package", + "Title": "Password Entry Utilities for R, Git, and SSH", + "Authors@R": "person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\"))", + "Description": "Cross-platform utilities for prompting the user for credentials or a passphrase, for example to authenticate with a server or read a protected key. Includes native programs for MacOS and Windows, hence no 'tcltk' is required. Password entry can be invoked in two different ways: directly from R via the askpass() function, or indirectly as password-entry back-end for 'ssh-agent' or 'git-credential' via the SSH_ASKPASS and GIT_ASKPASS environment variables. Thereby the user can be prompted for credentials or a passphrase if needed when R calls out to git or ssh.", + "License": "MIT + file LICENSE", + "URL": "https://r-lib.r-universe.dev/askpass", + "BugReports": "https://github.com/r-lib/askpass/issues", + "Encoding": "UTF-8", + "Imports": [ + "sys (>= 2.1)" + ], + "RoxygenNote": "7.2.3", + "Suggests": [ + "testthat" ], - "Hash": "cad6cf7f1d5f6e906700b9d3e718c796" + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] ()", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" }, - "beachmat": { - "Package": "beachmat", - "Version": "2.18.1", + "assorthead": { + "Package": "assorthead", + "Version": "1.0.1", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Requirements": [ - "BiocGenerics", - "DelayedArray", - "Matrix", - "Rcpp", - "SparseArray", - "methods" + "Date": "2024-11-26", + "Title": "Assorted Header-Only C++ Libraries", + "Authors@R": "person(\"Aaron\", \"Lun\", role=c(\"cre\", \"aut\"), email=\"infinite.monkeys.with.keyboards@gmail.com\")", + "Description": "Vendors an assortment of useful header-only C++ libraries. Bioconductor packages can use these libraries in their own C++ code by LinkingTo this package without introducing any additional dependencies. The use of a central repository avoids duplicate vendoring of libraries across multiple R packages, and enables better coordination of version updates across cohorts of interdependent C++ libraries.", + "License": "MIT + file LICENSE", + "Suggests": [ + "knitr", + "rmarkdown", + "BiocStyle" ], - "Hash": "c1c423ca7149d9e7f55d1e609342c2bd" + "VignetteBuilder": "knitr", + "URL": "https://github.com/LTLA/assorthead", + "BugReports": "https://github.com/LTLA/assorthead/issues", + "Encoding": "UTF-8", + "biocViews": "SingleCell, QualityControl, Normalization, DataRepresentation, DataImport, DifferentialExpression, Alignment", + "git_url": "https://git.bioconductor.org/packages/assorthead", + "git_branch": "RELEASE_3_20", + "git_last_commit": "4aa4462", + "git_last_commit_date": "2024-11-27", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "no", + "Author": "Aaron Lun [cre, aut]", + "Maintainer": "Aaron Lun " }, - "bit": { - "Package": "bit", - "Version": "4.0.5", + "backports": { + "Package": "backports", + "Version": "1.5.0", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Type": "Package", + "Title": "Reimplementations of Functions Introduced Since R-3.0.0", + "Authors@R": "c( person(\"Michel\", \"Lang\", NULL, \"michellang@gmail.com\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0001-9754-0393\")), person(\"Duncan\", \"Murdoch\", NULL, \"murdoch.duncan@gmail.com\", role = c(\"aut\")), person(\"R Core Team\", role = \"aut\"))", + "Maintainer": "Michel Lang ", + "Description": "Functions introduced or changed since R v3.0.0 are re-implemented in this package. The backports are conditionally exported in order to let R resolve the function name to either the implemented backport, or the respective base version, if available. Package developers can make use of new functions or arguments by selectively importing specific backports to support older installations.", + "URL": "https://github.com/r-lib/backports", + "BugReports": "https://github.com/r-lib/backports/issues", + "License": "GPL-2 | GPL-3", + "NeedsCompilation": "yes", + "ByteCompile": "yes", + "Depends": [ + "R (>= 3.0.0)" ], - "Hash": "d242abec29412ce988848d0294b208fd" + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Author": "Michel Lang [cre, aut] (), Duncan Murdoch [aut], R Core Team [aut]", + "Repository": "CRAN" }, - "bit64": { - "Package": "bit64", - "Version": "4.0.5", + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "bit", - "methods", - "stats", - "utils" + "Title": "Tools for base64 encoding", + "Author": "Simon Urbanek ", + "Maintainer": "Simon Urbanek ", + "Depends": [ + "R (>= 2.9.0)" + ], + "Enhances": [ + "png" + ], + "Description": "This package provides tools for handling base64 encoding. It is more flexible than the orphaned base64 package.", + "License": "GPL-2 | GPL-3", + "URL": "http://www.rforge.net/base64enc", + "NeedsCompilation": "yes", + "Repository": "CRAN" + }, + "beachmat": { + "Package": "beachmat", + "Version": "2.22.0", + "Source": "Bioconductor", + "Date": "2024-10-25", + "Title": "Compiling Bioconductor to Handle Each Matrix Type", + "Encoding": "UTF-8", + "Authors@R": "c(person(\"Aaron\", \"Lun\", role = c(\"aut\", \"cre\"), email = \"infinite.monkeys.with.keyboards@gmail.com\"), person(\"Hervé\", \"Pagès\", role=\"aut\"), person(\"Mike\", \"Smith\", role=\"aut\"))", + "Imports": [ + "methods", + "DelayedArray (>= 0.27.2)", + "SparseArray", + "BiocGenerics", + "Matrix", + "Rcpp" + ], + "Suggests": [ + "testthat", + "BiocStyle", + "knitr", + "rmarkdown", + "rcmdcheck", + "BiocParallel", + "HDF5Array", + "beachmat.hdf5" ], - "Hash": "9fe98599ca456d6552421db0d6772d8f" + "LinkingTo": [ + "Rcpp", + "assorthead" + ], + "biocViews": "DataRepresentation, DataImport, Infrastructure", + "Description": "Provides a consistent C++ class interface for reading from a variety of commonly used matrix types. Ordinary matrices and several sparse/dense Matrix classes are directly supported, along with a subset of the delayed operations implemented in the DelayedArray package. All other matrix-like objects are supported by calling back into R.", + "License": "GPL-3", + "NeedsCompilation": "yes", + "VignetteBuilder": "knitr", + "SystemRequirements": "C++17", + "URL": "https://github.com/tatami-inc/beachmat", + "BugReports": "https://github.com/tatami-inc/beachmat/issues", + "RoxygenNote": "7.3.2", + "git_url": "https://git.bioconductor.org/packages/beachmat", + "git_branch": "RELEASE_3_20", + "git_last_commit": "a143856", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "Author": "Aaron Lun [aut, cre], Hervé Pagès [aut], Mike Smith [aut]", + "Maintainer": "Aaron Lun " + }, + "bit": { + "Package": "bit", + "Version": "4.6.0", + "Source": "Repository", + "Title": "Classes and Methods for Fast Memory-Efficient Boolean Selections", + "Authors@R": "c( person(\"Michael\", \"Chirico\", email = \"MichaelChirico4@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Jens\", \"Oehlschlägel\", role = \"aut\"), person(\"Brian\", \"Ripley\", role = \"ctb\") )", + "Depends": [ + "R (>= 3.4.0)" + ], + "Suggests": [ + "testthat (>= 3.0.0)", + "roxygen2", + "knitr", + "markdown", + "rmarkdown", + "microbenchmark", + "bit64 (>= 4.0.0)", + "ff (>= 4.0.0)" + ], + "Description": "Provided are classes for boolean and skewed boolean vectors, fast boolean methods, fast unique and non-unique integer sorting, fast set operations on sorted and unsorted sets of integers, and foundations for ff (range index, compression, chunked processing).", + "License": "GPL-2 | GPL-3", + "LazyLoad": "yes", + "ByteCompile": "yes", + "Encoding": "UTF-8", + "URL": "https://github.com/r-lib/bit", + "VignetteBuilder": "knitr, rmarkdown", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Author": "Michael Chirico [aut, cre], Jens Oehlschlägel [aut], Brian Ripley [ctb]", + "Maintainer": "Michael Chirico ", + "Repository": "CRAN" }, - "bitops": { - "Package": "bitops", - "Version": "1.0-7", + "bit64": { + "Package": "bit64", + "Version": "4.6.0-1", "Source": "Repository", - "Repository": "RSPM", - "Hash": "b7d8d8ee39869c18d8846a184dd8a1af" + "Title": "A S3 Class for Vectors of 64bit Integers", + "Authors@R": "c( person(\"Michael\", \"Chirico\", email = \"michaelchirico4@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Jens\", \"Oehlschlägel\", role = \"aut\"), person(\"Leonardo\", \"Silvestri\", role = \"ctb\"), person(\"Ofek\", \"Shilon\", role = \"ctb\") )", + "Depends": [ + "R (>= 3.4.0)", + "bit (>= 4.0.0)" + ], + "Description": "Package 'bit64' provides serializable S3 atomic 64bit (signed) integers. These are useful for handling database keys and exact counting in +-2^63. WARNING: do not use them as replacement for 32bit integers, integer64 are not supported for subscripting by R-core and they have different semantics when combined with double, e.g. integer64 + double => integer64. Class integer64 can be used in vectors, matrices, arrays and data.frames. Methods are available for coercion from and to logicals, integers, doubles, characters and factors as well as many elementwise and summary functions. Many fast algorithmic operations such as 'match' and 'order' support inter- active data exploration and manipulation and optionally leverage caching.", + "License": "GPL-2 | GPL-3", + "LazyLoad": "yes", + "ByteCompile": "yes", + "URL": "https://github.com/r-lib/bit64", + "Encoding": "UTF-8", + "Imports": [ + "graphics", + "methods", + "stats", + "utils" + ], + "Suggests": [ + "testthat (>= 3.0.3)", + "withr" + ], + "Config/testthat/edition": "3", + "Config/needs/development": "testthat", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Michael Chirico [aut, cre], Jens Oehlschlägel [aut], Leonardo Silvestri [ctb], Ofek Shilon [ctb]", + "Maintainer": "Michael Chirico ", + "Repository": "CRAN" }, "blob": { "Package": "blob", "Version": "1.2.4", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ + "Title": "A Simple S3 Class for Representing Vectors of Binary Data ('BLOBS')", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Kirill\", \"Müller\", , \"kirill@cynkra.com\", role = \"cre\"), person(\"RStudio\", role = c(\"cph\", \"fnd\")) )", + "Description": "R's raw vector is useful for storing a single binary object. What if you want to put a vector of them in a data frame? The 'blob' package provides the blob object, a list of raw vectors, suitable for use as a column in data frame.", + "License": "MIT + file LICENSE", + "URL": "https://blob.tidyverse.org, https://github.com/tidyverse/blob", + "BugReports": "https://github.com/tidyverse/blob/issues", + "Imports": [ "methods", "rlang", - "vctrs" + "vctrs (>= 0.2.1)" + ], + "Suggests": [ + "covr", + "crayon", + "pillar (>= 1.2.1)", + "testthat" + ], + "Config/autostyle/scope": "line_breaks", + "Config/autostyle/strict": "false", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut], Kirill Müller [cre], RStudio [cph, fnd]", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "boot": { + "Package": "boot", + "Version": "1.3-31", + "Source": "Repository", + "Priority": "recommended", + "Date": "2024-08-28", + "Authors@R": "c(person(\"Angelo\", \"Canty\", role = \"aut\", email = \"cantya@mcmaster.ca\", comment = \"author of original code for S\"), person(\"Brian\", \"Ripley\", role = c(\"aut\", \"trl\"), email = \"ripley@stats.ox.ac.uk\", comment = \"conversion to R, maintainer 1999--2022, author of parallel support\"), person(\"Alessandra R.\", \"Brazzale\", role = c(\"ctb\", \"cre\"), email = \"brazzale@stat.unipd.it\", comment = \"minor bug fixes\"))", + "Maintainer": "Alessandra R. Brazzale ", + "Note": "Maintainers are not available to give advice on using a package they did not author.", + "Description": "Functions and datasets for bootstrapping from the book \"Bootstrap Methods and Their Application\" by A. C. Davison and D. V. Hinkley (1997, CUP), originally written by Angelo Canty for S.", + "Title": "Bootstrap Functions (Originally by Angelo Canty for S)", + "Depends": [ + "R (>= 3.0.0)", + "graphics", + "stats" + ], + "Suggests": [ + "MASS", + "survival" + ], + "LazyData": "yes", + "ByteCompile": "yes", + "License": "Unlimited", + "NeedsCompilation": "no", + "Author": "Angelo Canty [aut] (author of original code for S), Brian Ripley [aut, trl] (conversion to R, maintainer 1999--2022, author of parallel support), Alessandra R. Brazzale [ctb, cre] (minor bug fixes)", + "Repository": "CRAN" + }, + "broom": { + "Package": "broom", + "Version": "1.0.8", + "Source": "Repository", + "Type": "Package", + "Title": "Convert Statistical Objects into Tidy Tibbles", + "Authors@R": "c(person(given = \"David\", family = \"Robinson\", role = \"aut\", email = \"admiral.david@gmail.com\"), person(given = \"Alex\", family = \"Hayes\", role = \"aut\", email = \"alexpghayes@gmail.com\", comment = c(ORCID = \"0000-0002-4985-5160\")), person(given = \"Simon\", family = \"Couch\", role = c(\"aut\", \"cre\"), email = \"simon.couch@posit.co\", comment = c(ORCID = \"0000-0001-5676-5107\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(given = \"Indrajeet\", family = \"Patil\", role = \"ctb\", email = \"patilindrajeet.science@gmail.com\", comment = c(ORCID = \"0000-0003-1995-6531\")), person(given = \"Derek\", family = \"Chiu\", role = \"ctb\", email = \"dchiu@bccrc.ca\"), person(given = \"Matthieu\", family = \"Gomez\", role = \"ctb\", email = \"mattg@princeton.edu\"), person(given = \"Boris\", family = \"Demeshev\", role = \"ctb\", email = \"boris.demeshev@gmail.com\"), person(given = \"Dieter\", family = \"Menne\", role = \"ctb\", email = \"dieter.menne@menne-biomed.de\"), person(given = \"Benjamin\", family = \"Nutter\", role = \"ctb\", email = \"nutter@battelle.org\"), person(given = \"Luke\", family = \"Johnston\", role = \"ctb\", email = \"luke.johnston@mail.utoronto.ca\"), person(given = \"Ben\", family = \"Bolker\", role = \"ctb\", email = \"bolker@mcmaster.ca\"), person(given = \"Francois\", family = \"Briatte\", role = \"ctb\", email = \"f.briatte@gmail.com\"), person(given = \"Jeffrey\", family = \"Arnold\", role = \"ctb\", email = \"jeffrey.arnold@gmail.com\"), person(given = \"Jonah\", family = \"Gabry\", role = \"ctb\", email = \"jsg2201@columbia.edu\"), person(given = \"Luciano\", family = \"Selzer\", role = \"ctb\", email = \"luciano.selzer@gmail.com\"), person(given = \"Gavin\", family = \"Simpson\", role = \"ctb\", email = \"ucfagls@gmail.com\"), person(given = \"Jens\", family = \"Preussner\", role = \"ctb\", email = \" jens.preussner@mpi-bn.mpg.de\"), person(given = \"Jay\", family = \"Hesselberth\", role = \"ctb\", email = \"jay.hesselberth@gmail.com\"), person(given = \"Hadley\", family = \"Wickham\", role = \"ctb\", email = \"hadley@posit.co\"), person(given = \"Matthew\", family = \"Lincoln\", role = \"ctb\", email = \"matthew.d.lincoln@gmail.com\"), person(given = \"Alessandro\", family = \"Gasparini\", role = \"ctb\", email = \"ag475@leicester.ac.uk\"), person(given = \"Lukasz\", family = \"Komsta\", role = \"ctb\", email = \"lukasz.komsta@umlub.pl\"), person(given = \"Frederick\", family = \"Novometsky\", role = \"ctb\"), person(given = \"Wilson\", family = \"Freitas\", role = \"ctb\"), person(given = \"Michelle\", family = \"Evans\", role = \"ctb\"), person(given = \"Jason Cory\", family = \"Brunson\", role = \"ctb\", email = \"cornelioid@gmail.com\"), person(given = \"Simon\", family = \"Jackson\", role = \"ctb\", email = \"drsimonjackson@gmail.com\"), person(given = \"Ben\", family = \"Whalley\", role = \"ctb\", email = \"ben.whalley@plymouth.ac.uk\"), person(given = \"Karissa\", family = \"Whiting\", role = \"ctb\", email = \"karissa.whiting@gmail.com\"), person(given = \"Yves\", family = \"Rosseel\", role = \"ctb\", email = \"yrosseel@gmail.com\"), person(given = \"Michael\", family = \"Kuehn\", role = \"ctb\", email = \"mkuehn10@gmail.com\"), person(given = \"Jorge\", family = \"Cimentada\", role = \"ctb\", email = \"cimentadaj@gmail.com\"), person(given = \"Erle\", family = \"Holgersen\", role = \"ctb\", email = \"erle.holgersen@gmail.com\"), person(given = \"Karl\", family = \"Dunkle Werner\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0523-7309\")), person(given = \"Ethan\", family = \"Christensen\", role = \"ctb\", email = \"christensen.ej@gmail.com\"), person(given = \"Steven\", family = \"Pav\", role = \"ctb\", email = \"shabbychef@gmail.com\"), person(given = \"Paul\", family = \"PJ\", role = \"ctb\", email = \"pjpaul.stephens@gmail.com\"), person(given = \"Ben\", family = \"Schneider\", role = \"ctb\", email = \"benjamin.julius.schneider@gmail.com\"), person(given = \"Patrick\", family = \"Kennedy\", role = \"ctb\", email = \"pkqstr@protonmail.com\"), person(given = \"Lily\", family = \"Medina\", role = \"ctb\", email = \"lilymiru@gmail.com\"), person(given = \"Brian\", family = \"Fannin\", role = \"ctb\", email = \"captain@pirategrunt.com\"), person(given = \"Jason\", family = \"Muhlenkamp\", role = \"ctb\", email = \"jason.muhlenkamp@gmail.com\"), person(given = \"Matt\", family = \"Lehman\", role = \"ctb\"), person(given = \"Bill\", family = \"Denney\", role = \"ctb\", email = \"wdenney@humanpredictions.com\", comment = c(ORCID = \"0000-0002-5759-428X\")), person(given = \"Nic\", family = \"Crane\", role = \"ctb\"), person(given = \"Andrew\", family = \"Bates\", role = \"ctb\"), person(given = \"Vincent\", family = \"Arel-Bundock\", role = \"ctb\", email = \"vincent.arel-bundock@umontreal.ca\", comment = c(ORCID = \"0000-0003-2042-7063\")), person(given = \"Hideaki\", family = \"Hayashi\", role = \"ctb\"), person(given = \"Luis\", family = \"Tobalina\", role = \"ctb\"), person(given = \"Annie\", family = \"Wang\", role = \"ctb\", email = \"anniewang.uc@gmail.com\"), person(given = \"Wei Yang\", family = \"Tham\", role = \"ctb\", email = \"weiyang.tham@gmail.com\"), person(given = \"Clara\", family = \"Wang\", role = \"ctb\", email = \"clara.wang.94@gmail.com\"), person(given = \"Abby\", family = \"Smith\", role = \"ctb\", email = \"als1@u.northwestern.edu\", comment = c(ORCID = \"0000-0002-3207-0375\")), person(given = \"Jasper\", family = \"Cooper\", role = \"ctb\", email = \"jaspercooper@gmail.com\", comment = c(ORCID = \"0000-0002-8639-3188\")), person(given = \"E Auden\", family = \"Krauska\", role = \"ctb\", email = \"krauskae@gmail.com\", comment = c(ORCID = \"0000-0002-1466-5850\")), person(given = \"Alex\", family = \"Wang\", role = \"ctb\", email = \"x249wang@uwaterloo.ca\"), person(given = \"Malcolm\", family = \"Barrett\", role = \"ctb\", email = \"malcolmbarrett@gmail.com\", comment = c(ORCID = \"0000-0003-0299-5825\")), person(given = \"Charles\", family = \"Gray\", role = \"ctb\", email = \"charlestigray@gmail.com\", comment = c(ORCID = \"0000-0002-9978-011X\")), person(given = \"Jared\", family = \"Wilber\", role = \"ctb\"), person(given = \"Vilmantas\", family = \"Gegzna\", role = \"ctb\", email = \"GegznaV@gmail.com\", comment = c(ORCID = \"0000-0002-9500-5167\")), person(given = \"Eduard\", family = \"Szoecs\", role = \"ctb\", email = \"eduardszoecs@gmail.com\"), person(given = \"Frederik\", family = \"Aust\", role = \"ctb\", email = \"frederik.aust@uni-koeln.de\", comment = c(ORCID = \"0000-0003-4900-788X\")), person(given = \"Angus\", family = \"Moore\", role = \"ctb\", email = \"angusmoore9@gmail.com\"), person(given = \"Nick\", family = \"Williams\", role = \"ctb\", email = \"ntwilliams.personal@gmail.com\"), person(given = \"Marius\", family = \"Barth\", role = \"ctb\", email = \"marius.barth.uni.koeln@gmail.com\", comment = c(ORCID = \"0000-0002-3421-6665\")), person(given = \"Bruna\", family = \"Wundervald\", role = \"ctb\", email = \"brunadaviesw@gmail.com\", comment = c(ORCID = \"0000-0001-8163-220X\")), person(given = \"Joyce\", family = \"Cahoon\", role = \"ctb\", email = \"joyceyu48@gmail.com\", comment = c(ORCID = \"0000-0001-7217-4702\")), person(given = \"Grant\", family = \"McDermott\", role = \"ctb\", email = \"grantmcd@uoregon.edu\", comment = c(ORCID = \"0000-0001-7883-8573\")), person(given = \"Kevin\", family = \"Zarca\", role = \"ctb\", email = \"kevin.zarca@gmail.com\"), person(given = \"Shiro\", family = \"Kuriwaki\", role = \"ctb\", email = \"shirokuriwaki@gmail.com\", comment = c(ORCID = \"0000-0002-5687-2647\")), person(given = \"Lukas\", family = \"Wallrich\", role = \"ctb\", email = \"lukas.wallrich@gmail.com\", comment = c(ORCID = \"0000-0003-2121-5177\")), person(given = \"James\", family = \"Martherus\", role = \"ctb\", email = \"james@martherus.com\", comment = c(ORCID = \"0000-0002-8285-3300\")), person(given = \"Chuliang\", family = \"Xiao\", role = \"ctb\", email = \"cxiao@umich.edu\", comment = c(ORCID = \"0000-0002-8466-9398\")), person(given = \"Joseph\", family = \"Larmarange\", role = \"ctb\", email = \"joseph@larmarange.net\"), person(given = \"Max\", family = \"Kuhn\", role = \"ctb\", email = \"max@posit.co\"), person(given = \"Michal\", family = \"Bojanowski\", role = \"ctb\", email = \"michal2992@gmail.com\"), person(given = \"Hakon\", family = \"Malmedal\", role = \"ctb\", email = \"hmalmedal@gmail.com\"), person(given = \"Clara\", family = \"Wang\", role = \"ctb\"), person(given = \"Sergio\", family = \"Oller\", role = \"ctb\", email = \"sergioller@gmail.com\"), person(given = \"Luke\", family = \"Sonnet\", role = \"ctb\", email = \"luke.sonnet@gmail.com\"), person(given = \"Jim\", family = \"Hester\", role = \"ctb\", email = \"jim.hester@posit.co\"), person(given = \"Ben\", family = \"Schneider\", role = \"ctb\", email = \"benjamin.julius.schneider@gmail.com\"), person(given = \"Bernie\", family = \"Gray\", role = \"ctb\", email = \"bfgray3@gmail.com\", comment = c(ORCID = \"0000-0001-9190-6032\")), person(given = \"Mara\", family = \"Averick\", role = \"ctb\", email = \"mara@posit.co\"), person(given = \"Aaron\", family = \"Jacobs\", role = \"ctb\", email = \"atheriel@gmail.com\"), person(given = \"Andreas\", family = \"Bender\", role = \"ctb\", email = \"bender.at.R@gmail.com\"), person(given = \"Sven\", family = \"Templer\", role = \"ctb\", email = \"sven.templer@gmail.com\"), person(given = \"Paul-Christian\", family = \"Buerkner\", role = \"ctb\", email = \"paul.buerkner@gmail.com\"), person(given = \"Matthew\", family = \"Kay\", role = \"ctb\", email = \"mjskay@umich.edu\"), person(given = \"Erwan\", family = \"Le Pennec\", role = \"ctb\", email = \"lepennec@gmail.com\"), person(given = \"Johan\", family = \"Junkka\", role = \"ctb\", email = \"johan.junkka@umu.se\"), person(given = \"Hao\", family = \"Zhu\", role = \"ctb\", email = \"haozhu233@gmail.com\"), person(given = \"Benjamin\", family = \"Soltoff\", role = \"ctb\", email = \"soltoffbc@uchicago.edu\"), person(given = \"Zoe\", family = \"Wilkinson Saldana\", role = \"ctb\", email = \"zoewsaldana@gmail.com\"), person(given = \"Tyler\", family = \"Littlefield\", role = \"ctb\", email = \"tylurp1@gmail.com\"), person(given = \"Charles T.\", family = \"Gray\", role = \"ctb\", email = \"charlestigray@gmail.com\"), person(given = \"Shabbh E.\", family = \"Banks\", role = \"ctb\"), person(given = \"Serina\", family = \"Robinson\", role = \"ctb\", email = \"robi0916@umn.edu\"), person(given = \"Roger\", family = \"Bivand\", role = \"ctb\", email = \"Roger.Bivand@nhh.no\"), person(given = \"Riinu\", family = \"Ots\", role = \"ctb\", email = \"riinuots@gmail.com\"), person(given = \"Nicholas\", family = \"Williams\", role = \"ctb\", email = \"ntwilliams.personal@gmail.com\"), person(given = \"Nina\", family = \"Jakobsen\", role = \"ctb\"), person(given = \"Michael\", family = \"Weylandt\", role = \"ctb\", email = \"michael.weylandt@gmail.com\"), person(given = \"Lisa\", family = \"Lendway\", role = \"ctb\", email = \"llendway@macalester.edu\"), person(given = \"Karl\", family = \"Hailperin\", role = \"ctb\", email = \"khailper@gmail.com\"), person(given = \"Josue\", family = \"Rodriguez\", role = \"ctb\", email = \"jerrodriguez@ucdavis.edu\"), person(given = \"Jenny\", family = \"Bryan\", role = \"ctb\", email = \"jenny@posit.co\"), person(given = \"Chris\", family = \"Jarvis\", role = \"ctb\", email = \"Christopher1.jarvis@gmail.com\"), person(given = \"Greg\", family = \"Macfarlane\", role = \"ctb\", email = \"gregmacfarlane@gmail.com\"), person(given = \"Brian\", family = \"Mannakee\", role = \"ctb\", email = \"bmannakee@gmail.com\"), person(given = \"Drew\", family = \"Tyre\", role = \"ctb\", email = \"atyre2@unl.edu\"), person(given = \"Shreyas\", family = \"Singh\", role = \"ctb\", email = \"shreyas.singh.298@gmail.com\"), person(given = \"Laurens\", family = \"Geffert\", role = \"ctb\", email = \"laurensgeffert@gmail.com\"), person(given = \"Hong\", family = \"Ooi\", role = \"ctb\", email = \"hongooi@microsoft.com\"), person(given = \"Henrik\", family = \"Bengtsson\", role = \"ctb\", email = \"henrikb@braju.com\"), person(given = \"Eduard\", family = \"Szocs\", role = \"ctb\", email = \"eduardszoecs@gmail.com\"), person(given = \"David\", family = \"Hugh-Jones\", role = \"ctb\", email = \"davidhughjones@gmail.com\"), person(given = \"Matthieu\", family = \"Stigler\", role = \"ctb\", email = \"Matthieu.Stigler@gmail.com\"), person(given = \"Hugo\", family = \"Tavares\", role = \"ctb\", email = \"hm533@cam.ac.uk\", comment = c(ORCID = \"0000-0001-9373-2726\")), person(given = \"R. Willem\", family = \"Vervoort\", role = \"ctb\", email = \"Willemvervoort@gmail.com\"), person(given = \"Brenton M.\", family = \"Wiernik\", role = \"ctb\", email = \"brenton@wiernik.org\"), person(given = \"Josh\", family = \"Yamamoto\", role = \"ctb\", email = \"joshuayamamoto5@gmail.com\"), person(given = \"Jasme\", family = \"Lee\", role = \"ctb\"), person(given = \"Taren\", family = \"Sanders\", role = \"ctb\", email = \"taren.sanders@acu.edu.au\", comment = c(ORCID = \"0000-0002-4504-6008\")), person(given = \"Ilaria\", family = \"Prosdocimi\", role = \"ctb\", email = \"prosdocimi.ilaria@gmail.com\", comment = c(ORCID = \"0000-0001-8565-094X\")), person(given = \"Daniel D.\", family = \"Sjoberg\", role = \"ctb\", email = \"danield.sjoberg@gmail.com\", comment = c(ORCID = \"0000-0003-0862-2018\")), person(given = \"Alex\", family = \"Reinhart\", role = \"ctb\", email = \"areinhar@stat.cmu.edu\", comment = c(ORCID = \"0000-0002-6658-514X\")))", + "Description": "Summarizes key information about statistical objects in tidy tibbles. This makes it easy to report results, create plots and consistently work with large numbers of models at once. Broom provides three verbs that each provide different types of information about a model. tidy() summarizes information about model components such as coefficients of a regression. glance() reports information about an entire model, such as goodness of fit measures like AIC and BIC. augment() adds information about individual observations to a dataset, such as fitted values or influence measures.", + "License": "MIT + file LICENSE", + "URL": "https://broom.tidymodels.org/, https://github.com/tidymodels/broom", + "BugReports": "https://github.com/tidymodels/broom/issues", + "Depends": [ + "R (>= 3.5)" + ], + "Imports": [ + "backports", + "cli", + "dplyr (>= 1.0.0)", + "generics (>= 0.0.2)", + "glue", + "lifecycle", + "purrr", + "rlang (>= 1.1.0)", + "stringr", + "tibble (>= 3.0.0)", + "tidyr (>= 1.0.0)" + ], + "Suggests": [ + "AER", + "AUC", + "bbmle", + "betareg (>= 3.2-1)", + "biglm", + "binGroup", + "boot", + "btergm (>= 1.10.6)", + "car (>= 3.1-2)", + "carData", + "caret", + "cluster", + "cmprsk", + "coda", + "covr", + "drc", + "e1071", + "emmeans", + "epiR", + "ergm (>= 3.10.4)", + "fixest (>= 0.9.0)", + "gam (>= 1.15)", + "gee", + "geepack", + "ggplot2", + "glmnet", + "glmnetUtils", + "gmm", + "Hmisc", + "irlba", + "interp", + "joineRML", + "Kendall", + "knitr", + "ks", + "Lahman", + "lavaan (>= 0.6.18)", + "leaps", + "lfe", + "lm.beta", + "lme4", + "lmodel2", + "lmtest (>= 0.9.38)", + "lsmeans", + "maps", + "margins", + "MASS", + "mclust", + "mediation", + "metafor", + "mfx", + "mgcv", + "mlogit", + "modeldata", + "modeltests (>= 0.1.6)", + "muhaz", + "multcomp", + "network", + "nnet", + "ordinal", + "plm", + "poLCA", + "psych", + "quantreg", + "rmarkdown", + "robust", + "robustbase", + "rsample", + "sandwich", + "spdep (>= 1.1)", + "spatialreg", + "speedglm", + "spelling", + "survey", + "survival (>= 3.6-4)", + "systemfit", + "testthat (>= 3.0.0)", + "tseries", + "vars", + "zoo" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Language": "en-US", + "Collate": "'aaa-documentation-helper.R' 'null-and-default.R' 'aer.R' 'auc.R' 'base.R' 'bbmle.R' 'betareg.R' 'biglm.R' 'bingroup.R' 'boot.R' 'broom-package.R' 'broom.R' 'btergm.R' 'car.R' 'caret.R' 'cluster.R' 'cmprsk.R' 'data-frame.R' 'deprecated-0-7-0.R' 'drc.R' 'emmeans.R' 'epiR.R' 'ergm.R' 'fixest.R' 'gam.R' 'geepack.R' 'glmnet-cv-glmnet.R' 'glmnet-glmnet.R' 'gmm.R' 'hmisc.R' 'import-standalone-obj-type.R' 'import-standalone-types-check.R' 'joinerml.R' 'kendall.R' 'ks.R' 'lavaan.R' 'leaps.R' 'lfe.R' 'list-irlba.R' 'list-optim.R' 'list-svd.R' 'list-xyz.R' 'list.R' 'lm-beta.R' 'lmodel2.R' 'lmtest.R' 'maps.R' 'margins.R' 'mass-fitdistr.R' 'mass-negbin.R' 'mass-polr.R' 'mass-ridgelm.R' 'stats-lm.R' 'mass-rlm.R' 'mclust.R' 'mediation.R' 'metafor.R' 'mfx.R' 'mgcv.R' 'mlogit.R' 'muhaz.R' 'multcomp.R' 'nnet.R' 'nobs.R' 'ordinal-clm.R' 'ordinal-clmm.R' 'plm.R' 'polca.R' 'psych.R' 'stats-nls.R' 'quantreg-nlrq.R' 'quantreg-rq.R' 'quantreg-rqs.R' 'robust-glmrob.R' 'robust-lmrob.R' 'robustbase-glmrob.R' 'robustbase-lmrob.R' 'sp.R' 'spdep.R' 'speedglm-speedglm.R' 'speedglm-speedlm.R' 'stats-anova.R' 'stats-arima.R' 'stats-decompose.R' 'stats-factanal.R' 'stats-glm.R' 'stats-htest.R' 'stats-kmeans.R' 'stats-loess.R' 'stats-mlm.R' 'stats-prcomp.R' 'stats-smooth.spline.R' 'stats-summary-lm.R' 'stats-time-series.R' 'survey.R' 'survival-aareg.R' 'survival-cch.R' 'survival-coxph.R' 'survival-pyears.R' 'survival-survdiff.R' 'survival-survexp.R' 'survival-survfit.R' 'survival-survreg.R' 'systemfit.R' 'tseries.R' 'utilities.R' 'vars.R' 'zoo.R' 'zzz.R'", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "David Robinson [aut], Alex Hayes [aut] (), Simon Couch [aut, cre] (), Posit Software, PBC [cph, fnd], Indrajeet Patil [ctb] (), Derek Chiu [ctb], Matthieu Gomez [ctb], Boris Demeshev [ctb], Dieter Menne [ctb], Benjamin Nutter [ctb], Luke Johnston [ctb], Ben Bolker [ctb], Francois Briatte [ctb], Jeffrey Arnold [ctb], Jonah Gabry [ctb], Luciano Selzer [ctb], Gavin Simpson [ctb], Jens Preussner [ctb], Jay Hesselberth [ctb], Hadley Wickham [ctb], Matthew Lincoln [ctb], Alessandro Gasparini [ctb], Lukasz Komsta [ctb], Frederick Novometsky [ctb], Wilson Freitas [ctb], Michelle Evans [ctb], Jason Cory Brunson [ctb], Simon Jackson [ctb], Ben Whalley [ctb], Karissa Whiting [ctb], Yves Rosseel [ctb], Michael Kuehn [ctb], Jorge Cimentada [ctb], Erle Holgersen [ctb], Karl Dunkle Werner [ctb] (), Ethan Christensen [ctb], Steven Pav [ctb], Paul PJ [ctb], Ben Schneider [ctb], Patrick Kennedy [ctb], Lily Medina [ctb], Brian Fannin [ctb], Jason Muhlenkamp [ctb], Matt Lehman [ctb], Bill Denney [ctb] (), Nic Crane [ctb], Andrew Bates [ctb], Vincent Arel-Bundock [ctb] (), Hideaki Hayashi [ctb], Luis Tobalina [ctb], Annie Wang [ctb], Wei Yang Tham [ctb], Clara Wang [ctb], Abby Smith [ctb] (), Jasper Cooper [ctb] (), E Auden Krauska [ctb] (), Alex Wang [ctb], Malcolm Barrett [ctb] (), Charles Gray [ctb] (), Jared Wilber [ctb], Vilmantas Gegzna [ctb] (), Eduard Szoecs [ctb], Frederik Aust [ctb] (), Angus Moore [ctb], Nick Williams [ctb], Marius Barth [ctb] (), Bruna Wundervald [ctb] (), Joyce Cahoon [ctb] (), Grant McDermott [ctb] (), Kevin Zarca [ctb], Shiro Kuriwaki [ctb] (), Lukas Wallrich [ctb] (), James Martherus [ctb] (), Chuliang Xiao [ctb] (), Joseph Larmarange [ctb], Max Kuhn [ctb], Michal Bojanowski [ctb], Hakon Malmedal [ctb], Clara Wang [ctb], Sergio Oller [ctb], Luke Sonnet [ctb], Jim Hester [ctb], Ben Schneider [ctb], Bernie Gray [ctb] (), Mara Averick [ctb], Aaron Jacobs [ctb], Andreas Bender [ctb], Sven Templer [ctb], Paul-Christian Buerkner [ctb], Matthew Kay [ctb], Erwan Le Pennec [ctb], Johan Junkka [ctb], Hao Zhu [ctb], Benjamin Soltoff [ctb], Zoe Wilkinson Saldana [ctb], Tyler Littlefield [ctb], Charles T. Gray [ctb], Shabbh E. Banks [ctb], Serina Robinson [ctb], Roger Bivand [ctb], Riinu Ots [ctb], Nicholas Williams [ctb], Nina Jakobsen [ctb], Michael Weylandt [ctb], Lisa Lendway [ctb], Karl Hailperin [ctb], Josue Rodriguez [ctb], Jenny Bryan [ctb], Chris Jarvis [ctb], Greg Macfarlane [ctb], Brian Mannakee [ctb], Drew Tyre [ctb], Shreyas Singh [ctb], Laurens Geffert [ctb], Hong Ooi [ctb], Henrik Bengtsson [ctb], Eduard Szocs [ctb], David Hugh-Jones [ctb], Matthieu Stigler [ctb], Hugo Tavares [ctb] (), R. Willem Vervoort [ctb], Brenton M. Wiernik [ctb], Josh Yamamoto [ctb], Jasme Lee [ctb], Taren Sanders [ctb] (), Ilaria Prosdocimi [ctb] (), Daniel D. Sjoberg [ctb] (), Alex Reinhart [ctb] ()", + "Maintainer": "Simon Couch ", + "Repository": "CRAN" + }, + "bslib": { + "Package": "bslib", + "Version": "0.9.0", + "Source": "Repository", + "Title": "Custom 'Bootstrap' 'Sass' Themes for 'shiny' and 'rmarkdown'", + "Authors@R": "c( person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Garrick\", \"Aden-Buie\", , \"garrick@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0002-7111-0077\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(, \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Javi\", \"Aguilar\", role = c(\"ctb\", \"cph\"), comment = \"Bootstrap colorpicker library\"), person(\"Thomas\", \"Park\", role = c(\"ctb\", \"cph\"), comment = \"Bootswatch library\"), person(, \"PayPal\", role = c(\"ctb\", \"cph\"), comment = \"Bootstrap accessibility plugin\") )", + "Description": "Simplifies custom 'CSS' styling of both 'shiny' and 'rmarkdown' via 'Bootstrap' 'Sass'. Supports 'Bootstrap' 3, 4 and 5 as well as their various 'Bootswatch' themes. An interactive widget is also provided for previewing themes in real time.", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/bslib/, https://github.com/rstudio/bslib", + "BugReports": "https://github.com/rstudio/bslib/issues", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "base64enc", + "cachem", + "fastmap (>= 1.1.1)", + "grDevices", + "htmltools (>= 0.5.8)", + "jquerylib (>= 0.1.3)", + "jsonlite", + "lifecycle", + "memoise (>= 2.0.1)", + "mime", + "rlang", + "sass (>= 0.4.9)" + ], + "Suggests": [ + "bsicons", + "curl", + "fontawesome", + "future", + "ggplot2", + "knitr", + "magrittr", + "rappdirs", + "rmarkdown (>= 2.7)", + "shiny (> 1.8.1)", + "testthat", + "thematic", + "tools", + "utils", + "withr", + "yaml" ], - "Hash": "40415719b5a479b87949f3aa0aee737c" + "Config/Needs/deploy": "BH, chiflights22, colourpicker, commonmark, cpp11, cpsievert/chiflights22, cpsievert/histoslider, dplyr, DT, ggplot2, ggridges, gt, hexbin, histoslider, htmlwidgets, lattice, leaflet, lubridate, markdown, modelr, plotly, reactable, reshape2, rprojroot, rsconnect, rstudio/shiny, scales, styler, tibble", + "Config/Needs/routine": "chromote, desc, renv", + "Config/Needs/website": "brio, crosstalk, dplyr, DT, ggplot2, glue, htmlwidgets, leaflet, lorem, palmerpenguins, plotly, purrr, rprojroot, rstudio/htmltools, scales, stringr, tidyr, webshot2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "zzzz-bs-sass, fonts, zzz-precompile, theme-*, rmd-*", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Collate": "'accordion.R' 'breakpoints.R' 'bs-current-theme.R' 'bs-dependencies.R' 'bs-global.R' 'bs-remove.R' 'bs-theme-layers.R' 'bs-theme-preset-bootswatch.R' 'bs-theme-preset-brand.R' 'bs-theme-preset-builtin.R' 'bs-theme-preset.R' 'utils.R' 'bs-theme-preview.R' 'bs-theme-update.R' 'bs-theme.R' 'bslib-package.R' 'buttons.R' 'card.R' 'deprecated.R' 'files.R' 'fill.R' 'imports.R' 'input-dark-mode.R' 'input-switch.R' 'layout.R' 'nav-items.R' 'nav-update.R' 'navbar_options.R' 'navs-legacy.R' 'navs.R' 'onLoad.R' 'page.R' 'popover.R' 'precompiled.R' 'print.R' 'shiny-devmode.R' 'sidebar.R' 'staticimports.R' 'tooltip.R' 'utils-deps.R' 'utils-shiny.R' 'utils-tags.R' 'value-box.R' 'version-default.R' 'versions.R'", + "NeedsCompilation": "no", + "Author": "Carson Sievert [aut, cre] (), Joe Cheng [aut], Garrick Aden-Buie [aut] (), Posit Software, PBC [cph, fnd], Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Javi Aguilar [ctb, cph] (Bootstrap colorpicker library), Thomas Park [ctb, cph] (Bootswatch library), PayPal [ctb, cph] (Bootstrap accessibility plugin)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" }, "cachem": { "Package": "cachem", - "Version": "1.0.8", + "Version": "1.1.0", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "fastmap", - "rlang" + "Title": "Cache R Objects with Automatic Pruning", + "Description": "Key-value stores with automatic pruning. Caches can limit either their total size or the age of the oldest object (or both), automatically pruning objects to maintain the constraints.", + "Authors@R": "c( person(\"Winston\", \"Chang\", , \"winston@posit.co\", c(\"aut\", \"cre\")), person(family = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")))", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "ByteCompile": "true", + "URL": "https://cachem.r-lib.org/, https://github.com/r-lib/cachem", + "Imports": [ + "rlang", + "fastmap (>= 1.2.0)" + ], + "Suggests": [ + "testthat" + ], + "RoxygenNote": "7.2.3", + "Config/Needs/routine": "lobstr", + "Config/Needs/website": "pkgdown", + "NeedsCompilation": "yes", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "car": { + "Package": "car", + "Version": "3.1-3", + "Source": "Repository", + "Date": "2024-09-23", + "Title": "Companion to Applied Regression", + "Authors@R": "c(person(\"John\", \"Fox\", role = c(\"aut\", \"cre\"), email = \"jfox@mcmaster.ca\"), person(\"Sanford\", \"Weisberg\", role = \"aut\", email = \"sandy@umn.edu\"), person(\"Brad\", \"Price\", role = \"aut\", email = \"brad.price@mail.wvu.edu\"), person(\"Daniel\", \"Adler\", role=\"ctb\"), person(\"Douglas\", \"Bates\", role = \"ctb\"), person(\"Gabriel\", \"Baud-Bovy\", role = \"ctb\"), person(\"Ben\", \"Bolker\", role=\"ctb\"), person(\"Steve\", \"Ellison\", role=\"ctb\"), person(\"David\", \"Firth\", role = \"ctb\"), person(\"Michael\", \"Friendly\", role = \"ctb\"), person(\"Gregor\", \"Gorjanc\", role = \"ctb\"), person(\"Spencer\", \"Graves\", role = \"ctb\"), person(\"Richard\", \"Heiberger\", role = \"ctb\"), person(\"Pavel\", \"Krivitsky\", role = \"ctb\"), person(\"Rafael\", \"Laboissiere\", role = \"ctb\"), person(\"Martin\", \"Maechler\", role=\"ctb\"), person(\"Georges\", \"Monette\", role = \"ctb\"), person(\"Duncan\", \"Murdoch\", role=\"ctb\"), person(\"Henric\", \"Nilsson\", role = \"ctb\"), person(\"Derek\", \"Ogle\", role = \"ctb\"), person(\"Brian\", \"Ripley\", role = \"ctb\"), person(\"Tom\", \"Short\", role=\"ctb\"), person(\"William\", \"Venables\", role = \"ctb\"), person(\"Steve\", \"Walker\", role=\"ctb\"), person(\"David\", \"Winsemius\", role=\"ctb\"), person(\"Achim\", \"Zeileis\", role = \"ctb\"), person(\"R-Core\", role=\"ctb\"))", + "Depends": [ + "R (>= 3.5.0)", + "carData (>= 3.0-0)" + ], + "Imports": [ + "abind", + "Formula", + "MASS", + "mgcv", + "nnet", + "pbkrtest (>= 0.4-4)", + "quantreg", + "grDevices", + "utils", + "stats", + "graphics", + "lme4 (>= 1.1-27.1)", + "nlme", + "scales" + ], + "Suggests": [ + "alr4", + "boot", + "coxme", + "effects", + "knitr", + "leaps", + "lmtest", + "Matrix", + "MatrixModels", + "ordinal", + "plotrix", + "mvtnorm", + "rgl (>= 0.111.3)", + "rio", + "sandwich", + "SparseM", + "survival", + "survey" + ], + "ByteCompile": "yes", + "LazyLoad": "yes", + "Description": "Functions to Accompany J. Fox and S. Weisberg, An R Companion to Applied Regression, Third Edition, Sage, 2019.", + "License": "GPL (>= 2)", + "URL": "https://r-forge.r-project.org/projects/car/, https://CRAN.R-project.org/package=car, https://www.john-fox.ca/Companion/index.html", + "VignetteBuilder": "knitr", + "NeedsCompilation": "no", + "Author": "John Fox [aut, cre], Sanford Weisberg [aut], Brad Price [aut], Daniel Adler [ctb], Douglas Bates [ctb], Gabriel Baud-Bovy [ctb], Ben Bolker [ctb], Steve Ellison [ctb], David Firth [ctb], Michael Friendly [ctb], Gregor Gorjanc [ctb], Spencer Graves [ctb], Richard Heiberger [ctb], Pavel Krivitsky [ctb], Rafael Laboissiere [ctb], Martin Maechler [ctb], Georges Monette [ctb], Duncan Murdoch [ctb], Henric Nilsson [ctb], Derek Ogle [ctb], Brian Ripley [ctb], Tom Short [ctb], William Venables [ctb], Steve Walker [ctb], David Winsemius [ctb], Achim Zeileis [ctb], R-Core [ctb]", + "Maintainer": "John Fox ", + "Repository": "CRAN" + }, + "carData": { + "Package": "carData", + "Version": "3.0-5", + "Source": "Repository", + "Date": "2022-01-05", + "Title": "Companion to Applied Regression Data Sets", + "Authors@R": "c(person(\"John\", \"Fox\", role = c(\"aut\", \"cre\"), email = \"jfox@mcmaster.ca\"), person(\"Sanford\", \"Weisberg\", role = \"aut\", email = \"sandy@umn.edu\"), person(\"Brad\", \"Price\", role = \"aut\", email = \"brad.price@mail.wvu.edu\"))", + "Depends": [ + "R (>= 3.5.0)" ], - "Hash": "c35768291560ce302c0a6589f92e837d" + "Suggests": [ + "car (>= 3.0-0)" + ], + "LazyLoad": "yes", + "LazyData": "yes", + "Description": "Datasets to Accompany J. Fox and S. Weisberg, An R Companion to Applied Regression, Third Edition, Sage (2019).", + "License": "GPL (>= 2)", + "URL": "https://r-forge.r-project.org/projects/car/, https://CRAN.R-project.org/package=carData, https://socialsciences.mcmaster.ca/jfox/Books/Companion/index.html", + "Author": "John Fox [aut, cre], Sanford Weisberg [aut], Brad Price [aut]", + "Maintainer": "John Fox ", + "Repository": "CRAN", + "Repository/R-Forge/Project": "car", + "Repository/R-Forge/Revision": "694", + "Repository/R-Forge/DateTimeStamp": "2022-01-05 19:40:37", + "NeedsCompilation": "no" }, "cli": { "Package": "cli", - "Version": "3.6.2", + "Version": "3.6.5", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", + "Title": "Helpers for Developing Command Line Interfaces", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"gabor@posit.co\", role = c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Kirill\", \"Müller\", role = \"ctb\"), person(\"Salim\", \"Brüggemann\", , \"salim-b@pm.me\", role = \"ctb\", comment = c(ORCID = \"0000-0002-5329-5987\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A suite of tools to build attractive command line interfaces ('CLIs'), from semantic elements: headings, lists, alerts, paragraphs, etc. Supports custom themes via a 'CSS'-like language. It also contains a number of lower level 'CLI' elements: rules, boxes, trees, and 'Unicode' symbols with 'ASCII' alternatives. It support ANSI colors and text styles as well.", + "License": "MIT + file LICENSE", + "URL": "https://cli.r-lib.org, https://github.com/r-lib/cli", + "BugReports": "https://github.com/r-lib/cli/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ "utils" ], - "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52" + "Suggests": [ + "callr", + "covr", + "crayon", + "digest", + "glue (>= 1.6.0)", + "grDevices", + "htmltools", + "htmlwidgets", + "knitr", + "methods", + "processx", + "ps (>= 1.3.4.9000)", + "rlang (>= 1.0.2.9003)", + "rmarkdown", + "rprojroot", + "rstudioapi", + "testthat (>= 3.2.0)", + "tibble", + "whoami", + "withr" + ], + "Config/Needs/website": "r-lib/asciicast, bench, brio, cpp11, decor, desc, fansi, prettyunits, sessioninfo, tidyverse/tidytemplate, usethis, vctrs", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Gábor Csárdi [aut, cre], Hadley Wickham [ctb], Kirill Müller [ctb], Salim Brüggemann [ctb] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" }, "codetools": { "Package": "codetools", "Version": "0.2-20", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Priority": "recommended", + "Author": "Luke Tierney ", + "Description": "Code analysis tools for R.", + "Title": "Code Analysis Tools for R", + "Depends": [ + "R (>= 2.1)" + ], + "Maintainer": "Luke Tierney ", + "URL": "https://gitlab.com/luke-tierney/codetools", + "License": "GPL", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "corrplot": { + "Package": "corrplot", + "Version": "0.95", + "Source": "Repository", + "Type": "Package", + "Title": "Visualization of a Correlation Matrix", + "Date": "2024-10-14", + "Authors@R": "c( person('Taiyun', 'Wei', email = 'weitaiyun@gmail.com', role = c('cre', 'aut')), person('Viliam', 'Simko', email = 'viliam.simko@gmail.com', role = 'aut'), person('Michael', 'Levy', email = 'michael.levy@healthcatalyst.com', role = 'ctb'), person('Yihui', 'Xie', email = 'xie@yihui.name', role = 'ctb'), person('Yan', 'Jin', email = 'jyfeather@gmail.com', role = 'ctb'), person('Jeff', 'Zemla', email = 'zemla@wisc.edu', role = 'ctb'), person('Moritz', 'Freidank', email = 'freidankm@googlemail.com', role = 'ctb'), person('Jun', 'Cai', email = 'cai-j12@mails.tsinghua.edu.cn', role = 'ctb'), person('Tomas', 'Protivinsky', email = 'tomas.protivinsky@gmail.com', role = 'ctb') )", + "Maintainer": "Taiyun Wei ", + "Suggests": [ + "seriation", + "knitr", + "RColorBrewer", + "rmarkdown", + "magrittr", + "prettydoc", + "testthat" + ], + "Description": "Provides a visual exploratory tool on correlation matrix that supports automatic variable reordering to help detect hidden patterns among variables.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/taiyun/corrplot", + "BugReports": "https://github.com/taiyun/corrplot/issues", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.2.1", + "NeedsCompilation": "no", + "Author": "Taiyun Wei [cre, aut], Viliam Simko [aut], Michael Levy [ctb], Yihui Xie [ctb], Yan Jin [ctb], Jeff Zemla [ctb], Moritz Freidank [ctb], Jun Cai [ctb], Tomas Protivinsky [ctb]", + "Repository": "CRAN" + }, + "cowplot": { + "Package": "cowplot", + "Version": "1.2.0", + "Source": "Repository", + "Title": "Streamlined Plot Theme and Plot Annotations for 'ggplot2'", + "Authors@R": "person( given = \"Claus O.\", family = \"Wilke\", role = c(\"aut\", \"cre\"), email = \"wilke@austin.utexas.edu\", comment = c(ORCID = \"0000-0002-7470-9261\") )", + "Description": "Provides various features that help with creating publication-quality figures with 'ggplot2', such as a set of themes, functions to align plots and arrange them into complex compound figures, and functions that make it easy to annotate plots and or mix plots with images. The package was originally written for internal use in the Wilke lab, hence the name (Claus O. Wilke's plot package). It has also been used extensively in the book Fundamentals of Data Visualization.", + "URL": "https://wilkelab.org/cowplot/", + "BugReports": "https://github.com/wilkelab/cowplot/issues", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "ggplot2 (>= 3.5.2)", + "grid", + "gtable", + "grDevices", + "methods", + "rlang", + "scales" + ], + "License": "GPL-2", + "Suggests": [ + "Cairo", + "covr", + "dplyr", + "forcats", + "gridGraphics (>= 0.4-0)", + "knitr", + "lattice", + "magick", + "maps", + "PASWR", + "patchwork", + "rmarkdown", + "ragg", + "testthat (>= 1.0.0)", + "tidyr", + "vdiffr (>= 0.3.0)", + "VennDiagram" ], - "Hash": "61e097f35917d342622f21cdc79c256e" + "VignetteBuilder": "knitr", + "Collate": "'add_sub.R' 'align_plots.R' 'as_grob.R' 'as_gtable.R' 'axis_canvas.R' 'cowplot.R' 'draw.R' 'get_plot_component.R' 'get_axes.R' 'get_titles.R' 'get_legend.R' 'get_panel.R' 'gtable.R' 'key_glyph.R' 'plot_grid.R' 'save.R' 'set_null_device.R' 'setup.R' 'stamp.R' 'themes.R' 'utils_ggplot2.R'", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Claus O. Wilke [aut, cre] (ORCID: )", + "Maintainer": "Claus O. Wilke ", + "Repository": "CRAN" }, "cpp11": { "Package": "cpp11", - "Version": "0.4.7", + "Version": "0.5.2", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Title": "A C++11 Interface for R's C Interface", + "Authors@R": "c( person(\"Davis\", \"Vaughan\", email = \"davis@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4777-038X\")), person(\"Jim\",\"Hester\", role = \"aut\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Romain\", \"François\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Benjamin\", \"Kietzman\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides a header only, C++11 interface to R's C interface. Compared to other approaches 'cpp11' strives to be safe against long jumps from the C API as well as C++ exceptions, conform to normal R function semantics and supports interaction with 'ALTREP' vectors.", + "License": "MIT + file LICENSE", + "URL": "https://cpp11.r-lib.org, https://github.com/r-lib/cpp11", + "BugReports": "https://github.com/r-lib/cpp11/issues", + "Depends": [ + "R (>= 4.0.0)" + ], + "Suggests": [ + "bench", + "brio", + "callr", + "cli", + "covr", + "decor", + "desc", + "ggplot2", + "glue", + "knitr", + "lobstr", + "mockery", + "progress", + "rmarkdown", + "scales", + "Rcpp", + "testthat (>= 3.2.0)", + "tibble", + "utils", + "vctrs", + "withr" ], - "Hash": "5a295d7d963cc5035284dcdbaf334f4e" + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/Needs/cpp11/cpp_register": "brio, cli, decor, desc, glue, tibble, vctrs", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Davis Vaughan [aut, cre] (), Jim Hester [aut] (), Romain François [aut] (), Benjamin Kietzman [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN" }, "crayon": { "Package": "crayon", - "Version": "1.5.2", + "Version": "1.5.3", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ + "Title": "Colored Terminal Output", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Brodie\", \"Gaslam\", , \"brodie.gaslam@yahoo.com\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "The crayon package is now superseded. Please use the 'cli' package for new projects. Colored terminal output on terminals that support 'ANSI' color and highlight codes. It also works in 'Emacs' 'ESS'. 'ANSI' color support is automatically detected. Colors and highlighting can be combined and nested. New styles can also be created easily. This package was inspired by the 'chalk' 'JavaScript' project.", + "License": "MIT + file LICENSE", + "URL": "https://r-lib.github.io/crayon/, https://github.com/r-lib/crayon", + "BugReports": "https://github.com/r-lib/crayon/issues", + "Imports": [ "grDevices", "methods", "utils" ], - "Hash": "e8a1e41acf02548751f45c718d55aa6a" + "Suggests": [ + "mockery", + "rstudioapi", + "testthat", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Collate": "'aaa-rstudio-detect.R' 'aaaa-rematch2.R' 'aab-num-ansi-colors.R' 'aac-num-ansi-colors.R' 'ansi-256.R' 'ansi-palette.R' 'combine.R' 'string.R' 'utils.R' 'crayon-package.R' 'disposable.R' 'enc-utils.R' 'has_ansi.R' 'has_color.R' 'link.R' 'styles.R' 'machinery.R' 'parts.R' 'print.R' 'style-var.R' 'show.R' 'string_operations.R'", + "NeedsCompilation": "no", + "Author": "Gábor Csárdi [aut, cre], Brodie Gaslam [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "crosstalk": { + "Package": "crosstalk", + "Version": "1.2.1", + "Source": "Repository", + "Type": "Package", + "Title": "Inter-Widget Interactivity for HTML Widgets", + "Authors@R": "c( person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@posit.co\"), person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@posit.co\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(family = \"jQuery Foundation\", role = \"cph\", comment = \"jQuery library and jQuery UI library\"), person(family = \"jQuery contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt\"), person(\"Mark\", \"Otto\", role = \"ctb\", comment = \"Bootstrap library\"), person(\"Jacob\", \"Thornton\", role = \"ctb\", comment = \"Bootstrap library\"), person(family = \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(family = \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Brian\", \"Reavis\", role = c(\"ctb\", \"cph\"), comment = \"selectize.js library\"), person(\"Kristopher Michael\", \"Kowal\", role = c(\"ctb\", \"cph\"), comment = \"es5-shim library\"), person(family = \"es5-shim contributors\", role = c(\"ctb\", \"cph\"), comment = \"es5-shim library\"), person(\"Denis\", \"Ineshin\", role = c(\"ctb\", \"cph\"), comment = \"ion.rangeSlider library\"), person(\"Sami\", \"Samhuri\", role = c(\"ctb\", \"cph\"), comment = \"Javascript strftime library\") )", + "Description": "Provides building blocks for allowing HTML widgets to communicate with each other, with Shiny or without (i.e. static .html files). Currently supports linked brushing and filtering.", + "License": "MIT + file LICENSE", + "Imports": [ + "htmltools (>= 0.3.6)", + "jsonlite", + "lazyeval", + "R6" + ], + "Suggests": [ + "shiny", + "ggplot2", + "testthat (>= 2.1.0)", + "sass", + "bslib" + ], + "URL": "https://rstudio.github.io/crosstalk/, https://github.com/rstudio/crosstalk", + "BugReports": "https://github.com/rstudio/crosstalk/issues", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Joe Cheng [aut], Carson Sievert [aut, cre] (), Posit Software, PBC [cph, fnd], jQuery Foundation [cph] (jQuery library and jQuery UI library), jQuery contributors [ctb, cph] (jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt), Mark Otto [ctb] (Bootstrap library), Jacob Thornton [ctb] (Bootstrap library), Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Brian Reavis [ctb, cph] (selectize.js library), Kristopher Michael Kowal [ctb, cph] (es5-shim library), es5-shim contributors [ctb, cph] (es5-shim library), Denis Ineshin [ctb, cph] (ion.rangeSlider library), Sami Samhuri [ctb, cph] (Javascript strftime library)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" }, "curl": { "Package": "curl", - "Version": "5.2.1", + "Version": "6.4.0", + "Source": "Repository", + "Type": "Package", + "Title": "A Modern and Flexible Web Client for R", + "Authors@R": "c( person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Posit Software, PBC\", role = \"cph\"))", + "Description": "Bindings to 'libcurl' for performing fully configurable HTTP/FTP requests where responses can be processed in memory, on disk, or streaming via the callback or connection interfaces. Some knowledge of 'libcurl' is recommended; for a more-user-friendly web client see the 'httr2' package which builds on this package with http specific tools and logic.", + "License": "MIT + file LICENSE", + "SystemRequirements": "libcurl (>= 7.73): libcurl-devel (rpm) or libcurl4-openssl-dev (deb)", + "URL": "https://jeroen.r-universe.dev/curl", + "BugReports": "https://github.com/jeroen/curl/issues", + "Suggests": [ + "spelling", + "testthat (>= 1.0.0)", + "knitr", + "jsonlite", + "later", + "rmarkdown", + "httpuv (>= 1.4.4)", + "webutils" + ], + "VignetteBuilder": "knitr", + "Depends": [ + "R (>= 3.0.0)" + ], + "RoxygenNote": "7.3.2.9000", + "Encoding": "UTF-8", + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (ORCID: ), Hadley Wickham [ctb], Posit Software, PBC [cph]", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "data.table": { + "Package": "data.table", + "Version": "1.17.8", + "Source": "Repository", + "Title": "Extension of `data.frame`", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "bit64 (>= 4.0.0)", + "bit (>= 4.0.4)", + "R.utils", + "xts", + "zoo (>= 1.8-1)", + "yaml", + "knitr", + "markdown" + ], + "Description": "Fast aggregation of large data (e.g. 100GB in RAM), fast ordered joins, fast add/modify/delete of columns by group using no copies at all, list columns, friendly and fast character-separated-value read/write. Offers a natural and flexible syntax, for faster development.", + "License": "MPL-2.0 | file LICENSE", + "URL": "https://r-datatable.com, https://Rdatatable.gitlab.io/data.table, https://github.com/Rdatatable/data.table", + "BugReports": "https://github.com/Rdatatable/data.table/issues", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "ByteCompile": "TRUE", + "Authors@R": "c( person(\"Tyson\",\"Barrett\", role=c(\"aut\",\"cre\"), email=\"t.barrett88@gmail.com\", comment = c(ORCID=\"0000-0002-2137-1391\")), person(\"Matt\",\"Dowle\", role=\"aut\", email=\"mattjdowle@gmail.com\"), person(\"Arun\",\"Srinivasan\", role=\"aut\", email=\"asrini@pm.me\"), person(\"Jan\",\"Gorecki\", role=\"aut\"), person(\"Michael\",\"Chirico\", role=\"aut\", comment = c(ORCID=\"0000-0003-0787-087X\")), person(\"Toby\",\"Hocking\", role=\"aut\", comment = c(ORCID=\"0000-0002-3146-0865\")), person(\"Benjamin\",\"Schwendinger\",role=\"aut\", comment = c(ORCID=\"0000-0003-3315-8114\")), person(\"Ivan\", \"Krylov\", role=\"aut\", email=\"ikrylov@disroot.org\", comment = c(ORCID=\"0000-0002-0172-3812\")), person(\"Pasha\",\"Stetsenko\", role=\"ctb\"), person(\"Tom\",\"Short\", role=\"ctb\"), person(\"Steve\",\"Lianoglou\", role=\"ctb\"), person(\"Eduard\",\"Antonyan\", role=\"ctb\"), person(\"Markus\",\"Bonsch\", role=\"ctb\"), person(\"Hugh\",\"Parsonage\", role=\"ctb\"), person(\"Scott\",\"Ritchie\", role=\"ctb\"), person(\"Kun\",\"Ren\", role=\"ctb\"), person(\"Xianying\",\"Tan\", role=\"ctb\"), person(\"Rick\",\"Saporta\", role=\"ctb\"), person(\"Otto\",\"Seiskari\", role=\"ctb\"), person(\"Xianghui\",\"Dong\", role=\"ctb\"), person(\"Michel\",\"Lang\", role=\"ctb\"), person(\"Watal\",\"Iwasaki\", role=\"ctb\"), person(\"Seth\",\"Wenchel\", role=\"ctb\"), person(\"Karl\",\"Broman\", role=\"ctb\"), person(\"Tobias\",\"Schmidt\", role=\"ctb\"), person(\"David\",\"Arenburg\", role=\"ctb\"), person(\"Ethan\",\"Smith\", role=\"ctb\"), person(\"Francois\",\"Cocquemas\", role=\"ctb\"), person(\"Matthieu\",\"Gomez\", role=\"ctb\"), person(\"Philippe\",\"Chataignon\", role=\"ctb\"), person(\"Nello\",\"Blaser\", role=\"ctb\"), person(\"Dmitry\",\"Selivanov\", role=\"ctb\"), person(\"Andrey\",\"Riabushenko\", role=\"ctb\"), person(\"Cheng\",\"Lee\", role=\"ctb\"), person(\"Declan\",\"Groves\", role=\"ctb\"), person(\"Daniel\",\"Possenriede\", role=\"ctb\"), person(\"Felipe\",\"Parages\", role=\"ctb\"), person(\"Denes\",\"Toth\", role=\"ctb\"), person(\"Mus\",\"Yaramaz-David\", role=\"ctb\"), person(\"Ayappan\",\"Perumal\", role=\"ctb\"), person(\"James\",\"Sams\", role=\"ctb\"), person(\"Martin\",\"Morgan\", role=\"ctb\"), person(\"Michael\",\"Quinn\", role=\"ctb\"), person(\"@javrucebo\",\"\", role=\"ctb\"), person(\"@marc-outins\",\"\", role=\"ctb\"), person(\"Roy\",\"Storey\", role=\"ctb\"), person(\"Manish\",\"Saraswat\", role=\"ctb\"), person(\"Morgan\",\"Jacob\", role=\"ctb\"), person(\"Michael\",\"Schubmehl\", role=\"ctb\"), person(\"Davis\",\"Vaughan\", role=\"ctb\"), person(\"Leonardo\",\"Silvestri\", role=\"ctb\"), person(\"Jim\",\"Hester\", role=\"ctb\"), person(\"Anthony\",\"Damico\", role=\"ctb\"), person(\"Sebastian\",\"Freundt\", role=\"ctb\"), person(\"David\",\"Simons\", role=\"ctb\"), person(\"Elliott\",\"Sales de Andrade\", role=\"ctb\"), person(\"Cole\",\"Miller\", role=\"ctb\"), person(\"Jens Peder\",\"Meldgaard\", role=\"ctb\"), person(\"Vaclav\",\"Tlapak\", role=\"ctb\"), person(\"Kevin\",\"Ushey\", role=\"ctb\"), person(\"Dirk\",\"Eddelbuettel\", role=\"ctb\"), person(\"Tony\",\"Fischetti\", role=\"ctb\"), person(\"Ofek\",\"Shilon\", role=\"ctb\"), person(\"Vadim\",\"Khotilovich\", role=\"ctb\"), person(\"Hadley\",\"Wickham\", role=\"ctb\"), person(\"Bennet\",\"Becker\", role=\"ctb\"), person(\"Kyle\",\"Haynes\", role=\"ctb\"), person(\"Boniface Christian\",\"Kamgang\", role=\"ctb\"), person(\"Olivier\",\"Delmarcell\", role=\"ctb\"), person(\"Josh\",\"O'Brien\", role=\"ctb\"), person(\"Dereck\",\"de Mezquita\", role=\"ctb\"), person(\"Michael\",\"Czekanski\", role=\"ctb\"), person(\"Dmitry\", \"Shemetov\", role=\"ctb\"), person(\"Nitish\", \"Jha\", role=\"ctb\"), person(\"Joshua\", \"Wu\", role=\"ctb\"), person(\"Iago\", \"Giné-Vázquez\", role=\"ctb\"), person(\"Anirban\", \"Chetia\", role=\"ctb\"), person(\"Doris\", \"Amoakohene\", role=\"ctb\"), person(\"Angel\", \"Feliz\", role=\"ctb\"), person(\"Michael\",\"Young\", role=\"ctb\"), person(\"Mark\", \"Seeto\", role=\"ctb\"), person(\"Philippe\", \"Grosjean\", role=\"ctb\"), person(\"Vincent\", \"Runge\", role=\"ctb\"), person(\"Christian\", \"Wia\", role=\"ctb\"), person(\"Elise\", \"Maigné\", role=\"ctb\"), person(\"Vincent\", \"Rocher\", role=\"ctb\"), person(\"Vijay\", \"Lulla\", role=\"ctb\"), person(\"Aljaž\", \"Sluga\", role=\"ctb\"), person(\"Bill\", \"Evans\", role=\"ctb\") )", + "NeedsCompilation": "yes", + "Author": "Tyson Barrett [aut, cre] (ORCID: ), Matt Dowle [aut], Arun Srinivasan [aut], Jan Gorecki [aut], Michael Chirico [aut] (ORCID: ), Toby Hocking [aut] (ORCID: ), Benjamin Schwendinger [aut] (ORCID: ), Ivan Krylov [aut] (ORCID: ), Pasha Stetsenko [ctb], Tom Short [ctb], Steve Lianoglou [ctb], Eduard Antonyan [ctb], Markus Bonsch [ctb], Hugh Parsonage [ctb], Scott Ritchie [ctb], Kun Ren [ctb], Xianying Tan [ctb], Rick Saporta [ctb], Otto Seiskari [ctb], Xianghui Dong [ctb], Michel Lang [ctb], Watal Iwasaki [ctb], Seth Wenchel [ctb], Karl Broman [ctb], Tobias Schmidt [ctb], David Arenburg [ctb], Ethan Smith [ctb], Francois Cocquemas [ctb], Matthieu Gomez [ctb], Philippe Chataignon [ctb], Nello Blaser [ctb], Dmitry Selivanov [ctb], Andrey Riabushenko [ctb], Cheng Lee [ctb], Declan Groves [ctb], Daniel Possenriede [ctb], Felipe Parages [ctb], Denes Toth [ctb], Mus Yaramaz-David [ctb], Ayappan Perumal [ctb], James Sams [ctb], Martin Morgan [ctb], Michael Quinn [ctb], @javrucebo [ctb], @marc-outins [ctb], Roy Storey [ctb], Manish Saraswat [ctb], Morgan Jacob [ctb], Michael Schubmehl [ctb], Davis Vaughan [ctb], Leonardo Silvestri [ctb], Jim Hester [ctb], Anthony Damico [ctb], Sebastian Freundt [ctb], David Simons [ctb], Elliott Sales de Andrade [ctb], Cole Miller [ctb], Jens Peder Meldgaard [ctb], Vaclav Tlapak [ctb], Kevin Ushey [ctb], Dirk Eddelbuettel [ctb], Tony Fischetti [ctb], Ofek Shilon [ctb], Vadim Khotilovich [ctb], Hadley Wickham [ctb], Bennet Becker [ctb], Kyle Haynes [ctb], Boniface Christian Kamgang [ctb], Olivier Delmarcell [ctb], Josh O'Brien [ctb], Dereck de Mezquita [ctb], Michael Czekanski [ctb], Dmitry Shemetov [ctb], Nitish Jha [ctb], Joshua Wu [ctb], Iago Giné-Vázquez [ctb], Anirban Chetia [ctb], Doris Amoakohene [ctb], Angel Feliz [ctb], Michael Young [ctb], Mark Seeto [ctb], Philippe Grosjean [ctb], Vincent Runge [ctb], Christian Wia [ctb], Elise Maigné [ctb], Vincent Rocher [ctb], Vijay Lulla [ctb], Aljaž Sluga [ctb], Bill Evans [ctb]", + "Maintainer": "Tyson Barrett ", + "Repository": "CRAN" + }, + "dbplyr": { + "Package": "dbplyr", + "Version": "2.5.0", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Type": "Package", + "Title": "A 'dplyr' Back End for Databases", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Maximilian\", \"Girlich\", role = \"aut\"), person(\"Edgar\", \"Ruiz\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A 'dplyr' back end for databases that allows you to work with remote database tables as if they are in-memory data frames. Basic features works with any database that has a 'DBI' back end; more advanced features require 'SQL' translation to be provided by the package author.", + "License": "MIT + file LICENSE", + "URL": "https://dbplyr.tidyverse.org/, https://github.com/tidyverse/dbplyr", + "BugReports": "https://github.com/tidyverse/dbplyr/issues", + "Depends": [ + "R (>= 3.6)" ], - "Hash": "411ca2c03b1ce5f548345d2fc2685f7a" + "Imports": [ + "blob (>= 1.2.0)", + "cli (>= 3.6.1)", + "DBI (>= 1.1.3)", + "dplyr (>= 1.1.2)", + "glue (>= 1.6.2)", + "lifecycle (>= 1.0.3)", + "magrittr", + "methods", + "pillar (>= 1.9.0)", + "purrr (>= 1.0.1)", + "R6 (>= 2.2.2)", + "rlang (>= 1.1.1)", + "tibble (>= 3.2.1)", + "tidyr (>= 1.3.0)", + "tidyselect (>= 1.2.1)", + "utils", + "vctrs (>= 0.6.3)", + "withr (>= 2.5.0)" + ], + "Suggests": [ + "bit64", + "covr", + "knitr", + "Lahman", + "nycflights13", + "odbc (>= 1.4.2)", + "RMariaDB (>= 1.2.2)", + "rmarkdown", + "RPostgres (>= 1.4.5)", + "RPostgreSQL", + "RSQLite (>= 2.3.1)", + "testthat (>= 3.1.10)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "TRUE", + "Encoding": "UTF-8", + "Language": "en-gb", + "RoxygenNote": "7.3.1", + "Collate": "'db-sql.R' 'utils-check.R' 'import-standalone-types-check.R' 'import-standalone-obj-type.R' 'utils.R' 'sql.R' 'escape.R' 'translate-sql-cut.R' 'translate-sql-quantile.R' 'translate-sql-string.R' 'translate-sql-paste.R' 'translate-sql-helpers.R' 'translate-sql-window.R' 'translate-sql-conditional.R' 'backend-.R' 'backend-access.R' 'backend-hana.R' 'backend-hive.R' 'backend-impala.R' 'verb-copy-to.R' 'backend-mssql.R' 'backend-mysql.R' 'backend-odbc.R' 'backend-oracle.R' 'backend-postgres.R' 'backend-postgres-old.R' 'backend-redshift.R' 'backend-snowflake.R' 'backend-spark-sql.R' 'backend-sqlite.R' 'backend-teradata.R' 'build-sql.R' 'data-cache.R' 'data-lahman.R' 'data-nycflights13.R' 'db-escape.R' 'db-io.R' 'db.R' 'dbplyr.R' 'explain.R' 'ident.R' 'import-standalone-s3-register.R' 'join-by-compat.R' 'join-cols-compat.R' 'lazy-join-query.R' 'lazy-ops.R' 'lazy-query.R' 'lazy-select-query.R' 'lazy-set-op-query.R' 'memdb.R' 'optimise-utils.R' 'pillar.R' 'progress.R' 'sql-build.R' 'query-join.R' 'query-select.R' 'query-semi-join.R' 'query-set-op.R' 'query.R' 'reexport.R' 'remote.R' 'rows.R' 'schema.R' 'simulate.R' 'sql-clause.R' 'sql-expr.R' 'src-sql.R' 'src_dbi.R' 'table-name.R' 'tbl-lazy.R' 'tbl-sql.R' 'test-frame.R' 'testthat.R' 'tidyeval-across.R' 'tidyeval.R' 'translate-sql.R' 'utils-format.R' 'verb-arrange.R' 'verb-compute.R' 'verb-count.R' 'verb-distinct.R' 'verb-do-query.R' 'verb-do.R' 'verb-expand.R' 'verb-fill.R' 'verb-filter.R' 'verb-group_by.R' 'verb-head.R' 'verb-joins.R' 'verb-mutate.R' 'verb-pivot-longer.R' 'verb-pivot-wider.R' 'verb-pull.R' 'verb-select.R' 'verb-set-ops.R' 'verb-slice.R' 'verb-summarise.R' 'verb-uncount.R' 'verb-window.R' 'zzz.R'", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], Maximilian Girlich [aut], Edgar Ruiz [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "digest": { + "Package": "digest", + "Version": "0.6.37", + "Source": "Repository", + "Authors@R": "c(person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Antoine\", \"Lucas\", role=\"ctb\"), person(\"Jarek\", \"Tuszynski\", role=\"ctb\"), person(\"Henrik\", \"Bengtsson\", role=\"ctb\", comment = c(ORCID = \"0000-0002-7579-5165\")), person(\"Simon\", \"Urbanek\", role=\"ctb\", comment = c(ORCID = \"0000-0003-2297-1732\")), person(\"Mario\", \"Frasca\", role=\"ctb\"), person(\"Bryan\", \"Lewis\", role=\"ctb\"), person(\"Murray\", \"Stokely\", role=\"ctb\"), person(\"Hannes\", \"Muehleisen\", role=\"ctb\"), person(\"Duncan\", \"Murdoch\", role=\"ctb\"), person(\"Jim\", \"Hester\", role=\"ctb\"), person(\"Wush\", \"Wu\", role=\"ctb\", comment = c(ORCID = \"0000-0001-5180-0567\")), person(\"Qiang\", \"Kou\", role=\"ctb\", comment = c(ORCID = \"0000-0001-6786-5453\")), person(\"Thierry\", \"Onkelinx\", role=\"ctb\", comment = c(ORCID = \"0000-0001-8804-4216\")), person(\"Michel\", \"Lang\", role=\"ctb\", comment = c(ORCID = \"0000-0001-9754-0393\")), person(\"Viliam\", \"Simko\", role=\"ctb\"), person(\"Kurt\", \"Hornik\", role=\"ctb\", comment = c(ORCID = \"0000-0003-4198-9911\")), person(\"Radford\", \"Neal\", role=\"ctb\", comment = c(ORCID = \"0000-0002-2473-3407\")), person(\"Kendon\", \"Bell\", role=\"ctb\", comment = c(ORCID = \"0000-0002-9093-8312\")), person(\"Matthew\", \"de Queljoe\", role=\"ctb\"), person(\"Dmitry\", \"Selivanov\", role=\"ctb\"), person(\"Ion\", \"Suruceanu\", role=\"ctb\"), person(\"Bill\", \"Denney\", role=\"ctb\"), person(\"Dirk\", \"Schumacher\", role=\"ctb\"), person(\"András\", \"Svraka\", role=\"ctb\"), person(\"Sergey\", \"Fedorov\", role=\"ctb\"), person(\"Will\", \"Landau\", role=\"ctb\", comment = c(ORCID = \"0000-0003-1878-3253\")), person(\"Floris\", \"Vanderhaeghe\", role=\"ctb\", comment = c(ORCID = \"0000-0002-6378-6229\")), person(\"Kevin\", \"Tappe\", role=\"ctb\"), person(\"Harris\", \"McGehee\", role=\"ctb\"), person(\"Tim\", \"Mastny\", role=\"ctb\"), person(\"Aaron\", \"Peikert\", role=\"ctb\", comment = c(ORCID = \"0000-0001-7813-818X\")), person(\"Mark\", \"van der Loo\", role=\"ctb\", comment = c(ORCID = \"0000-0002-9807-4686\")), person(\"Chris\", \"Muir\", role=\"ctb\", comment = c(ORCID = \"0000-0003-2555-3878\")), person(\"Moritz\", \"Beller\", role=\"ctb\", comment = c(ORCID = \"0000-0003-4852-0526\")), person(\"Sebastian\", \"Campbell\", role=\"ctb\"), person(\"Winston\", \"Chang\", role=\"ctb\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Dean\", \"Attali\", role=\"ctb\", comment = c(ORCID = \"0000-0002-5645-3493\")), person(\"Michael\", \"Chirico\", role=\"ctb\", comment = c(ORCID = \"0000-0003-0787-087X\")), person(\"Kevin\", \"Ushey\", role=\"ctb\"))", + "Date": "2024-08-19", + "Title": "Create Compact Hash Digests of R Objects", + "Description": "Implementation of a function 'digest()' for the creation of hash digests of arbitrary R objects (using the 'md5', 'sha-1', 'sha-256', 'crc32', 'xxhash', 'murmurhash', 'spookyhash', 'blake3', 'crc32c', 'xxh3_64', and 'xxh3_128' algorithms) permitting easy comparison of R language objects, as well as functions such as'hmac()' to create hash-based message authentication code. Please note that this package is not meant to be deployed for cryptographic purposes for which more comprehensive (and widely tested) libraries such as 'OpenSSL' should be used.", + "URL": "https://github.com/eddelbuettel/digest, https://dirk.eddelbuettel.com/code/digest.html", + "BugReports": "https://github.com/eddelbuettel/digest/issues", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "utils" + ], + "License": "GPL (>= 2)", + "Suggests": [ + "tinytest", + "simplermarkdown" + ], + "VignetteBuilder": "simplermarkdown", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Dirk Eddelbuettel [aut, cre] (), Antoine Lucas [ctb], Jarek Tuszynski [ctb], Henrik Bengtsson [ctb] (), Simon Urbanek [ctb] (), Mario Frasca [ctb], Bryan Lewis [ctb], Murray Stokely [ctb], Hannes Muehleisen [ctb], Duncan Murdoch [ctb], Jim Hester [ctb], Wush Wu [ctb] (), Qiang Kou [ctb] (), Thierry Onkelinx [ctb] (), Michel Lang [ctb] (), Viliam Simko [ctb], Kurt Hornik [ctb] (), Radford Neal [ctb] (), Kendon Bell [ctb] (), Matthew de Queljoe [ctb], Dmitry Selivanov [ctb], Ion Suruceanu [ctb], Bill Denney [ctb], Dirk Schumacher [ctb], András Svraka [ctb], Sergey Fedorov [ctb], Will Landau [ctb] (), Floris Vanderhaeghe [ctb] (), Kevin Tappe [ctb], Harris McGehee [ctb], Tim Mastny [ctb], Aaron Peikert [ctb] (), Mark van der Loo [ctb] (), Chris Muir [ctb] (), Moritz Beller [ctb] (), Sebastian Campbell [ctb], Winston Chang [ctb] (), Dean Attali [ctb] (), Michael Chirico [ctb] (), Kevin Ushey [ctb]", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "CRAN" + }, + "doBy": { + "Package": "doBy", + "Version": "4.7.0", + "Source": "Repository", + "Title": "Groupwise Statistics, LSmeans, Linear Estimates, Utilities", + "Authors@R": "c( person(given = \"Ulrich\", family = \"Halekoh\", email = \"uhalekoh@health.sdu.dk\", role = c(\"aut\", \"cph\")), person(given = \"Søren\", family = \"Højsgaard\", email = \"sorenh@math.aau.dk\", role = c(\"aut\", \"cre\", \"cph\")) )", + "Description": "Utility package containing: Main categories: Working with grouped data: 'do' something to data when stratified 'by' some variables. General linear estimates. Data handling utilities. Functional programming, in particular restrict functions to a smaller domain. Miscellaneous functions for data handling. Model stability in connection with model selection. Miscellaneous other tools.", + "Encoding": "UTF-8", + "VignetteBuilder": "knitr", + "LazyData": "true", + "LazyDataCompression": "xz", + "URL": "https://github.com/hojsgaard/doBy", + "License": "GPL (>= 2)", + "Depends": [ + "R (>= 4.2.0)", + "methods" + ], + "Imports": [ + "boot", + "broom", + "cowplot", + "Deriv", + "dplyr", + "ggplot2", + "MASS", + "Matrix", + "modelr", + "microbenchmark", + "rlang", + "tibble", + "tidyr" + ], + "Suggests": [ + "geepack", + "knitr", + "lme4", + "markdown", + "multcomp", + "pbkrtest (>= 0.5.2)", + "survival", + "testthat (>= 2.1.0)" + ], + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Ulrich Halekoh [aut, cph], Søren Højsgaard [aut, cre, cph]", + "Maintainer": "Søren Højsgaard ", + "Repository": "CRAN" + }, + "dpGMM": { + "Package": "dpGMM", + "Version": "0.1.9", + "Source": "GitHub", + "Type": "Package", + "Title": "dpGMM: dynamic programming based Gaussian mixture modelling tool for 1D and 2D data", + "Author": "c( person(\"Michal\", \"Marczyk\",email = \"michal.marczyk@polsl.pl\", role = c(\"aut\",\"cre\")), person(\"Kamila\", \"Szumala\", role = c(\"aut\",\"cre\")), person(\"Joanna\", \"Zyla\", email = \"joanna.zyla@polsl.pl\",role = c(\"aut\",\"cre\")))", + "Maintainer": "The package maintainer ", + "Description": "Package for Gaussian mixture modeling of 1D and 2D data (original or binned) with the option to estimate the number of model components. The unique method for finding the initial parameters of GMM is based on a dynamic programming algorithm.", + "Depends": [ + "R (>= 3.5)", + "ggplot2", + "RColorBrewer", + "stats", + "pracma" + ], + "Imports": [ + "grDevices", + "ggpubr", + "Matrix", + "reshape2", + "graphics", + "methods", + "mvtnorm" + ], + "License": "GPL-3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "RemoteType": "github", + "RemoteHost": "api.github.com", + "RemoteUsername": "ZAEDPolSl", + "RemoteRepo": "dpGMM", + "RemoteRef": "master", + "RemoteSha": "3fd1654169ef60ff8b129c8133bc25c0c7cff4a9" + }, + "dplyr": { + "Package": "dplyr", + "Version": "1.1.4", + "Source": "Repository", + "Type": "Package", + "Title": "A Grammar of Data Manipulation", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Romain\", \"François\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Lionel\", \"Henry\", role = \"aut\"), person(\"Kirill\", \"Müller\", role = \"aut\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4777-038X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A fast, consistent tool for working with data frame like objects, both in memory and out of memory.", + "License": "MIT + file LICENSE", + "URL": "https://dplyr.tidyverse.org, https://github.com/tidyverse/dplyr", + "BugReports": "https://github.com/tidyverse/dplyr/issues", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "cli (>= 3.4.0)", + "generics", + "glue (>= 1.3.2)", + "lifecycle (>= 1.0.3)", + "magrittr (>= 1.5)", + "methods", + "pillar (>= 1.9.0)", + "R6", + "rlang (>= 1.1.0)", + "tibble (>= 3.2.0)", + "tidyselect (>= 1.2.0)", + "utils", + "vctrs (>= 0.6.4)" + ], + "Suggests": [ + "bench", + "broom", + "callr", + "covr", + "DBI", + "dbplyr (>= 2.2.1)", + "ggplot2", + "knitr", + "Lahman", + "lobstr", + "microbenchmark", + "nycflights13", + "purrr", + "rmarkdown", + "RMySQL", + "RPostgreSQL", + "RSQLite", + "stringi (>= 1.7.6)", + "testthat (>= 3.1.5)", + "tidyr (>= 1.3.0)", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse, shiny, pkgdown, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre] (), Romain François [aut] (), Lionel Henry [aut], Kirill Müller [aut] (), Davis Vaughan [aut] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "evaluate": { + "Package": "evaluate", + "Version": "1.0.4", + "Source": "Repository", + "Type": "Package", + "Title": "Parsing and Evaluation Tools that Provide More Details than the Default", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Yihui\", \"Xie\", role = \"aut\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Michael\", \"Lawrence\", role = \"ctb\"), person(\"Thomas\", \"Kluyver\", role = \"ctb\"), person(\"Jeroen\", \"Ooms\", role = \"ctb\"), person(\"Barret\", \"Schloerke\", role = \"ctb\"), person(\"Adam\", \"Ryczkowski\", role = \"ctb\"), person(\"Hiroaki\", \"Yutani\", role = \"ctb\"), person(\"Michel\", \"Lang\", role = \"ctb\"), person(\"Karolis\", \"Koncevičius\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Parsing and evaluation tools that make it easy to recreate the command line behaviour of R.", + "License": "MIT + file LICENSE", + "URL": "https://evaluate.r-lib.org/, https://github.com/r-lib/evaluate", + "BugReports": "https://github.com/r-lib/evaluate/issues", + "Depends": [ + "R (>= 3.6.0)" + ], + "Suggests": [ + "callr", + "covr", + "ggplot2 (>= 3.3.6)", + "lattice", + "methods", + "pkgload", + "ragg (>= 1.4.0)", + "rlang (>= 1.1.5)", + "knitr", + "testthat (>= 3.0.0)", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], Yihui Xie [aut] (ORCID: ), Michael Lawrence [ctb], Thomas Kluyver [ctb], Jeroen Ooms [ctb], Barret Schloerke [ctb], Adam Ryczkowski [ctb], Hiroaki Yutani [ctb], Michel Lang [ctb], Karolis Koncevičius [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "farver": { + "Package": "farver", + "Version": "2.1.2", + "Source": "Repository", + "Type": "Package", + "Title": "High Performance Colour Space Manipulation", + "Authors@R": "c( person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Berendea\", \"Nicolae\", role = \"aut\", comment = \"Author of the ColorSpace C++ library\"), person(\"Romain\", \"François\", , \"romain@purrple.cat\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "The encoding of colour can be handled in many different ways, using different colour spaces. As different colour spaces have different uses, efficient conversion between these representations are important. The 'farver' package provides a set of functions that gives access to very fast colour space conversion and comparisons implemented in C++, and offers speed improvements over the 'convertColor' function in the 'grDevices' package.", + "License": "MIT + file LICENSE", + "URL": "https://farver.data-imaginist.com, https://github.com/thomasp85/farver", + "BugReports": "https://github.com/thomasp85/farver/issues", + "Suggests": [ + "covr", + "testthat (>= 3.0.0)" + ], + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "NeedsCompilation": "yes", + "Author": "Thomas Lin Pedersen [cre, aut] (), Berendea Nicolae [aut] (Author of the ColorSpace C++ library), Romain François [aut] (), Posit, PBC [cph, fnd]", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" }, "fastmap": { "Package": "fastmap", - "Version": "1.1.1", + "Version": "1.2.0", "Source": "Repository", - "Repository": "RSPM", - "Hash": "f7736a18de97dea803bde0a2daaafb27" + "Title": "Fast Data Structures", + "Authors@R": "c( person(\"Winston\", \"Chang\", email = \"winston@posit.co\", role = c(\"aut\", \"cre\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(given = \"Tessil\", role = \"cph\", comment = \"hopscotch_map library\") )", + "Description": "Fast implementation of data structures, including a key-value store, stack, and queue. Environments are commonly used as key-value stores in R, but every time a new key is used, it is added to R's global symbol table, causing a small amount of memory leakage. This can be problematic in cases where many different keys are used. Fastmap avoids this memory leak issue by implementing the map using data structures in C++.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "Suggests": [ + "testthat (>= 2.1.1)" + ], + "URL": "https://r-lib.github.io/fastmap/, https://github.com/r-lib/fastmap", + "BugReports": "https://github.com/r-lib/fastmap/issues", + "NeedsCompilation": "yes", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd], Tessil [cph] (hopscotch_map library)", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "filelock": { + "Package": "filelock", + "Version": "1.0.3", + "Source": "Repository", + "Title": "Portable File Locking", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Place an exclusive or shared lock on a file. It uses 'LockFile' on Windows and 'fcntl' locks on Unix-like systems.", + "License": "MIT + file LICENSE", + "URL": "https://r-lib.github.io/filelock/, https://github.com/r-lib/filelock", + "BugReports": "https://github.com/r-lib/filelock/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Suggests": [ + "callr (>= 2.0.0)", + "covr", + "testthat (>= 3.0.0)" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Gábor Csárdi [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.3", + "Source": "Repository", + "Type": "Package", + "Title": "Easily Work with 'Font Awesome' Icons", + "Description": "Easily and flexibly insert 'Font Awesome' icons into 'R Markdown' documents and 'Shiny' apps. These icons can be inserted into HTML content through inline 'SVG' tags or 'i' tags. There is also a utility function for exporting 'Font Awesome' icons as 'PNG' images for those situations where raster graphics are needed.", + "Authors@R": "c( person(\"Richard\", \"Iannone\", , \"rich@posit.co\", c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"ctb\"), person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"), comment = \"Font-Awesome font\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/fontawesome, https://rstudio.github.io/fontawesome/", + "BugReports": "https://github.com/rstudio/fontawesome/issues", + "Encoding": "UTF-8", + "ByteCompile": "true", + "RoxygenNote": "7.3.2", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "rlang (>= 1.0.6)", + "htmltools (>= 0.5.1.1)" + ], + "Suggests": [ + "covr", + "dplyr (>= 1.0.8)", + "gt (>= 0.9.0)", + "knitr (>= 1.31)", + "testthat (>= 3.0.0)", + "rsvg" + ], + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Richard Iannone [aut, cre] (), Christophe Dervieux [ctb] (), Winston Chang [ctb], Dave Gandy [ctb, cph] (Font-Awesome font), Posit Software, PBC [cph, fnd]", + "Maintainer": "Richard Iannone ", + "Repository": "CRAN" }, "formatR": { "Package": "formatR", "Version": "1.14", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Type": "Package", + "Title": "Format R Code Automatically", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Ed\", \"Lee\", role = \"ctb\"), person(\"Eugene\", \"Ha\", role = \"ctb\"), person(\"Kohske\", \"Takahashi\", role = \"ctb\"), person(\"Pavel\", \"Krivitsky\", role = \"ctb\"), person() )", + "Description": "Provides a function tidy_source() to format R source code. Spaces and indent will be added to the code automatically, and comments will be preserved under certain conditions, so that R code will be more human-readable and tidy. There is also a Shiny app as a user interface in this package (see tidy_app()).", + "Depends": [ + "R (>= 3.2.3)" + ], + "Suggests": [ + "rstudioapi", + "shiny", + "testit", + "rmarkdown", + "knitr" + ], + "License": "GPL", + "URL": "https://github.com/yihui/formatR", + "BugReports": "https://github.com/yihui/formatR/issues", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (), Ed Lee [ctb], Eugene Ha [ctb], Kohske Takahashi [ctb], Pavel Krivitsky [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "fs": { + "Package": "fs", + "Version": "1.6.6", + "Source": "Repository", + "Title": "Cross-Platform File System Operations Based on 'libuv'", + "Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"libuv project contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Joyent, Inc. and other Node contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A cross-platform interface to file system operations, built on top of the 'libuv' C library.", + "License": "MIT + file LICENSE", + "URL": "https://fs.r-lib.org, https://github.com/r-lib/fs", + "BugReports": "https://github.com/r-lib/fs/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "methods" ], - "Hash": "63cb26d12517c7863f5abb006c5e0f25" + "Suggests": [ + "covr", + "crayon", + "knitr", + "pillar (>= 1.0.0)", + "rmarkdown", + "spelling", + "testthat (>= 3.0.0)", + "tibble (>= 1.1.0)", + "vctrs (>= 0.3.0)", + "withr" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Copyright": "file COPYRIGHTS", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.2.3", + "SystemRequirements": "GNU make", + "NeedsCompilation": "yes", + "Author": "Jim Hester [aut], Hadley Wickham [aut], Gábor Csárdi [aut, cre], libuv project contributors [cph] (libuv library), Joyent, Inc. and other Node contributors [cph] (libuv library), Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" }, "futile.logger": { "Package": "futile.logger", "Version": "1.4.3", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "futile.options", - "lambda.r", - "utils" + "Type": "Package", + "Title": "A Logging Utility for R", + "Date": "2016-07-10", + "Author": "Brian Lee Yung Rowe", + "Maintainer": "Brian Lee Yung Rowe ", + "Depends": [ + "R (>= 3.0.0)" + ], + "Imports": [ + "utils", + "lambda.r (>= 1.1.0)", + "futile.options" + ], + "Suggests": [ + "testthat", + "jsonlite" ], - "Hash": "99f0ace8c05ec7d3683d27083c4f1e7e" + "Description": "Provides a simple yet powerful logging utility. Based loosely on log4j, futile.logger takes advantage of R idioms to make logging a convenient and easy to use replacement for cat and print statements.", + "License": "LGPL-3", + "LazyLoad": "yes", + "NeedsCompilation": "no", + "ByteCompile": "yes", + "Collate": "'options.R' 'appender.R' 'constants.R' 'layout.R' 'logger.R' 'scat.R' 'futile.logger-package.R'", + "RoxygenNote": "5.0.1", + "Repository": "CRAN" }, "futile.options": { "Package": "futile.options", "Version": "1.0.1", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Type": "Package", + "Title": "Futile Options Management", + "Date": "2018-04-20", + "Author": "Brian Lee Yung Rowe", + "Maintainer": "Brian Lee Yung Rowe ", + "Depends": [ + "R (>= 2.8.0)" + ], + "Description": "A scoped options management framework. Used in other packages.", + "License": "LGPL-3", + "LazyLoad": "yes", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "generics": { + "Package": "generics", + "Version": "0.1.4", + "Source": "Repository", + "Title": "Common S3 Generics not Provided by Base R Methods Related to Model Fitting", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Max\", \"Kuhn\", , \"max@posit.co\", role = \"aut\"), person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"https://ror.org/03wc8by49\")) )", + "Description": "In order to reduce potential package dependencies and conflicts, generics provides a number of commonly used S3 generics.", + "License": "MIT + file LICENSE", + "URL": "https://generics.r-lib.org, https://github.com/r-lib/generics", + "BugReports": "https://github.com/r-lib/generics/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "covr", + "pkgload", + "testthat (>= 3.0.0)", + "tibble", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre] (ORCID: ), Max Kuhn [aut], Davis Vaughan [aut], Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "ggplot2": { + "Package": "ggplot2", + "Version": "3.5.2", + "Source": "Repository", + "Title": "Create Elegant Data Visualisations Using the Grammar of Graphics", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Winston\", \"Chang\", role = \"aut\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Lionel\", \"Henry\", role = \"aut\"), person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Kohske\", \"Takahashi\", role = \"aut\"), person(\"Claus\", \"Wilke\", role = \"aut\", comment = c(ORCID = \"0000-0002-7470-9261\")), person(\"Kara\", \"Woo\", role = \"aut\", comment = c(ORCID = \"0000-0002-5125-4188\")), person(\"Hiroaki\", \"Yutani\", role = \"aut\", comment = c(ORCID = \"0000-0002-3385-7233\")), person(\"Dewey\", \"Dunnington\", role = \"aut\", comment = c(ORCID = \"0000-0002-9415-4582\")), person(\"Teun\", \"van den Brand\", role = \"aut\", comment = c(ORCID = \"0000-0002-9335-7468\")), person(\"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A system for 'declaratively' creating graphics, based on \"The Grammar of Graphics\". You provide the data, tell 'ggplot2' how to map variables to aesthetics, what graphical primitives to use, and it takes care of the details.", + "License": "MIT + file LICENSE", + "URL": "https://ggplot2.tidyverse.org, https://github.com/tidyverse/ggplot2", + "BugReports": "https://github.com/tidyverse/ggplot2/issues", + "Depends": [ + "R (>= 3.5)" + ], + "Imports": [ + "cli", + "glue", + "grDevices", + "grid", + "gtable (>= 0.1.1)", + "isoband", + "lifecycle (> 1.0.1)", + "MASS", + "mgcv", + "rlang (>= 1.1.0)", + "scales (>= 1.3.0)", + "stats", + "tibble", + "vctrs (>= 0.6.0)", + "withr (>= 2.5.0)" + ], + "Suggests": [ + "covr", + "dplyr", + "ggplot2movies", + "hexbin", + "Hmisc", + "knitr", + "mapproj", + "maps", + "multcomp", + "munsell", + "nlme", + "profvis", + "quantreg", + "ragg (>= 1.2.6)", + "RColorBrewer", + "rmarkdown", + "rpart", + "sf (>= 0.7-3)", + "svglite (>= 2.1.2)", + "testthat (>= 3.1.2)", + "vdiffr (>= 1.0.6)", + "xml2" + ], + "Enhances": [ + "sp" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "ggtext, tidyr, forcats, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "Collate": "'ggproto.R' 'ggplot-global.R' 'aaa-.R' 'aes-colour-fill-alpha.R' 'aes-evaluation.R' 'aes-group-order.R' 'aes-linetype-size-shape.R' 'aes-position.R' 'compat-plyr.R' 'utilities.R' 'aes.R' 'utilities-checks.R' 'legend-draw.R' 'geom-.R' 'annotation-custom.R' 'annotation-logticks.R' 'geom-polygon.R' 'geom-map.R' 'annotation-map.R' 'geom-raster.R' 'annotation-raster.R' 'annotation.R' 'autolayer.R' 'autoplot.R' 'axis-secondary.R' 'backports.R' 'bench.R' 'bin.R' 'coord-.R' 'coord-cartesian-.R' 'coord-fixed.R' 'coord-flip.R' 'coord-map.R' 'coord-munch.R' 'coord-polar.R' 'coord-quickmap.R' 'coord-radial.R' 'coord-sf.R' 'coord-transform.R' 'data.R' 'docs_layer.R' 'facet-.R' 'facet-grid-.R' 'facet-null.R' 'facet-wrap.R' 'fortify-lm.R' 'fortify-map.R' 'fortify-multcomp.R' 'fortify-spatial.R' 'fortify.R' 'stat-.R' 'geom-abline.R' 'geom-rect.R' 'geom-bar.R' 'geom-bin2d.R' 'geom-blank.R' 'geom-boxplot.R' 'geom-col.R' 'geom-path.R' 'geom-contour.R' 'geom-count.R' 'geom-crossbar.R' 'geom-segment.R' 'geom-curve.R' 'geom-defaults.R' 'geom-ribbon.R' 'geom-density.R' 'geom-density2d.R' 'geom-dotplot.R' 'geom-errorbar.R' 'geom-errorbarh.R' 'geom-freqpoly.R' 'geom-function.R' 'geom-hex.R' 'geom-histogram.R' 'geom-hline.R' 'geom-jitter.R' 'geom-label.R' 'geom-linerange.R' 'geom-point.R' 'geom-pointrange.R' 'geom-quantile.R' 'geom-rug.R' 'geom-sf.R' 'geom-smooth.R' 'geom-spoke.R' 'geom-text.R' 'geom-tile.R' 'geom-violin.R' 'geom-vline.R' 'ggplot2-package.R' 'grob-absolute.R' 'grob-dotstack.R' 'grob-null.R' 'grouping.R' 'theme-elements.R' 'guide-.R' 'guide-axis.R' 'guide-axis-logticks.R' 'guide-axis-stack.R' 'guide-axis-theta.R' 'guide-legend.R' 'guide-bins.R' 'guide-colorbar.R' 'guide-colorsteps.R' 'guide-custom.R' 'layer.R' 'guide-none.R' 'guide-old.R' 'guides-.R' 'guides-grid.R' 'hexbin.R' 'import-standalone-obj-type.R' 'import-standalone-types-check.R' 'labeller.R' 'labels.R' 'layer-sf.R' 'layout.R' 'limits.R' 'margins.R' 'performance.R' 'plot-build.R' 'plot-construction.R' 'plot-last.R' 'plot.R' 'position-.R' 'position-collide.R' 'position-dodge.R' 'position-dodge2.R' 'position-identity.R' 'position-jitter.R' 'position-jitterdodge.R' 'position-nudge.R' 'position-stack.R' 'quick-plot.R' 'reshape-add-margins.R' 'save.R' 'scale-.R' 'scale-alpha.R' 'scale-binned.R' 'scale-brewer.R' 'scale-colour.R' 'scale-continuous.R' 'scale-date.R' 'scale-discrete-.R' 'scale-expansion.R' 'scale-gradient.R' 'scale-grey.R' 'scale-hue.R' 'scale-identity.R' 'scale-linetype.R' 'scale-linewidth.R' 'scale-manual.R' 'scale-shape.R' 'scale-size.R' 'scale-steps.R' 'scale-type.R' 'scale-view.R' 'scale-viridis.R' 'scales-.R' 'stat-align.R' 'stat-bin.R' 'stat-bin2d.R' 'stat-bindot.R' 'stat-binhex.R' 'stat-boxplot.R' 'stat-contour.R' 'stat-count.R' 'stat-density-2d.R' 'stat-density.R' 'stat-ecdf.R' 'stat-ellipse.R' 'stat-function.R' 'stat-identity.R' 'stat-qq-line.R' 'stat-qq.R' 'stat-quantilemethods.R' 'stat-sf-coordinates.R' 'stat-sf.R' 'stat-smooth-methods.R' 'stat-smooth.R' 'stat-sum.R' 'stat-summary-2d.R' 'stat-summary-bin.R' 'stat-summary-hex.R' 'stat-summary.R' 'stat-unique.R' 'stat-ydensity.R' 'summarise-plot.R' 'summary.R' 'theme.R' 'theme-defaults.R' 'theme-current.R' 'utilities-break.R' 'utilities-grid.R' 'utilities-help.R' 'utilities-matrix.R' 'utilities-patterns.R' 'utilities-resolution.R' 'utilities-tidy-eval.R' 'zxx.R' 'zzz.R'", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut] (), Winston Chang [aut] (), Lionel Henry [aut], Thomas Lin Pedersen [aut, cre] (), Kohske Takahashi [aut], Claus Wilke [aut] (), Kara Woo [aut] (), Hiroaki Yutani [aut] (), Dewey Dunnington [aut] (), Teun van den Brand [aut] (), Posit, PBC [cph, fnd]", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" + }, + "ggpubr": { + "Package": "ggpubr", + "Version": "0.6.1", + "Source": "Repository", + "Type": "Package", + "Title": "'ggplot2' Based Publication Ready Plots", + "Date": "2025-06-27", + "Authors@R": "c( person(\"Alboukadel\", \"Kassambara\", role = c(\"aut\", \"cre\"), email = \"alboukadel.kassambara@gmail.com\"))", + "Description": "The 'ggplot2' package is excellent and flexible for elegant data visualization in R. However the default generated plots requires some formatting before we can send them for publication. Furthermore, to customize a 'ggplot', the syntax is opaque and this raises the level of difficulty for researchers with no advanced R programming skills. 'ggpubr' provides some easy-to-use functions for creating and customizing 'ggplot2'- based publication ready plots.", + "License": "GPL (>= 2)", + "LazyData": "TRUE", + "Encoding": "UTF-8", + "Depends": [ + "R (>= 3.1.0)", + "ggplot2 (>= 3.5.2)" + ], + "Imports": [ + "ggrepel (>= 0.9.2)", + "grid", + "ggsci", + "stats", + "utils", + "tidyr (>= 1.3.0)", + "purrr", + "dplyr (>= 0.7.1)", + "cowplot (>= 1.1.1)", + "ggsignif", + "scales", + "gridExtra", + "glue", + "polynom", + "rlang (>= 0.4.6)", + "rstatix (>= 0.7.2)", + "tibble", + "magrittr" + ], + "Suggests": [ + "grDevices", + "knitr", + "RColorBrewer", + "gtable", + "testthat" + ], + "URL": "https://rpkgs.datanovia.com/ggpubr/", + "BugReports": "https://github.com/kassambara/ggpubr/issues", + "RoxygenNote": "7.3.2", + "Collate": "'utilities_color.R' 'utilities_base.R' 'desc_statby.R' 'utilities.R' 'add_summary.R' 'annotate_figure.R' 'as_ggplot.R' 'as_npc.R' 'axis_scale.R' 'background_image.R' 'bgcolor.R' 'border.R' 'compare_means.R' 'create_aes.R' 'diff_express.R' 'facet.R' 'font.R' 'gene_citation.R' 'gene_expression.R' 'geom_bracket.R' 'geom_exec.R' 'utils-aes.R' 'utils_stat_test_label.R' 'geom_pwc.R' 'get_breaks.R' 'get_coord.R' 'get_legend.R' 'get_palette.R' 'ggadd.R' 'ggadjust_pvalue.R' 'ggarrange.R' 'ggballoonplot.R' 'ggpar.R' 'ggbarplot.R' 'ggboxplot.R' 'ggdensity.R' 'ggpie.R' 'ggdonutchart.R' 'stat_conf_ellipse.R' 'stat_chull.R' 'ggdotchart.R' 'ggdotplot.R' 'ggecdf.R' 'ggerrorplot.R' 'ggexport.R' 'gghistogram.R' 'ggline.R' 'ggmaplot.R' 'ggpaired.R' 'ggparagraph.R' 'ggpubr-package.R' 'ggpubr_args.R' 'ggpubr_options.R' 'ggqqplot.R' 'utilities_label.R' 'stat_cor.R' 'stat_stars.R' 'ggscatter.R' 'ggscatterhist.R' 'ggstripchart.R' 'ggsummarystats.R' 'ggtext.R' 'ggtexttable.R' 'ggviolin.R' 'gradient_color.R' 'grids.R' 'npc_to_data_coord.R' 'reexports.R' 'rotate.R' 'rotate_axis_text.R' 'rremove.R' 'set_palette.R' 'shared_docs.R' 'show_line_types.R' 'show_point_shapes.R' 'stat_anova_test.R' 'stat_central_tendency.R' 'stat_compare_means.R' 'stat_friedman_test.R' 'stat_kruskal_test.R' 'stat_mean.R' 'stat_overlay_normal_density.R' 'stat_pvalue_manual.R' 'stat_regline_equation.R' 'stat_welch_anova_test.R' 'text_grob.R' 'theme_pubr.R' 'theme_transparent.R' 'utils-geom-signif.R' 'utils-pipe.R' 'utils-tidyr.R'", + "NeedsCompilation": "no", + "Author": "Alboukadel Kassambara [aut, cre]", + "Maintainer": "Alboukadel Kassambara ", + "Repository": "CRAN" + }, + "ggrepel": { + "Package": "ggrepel", + "Version": "0.9.6", + "Source": "Repository", + "Authors@R": "c( person(\"Kamil\", \"Slowikowski\", email = \"kslowikowski@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-2843-6370\")), person(\"Alicia\", \"Schep\", role = \"ctb\", comment = c(ORCID = \"0000-0002-3915-0618\")), person(\"Sean\", \"Hughes\", role = \"ctb\", comment = c(ORCID = \"0000-0002-9409-9405\")), person(\"Trung Kien\", \"Dang\", role = \"ctb\", comment = c(ORCID = \"0000-0001-7562-6495\")), person(\"Saulius\", \"Lukauskas\", role = \"ctb\"), person(\"Jean-Olivier\", \"Irisson\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4920-3880\")), person(\"Zhian N\", \"Kamvar\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1458-7108\")), person(\"Thompson\", \"Ryan\", role = \"ctb\", comment = c(ORCID = \"0000-0002-0450-8181\")), person(\"Dervieux\", \"Christophe\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Yutani\", \"Hiroaki\", role = \"ctb\"), person(\"Pierre\", \"Gramme\", role = \"ctb\"), person(\"Amir Masoud\", \"Abdol\", role = \"ctb\"), person(\"Malcolm\", \"Barrett\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0299-5825\")), person(\"Robrecht\", \"Cannoodt\", role = \"ctb\", comment = c(ORCID = \"0000-0003-3641-729X\")), person(\"Michał\", \"Krassowski\", role = \"ctb\", comment = c(ORCID = \"0000-0002-9638-7785\")), person(\"Michael\", \"Chirico\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0787-087X\")), person(\"Pedro\", \"Aphalo\", role = \"ctb\", comment = c(ORCID = \"0000-0003-3385-972X\")), person(\"Francis\", \"Barton\", role = \"ctb\") )", + "Title": "Automatically Position Non-Overlapping Text Labels with 'ggplot2'", + "Description": "Provides text and label geoms for 'ggplot2' that help to avoid overlapping text labels. Labels repel away from each other and away from the data points.", + "Depends": [ + "R (>= 3.0.0)", + "ggplot2 (>= 2.2.0)" + ], + "Imports": [ + "grid", + "Rcpp", + "rlang (>= 0.3.0)", + "scales (>= 0.5.0)", + "withr (>= 2.5.0)" + ], + "Suggests": [ + "knitr", + "rmarkdown", + "testthat", + "svglite", + "vdiffr", + "gridExtra", + "ggpp", + "patchwork", + "devtools", + "prettydoc", + "ggbeeswarm", + "dplyr", + "magrittr", + "readr", + "stringr" + ], + "VignetteBuilder": "knitr", + "License": "GPL-3 | file LICENSE", + "URL": "https://ggrepel.slowkow.com/, https://github.com/slowkow/ggrepel", + "BugReports": "https://github.com/slowkow/ggrepel/issues", + "RoxygenNote": "7.3.1", + "LinkingTo": [ + "Rcpp" + ], + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Kamil Slowikowski [aut, cre] (), Alicia Schep [ctb] (), Sean Hughes [ctb] (), Trung Kien Dang [ctb] (), Saulius Lukauskas [ctb], Jean-Olivier Irisson [ctb] (), Zhian N Kamvar [ctb] (), Thompson Ryan [ctb] (), Dervieux Christophe [ctb] (), Yutani Hiroaki [ctb], Pierre Gramme [ctb], Amir Masoud Abdol [ctb], Malcolm Barrett [ctb] (), Robrecht Cannoodt [ctb] (), Michał Krassowski [ctb] (), Michael Chirico [ctb] (), Pedro Aphalo [ctb] (), Francis Barton [ctb]", + "Maintainer": "Kamil Slowikowski ", + "Repository": "CRAN" + }, + "ggsci": { + "Package": "ggsci", + "Version": "3.2.0", + "Source": "Repository", + "Type": "Package", + "Title": "Scientific Journal and Sci-Fi Themed Color Palettes for 'ggplot2'", + "Authors@R": "c( person(\"Nan\", \"Xiao\", email = \"me@nanx.me\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-0250-5673\")), person(\"Joshua\", \"Cook\", email = \"joshuacook0023@gmail.com\", role = \"ctb\"), person(\"Clara\", \"Jégousse\", email = \"cat3@hi.is\", role = \"ctb\"), person(\"Hui\", \"Chen\", email = \"huichen@zju.edu.cn\", role = \"ctb\"), person(\"Miaozhu\", \"Li\", email = \"miaozhu.li@duke.edu\", role = \"ctb\") )", + "Maintainer": "Nan Xiao ", + "Description": "A collection of 'ggplot2' color palettes inspired by plots in scientific journals, data visualization libraries, science fiction movies, and TV shows.", + "License": "GPL (>= 3)", + "URL": "https://nanx.me/ggsci/, https://github.com/nanxstats/ggsci", + "BugReports": "https://github.com/nanxstats/ggsci/issues", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "ggplot2 (>= 2.0.0)", + "grDevices", + "scales" + ], + "Suggests": [ + "gridExtra", + "knitr", + "ragg", + "rmarkdown" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "NeedsCompilation": "no", + "Author": "Nan Xiao [aut, cre] (), Joshua Cook [ctb], Clara Jégousse [ctb], Hui Chen [ctb], Miaozhu Li [ctb]", + "Repository": "CRAN" + }, + "ggsignif": { + "Package": "ggsignif", + "Version": "0.6.4", + "Source": "Repository", + "Type": "Package", + "Title": "Significance Brackets for 'ggplot2'", + "Authors@R": "c( person(given = \"Constantin\", family = \"Ahlmann-Eltze\", role = c(\"aut\", \"cre\", \"ctb\"), email = \"artjom31415@googlemail.com\", comment = c(ORCID = \"0000-0002-3762-068X\", Twitter = \"@const_ae\")), person(given = \"Indrajeet\", family = \"Patil\", role = c(\"aut\", \"ctb\"), email = \"patilindrajeet.science@gmail.com\", comment = c(ORCID = \"0000-0003-1995-6531\", Twitter = \"@patilindrajeets\")) )", + "Description": "Enrich your 'ggplots' with group-wise comparisons. This package provides an easy way to indicate if two groups are significantly different. Commonly this is shown by a bracket on top connecting the groups of interest which itself is annotated with the level of significance (NS, *, **, ***). The package provides a single layer (geom_signif()) that takes the groups for comparison and the test (t.test(), wilcox.text() etc.) as arguments and adds the annotation to the plot.", + "License": "GPL-3 | file LICENSE", + "URL": "https://const-ae.github.io/ggsignif/, https://github.com/const-ae/ggsignif", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "Language": "en-US", + "Imports": [ + "ggplot2 (>= 3.3.5)" ], - "Hash": "0d9bf02413ddc2bbe8da9ce369dcdd2b" + "Suggests": [ + "knitr", + "rmarkdown", + "testthat", + "vdiffr (>= 1.0.2)" + ], + "RoxygenNote": "7.2.1", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "NeedsCompilation": "no", + "Author": "Constantin Ahlmann-Eltze [aut, cre, ctb] (, @const_ae), Indrajeet Patil [aut, ctb] (, @patilindrajeets)", + "Maintainer": "Constantin Ahlmann-Eltze ", + "Repository": "CRAN" }, "glue": { "Package": "glue", - "Version": "1.7.0", + "Version": "1.8.0", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", + "Title": "Interpreted String Literals", + "Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Jennifer\", \"Bryan\", , \"jenny@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-6983-2759\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "An implementation of interpreted string literals, inspired by Python's Literal String Interpolation and Docstrings and Julia's Triple-Quoted String Literals .", + "License": "MIT + file LICENSE", + "URL": "https://glue.tidyverse.org/, https://github.com/tidyverse/glue", + "BugReports": "https://github.com/tidyverse/glue/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ "methods" ], - "Hash": "e0b3a53876554bd45879e596cdb10a52" + "Suggests": [ + "crayon", + "DBI (>= 1.2.0)", + "dplyr", + "knitr", + "magrittr", + "rlang", + "rmarkdown", + "RSQLite", + "testthat (>= 3.2.0)", + "vctrs (>= 0.3.0)", + "waldo (>= 0.5.3)", + "withr" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/Needs/website": "bench, forcats, ggbeeswarm, ggplot2, R.utils, rprintf, tidyr, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Jim Hester [aut] (), Jennifer Bryan [aut, cre] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN" }, "graph": { "Package": "graph", - "Version": "1.80.0", + "Version": "1.84.1", "Source": "Bioconductor", - "Requirements": [ - "BiocGenerics", - "R", + "Title": "graph: A package to handle graph data structures", + "Authors@R": "c( person(\"R\", \"Gentleman\", role = \"aut\"), person(\"Elizabeth\", \"Whalen\", role=\"aut\"), person(\"W\", \"Huber\", role=\"aut\"), person(\"S\", \"Falcon\", role=\"aut\"), person(\"Jeff\", \"Gentry\", role=\"aut\"), person(\"Paul\", \"Shannon\", role=\"aut\"), person(\"Halimat C.\", \"Atanda\", role = \"ctb\", comment = \"Converted 'MultiGraphClass' and 'GraphClass' vignettes from Sweave to RMarkdown / HTML.\" ), person(\"Paul\", \"Villafuerte\", role = \"ctb\", comment = \"Converted vignettes from Sweave to RMarkdown / HTML.\" ), person(\"Aliyu Atiku\", \"Mustapha\", role = \"ctb\", comment = \"Converted 'Graph' vignette from Sweave to RMarkdown / HTML.\" ), person(\"Bioconductor Package Maintainer\", role = \"cre\", email = \"maintainer@bioconductor.org\" ))", + "Description": "A package that implements some simple graph handling capabilities.", + "License": "Artistic-2.0", + "Depends": [ + "R (>= 2.10)", "methods", + "BiocGenerics (>= 0.13.11)" + ], + "Imports": [ "stats", "stats4", "utils" ], - "Hash": "af02a936ce577656083213cdd8f5584d" + "Suggests": [ + "SparseM (>= 0.36)", + "XML", + "RBGL", + "RUnit", + "cluster", + "BiocStyle", + "knitr" + ], + "Enhances": [ + "Rgraphviz" + ], + "Collate": "AllClasses.R AllGenerics.R bitarray.R buildDepGraph.R methods-graph.R graphNEL.R clustergraph.R NELhandler.R edgefunctions.R graphfunctions.R GXLformals.R gxlReader.R random.R write.tlp.R mat2graph.R settings.R zzz.R standardLabeling.R TODOT.R toDotWithRI.R methods-graphAM.R attrData.R reverseEdgeDirections.R nodes-methods.R methods-multiGraph.R MultiGraph.R methods-graphBAM.R graph-constructors.R", + "LazyLoad": "yes", + "biocViews": "GraphAndNetwork", + "RoxygenNote": "7.2.3", + "VignetteBuilder": "knitr", + "git_url": "https://git.bioconductor.org/packages/graph", + "git_branch": "RELEASE_3_20", + "git_last_commit": "41ac6e9", + "git_last_commit_date": "2024-12-30", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "R Gentleman [aut], Elizabeth Whalen [aut], W Huber [aut], S Falcon [aut], Jeff Gentry [aut], Paul Shannon [aut], Halimat C. Atanda [ctb] (Converted 'MultiGraphClass' and 'GraphClass' vignettes from Sweave to RMarkdown / HTML.), Paul Villafuerte [ctb] (Converted vignettes from Sweave to RMarkdown / HTML.), Aliyu Atiku Mustapha [ctb] (Converted 'Graph' vignette from Sweave to RMarkdown / HTML.), Bioconductor Package Maintainer [cre]", + "Maintainer": "Bioconductor Package Maintainer " }, - "httr": { - "Package": "httr", - "Version": "1.4.7", + "gridExtra": { + "Package": "gridExtra", + "Version": "2.3", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "R6", - "curl", + "Authors@R": "c(person(\"Baptiste\", \"Auguie\", email = \"baptiste.auguie@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Anton\", \"Antonov\", email = \"tonytonov@gmail.com\", role = c(\"ctb\")))", + "License": "GPL (>= 2)", + "Title": "Miscellaneous Functions for \"Grid\" Graphics", + "Type": "Package", + "Description": "Provides a number of user-level functions to work with \"grid\" graphics, notably to arrange multiple grid-based plots on a page, and draw tables.", + "VignetteBuilder": "knitr", + "Imports": [ + "gtable", + "grid", + "grDevices", + "graphics", + "utils" + ], + "Suggests": [ + "ggplot2", + "egg", + "lattice", + "knitr", + "testthat" + ], + "RoxygenNote": "6.0.1", + "NeedsCompilation": "no", + "Author": "Baptiste Auguie [aut, cre], Anton Antonov [ctb]", + "Maintainer": "Baptiste Auguie ", + "Repository": "CRAN" + }, + "gtable": { + "Package": "gtable", + "Version": "0.3.6", + "Source": "Repository", + "Title": "Arrange 'Grobs' in Tables", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Tools to make it easier to work with \"tables\" of 'grobs'. The 'gtable' package defines a 'gtable' grob class that specifies a grid along with a list of grobs and their placement in the grid. Further the package makes it easy to manipulate and combine 'gtable' objects so that complex compositions can be built up sequentially.", + "License": "MIT + file LICENSE", + "URL": "https://gtable.r-lib.org, https://github.com/r-lib/gtable", + "BugReports": "https://github.com/r-lib/gtable/issues", + "Depends": [ + "R (>= 4.0)" + ], + "Imports": [ + "cli", + "glue", + "grid", + "lifecycle", + "rlang (>= 1.1.0)", + "stats" + ], + "Suggests": [ + "covr", + "ggplot2", + "knitr", + "profvis", + "rmarkdown", + "testthat (>= 3.0.0)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2024-10-25", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut], Thomas Lin Pedersen [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" + }, + "highr": { + "Package": "highr", + "Version": "0.11", + "Source": "Repository", + "Type": "Package", + "Title": "Syntax Highlighting for R Source Code", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Yixuan\", \"Qiu\", role = \"aut\"), person(\"Christopher\", \"Gandrud\", role = \"ctb\"), person(\"Qiang\", \"Li\", role = \"ctb\") )", + "Description": "Provides syntax highlighting for R source code. Currently it supports LaTeX and HTML output. Source code of other languages is supported via Andre Simon's highlight package ().", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "xfun (>= 0.18)" + ], + "Suggests": [ + "knitr", + "markdown", + "testit" + ], + "License": "GPL", + "URL": "https://github.com/yihui/highr", + "BugReports": "https://github.com/yihui/highr/issues", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (), Yixuan Qiu [aut], Christopher Gandrud [ctb], Qiang Li [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.8.1", + "Source": "Repository", + "Type": "Package", + "Title": "Tools for HTML", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Barret\", \"Schloerke\", , \"barret@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0001-9986-114X\")), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Yihui\", \"Xie\", , \"yihui@posit.co\", role = \"aut\"), person(\"Jeff\", \"Allen\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Tools for HTML generation and output.", + "License": "GPL (>= 2)", + "URL": "https://github.com/rstudio/htmltools, https://rstudio.github.io/htmltools/", + "BugReports": "https://github.com/rstudio/htmltools/issues", + "Depends": [ + "R (>= 2.14.1)" + ], + "Imports": [ + "base64enc", + "digest", + "fastmap (>= 1.1.0)", + "grDevices", + "rlang (>= 1.0.0)", + "utils" + ], + "Suggests": [ + "Cairo", + "markdown", + "ragg", + "shiny", + "testthat", + "withr" + ], + "Enhances": [ + "knitr" + ], + "Config/Needs/check": "knitr", + "Config/Needs/website": "rstudio/quillt, bench", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Collate": "'colors.R' 'fill.R' 'html_dependency.R' 'html_escape.R' 'html_print.R' 'htmltools-package.R' 'images.R' 'known_tags.R' 'selector.R' 'staticimports.R' 'tag_query.R' 'utils.R' 'tags.R' 'template.R'", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut], Carson Sievert [aut, cre] (), Barret Schloerke [aut] (), Winston Chang [aut] (), Yihui Xie [aut], Jeff Allen [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "htmlwidgets": { + "Package": "htmlwidgets", + "Version": "1.6.4", + "Source": "Repository", + "Type": "Package", + "Title": "HTML Widgets for R", + "Authors@R": "c( person(\"Ramnath\", \"Vaidyanathan\", role = c(\"aut\", \"cph\")), person(\"Yihui\", \"Xie\", role = \"aut\"), person(\"JJ\", \"Allaire\", role = \"aut\"), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Kenton\", \"Russell\", role = c(\"aut\", \"cph\")), person(\"Ellis\", \"Hughes\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A framework for creating HTML widgets that render in various contexts including the R console, 'R Markdown' documents, and 'Shiny' web applications.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/ramnathv/htmlwidgets", + "BugReports": "https://github.com/ramnathv/htmlwidgets/issues", + "Imports": [ + "grDevices", + "htmltools (>= 0.5.7)", + "jsonlite (>= 0.9.16)", + "knitr (>= 1.8)", + "rmarkdown", + "yaml" + ], + "Suggests": [ + "testthat" + ], + "Enhances": [ + "shiny (>= 1.1)" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Ramnath Vaidyanathan [aut, cph], Yihui Xie [aut], JJ Allaire [aut], Joe Cheng [aut], Carson Sievert [aut, cre] (), Kenton Russell [aut, cph], Ellis Hughes [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "httr": { + "Package": "httr", + "Version": "1.4.7", + "Source": "Repository", + "Title": "Tools for Working with URLs and HTTP", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Useful tools for working with HTTP organised by HTTP verbs (GET(), POST(), etc). Configuration functions make it easy to control additional request components (authenticate(), add_headers() and so on).", + "License": "MIT + file LICENSE", + "URL": "https://httr.r-lib.org/, https://github.com/r-lib/httr", + "BugReports": "https://github.com/r-lib/httr/issues", + "Depends": [ + "R (>= 3.5)" + ], + "Imports": [ + "curl (>= 5.0.2)", "jsonlite", "mime", - "openssl" + "openssl (>= 0.8)", + "R6" + ], + "Suggests": [ + "covr", + "httpuv", + "jpeg", + "knitr", + "png", + "readr", + "rmarkdown", + "testthat (>= 0.8.0)", + "xml2" ], - "Hash": "ac107251d9d9fd72f0ca8049988f1d7f" + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], Posit, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" }, "irlba": { "Package": "irlba", "Version": "2.3.5.1", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ + "Type": "Package", + "Title": "Fast Truncated Singular Value Decomposition and Principal Components Analysis for Large Dense and Sparse Matrices", + "Date": "2021-12-05", + "Authors@R": "c( person(\"Jim\", \"Baglama\", role=c(\"aut\", \"cph\"), email=\"jbaglama@uri.edu\"), person(\"Lothar\", \"Reichel\", role=c(\"aut\", \"cph\"), email=\"reichel@math.kent.edu\"), person(\"B. W.\", \"Lewis\", role=c(\"aut\",\"cre\",\"cph\"), email=\"blewis@illposed.net\"))", + "Description": "Fast and memory efficient methods for truncated singular value decomposition and principal components analysis of large sparse and dense matrices.", + "Depends": [ + "R (>= 3.6.2)", + "Matrix" + ], + "LinkingTo": [ + "Matrix" + ], + "Imports": [ + "stats", + "methods" + ], + "License": "GPL-3", + "BugReports": "https://github.com/bwlewis/irlba/issues", + "RoxygenNote": "5.0.1", + "NeedsCompilation": "yes", + "Author": "Jim Baglama [aut, cph], Lothar Reichel [aut, cph], B. W. Lewis [aut, cre, cph]", + "Maintainer": "B. W. Lewis ", + "Repository": "CRAN" + }, + "isoband": { + "Package": "isoband", + "Version": "0.2.7", + "Source": "Repository", + "Title": "Generate Isolines and Isobands from Regularly Spaced Elevation Grids", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Claus O.\", \"Wilke\", , \"wilke@austin.utexas.edu\", role = \"aut\", comment = c(\"Original author\", ORCID = \"0000-0002-7470-9261\")), person(\"Thomas Lin\", \"Pedersen\", , \"thomasp85@gmail.com\", role = \"aut\", comment = c(ORCID = \"0000-0002-5147-4711\")) )", + "Description": "A fast C++ implementation to generate contour lines (isolines) and contour polygons (isobands) from regularly spaced grids containing elevation data.", + "License": "MIT + file LICENSE", + "URL": "https://isoband.r-lib.org", + "BugReports": "https://github.com/r-lib/isoband/issues", + "Imports": [ + "grid", + "utils" + ], + "Suggests": [ + "covr", + "ggplot2", + "knitr", + "magick", + "microbenchmark", + "rmarkdown", + "sf", + "testthat", + "xml2" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "C++11", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre] (), Claus O. Wilke [aut] (Original author, ), Thomas Lin Pedersen [aut] ()", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Title": "Obtain 'jQuery' as an HTML Dependency Object", + "Authors@R": "c( person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"), person(family = \"RStudio\", role = \"cph\"), person(family = \"jQuery Foundation\", role = \"cph\", comment = \"jQuery library and jQuery UI library\"), person(family = \"jQuery contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery library; authors listed in inst/lib/jquery-AUTHORS.txt\") )", + "Description": "Obtain any major version of 'jQuery' () and use it in any webpage generated by 'htmltools' (e.g. 'shiny', 'htmlwidgets', and 'rmarkdown'). Most R users don't need to use this package directly, but other R packages (e.g. 'shiny', 'rmarkdown', etc.) depend on this package to avoid bundling redundant copies of 'jQuery'.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Config/testthat/edition": "3", + "RoxygenNote": "7.0.2", + "Imports": [ + "htmltools" + ], + "Suggests": [ + "testthat" + ], + "NeedsCompilation": "no", + "Author": "Carson Sievert [aut, cre] (), Joe Cheng [aut], RStudio [cph], jQuery Foundation [cph] (jQuery library and jQuery UI library), jQuery contributors [ctb, cph] (jQuery library; authors listed in inst/lib/jquery-AUTHORS.txt)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "2.0.0", + "Source": "Repository", + "Title": "A Simple and Robust JSON Parser and Generator for R", + "License": "MIT + file LICENSE", + "Depends": [ + "methods" + ], + "Authors@R": "c( person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Duncan\", \"Temple Lang\", role = \"ctb\"), person(\"Lloyd\", \"Hilaiel\", role = \"cph\", comment=\"author of bundled libyajl\"))", + "URL": "https://jeroen.r-universe.dev/jsonlite https://arxiv.org/abs/1403.2805", + "BugReports": "https://github.com/jeroen/jsonlite/issues", + "Maintainer": "Jeroen Ooms ", + "VignetteBuilder": "knitr, R.rsp", + "Description": "A reasonably fast JSON parser and generator, optimized for statistical data and the web. Offers simple, flexible tools for working with JSON in R, and is particularly powerful for building pipelines and interacting with a web API. The implementation is based on the mapping described in the vignette (Ooms, 2014). In addition to converting JSON data from/to R objects, 'jsonlite' contains functions to stream, validate, and prettify JSON data. The unit tests included with the package verify that all edge cases are encoded and decoded consistently for use with dynamic data in systems and applications.", + "Suggests": [ + "httr", + "vctrs", + "testthat", + "knitr", + "rmarkdown", + "R.rsp", + "sf" + ], + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), Duncan Temple Lang [ctb], Lloyd Hilaiel [cph] (author of bundled libyajl)", + "Repository": "CRAN" + }, + "kernlab": { + "Package": "kernlab", + "Version": "0.9-33", + "Source": "Repository", + "Title": "Kernel-Based Machine Learning Lab", + "Authors@R": "c(person(\"Alexandros\", \"Karatzoglou\", role = c(\"aut\", \"cre\"), email = \"alexandros.karatzoglou@gmail.com\"), person(\"Alex\", \"Smola\", role = \"aut\"), person(\"Kurt\", \"Hornik\", role = \"aut\", email = \"Kurt.Hornik@R-project.org\", comment = c(ORCID = \"0000-0003-4198-9911\")), person(\"National ICT Australia (NICTA)\", role = \"cph\"), person(c(\"Michael\", \"A.\"), \"Maniscalco\", role = c(\"ctb\", \"cph\")), person(c(\"Choon\", \"Hui\"), \"Teo\", role = \"ctb\"))", + "Description": "Kernel-based machine learning methods for classification, regression, clustering, novelty detection, quantile regression and dimensionality reduction. Among other methods 'kernlab' includes Support Vector Machines, Spectral Clustering, Kernel PCA, Gaussian Processes and a QP solver.", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "methods", + "stats", + "grDevices", + "graphics" + ], + "LazyLoad": "Yes", + "License": "GPL-2", + "NeedsCompilation": "yes", + "Author": "Alexandros Karatzoglou [aut, cre], Alex Smola [aut], Kurt Hornik [aut] (), National ICT Australia (NICTA) [cph], Michael A. Maniscalco [ctb, cph], Choon Hui Teo [ctb]", + "Maintainer": "Alexandros Karatzoglou ", + "Repository": "CRAN" + }, + "knitr": { + "Package": "knitr", + "Version": "1.50", + "Source": "Repository", + "Type": "Package", + "Title": "A General-Purpose Package for Dynamic Report Generation in R", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Abhraneel\", \"Sarma\", role = \"ctb\"), person(\"Adam\", \"Vogt\", role = \"ctb\"), person(\"Alastair\", \"Andrew\", role = \"ctb\"), person(\"Alex\", \"Zvoleff\", role = \"ctb\"), person(\"Amar\", \"Al-Zubaidi\", role = \"ctb\"), person(\"Andre\", \"Simon\", role = \"ctb\", comment = \"the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de\"), person(\"Aron\", \"Atkins\", role = \"ctb\"), person(\"Aaron\", \"Wolen\", role = \"ctb\"), person(\"Ashley\", \"Manton\", role = \"ctb\"), person(\"Atsushi\", \"Yasumoto\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8335-495X\")), person(\"Ben\", \"Baumer\", role = \"ctb\"), person(\"Brian\", \"Diggs\", role = \"ctb\"), person(\"Brian\", \"Zhang\", role = \"ctb\"), person(\"Bulat\", \"Yapparov\", role = \"ctb\"), person(\"Cassio\", \"Pereira\", role = \"ctb\"), person(\"Christophe\", \"Dervieux\", role = \"ctb\"), person(\"David\", \"Hall\", role = \"ctb\"), person(\"David\", \"Hugh-Jones\", role = \"ctb\"), person(\"David\", \"Robinson\", role = \"ctb\"), person(\"Doug\", \"Hemken\", role = \"ctb\"), person(\"Duncan\", \"Murdoch\", role = \"ctb\"), person(\"Elio\", \"Campitelli\", role = \"ctb\"), person(\"Ellis\", \"Hughes\", role = \"ctb\"), person(\"Emily\", \"Riederer\", role = \"ctb\"), person(\"Fabian\", \"Hirschmann\", role = \"ctb\"), person(\"Fitch\", \"Simeon\", role = \"ctb\"), person(\"Forest\", \"Fang\", role = \"ctb\"), person(c(\"Frank\", \"E\", \"Harrell\", \"Jr\"), role = \"ctb\", comment = \"the Sweavel package at inst/misc/Sweavel.sty\"), person(\"Garrick\", \"Aden-Buie\", role = \"ctb\"), person(\"Gregoire\", \"Detrez\", role = \"ctb\"), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Hao\", \"Zhu\", role = \"ctb\"), person(\"Heewon\", \"Jeon\", role = \"ctb\"), person(\"Henrik\", \"Bengtsson\", role = \"ctb\"), person(\"Hiroaki\", \"Yutani\", role = \"ctb\"), person(\"Ian\", \"Lyttle\", role = \"ctb\"), person(\"Hodges\", \"Daniel\", role = \"ctb\"), person(\"Jacob\", \"Bien\", role = \"ctb\"), person(\"Jake\", \"Burkhead\", role = \"ctb\"), person(\"James\", \"Manton\", role = \"ctb\"), person(\"Jared\", \"Lander\", role = \"ctb\"), person(\"Jason\", \"Punyon\", role = \"ctb\"), person(\"Javier\", \"Luraschi\", role = \"ctb\"), person(\"Jeff\", \"Arnold\", role = \"ctb\"), person(\"Jenny\", \"Bryan\", role = \"ctb\"), person(\"Jeremy\", \"Ashkenas\", role = c(\"ctb\", \"cph\"), comment = \"the CSS file at inst/misc/docco-classic.css\"), person(\"Jeremy\", \"Stephens\", role = \"ctb\"), person(\"Jim\", \"Hester\", role = \"ctb\"), person(\"Joe\", \"Cheng\", role = \"ctb\"), person(\"Johannes\", \"Ranke\", role = \"ctb\"), person(\"John\", \"Honaker\", role = \"ctb\"), person(\"John\", \"Muschelli\", role = \"ctb\"), person(\"Jonathan\", \"Keane\", role = \"ctb\"), person(\"JJ\", \"Allaire\", role = \"ctb\"), person(\"Johan\", \"Toloe\", role = \"ctb\"), person(\"Jonathan\", \"Sidi\", role = \"ctb\"), person(\"Joseph\", \"Larmarange\", role = \"ctb\"), person(\"Julien\", \"Barnier\", role = \"ctb\"), person(\"Kaiyin\", \"Zhong\", role = \"ctb\"), person(\"Kamil\", \"Slowikowski\", role = \"ctb\"), person(\"Karl\", \"Forner\", role = \"ctb\"), person(c(\"Kevin\", \"K.\"), \"Smith\", role = \"ctb\"), person(\"Kirill\", \"Mueller\", role = \"ctb\"), person(\"Kohske\", \"Takahashi\", role = \"ctb\"), person(\"Lorenz\", \"Walthert\", role = \"ctb\"), person(\"Lucas\", \"Gallindo\", role = \"ctb\"), person(\"Marius\", \"Hofert\", role = \"ctb\"), person(\"Martin\", \"Modrák\", role = \"ctb\"), person(\"Michael\", \"Chirico\", role = \"ctb\"), person(\"Michael\", \"Friendly\", role = \"ctb\"), person(\"Michal\", \"Bojanowski\", role = \"ctb\"), person(\"Michel\", \"Kuhlmann\", role = \"ctb\"), person(\"Miller\", \"Patrick\", role = \"ctb\"), person(\"Nacho\", \"Caballero\", role = \"ctb\"), person(\"Nick\", \"Salkowski\", role = \"ctb\"), person(\"Niels Richard\", \"Hansen\", role = \"ctb\"), person(\"Noam\", \"Ross\", role = \"ctb\"), person(\"Obada\", \"Mahdi\", role = \"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role = \"ctb\", comment=c(ORCID = \"0000-0002-9101-3362\")), person(\"Pedro\", \"Faria\", role = \"ctb\"), person(\"Qiang\", \"Li\", role = \"ctb\"), person(\"Ramnath\", \"Vaidyanathan\", role = \"ctb\"), person(\"Richard\", \"Cotton\", role = \"ctb\"), person(\"Robert\", \"Krzyzanowski\", role = \"ctb\"), person(\"Rodrigo\", \"Copetti\", role = \"ctb\"), person(\"Romain\", \"Francois\", role = \"ctb\"), person(\"Ruaridh\", \"Williamson\", role = \"ctb\"), person(\"Sagiru\", \"Mati\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1413-3974\")), person(\"Scott\", \"Kostyshak\", role = \"ctb\"), person(\"Sebastian\", \"Meyer\", role = \"ctb\"), person(\"Sietse\", \"Brouwer\", role = \"ctb\"), person(c(\"Simon\", \"de\"), \"Bernard\", role = \"ctb\"), person(\"Sylvain\", \"Rousseau\", role = \"ctb\"), person(\"Taiyun\", \"Wei\", role = \"ctb\"), person(\"Thibaut\", \"Assus\", role = \"ctb\"), person(\"Thibaut\", \"Lamadon\", role = \"ctb\"), person(\"Thomas\", \"Leeper\", role = \"ctb\"), person(\"Tim\", \"Mastny\", role = \"ctb\"), person(\"Tom\", \"Torsney-Weir\", role = \"ctb\"), person(\"Trevor\", \"Davis\", role = \"ctb\"), person(\"Viktoras\", \"Veitas\", role = \"ctb\"), person(\"Weicheng\", \"Zhu\", role = \"ctb\"), person(\"Wush\", \"Wu\", role = \"ctb\"), person(\"Zachary\", \"Foster\", role = \"ctb\"), person(\"Zhian N.\", \"Kamvar\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1458-7108\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides a general-purpose tool for dynamic report generation in R using Literate Programming techniques.", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "evaluate (>= 0.15)", + "highr (>= 0.11)", + "methods", + "tools", + "xfun (>= 0.51)", + "yaml (>= 2.1.19)" + ], + "Suggests": [ + "bslib", + "codetools", + "DBI (>= 0.4-1)", + "digest", + "formatR", + "gifski", + "gridSVG", + "htmlwidgets (>= 0.7)", + "jpeg", + "JuliaCall (>= 0.11.1)", + "magick", + "litedown", + "markdown (>= 1.3)", + "png", + "ragg", + "reticulate (>= 1.4)", + "rgl (>= 0.95.1201)", + "rlang", + "rmarkdown", + "sass", + "showtext", + "styler (>= 1.2.0)", + "targets (>= 0.6.0)", + "testit", + "tibble", + "tikzDevice (>= 0.10)", + "tinytex (>= 0.56)", + "webshot", + "rstudioapi", + "svglite" + ], + "License": "GPL", + "URL": "https://yihui.org/knitr/", + "BugReports": "https://github.com/yihui/knitr/issues", + "Encoding": "UTF-8", + "VignetteBuilder": "litedown, knitr", + "SystemRequirements": "Package vignettes based on R Markdown v2 or reStructuredText require Pandoc (http://pandoc.org). The function rst2pdf() requires rst2pdf (https://github.com/rst2pdf/rst2pdf).", + "Collate": "'block.R' 'cache.R' 'citation.R' 'hooks-html.R' 'plot.R' 'utils.R' 'defaults.R' 'concordance.R' 'engine.R' 'highlight.R' 'themes.R' 'header.R' 'hooks-asciidoc.R' 'hooks-chunk.R' 'hooks-extra.R' 'hooks-latex.R' 'hooks-md.R' 'hooks-rst.R' 'hooks-textile.R' 'hooks.R' 'output.R' 'package.R' 'pandoc.R' 'params.R' 'parser.R' 'pattern.R' 'rocco.R' 'spin.R' 'table.R' 'template.R' 'utils-conversion.R' 'utils-rd2html.R' 'utils-string.R' 'utils-sweave.R' 'utils-upload.R' 'utils-vignettes.R' 'zzz.R'", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (, https://yihui.org), Abhraneel Sarma [ctb], Adam Vogt [ctb], Alastair Andrew [ctb], Alex Zvoleff [ctb], Amar Al-Zubaidi [ctb], Andre Simon [ctb] (the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de), Aron Atkins [ctb], Aaron Wolen [ctb], Ashley Manton [ctb], Atsushi Yasumoto [ctb] (), Ben Baumer [ctb], Brian Diggs [ctb], Brian Zhang [ctb], Bulat Yapparov [ctb], Cassio Pereira [ctb], Christophe Dervieux [ctb], David Hall [ctb], David Hugh-Jones [ctb], David Robinson [ctb], Doug Hemken [ctb], Duncan Murdoch [ctb], Elio Campitelli [ctb], Ellis Hughes [ctb], Emily Riederer [ctb], Fabian Hirschmann [ctb], Fitch Simeon [ctb], Forest Fang [ctb], Frank E Harrell Jr [ctb] (the Sweavel package at inst/misc/Sweavel.sty), Garrick Aden-Buie [ctb], Gregoire Detrez [ctb], Hadley Wickham [ctb], Hao Zhu [ctb], Heewon Jeon [ctb], Henrik Bengtsson [ctb], Hiroaki Yutani [ctb], Ian Lyttle [ctb], Hodges Daniel [ctb], Jacob Bien [ctb], Jake Burkhead [ctb], James Manton [ctb], Jared Lander [ctb], Jason Punyon [ctb], Javier Luraschi [ctb], Jeff Arnold [ctb], Jenny Bryan [ctb], Jeremy Ashkenas [ctb, cph] (the CSS file at inst/misc/docco-classic.css), Jeremy Stephens [ctb], Jim Hester [ctb], Joe Cheng [ctb], Johannes Ranke [ctb], John Honaker [ctb], John Muschelli [ctb], Jonathan Keane [ctb], JJ Allaire [ctb], Johan Toloe [ctb], Jonathan Sidi [ctb], Joseph Larmarange [ctb], Julien Barnier [ctb], Kaiyin Zhong [ctb], Kamil Slowikowski [ctb], Karl Forner [ctb], Kevin K. Smith [ctb], Kirill Mueller [ctb], Kohske Takahashi [ctb], Lorenz Walthert [ctb], Lucas Gallindo [ctb], Marius Hofert [ctb], Martin Modrák [ctb], Michael Chirico [ctb], Michael Friendly [ctb], Michal Bojanowski [ctb], Michel Kuhlmann [ctb], Miller Patrick [ctb], Nacho Caballero [ctb], Nick Salkowski [ctb], Niels Richard Hansen [ctb], Noam Ross [ctb], Obada Mahdi [ctb], Pavel N. Krivitsky [ctb] (), Pedro Faria [ctb], Qiang Li [ctb], Ramnath Vaidyanathan [ctb], Richard Cotton [ctb], Robert Krzyzanowski [ctb], Rodrigo Copetti [ctb], Romain Francois [ctb], Ruaridh Williamson [ctb], Sagiru Mati [ctb] (), Scott Kostyshak [ctb], Sebastian Meyer [ctb], Sietse Brouwer [ctb], Simon de Bernard [ctb], Sylvain Rousseau [ctb], Taiyun Wei [ctb], Thibaut Assus [ctb], Thibaut Lamadon [ctb], Thomas Leeper [ctb], Tim Mastny [ctb], Tom Torsney-Weir [ctb], Trevor Davis [ctb], Viktoras Veitas [ctb], Weicheng Zhu [ctb], Wush Wu [ctb], Zachary Foster [ctb], Zhian N. Kamvar [ctb] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "labeling": { + "Package": "labeling", + "Version": "0.4.3", + "Source": "Repository", + "Type": "Package", + "Title": "Axis Labeling", + "Date": "2023-08-29", + "Author": "Justin Talbot,", + "Maintainer": "Nuno Sempere ", + "Description": "Functions which provide a range of axis labeling algorithms.", + "License": "MIT + file LICENSE | Unlimited", + "Collate": "'labeling.R'", + "NeedsCompilation": "no", + "Imports": [ + "stats", + "graphics" + ], + "Repository": "CRAN" + }, + "lambda.r": { + "Package": "lambda.r", + "Version": "1.2.4", + "Source": "Repository", + "Type": "Package", + "Title": "Modeling Data with Functional Programming", + "Date": "2019-09-15", + "Depends": [ + "R (>= 3.0.0)" + ], + "Imports": [ + "formatR" + ], + "Suggests": [ + "testit" + ], + "Author": "Brian Lee Yung Rowe", + "Maintainer": "Brian Lee Yung Rowe ", + "Description": "A language extension to efficiently write functional programs in R. Syntax extensions include multi-part function definitions, pattern matching, guard statements, built-in (optional) type safety.", + "License": "LGPL-3", + "LazyLoad": "yes", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "later": { + "Package": "later", + "Version": "1.4.2", + "Source": "Repository", + "Type": "Package", + "Title": "Utilities for Scheduling Functions to Execute Later with Event Loops", + "Authors@R": "c( person(\"Winston\", \"Chang\", role = c(\"aut\", \"cre\"), email = \"winston@posit.co\"), person(\"Joe\", \"Cheng\", role = c(\"aut\"), email = \"joe@posit.co\"), person(\"Charlie\", \"Gao\", role = c(\"aut\"), email = \"charlie.gao@shikokuchuo.net\", comment = c(ORCID = \"0000-0002-0750-061X\")), person(family = \"Posit Software, PBC\", role = \"cph\"), person(\"Marcus\", \"Geelnard\", role = c(\"ctb\", \"cph\"), comment = \"TinyCThread library, https://tinycthread.github.io/\"), person(\"Evan\", \"Nemerson\", role = c(\"ctb\", \"cph\"), comment = \"TinyCThread library, https://tinycthread.github.io/\") )", + "Description": "Executes arbitrary R or C functions some time after the current time, after the R execution stack has emptied. The functions are scheduled in an event loop.", + "URL": "https://r-lib.github.io/later/, https://github.com/r-lib/later", + "BugReports": "https://github.com/r-lib/later/issues", + "License": "MIT + file LICENSE", + "Imports": [ + "Rcpp (>= 0.12.9)", + "rlang" + ], + "LinkingTo": [ + "Rcpp" + ], + "RoxygenNote": "7.3.2", + "Suggests": [ + "knitr", + "nanonext", + "R6", + "rmarkdown", + "testthat (>= 2.1.0)" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Winston Chang [aut, cre], Joe Cheng [aut], Charlie Gao [aut] (), Posit Software, PBC [cph], Marcus Geelnard [ctb, cph] (TinyCThread library, https://tinycthread.github.io/), Evan Nemerson [ctb, cph] (TinyCThread library, https://tinycthread.github.io/)", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "lattice": { + "Package": "lattice", + "Version": "0.22-7", + "Source": "Repository", + "Date": "2025-03-31", + "Priority": "recommended", + "Title": "Trellis Graphics for R", + "Authors@R": "c(person(\"Deepayan\", \"Sarkar\", role = c(\"aut\", \"cre\"), email = \"deepayan.sarkar@r-project.org\", comment = c(ORCID = \"0000-0003-4107-1553\")), person(\"Felix\", \"Andrews\", role = \"ctb\"), person(\"Kevin\", \"Wright\", role = \"ctb\", comment = \"documentation\"), person(\"Neil\", \"Klepeis\", role = \"ctb\"), person(\"Johan\", \"Larsson\", role = \"ctb\", comment = \"miscellaneous improvements\"), person(\"Zhijian (Jason)\", \"Wen\", role = \"cph\", comment = \"filled contour code\"), person(\"Paul\", \"Murrell\", role = \"ctb\", email = \"paul@stat.auckland.ac.nz\"), person(\"Stefan\", \"Eng\", role = \"ctb\", comment = \"violin plot improvements\"), person(\"Achim\", \"Zeileis\", role = \"ctb\", comment = \"modern colors\"), person(\"Alexandre\", \"Courtiol\", role = \"ctb\", comment = \"generics for larrows, lpolygon, lrect and lsegments\") )", + "Description": "A powerful and elegant high-level data visualization system inspired by Trellis graphics, with an emphasis on multivariate data. Lattice is sufficient for typical graphics needs, and is also flexible enough to handle most nonstandard requirements. See ?Lattice for an introduction.", + "Depends": [ + "R (>= 4.0.0)" + ], + "Suggests": [ + "KernSmooth", + "MASS", + "latticeExtra", + "colorspace" + ], + "Imports": [ + "grid", + "grDevices", + "graphics", + "stats", + "utils" + ], + "Enhances": [ + "chron", + "zoo" + ], + "LazyLoad": "yes", + "LazyData": "yes", + "License": "GPL (>= 2)", + "URL": "https://lattice.r-forge.r-project.org/", + "BugReports": "https://github.com/deepayan/lattice/issues", + "NeedsCompilation": "yes", + "Author": "Deepayan Sarkar [aut, cre] (), Felix Andrews [ctb], Kevin Wright [ctb] (documentation), Neil Klepeis [ctb], Johan Larsson [ctb] (miscellaneous improvements), Zhijian (Jason) Wen [cph] (filled contour code), Paul Murrell [ctb], Stefan Eng [ctb] (violin plot improvements), Achim Zeileis [ctb] (modern colors), Alexandre Courtiol [ctb] (generics for larrows, lpolygon, lrect and lsegments)", + "Maintainer": "Deepayan Sarkar ", + "Repository": "CRAN" + }, + "lazyeval": { + "Package": "lazyeval", + "Version": "0.2.2", + "Source": "Repository", + "Title": "Lazy (Non-Standard) Evaluation", + "Description": "An alternative approach to non-standard evaluation using formulas. Provides a full implementation of LISP style 'quasiquotation', making it easier to generate code with other code.", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", ,\"hadley@rstudio.com\", c(\"aut\", \"cre\")), person(\"RStudio\", role = \"cph\") )", + "License": "GPL-3", + "LazyData": "true", + "Depends": [ + "R (>= 3.1.0)" + ], + "Suggests": [ + "knitr", + "rmarkdown (>= 0.2.65)", + "testthat", + "covr" + ], + "VignetteBuilder": "knitr", + "RoxygenNote": "6.1.1", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre], RStudio [cph]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.4", + "Source": "Repository", + "Title": "Manage the Life Cycle of your Package Functions", + "Authors@R": "c( person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Manage the life cycle of your exported functions with shared conventions, documentation badges, and user-friendly deprecation warnings.", + "License": "MIT + file LICENSE", + "URL": "https://lifecycle.r-lib.org/, https://github.com/r-lib/lifecycle", + "BugReports": "https://github.com/r-lib/lifecycle/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli (>= 3.4.0)", + "glue", + "rlang (>= 1.1.0)" + ], + "Suggests": [ + "covr", + "crayon", + "knitr", + "lintr", + "rmarkdown", + "testthat (>= 3.0.1)", + "tibble", + "tidyverse", + "tools", + "vctrs", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate, usethis", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.1", + "NeedsCompilation": "no", + "Author": "Lionel Henry [aut, cre], Hadley Wickham [aut] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "lme4": { + "Package": "lme4", + "Version": "1.1-37", + "Source": "Repository", + "Title": "Linear Mixed-Effects Models using 'Eigen' and S4", + "Authors@R": "c( person(\"Douglas\",\"Bates\", role=\"aut\", comment=c(ORCID=\"0000-0001-8316-9503\")), person(\"Martin\",\"Maechler\", role=\"aut\", comment=c(ORCID=\"0000-0002-8685-9910\")), person(\"Ben\",\"Bolker\",email=\"bbolker+lme4@gmail.com\", role=c(\"aut\",\"cre\"), comment=c(ORCID=\"0000-0002-2127-0443\")), person(\"Steven\",\"Walker\",role=\"aut\", comment=c(ORCID=\"0000-0002-4394-9078\")), person(\"Rune Haubo Bojesen\",\"Christensen\", role=\"ctb\", comment=c(ORCID=\"0000-0002-4494-3399\")), person(\"Henrik\",\"Singmann\", role=\"ctb\", comment=c(ORCID=\"0000-0002-4842-3657\")), person(\"Bin\", \"Dai\", role=\"ctb\"), person(\"Fabian\", \"Scheipl\", role=\"ctb\", comment=c(ORCID=\"0000-0001-8172-3603\")), person(\"Gabor\", \"Grothendieck\", role=\"ctb\"), person(\"Peter\", \"Green\", role=\"ctb\", comment=c(ORCID=\"0000-0002-0238-9852\")), person(\"John\", \"Fox\", role=\"ctb\"), person(\"Alexander\", \"Bauer\", role=\"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role=c(\"ctb\",\"cph\"), comment=c(ORCID=\"0000-0002-9101-3362\", \"shared copyright on simulate.formula\")), person(\"Emi\", \"Tanaka\", role = \"ctb\", comment = c(ORCID=\"0000-0002-1455-259X\")), person(\"Mikael\", \"Jagan\", role = \"ctb\", comment = c(ORCID=\"0000-0002-3542-2938\")), person(\"Ross D.\", \"Boylan\", email=\"ross.boylan@ucsf.edu\", role=(\"ctb\"), comment = c(ORCID=\"0009-0003-4123-8090\")) )", + "Description": "Fit linear and generalized linear mixed-effects models. The models and their components are represented using S4 classes and methods. The core computational algorithms are implemented using the 'Eigen' C++ library for numerical linear algebra and 'RcppEigen' \"glue\".", + "Depends": [ + "R (>= 3.6.0)", "Matrix", - "R", "methods", "stats" ], - "Hash": "acb06a47b732c6251afd16e19c3201ff" + "LinkingTo": [ + "Rcpp (>= 0.10.5)", + "RcppEigen (>= 0.3.3.9.4)", + "Matrix (>= 1.2-3)" + ], + "Imports": [ + "graphics", + "grid", + "splines", + "utils", + "parallel", + "MASS", + "lattice", + "boot", + "nlme (>= 3.1-123)", + "minqa (>= 1.1.15)", + "nloptr (>= 1.0.4)", + "reformulas (>= 0.3.0)" + ], + "Suggests": [ + "knitr", + "rmarkdown", + "MEMSS", + "testthat (>= 0.8.1)", + "ggplot2", + "mlmRev", + "optimx (>= 2013.8.6)", + "gamm4", + "pbkrtest", + "HSAUR3", + "numDeriv", + "car", + "dfoptim", + "mgcv", + "statmod", + "rr2", + "semEff", + "tibble", + "merDeriv" + ], + "VignetteBuilder": "knitr", + "LazyData": "yes", + "License": "GPL (>= 2)", + "URL": "https://github.com/lme4/lme4/", + "BugReports": "https://github.com/lme4/lme4/issues", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Douglas Bates [aut] (), Martin Maechler [aut] (), Ben Bolker [aut, cre] (), Steven Walker [aut] (), Rune Haubo Bojesen Christensen [ctb] (), Henrik Singmann [ctb] (), Bin Dai [ctb], Fabian Scheipl [ctb] (), Gabor Grothendieck [ctb], Peter Green [ctb] (), John Fox [ctb], Alexander Bauer [ctb], Pavel N. Krivitsky [ctb, cph] (, shared copyright on simulate.formula), Emi Tanaka [ctb] (), Mikael Jagan [ctb] (), Ross D. Boylan [ctb] ()", + "Maintainer": "Ben Bolker ", + "Repository": "CRAN" }, - "jsonlite": { - "Package": "jsonlite", - "Version": "1.8.8", + "magick": { + "Package": "magick", + "Version": "2.8.7", + "Source": "Repository", + "Type": "Package", + "Title": "Advanced Graphics and Image-Processing in R", + "Authors@R": "person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\"))", + "Description": "Bindings to 'ImageMagick': the most comprehensive open-source image processing library available. Supports many common formats (png, jpeg, tiff, pdf, etc) and manipulations (rotate, scale, crop, trim, flip, blur, etc). All operations are vectorized via the Magick++ STL meaning they operate either on a single frame or a series of frames for working with layers, collages, or animation. In RStudio images are automatically previewed when printed to the console, resulting in an interactive editing environment. The latest version of the package includes a native graphics device for creating in-memory graphics or drawing onto images using pixel coordinates.", + "License": "MIT + file LICENSE", + "URL": "https://docs.ropensci.org/magick/ https://ropensci.r-universe.dev/magick", + "BugReports": "https://github.com/ropensci/magick/issues", + "SystemRequirements": "ImageMagick++: ImageMagick-c++-devel (rpm) or libmagick++-dev (deb)", + "VignetteBuilder": "knitr", + "Depends": [ + "R (>= 4.1.0)" + ], + "Imports": [ + "Rcpp (>= 0.12.12)", + "magrittr", + "curl" + ], + "LinkingTo": [ + "Rcpp" + ], + "Suggests": [ + "av (>= 0.3)", + "spelling", + "jsonlite", + "methods", + "knitr", + "rmarkdown", + "rsvg", + "webp", + "pdftools", + "ggplot2", + "gapminder", + "IRdisplay", + "tesseract (>= 2.0)", + "gifski" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (ORCID: )", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Type": "Package", + "Title": "A Forward-Pipe Operator for R", + "Authors@R": "c( person(\"Stefan Milton\", \"Bache\", , \"stefan@stefanbache.dk\", role = c(\"aut\", \"cph\"), comment = \"Original author and creator of magrittr\"), person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = \"aut\"), person(\"Lionel\", \"Henry\", , \"lionel@rstudio.com\", role = \"cre\"), person(\"RStudio\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides a mechanism for chaining commands with a new forward-pipe operator, %>%. This operator will forward a value, or the result of an expression, into the next function call/expression. There is flexible support for the type of right-hand side expressions. For more information, see package vignette. To quote Rene Magritte, \"Ceci n'est pas un pipe.\"", + "License": "MIT + file LICENSE", + "URL": "https://magrittr.tidyverse.org, https://github.com/tidyverse/magrittr", + "BugReports": "https://github.com/tidyverse/magrittr/issues", + "Depends": [ + "R (>= 3.4.0)" + ], + "Suggests": [ + "covr", + "knitr", + "rlang", + "rmarkdown", + "testthat" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "Yes", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "yes", + "Author": "Stefan Milton Bache [aut, cph] (Original author and creator of magrittr), Hadley Wickham [aut], Lionel Henry [cre], RStudio [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "matrixStats": { + "Package": "matrixStats", + "Version": "1.5.0", + "Source": "Repository", + "Depends": [ + "R (>= 3.4.0)" + ], + "Suggests": [ + "utils", + "base64enc", + "ggplot2", + "knitr", + "markdown", + "microbenchmark", + "R.devices", + "R.rsp" + ], + "VignetteBuilder": "R.rsp", + "Title": "Functions that Apply to Rows and Columns of Matrices (and to Vectors)", + "Authors@R": "c( person(\"Henrik\", \"Bengtsson\", role=c(\"aut\", \"cre\", \"cph\"), email=\"henrikb@braju.com\"), person(\"Constantin\", \"Ahlmann-Eltze\", role = \"ctb\"), person(\"Hector\", \"Corrada Bravo\", role=\"ctb\"), person(\"Robert\", \"Gentleman\", role=\"ctb\"), person(\"Jan\", \"Gleixner\", role=\"ctb\"), person(\"Peter\", \"Hickey\", role=\"ctb\"), person(\"Ola\", \"Hossjer\", role=\"ctb\"), person(\"Harris\", \"Jaffee\", role=\"ctb\"), person(\"Dongcan\", \"Jiang\", role=\"ctb\"), person(\"Peter\", \"Langfelder\", role=\"ctb\"), person(\"Brian\", \"Montgomery\", role=\"ctb\"), person(\"Angelina\", \"Panagopoulou\", role=\"ctb\"), person(\"Hugh\", \"Parsonage\", role=\"ctb\"), person(\"Jakob Peder\", \"Pettersen\", role=\"ctb\"))", + "Author": "Henrik Bengtsson [aut, cre, cph], Constantin Ahlmann-Eltze [ctb], Hector Corrada Bravo [ctb], Robert Gentleman [ctb], Jan Gleixner [ctb], Peter Hickey [ctb], Ola Hossjer [ctb], Harris Jaffee [ctb], Dongcan Jiang [ctb], Peter Langfelder [ctb], Brian Montgomery [ctb], Angelina Panagopoulou [ctb], Hugh Parsonage [ctb], Jakob Peder Pettersen [ctb]", + "Maintainer": "Henrik Bengtsson ", + "Description": "High-performing functions operating on rows and columns of matrices, e.g. col / rowMedians(), col / rowRanks(), and col / rowSds(). Functions optimized per data type and for subsetted calculations such that both memory usage and processing time is minimized. There are also optimized vector-based methods, e.g. binMeans(), madDiff() and weightedMedian().", + "License": "Artistic-2.0", + "LazyLoad": "TRUE", + "NeedsCompilation": "yes", + "ByteCompile": "TRUE", + "URL": "https://github.com/HenrikBengtsson/matrixStats", + "BugReports": "https://github.com/HenrikBengtsson/matrixStats/issues", + "RoxygenNote": "7.3.2", + "Repository": "CRAN" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Title": "'Memoisation' of Functions", + "Authors@R": "c(person(given = \"Hadley\", family = \"Wickham\", role = \"aut\", email = \"hadley@rstudio.com\"), person(given = \"Jim\", family = \"Hester\", role = \"aut\"), person(given = \"Winston\", family = \"Chang\", role = c(\"aut\", \"cre\"), email = \"winston@rstudio.com\"), person(given = \"Kirill\", family = \"Müller\", role = \"aut\", email = \"krlmlr+r@mailbox.org\"), person(given = \"Daniel\", family = \"Cook\", role = \"aut\", email = \"danielecook@gmail.com\"), person(given = \"Mark\", family = \"Edmondson\", role = \"ctb\", email = \"r@sunholo.com\"))", + "Description": "Cache the results of a function so that when you call it again with the same arguments it returns the previously computed value.", + "License": "MIT + file LICENSE", + "URL": "https://memoise.r-lib.org, https://github.com/r-lib/memoise", + "BugReports": "https://github.com/r-lib/memoise/issues", + "Imports": [ + "rlang (>= 0.4.10)", + "cachem" + ], + "Suggests": [ + "digest", + "aws.s3", + "covr", + "googleAuthR", + "googleCloudStorageR", + "httr", + "testthat" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut], Jim Hester [aut], Winston Chang [aut, cre], Kirill Müller [aut], Daniel Cook [aut], Mark Edmondson [ctb]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "mgcv": { + "Package": "mgcv", + "Version": "1.9-3", + "Source": "Repository", + "Authors@R": "person(given = \"Simon\", family = \"Wood\", role = c(\"aut\", \"cre\"), email = \"simon.wood@r-project.org\")", + "Title": "Mixed GAM Computation Vehicle with Automatic Smoothness Estimation", + "Description": "Generalized additive (mixed) models, some of their extensions and other generalized ridge regression with multiple smoothing parameter estimation by (Restricted) Marginal Likelihood, Generalized Cross Validation and similar, or using iterated nested Laplace approximation for fully Bayesian inference. See Wood (2017) for an overview. Includes a gam() function, a wide variety of smoothers, 'JAGS' support and distributions beyond the exponential family.", + "Priority": "recommended", + "Depends": [ + "R (>= 3.6.0)", + "nlme (>= 3.1-64)" + ], + "Imports": [ + "methods", + "stats", + "graphics", + "Matrix", + "splines", + "utils" + ], + "Suggests": [ + "parallel", + "survival", + "MASS" + ], + "LazyLoad": "yes", + "ByteCompile": "yes", + "License": "GPL (>= 2)", + "NeedsCompilation": "yes", + "Author": "Simon Wood [aut, cre]", + "Maintainer": "Simon Wood ", + "Repository": "CRAN" + }, + "microbenchmark": { + "Package": "microbenchmark", + "Version": "1.5.0", + "Source": "Repository", + "Title": "Accurate Timing Functions", + "Description": "Provides infrastructure to accurately measure and compare the execution time of R expressions.", + "Authors@R": "c(person(\"Olaf\", \"Mersmann\", role=c(\"aut\")), person(\"Claudia\", \"Beleites\", role=c(\"ctb\")), person(\"Rainer\", \"Hurling\", role=c(\"ctb\")), person(\"Ari\", \"Friedman\", role=c(\"ctb\")), person(given=c(\"Joshua\",\"M.\"), family=\"Ulrich\", role=\"cre\", email=\"josh.m.ulrich@gmail.com\"))", + "URL": "https://github.com/joshuaulrich/microbenchmark/", + "BugReports": "https://github.com/joshuaulrich/microbenchmark/issues/", + "License": "BSD_2_clause + file LICENSE", + "Depends": [ + "R (>= 3.2.0)" + ], + "Imports": [ + "graphics", + "stats" + ], + "Suggests": [ + "ggplot2", + "multcomp", + "RUnit" + ], + "SystemRequirements": "On a Unix-alike, one of the C functions mach_absolute_time (macOS), clock_gettime or gethrtime. If none of these is found, the obsolescent POSIX function gettimeofday will be tried.", + "ByteCompile": "yes", + "NeedsCompilation": "yes", + "Author": "Olaf Mersmann [aut], Claudia Beleites [ctb], Rainer Hurling [ctb], Ari Friedman [ctb], Joshua M. Ulrich [cre]", + "Maintainer": "Joshua M. Ulrich ", + "Repository": "CRAN" + }, + "mime": { + "Package": "mime", + "Version": "0.13", + "Source": "Repository", + "Type": "Package", + "Title": "Map Filenames to MIME Types", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Jeffrey\", \"Horner\", role = \"ctb\"), person(\"Beilei\", \"Bian\", role = \"ctb\") )", + "Description": "Guesses the MIME type from a filename extension using the data derived from /etc/mime.types in UNIX-type systems.", + "Imports": [ + "tools" + ], + "License": "GPL", + "URL": "https://github.com/yihui/mime", + "BugReports": "https://github.com/yihui/mime/issues", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Yihui Xie [aut, cre] (, https://yihui.org), Jeffrey Horner [ctb], Beilei Bian [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "minqa": { + "Package": "minqa", + "Version": "1.2.8", + "Source": "Repository", + "Type": "Package", + "Title": "Derivative-Free Optimization Algorithms by Quadratic Approximation", + "Authors@R": "c(person(given = \"Douglas\", family = \"Bates\", role = \"aut\"), person(given = c(\"Katharine\", \"M.\"), family = \"Mullen\", role = c(\"aut\", \"cre\"), email = \"katharine.mullen@stat.ucla.edu\"), person(given = c(\"John\", \"C.\"), family = \"Nash\", role = \"aut\"), person(given = \"Ravi\", family = \"Varadhan\", role = \"aut\"))", + "Maintainer": "Katharine M. Mullen ", + "Description": "Derivative-free optimization by quadratic approximation based on an interface to Fortran implementations by M. J. D. Powell.", + "License": "GPL-2", + "URL": "http://optimizer.r-forge.r-project.org", + "Imports": [ + "Rcpp (>= 0.9.10)" + ], + "LinkingTo": [ + "Rcpp" + ], + "SystemRequirements": "GNU make", + "NeedsCompilation": "yes", + "Repository": "CRAN", + "Author": "Douglas Bates [aut], Katharine M. Mullen [aut, cre], John C. Nash [aut], Ravi Varadhan [aut]" + }, + "mixtools": { + "Package": "mixtools", + "Version": "2.0.0.1", + "Source": "Repository", + "Date": "2022-12-04", + "Title": "Tools for Analyzing Finite Mixture Models", + "Authors@R": "c(person(\"Derek\", \"Young\", role = c(\"aut\", \"cre\"), email = \"derek.young@uky.edu\", comment = c(ORCID = \"0000-0002-3048-3803\")), person(\"Tatiana\", \"Benaglia\", role = \"aut\"), person(\"Didier\", \"Chauveau\", role = \"aut\"), person(\"David\", \"Hunter\", role = \"aut\"), person(\"Kedai\", \"Cheng\", role = \"aut\"), person(\"Ryan\", \"Elmore\", role = \"ctb\"), person(\"Thomas\", \"Hettmansperger\", role = \"ctb\"), person(\"Hoben\", \"Thomas\", role = \"ctb\"), person(\"Fengjuan\", \"Xuan\", role = \"ctb\"))", + "Depends": [ + "R (>= 4.0.0)" + ], + "Imports": [ + "kernlab", + "MASS", + "plotly", + "scales", + "segmented", + "stats", + "survival" + ], + "URL": "https://github.com/dsy109/mixtools", + "Description": "Analyzes finite mixture models for various parametric and semiparametric settings. This includes mixtures of parametric distributions (normal, multivariate normal, multinomial, gamma), various Reliability Mixture Models (RMMs), mixtures-of-regressions settings (linear regression, logistic regression, Poisson regression, linear regression with changepoints, predictor-dependent mixing proportions, random effects regressions, hierarchical mixtures-of-experts), and tools for selecting the number of components (bootstrapping the likelihood ratio test statistic, mixturegrams, and model selection criteria). Bayesian estimation of mixtures-of-linear-regressions models is available as well as a novel data depth method for obtaining credible bands. This package is based upon work supported by the National Science Foundation under Grant No. SES-0518772 and the Chan Zuckerberg Initiative: Essential Open Source Software for Science (Grant No. 2020-255193).", + "License": "GPL (>= 2)", + "NeedsCompilation": "yes", + "Author": "Derek Young [aut, cre] (), Tatiana Benaglia [aut], Didier Chauveau [aut], David Hunter [aut], Kedai Cheng [aut], Ryan Elmore [ctb], Thomas Hettmansperger [ctb], Hoben Thomas [ctb], Fengjuan Xuan [ctb]", + "Maintainer": "Derek Young ", + "Repository": "CRAN" + }, + "modelr": { + "Package": "modelr", + "Version": "0.1.11", + "Source": "Repository", + "Title": "Modelling Functions that Work with the Pipe", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Functions for modelling that help you seamlessly integrate modelling into a pipeline of data manipulation and visualisation.", + "License": "GPL-3", + "URL": "https://modelr.tidyverse.org, https://github.com/tidyverse/modelr", + "BugReports": "https://github.com/tidyverse/modelr/issues", + "Depends": [ + "R (>= 3.2)" + ], + "Imports": [ + "broom", + "magrittr", + "purrr (>= 0.2.2)", + "rlang (>= 1.0.6)", + "tibble", + "tidyr (>= 0.8.0)", + "tidyselect", + "vctrs" + ], + "Suggests": [ + "compiler", + "covr", + "ggplot2", + "testthat (>= 3.0.0)" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "mvtnorm": { + "Package": "mvtnorm", + "Version": "1.3-3", + "Source": "Repository", + "Title": "Multivariate Normal and t Distributions", + "Date": "2025-01-09", + "Authors@R": "c(person(\"Alan\", \"Genz\", role = \"aut\"), person(\"Frank\", \"Bretz\", role = \"aut\"), person(\"Tetsuhisa\", \"Miwa\", role = \"aut\"), person(\"Xuefei\", \"Mi\", role = \"aut\"), person(\"Friedrich\", \"Leisch\", role = \"ctb\"), person(\"Fabian\", \"Scheipl\", role = \"ctb\"), person(\"Bjoern\", \"Bornkamp\", role = \"ctb\", comment = c(ORCID = \"0000-0002-6294-8185\")), person(\"Martin\", \"Maechler\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8685-9910\")), person(\"Torsten\", \"Hothorn\", role = c(\"aut\", \"cre\"), email = \"Torsten.Hothorn@R-project.org\", comment = c(ORCID = \"0000-0001-8301-0471\")))", + "Description": "Computes multivariate normal and t probabilities, quantiles, random deviates, and densities. Log-likelihoods for multivariate Gaussian models and Gaussian copulae parameterised by Cholesky factors of covariance or precision matrices are implemented for interval-censored and exact data, or a mix thereof. Score functions for these log-likelihoods are available. A class representing multiple lower triangular matrices and corresponding methods are part of this package.", + "Imports": [ + "stats" + ], + "Depends": [ + "R(>= 3.5.0)" + ], + "Suggests": [ + "qrng", + "numDeriv" + ], + "License": "GPL-2", + "URL": "http://mvtnorm.R-forge.R-project.org", + "NeedsCompilation": "yes", + "Author": "Alan Genz [aut], Frank Bretz [aut], Tetsuhisa Miwa [aut], Xuefei Mi [aut], Friedrich Leisch [ctb], Fabian Scheipl [ctb], Bjoern Bornkamp [ctb] (), Martin Maechler [ctb] (), Torsten Hothorn [aut, cre] ()", + "Maintainer": "Torsten Hothorn ", + "Repository": "CRAN" + }, + "nlme": { + "Package": "nlme", + "Version": "3.1-168", + "Source": "Repository", + "Date": "2025-03-31", + "Priority": "recommended", + "Title": "Linear and Nonlinear Mixed Effects Models", + "Authors@R": "c(person(\"José\", \"Pinheiro\", role = \"aut\", comment = \"S version\"), person(\"Douglas\", \"Bates\", role = \"aut\", comment = \"up to 2007\"), person(\"Saikat\", \"DebRoy\", role = \"ctb\", comment = \"up to 2002\"), person(\"Deepayan\", \"Sarkar\", role = \"ctb\", comment = \"up to 2005\"), person(\"EISPACK authors\", role = \"ctb\", comment = \"src/rs.f\"), person(\"Siem\", \"Heisterkamp\", role = \"ctb\", comment = \"Author fixed sigma\"), person(\"Bert\", \"Van Willigen\",role = \"ctb\", comment = \"Programmer fixed sigma\"), person(\"Johannes\", \"Ranke\", role = \"ctb\", comment = \"varConstProp()\"), person(\"R Core Team\", email = \"R-core@R-project.org\", role = c(\"aut\", \"cre\"), comment = c(ROR = \"02zz1nj61\")))", + "Contact": "see 'MailingList'", + "Description": "Fit and compare Gaussian linear and nonlinear mixed-effects models.", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "graphics", + "stats", + "utils", + "lattice" + ], + "Suggests": [ + "MASS", + "SASmixed" + ], + "LazyData": "yes", + "Encoding": "UTF-8", + "License": "GPL (>= 2)", + "BugReports": "https://bugs.r-project.org", + "MailingList": "R-help@r-project.org", + "URL": "https://svn.r-project.org/R-packages/trunk/nlme/", + "NeedsCompilation": "yes", + "Author": "José Pinheiro [aut] (S version), Douglas Bates [aut] (up to 2007), Saikat DebRoy [ctb] (up to 2002), Deepayan Sarkar [ctb] (up to 2005), EISPACK authors [ctb] (src/rs.f), Siem Heisterkamp [ctb] (Author fixed sigma), Bert Van Willigen [ctb] (Programmer fixed sigma), Johannes Ranke [ctb] (varConstProp()), R Core Team [aut, cre] (02zz1nj61)", + "Maintainer": "R Core Team ", + "Repository": "CRAN" + }, + "nloptr": { + "Package": "nloptr", + "Version": "2.2.1", + "Source": "Repository", + "Type": "Package", + "Title": "R Interface to NLopt", + "Authors@R": "c(person(\"Jelmer\", \"Ypma\", role = \"aut\", email = \"uctpjyy@ucl.ac.uk\"), person(c(\"Steven\", \"G.\"), \"Johnson\", role = \"aut\", comment = \"author of the NLopt C library\"), person(\"Aymeric\", \"Stamm\", role = c(\"ctb\", \"cre\"), email = \"aymeric.stamm@cnrs.fr\", comment = c(ORCID = \"0000-0002-8725-3654\")), person(c(\"Hans\", \"W.\"), \"Borchers\", role = \"ctb\", email = \"hwborchers@googlemail.com\"), person(\"Dirk\", \"Eddelbuettel\", role = \"ctb\", email = \"edd@debian.org\"), person(\"Brian\", \"Ripley\", role = \"ctb\", comment = \"build process on multiple OS\"), person(\"Kurt\", \"Hornik\", role = \"ctb\", comment = \"build process on multiple OS\"), person(\"Julien\", \"Chiquet\", role = \"ctb\"), person(\"Avraham\", \"Adler\", role = \"ctb\", email = \"Avraham.Adler@gmail.com\", comment = c(ORCID = \"0000-0002-3039-0703\")), person(\"Xiongtao\", \"Dai\", role = \"ctb\"), person(\"Jeroen\", \"Ooms\", role = \"ctb\", email = \"jeroen@berkeley.edu\"), person(\"Tomas\", \"Kalibera\", role = \"ctb\"), person(\"Mikael\", \"Jagan\", role = \"ctb\"))", + "Description": "Solve optimization problems using an R interface to NLopt. NLopt is a free/open-source library for nonlinear optimization, providing a common interface for a number of different free optimization routines available online as well as original implementations of various other algorithms. See for more information on the available algorithms. Building from included sources requires 'CMake'. On Linux and 'macOS', if a suitable system build of NLopt (2.7.0 or later) is found, it is used; otherwise, it is built from included sources via 'CMake'. On Windows, NLopt is obtained through 'rwinlib' for 'R <= 4.1.x' or grabbed from the appropriate toolchain for 'R >= 4.2.0'.", + "License": "LGPL (>= 3)", + "SystemRequirements": "cmake (>= 3.2.0) which is used only on Linux or macOS systems when no system build of nlopt (>= 2.7.0) can be found.", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Suggests": [ + "knitr", + "rmarkdown", + "covr", + "tinytest" + ], + "VignetteBuilder": "knitr", + "URL": "https://github.com/astamm/nloptr, https://astamm.github.io/nloptr/", + "BugReports": "https://github.com/astamm/nloptr/issues", + "NeedsCompilation": "yes", + "UseLTO": "yes", + "Author": "Jelmer Ypma [aut], Steven G. Johnson [aut] (author of the NLopt C library), Aymeric Stamm [ctb, cre] (), Hans W. Borchers [ctb], Dirk Eddelbuettel [ctb], Brian Ripley [ctb] (build process on multiple OS), Kurt Hornik [ctb] (build process on multiple OS), Julien Chiquet [ctb], Avraham Adler [ctb] (), Xiongtao Dai [ctb], Jeroen Ooms [ctb], Tomas Kalibera [ctb], Mikael Jagan [ctb]", + "Maintainer": "Aymeric Stamm ", + "Repository": "CRAN" + }, + "nnet": { + "Package": "nnet", + "Version": "7.3-20", + "Source": "Repository", + "Priority": "recommended", + "Date": "2025-01-01", + "Depends": [ + "R (>= 3.0.0)", + "stats", + "utils" + ], + "Suggests": [ + "MASS" + ], + "Authors@R": "c(person(\"Brian\", \"Ripley\", role = c(\"aut\", \"cre\", \"cph\"), email = \"Brian.Ripley@R-project.org\"), person(\"William\", \"Venables\", role = \"cph\"))", + "Description": "Software for feed-forward neural networks with a single hidden layer, and for multinomial log-linear models.", + "Title": "Feed-Forward Neural Networks and Multinomial Log-Linear Models", + "ByteCompile": "yes", + "License": "GPL-2 | GPL-3", + "URL": "http://www.stats.ox.ac.uk/pub/MASS4/", + "NeedsCompilation": "yes", + "Author": "Brian Ripley [aut, cre, cph], William Venables [cph]", + "Maintainer": "Brian Ripley ", + "Repository": "CRAN" + }, + "numDeriv": { + "Package": "numDeriv", + "Version": "2016.8-1.1", + "Source": "Repository", + "Title": "Accurate Numerical Derivatives", + "Description": "Methods for calculating (usually) accurate numerical first and second order derivatives. Accurate calculations are done using 'Richardson''s' extrapolation or, when applicable, a complex step derivative is available. A simple difference method is also provided. Simple difference is (usually) less accurate but is much quicker than 'Richardson''s' extrapolation and provides a useful cross-check. Methods are provided for real scalar and vector valued functions.", + "Depends": [ + "R (>= 2.11.1)" + ], + "LazyLoad": "yes", + "ByteCompile": "yes", + "License": "GPL-2", + "Copyright": "2006-2011, Bank of Canada. 2012-2016, Paul Gilbert", + "Author": "Paul Gilbert and Ravi Varadhan", + "Maintainer": "Paul Gilbert ", + "URL": "http://optimizer.r-forge.r-project.org/", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "openssl": { + "Package": "openssl", + "Version": "2.3.3", + "Source": "Repository", + "Type": "Package", + "Title": "Toolkit for Encryption, Signatures and Certificates Based on OpenSSL", + "Authors@R": "c(person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Oliver\", \"Keyes\", role = \"ctb\"))", + "Description": "Bindings to OpenSSL libssl and libcrypto, plus custom SSH key parsers. Supports RSA, DSA and EC curves P-256, P-384, P-521, and curve25519. Cryptographic signatures can either be created and verified manually or via x509 certificates. AES can be used in cbc, ctr or gcm mode for symmetric encryption; RSA for asymmetric (public key) encryption or EC for Diffie Hellman. High-level envelope functions combine RSA and AES for encrypting arbitrary sized data. Other utilities include key generators, hash functions (md5, sha1, sha256, etc), base64 encoder, a secure random number generator, and 'bignum' math methods for manually performing crypto calculations on large multibyte integers.", + "License": "MIT + file LICENSE", + "URL": "https://jeroen.r-universe.dev/openssl", + "BugReports": "https://github.com/jeroen/openssl/issues", + "SystemRequirements": "OpenSSL >= 1.0.2", + "VignetteBuilder": "knitr", + "Imports": [ + "askpass" + ], + "Suggests": [ + "curl", + "testthat (>= 2.1.0)", + "digest", + "knitr", + "rmarkdown", + "jsonlite", + "jose", + "sodium" + ], + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (ORCID: ), Oliver Keyes [ctb]", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "pbkrtest": { + "Package": "pbkrtest", + "Version": "0.5.4", + "Source": "Repository", + "Title": "Parametric Bootstrap, Kenward-Roger and Satterthwaite Based Methods for Test in Mixed Models", + "Authors@R": "c( person(given = \"Ulrich\", family = \"Halekoh\", email = \"uhalekoh@health.sdu.dk\", role = c(\"aut\", \"cph\")), person(given = \"Søren\", family = \"Højsgaard\", email = \"sorenh@math.aau.dk\", role = c(\"aut\", \"cre\", \"cph\")) )", + "Maintainer": "Søren Højsgaard ", + "Description": "Computes p-values based on (a) Satterthwaite or Kenward-Rogers degree of freedom methods and (b) parametric bootstrap for mixed effects models as implemented in the 'lme4' package. Implements parametric bootstrap test for generalized linear mixed models as implemented in 'lme4' and generalized linear models. The package is documented in the paper by Halekoh and Højsgaard, (2012, ). Please see 'citation(\"pbkrtest\")' for citation details.", + "URL": "https://people.math.aau.dk/~sorenh/software/pbkrtest/", + "Depends": [ + "R (>= 4.2.0)", + "lme4 (>= 1.1.31)" + ], + "Imports": [ + "broom", + "dplyr", + "MASS", + "methods", + "numDeriv", + "Matrix (>= 1.2.3)", + "doBy (>= 4.6.22)" + ], + "Suggests": [ + "markdown", + "knitr" + ], + "Encoding": "UTF-8", + "VignetteBuilder": "knitr", + "License": "GPL (>= 2)", + "ByteCompile": "Yes", + "RoxygenNote": "7.3.2", + "LazyData": "true", + "NeedsCompilation": "no", + "Author": "Ulrich Halekoh [aut, cph], Søren Højsgaard [aut, cre, cph]", + "Repository": "CRAN" + }, + "pillar": { + "Package": "pillar", + "Version": "1.11.0", + "Source": "Repository", + "Title": "Coloured Formatting for Columns", + "Authors@R": "c(person(given = \"Kirill\", family = \"M\\u00fcller\", role = c(\"aut\", \"cre\"), email = \"kirill@cynkra.com\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(given = \"Hadley\", family = \"Wickham\", role = \"aut\"), person(given = \"RStudio\", role = \"cph\"))", + "Description": "Provides 'pillar' and 'colonnade' generics designed for formatting columns of data using the full range of colours provided by modern terminals.", + "License": "MIT + file LICENSE", + "URL": "https://pillar.r-lib.org/, https://github.com/r-lib/pillar", + "BugReports": "https://github.com/r-lib/pillar/issues", + "Imports": [ + "cli (>= 2.3.0)", + "glue", + "lifecycle", + "rlang (>= 1.0.2)", + "utf8 (>= 1.1.0)", + "utils", + "vctrs (>= 0.5.0)" + ], + "Suggests": [ + "bit64", + "DBI", + "debugme", + "DiagrammeR", + "dplyr", + "formattable", + "ggplot2", + "knitr", + "lubridate", + "nanotime", + "nycflights13", + "palmerpenguins", + "rmarkdown", + "scales", + "stringi", + "survival", + "testthat (>= 3.1.1)", + "tibble", + "units (>= 0.7.2)", + "vdiffr", + "withr" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2.9000", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "format_multi_fuzz, format_multi_fuzz_2, format_multi, ctl_colonnade, ctl_colonnade_1, ctl_colonnade_2", + "Config/autostyle/scope": "line_breaks", + "Config/autostyle/strict": "true", + "Config/gha/extra-packages": "units=?ignore-before-r=4.3.0", + "Config/Needs/website": "tidyverse/tidytemplate", + "NeedsCompilation": "no", + "Author": "Kirill Müller [aut, cre] (ORCID: ), Hadley Wickham [aut], RStudio [cph]", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "pkgconfig": { + "Package": "pkgconfig", + "Version": "2.0.3", + "Source": "Repository", + "Title": "Private Configuration for 'R' Packages", + "Author": "Gábor Csárdi", + "Maintainer": "Gábor Csárdi ", + "Description": "Set configuration options on a per-package basis. Options set by a given package only apply to that package, other packages are unaffected.", + "License": "MIT + file LICENSE", + "LazyData": "true", + "Imports": [ + "utils" + ], + "Suggests": [ + "covr", + "testthat", + "disposables (>= 1.0.3)" + ], + "URL": "https://github.com/r-lib/pkgconfig#readme", + "BugReports": "https://github.com/r-lib/pkgconfig/issues", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "plogr": { + "Package": "plogr", + "Version": "0.2.0", + "Source": "Repository", + "Title": "The 'plog' C++ Logging Library", + "Date": "2018-03-24", + "Authors@R": "c( person(\"Kirill\", \"Müller\", role = c(\"aut\", \"cre\"), email = \"krlmlr+r@mailbox.org\"), person(\"Sergey\", \"Podobry\", role = \"cph\", comment = \"Author of the bundled plog library\"))", + "Description": "A simple header-only logging library for C++. Add 'LinkingTo: plogr' to 'DESCRIPTION', and '#include ' in your C++ modules to use it.", + "Suggests": [ + "Rcpp" + ], + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "LazyData": "true", + "URL": "https://github.com/krlmlr/plogr#readme", + "BugReports": "https://github.com/krlmlr/plogr/issues", + "RoxygenNote": "6.0.1.9000", + "NeedsCompilation": "no", + "Author": "Kirill Müller [aut, cre], Sergey Podobry [cph] (Author of the bundled plog library)", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "plotly": { + "Package": "plotly", + "Version": "4.11.0", + "Source": "Repository", + "Title": "Create Interactive Web Graphics via 'plotly.js'", + "Authors@R": "c(person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"cpsievert1@gmail.com\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Chris\", \"Parmer\", role = \"aut\", email = \"chris@plot.ly\"), person(\"Toby\", \"Hocking\", role = \"aut\", email = \"tdhock5@gmail.com\"), person(\"Scott\", \"Chamberlain\", role = \"aut\", email = \"myrmecocystus@gmail.com\"), person(\"Karthik\", \"Ram\", role = \"aut\", email = \"karthik.ram@gmail.com\"), person(\"Marianne\", \"Corvellec\", role = \"aut\", email = \"marianne.corvellec@igdore.org\", comment = c(ORCID = \"0000-0002-1994-3581\")), person(\"Pedro\", \"Despouy\", role = \"aut\", email = \"pedro@plot.ly\"), person(\"Salim\", \"Brüggemann\", role = \"ctb\", email = \"salim-b@pm.me\", comment = c(ORCID = \"0000-0002-5329-5987\")), person(\"Plotly Technologies Inc.\", role = \"cph\"))", + "License": "MIT + file LICENSE", + "Description": "Create interactive web graphics from 'ggplot2' graphs and/or a custom interface to the (MIT-licensed) JavaScript library 'plotly.js' inspired by the grammar of graphics.", + "URL": "https://plotly-r.com, https://github.com/plotly/plotly.R, https://plotly.com/r/", + "BugReports": "https://github.com/plotly/plotly.R/issues", + "Depends": [ + "R (>= 3.2.0)", + "ggplot2 (>= 3.0.0)" + ], + "Imports": [ + "tools", + "scales", + "httr (>= 1.3.0)", + "jsonlite (>= 1.6)", + "magrittr", + "digest", + "viridisLite", + "base64enc", + "htmltools (>= 0.3.6)", + "htmlwidgets (>= 1.5.2.9001)", + "tidyr (>= 1.0.0)", + "RColorBrewer", + "dplyr", + "vctrs", + "tibble", + "lazyeval (>= 0.2.0)", + "rlang (>= 1.0.0)", + "crosstalk", + "purrr", + "data.table", + "promises" + ], + "Suggests": [ + "MASS", + "maps", + "hexbin", + "ggthemes", + "GGally", + "ggalluvial", + "testthat", + "knitr", + "shiny (>= 1.1.0)", + "shinytest2", + "curl", + "rmarkdown", + "Cairo", + "broom", + "webshot", + "listviewer", + "dendextend", + "sf", + "png", + "IRdisplay", + "processx", + "plotlyGeoAssets", + "forcats", + "withr", + "palmerpenguins", + "rversions", + "reticulate", + "rsvg", + "ggridges" + ], + "LazyData": "true", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "Config/Needs/check": "tidyverse/ggplot2, ggobi/GGally, rcmdcheck, devtools, reshape2, s2", + "NeedsCompilation": "no", + "Author": "Carson Sievert [aut, cre] (ORCID: ), Chris Parmer [aut], Toby Hocking [aut], Scott Chamberlain [aut], Karthik Ram [aut], Marianne Corvellec [aut] (ORCID: ), Pedro Despouy [aut], Salim Brüggemann [ctb] (ORCID: ), Plotly Technologies Inc. [cph]", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "plyr": { + "Package": "plyr", + "Version": "1.8.9", + "Source": "Repository", + "Title": "Tools for Splitting, Applying and Combining Data", + "Authors@R": "person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = c(\"aut\", \"cre\"))", + "Description": "A set of tools that solves a common set of problems: you need to break a big problem down into manageable pieces, operate on each piece and then put all the pieces back together. For example, you might want to fit a model to each spatial location or time point in your study, summarise data by panels or collapse high-dimensional arrays to simpler summary statistics. The development of 'plyr' has been generously supported by 'Becton Dickinson'.", + "License": "MIT + file LICENSE", + "URL": "http://had.co.nz/plyr, https://github.com/hadley/plyr", + "BugReports": "https://github.com/hadley/plyr/issues", + "Depends": [ + "R (>= 3.1.0)" + ], + "Imports": [ + "Rcpp (>= 0.11.0)" + ], + "Suggests": [ + "abind", + "covr", + "doParallel", + "foreach", + "iterators", + "itertools", + "tcltk", + "testthat" + ], + "LinkingTo": [ + "Rcpp" + ], + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "png": { + "Package": "png", + "Version": "0.1-8", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "methods" + "Title": "Read and write PNG images", + "Author": "Simon Urbanek ", + "Maintainer": "Simon Urbanek ", + "Depends": [ + "R (>= 2.9.0)" ], - "Hash": "e1b9c55281c5adc4dd113652d9e26768" + "Description": "This package provides an easy and simple way to read, write and display bitmap images stored in the PNG format. It can read and write both files and in-memory raw vectors.", + "License": "GPL-2 | GPL-3", + "SystemRequirements": "libpng", + "URL": "http://www.rforge.net/png/", + "NeedsCompilation": "yes", + "Repository": "CRAN" }, - "lambda.r": { - "Package": "lambda.r", - "Version": "1.2.4", + "polynom": { + "Package": "polynom", + "Version": "1.4-1", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "formatR" + "Title": "A Collection of Functions to Implement a Class for Univariate Polynomial Manipulations", + "Authors@R": "c(person(\"Bill\", \"Venables\", role = c(\"aut\", \"cre\"), email = \"Bill.Venables@gmail.com\", comment = \"S original\"), person(\"Kurt\", \"Hornik\", role = \"aut\", email = \"Kurt.Hornik@R-project.org\", comment = \"R port\"), person(\"Martin\", \"Maechler\", role = \"aut\", email = \"maechler@stat.math.ethz.ch\", comment = \"R port\"))", + "Description": "A collection of functions to implement a class for univariate polynomial manipulations.", + "Imports": [ + "stats", + "graphics" + ], + "License": "GPL-2", + "NeedsCompilation": "no", + "Author": "Bill Venables [aut, cre] (S original), Kurt Hornik [aut] (R port), Martin Maechler [aut] (R port)", + "Maintainer": "Bill Venables ", + "Suggests": [ + "knitr", + "rmarkdown" ], - "Hash": "b1e925c4b9ffeb901bacf812cbe9a6ad" + "VignetteBuilder": "knitr", + "Repository": "CRAN" }, - "lattice": { - "Package": "lattice", - "Version": "0.22-6", + "pracma": { + "Package": "pracma", + "Version": "2.4.4", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "grDevices", + "Type": "Package", + "Date": "2023-11-08", + "Title": "Practical Numerical Math Functions", + "Authors@R": "person(\"Hans W.\", \"Borchers\", email=\"hwborchers@googlemail.com\", role=c(\"aut\", \"cre\"))", + "Depends": [ + "R (>= 3.1.0)" + ], + "Imports": [ "graphics", - "grid", + "grDevices", "stats", "utils" ], - "Hash": "cc5ac1ba4c238c7ca9fa6a87ca11a7e2" - }, - "lifecycle": { - "Package": "lifecycle", - "Version": "1.0.4", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "cli", - "glue", - "rlang" + "Suggests": [ + "NlcOptim", + "quadprog" ], - "Hash": "b8552d117e1b808b09a832f589b79035" + "Description": "Provides a large number of functions from numerical analysis and linear algebra, numerical optimization, differential equations, time series, plus some well-known special mathematical functions. Uses 'MATLAB' function names where appropriate to simplify porting.", + "License": "GPL (>= 3)", + "ByteCompile": "true", + "LazyData": "yes", + "NeedsCompilation": "no", + "Author": "Hans W. Borchers [aut, cre]", + "Maintainer": "Hans W. Borchers ", + "Repository": "CRAN" }, - "matrixStats": { - "Package": "matrixStats", - "Version": "1.2.0", + "promises": { + "Package": "promises", + "Version": "1.3.3", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Type": "Package", + "Title": "Abstractions for Promise-Based Asynchronous Programming", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "Provides fundamental abstractions for doing asynchronous programming in R using promises. Asynchronous programming is useful for allowing a single R process to orchestrate multiple tasks in the background while also attending to something else. Semantics are similar to 'JavaScript' promises, but with a syntax that is idiomatic R.", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/promises/, https://github.com/rstudio/promises", + "BugReports": "https://github.com/rstudio/promises/issues", + "Imports": [ + "fastmap (>= 1.1.0)", + "later", + "magrittr (>= 1.5)", + "R6", + "Rcpp", + "rlang", + "stats" ], - "Hash": "33a3ca9e732b57244d14f5d732ffc9eb" - }, - "memoise": { - "Package": "memoise", - "Version": "2.0.1", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "cachem", - "rlang" + "Suggests": [ + "future (>= 1.21.0)", + "knitr", + "purrr", + "rmarkdown", + "spelling", + "testthat (>= 3.0.0)", + "vembedr" ], - "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + "LinkingTo": [ + "later", + "Rcpp" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "rsconnect, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2025-05-27", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut, cre], Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Joe Cheng ", + "Repository": "CRAN" }, - "mime": { - "Package": "mime", - "Version": "0.12", + "purrr": { + "Package": "purrr", + "Version": "1.1.0", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "tools" + "Title": "Functional Programming Tools", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"https://ror.org/03wc8by49\")) )", + "Description": "A complete and consistent functional programming toolkit for R.", + "License": "MIT + file LICENSE", + "URL": "https://purrr.tidyverse.org/, https://github.com/tidyverse/purrr", + "BugReports": "https://github.com/tidyverse/purrr/issues", + "Depends": [ + "R (>= 4.1)" ], - "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + "Imports": [ + "cli (>= 3.6.1)", + "lifecycle (>= 1.0.3)", + "magrittr (>= 1.5.0)", + "rlang (>= 1.1.1)", + "vctrs (>= 0.6.3)" + ], + "Suggests": [ + "carrier (>= 0.2.0)", + "covr", + "dplyr (>= 0.7.8)", + "httr", + "knitr", + "lubridate", + "mirai (>= 2.4.0)", + "rmarkdown", + "testthat (>= 3.0.0)", + "tibble", + "tidyselect" + ], + "LinkingTo": [ + "cli" + ], + "VignetteBuilder": "knitr", + "Biarch": "true", + "Config/build/compilation-database": "true", + "Config/Needs/website": "tidyverse/tidytemplate, tidyr", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "TRUE", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre] (ORCID: ), Lionel Henry [aut], Posit Software, PBC [cph, fnd] (ROR: )", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" }, - "openssl": { - "Package": "openssl", - "Version": "2.1.1", + "quantreg": { + "Package": "quantreg", + "Version": "6.1", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "askpass" + "Title": "Quantile Regression", + "Description": "Estimation and inference methods for models for conditional quantile functions: Linear and nonlinear parametric and non-parametric (total variation penalized) models for conditional quantiles of a univariate response and several methods for handling censored survival data. Portfolio selection methods based on expected shortfall risk are also now included. See Koenker, R. (2005) Quantile Regression, Cambridge U. Press, and Koenker, R. et al. (2017) Handbook of Quantile Regression, CRC Press, .", + "Authors@R": "c( person(\"Roger\", \"Koenker\", role = c(\"cre\",\"aut\"), email = \"rkoenker@illinois.edu\"), person(\"Stephen\", \"Portnoy\", role = c(\"ctb\"), comment = \"Contributions to Censored QR code\", email = \"sportnoy@illinois.edu\"), person(c(\"Pin\", \"Tian\"), \"Ng\", role = c(\"ctb\"), comment = \"Contributions to Sparse QR code\", email = \"pin.ng@nau.edu\"), person(\"Blaise\", \"Melly\", role = c(\"ctb\"), comment = \"Contributions to preprocessing code\", email = \"mellyblaise@gmail.com\"), person(\"Achim\", \"Zeileis\", role = c(\"ctb\"), comment = \"Contributions to dynrq code essentially identical to his dynlm code\", email = \"Achim.Zeileis@uibk.ac.at\"), person(\"Philip\", \"Grosjean\", role = c(\"ctb\"), comment = \"Contributions to nlrq code\", email = \"phgrosjean@sciviews.org\"), person(\"Cleve\", \"Moler\", role = c(\"ctb\"), comment = \"author of several linpack routines\"), person(\"Yousef\", \"Saad\", role = c(\"ctb\"), comment = \"author of sparskit2\"), person(\"Victor\", \"Chernozhukov\", role = c(\"ctb\"), comment = \"contributions to extreme value inference code\"), person(\"Ivan\", \"Fernandez-Val\", role = c(\"ctb\"), comment = \"contributions to extreme value inference code\"), person(\"Martin\", \"Maechler\", role = \"ctb\", comment = c(\"tweaks (src/chlfct.f, 'tiny','Large')\", ORCID = \"0000-0002-8685-9910\")), person(c(\"Brian\", \"D\"), \"Ripley\", role = c(\"trl\",\"ctb\"), comment = \"Initial (2001) R port from S (to my everlasting shame -- how could I have been so slow to adopt R!) and for numerous other suggestions and useful advice\", email = \"ripley@stats.ox.ac.uk\"))", + "Maintainer": "Roger Koenker ", + "Repository": "CRAN", + "Depends": [ + "R (>= 3.5)", + "stats", + "SparseM" + ], + "Imports": [ + "methods", + "graphics", + "Matrix", + "MatrixModels", + "survival", + "MASS" + ], + "Suggests": [ + "interp", + "rgl", + "logspline", + "nor1mix", + "Formula", + "zoo", + "R.rsp", + "conquer" ], - "Hash": "2a0dc8c6adfb6f032e4d4af82d258ab5" + "License": "GPL (>= 2)", + "URL": "https://www.r-project.org", + "NeedsCompilation": "yes", + "VignetteBuilder": "R.rsp", + "Author": "Roger Koenker [cre, aut], Stephen Portnoy [ctb] (Contributions to Censored QR code), Pin Tian Ng [ctb] (Contributions to Sparse QR code), Blaise Melly [ctb] (Contributions to preprocessing code), Achim Zeileis [ctb] (Contributions to dynrq code essentially identical to his dynlm code), Philip Grosjean [ctb] (Contributions to nlrq code), Cleve Moler [ctb] (author of several linpack routines), Yousef Saad [ctb] (author of sparskit2), Victor Chernozhukov [ctb] (contributions to extreme value inference code), Ivan Fernandez-Val [ctb] (contributions to extreme value inference code), Martin Maechler [ctb] (tweaks (src/chlfct.f, 'tiny','Large'), ), Brian D Ripley [trl, ctb] (Initial (2001) R port from S (to my everlasting shame -- how could I have been so slow to adopt R!) and for numerous other suggestions and useful advice)" }, - "pkgconfig": { - "Package": "pkgconfig", - "Version": "2.0.3", + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "utils" + "Type": "Package", + "Title": "Application Directories: Determine Where to Save Data, Caches, and Logs", + "Authors@R": "c(person(given = \"Hadley\", family = \"Wickham\", role = c(\"trl\", \"cre\", \"cph\"), email = \"hadley@rstudio.com\"), person(given = \"RStudio\", role = \"cph\"), person(given = \"Sridhar\", family = \"Ratnakumar\", role = \"aut\"), person(given = \"Trent\", family = \"Mick\", role = \"aut\"), person(given = \"ActiveState\", role = \"cph\", comment = \"R/appdir.r, R/cache.r, R/data.r, R/log.r translated from appdirs\"), person(given = \"Eddy\", family = \"Petrisor\", role = \"ctb\"), person(given = \"Trevor\", family = \"Davis\", role = c(\"trl\", \"aut\")), person(given = \"Gabor\", family = \"Csardi\", role = \"ctb\"), person(given = \"Gregory\", family = \"Jefferis\", role = \"ctb\"))", + "Description": "An easy way to determine which directories on the users computer you should use to save data, caches and logs. A port of Python's 'Appdirs' () to R.", + "License": "MIT + file LICENSE", + "URL": "https://rappdirs.r-lib.org, https://github.com/r-lib/rappdirs", + "BugReports": "https://github.com/r-lib/rappdirs/issues", + "Depends": [ + "R (>= 3.2)" ], - "Hash": "01f28d4278f15c76cddbea05899c5d6f" + "Suggests": [ + "roxygen2", + "testthat (>= 3.0.0)", + "covr", + "withr" + ], + "Copyright": "Original python appdirs module copyright (c) 2010 ActiveState Software Inc. R port copyright Hadley Wickham, RStudio. See file LICENSE for details.", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.1", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [trl, cre, cph], RStudio [cph], Sridhar Ratnakumar [aut], Trent Mick [aut], ActiveState [cph] (R/appdir.r, R/cache.r, R/data.r, R/log.r translated from appdirs), Eddy Petrisor [ctb], Trevor Davis [trl, aut], Gabor Csardi [ctb], Gregory Jefferis [ctb]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" }, - "plogr": { - "Package": "plogr", - "Version": "0.2.0", + "rbibutils": { + "Package": "rbibutils", + "Version": "2.3", "Source": "Repository", - "Repository": "RSPM", - "Hash": "09eb987710984fc2905c7129c7d85e65" + "Type": "Package", + "Title": "Read 'Bibtex' Files and Convert Between Bibliography Formats", + "Authors@R": "c( person(given = c(\"Georgi\", \"N.\"), family = \"Boshnakov\", role = c(\"aut\", \"cre\"), \t email = \"georgi.boshnakov@manchester.ac.uk\", comment = \"R port, R code, new C code and modifications to bibutils' C code, conversion to Bibentry (R and C code)\" ), person(given = \"Chris\", family = \"Putman\", role = \"aut\", comment = \"src/*, author of the bibutils libraries, https://sourceforge.net/projects/bibutils/\"), person(given = \"Richard\", family = \"Mathar\", role = \"ctb\", comment = \"src/addsout.c\"), person(given = \"Johannes\", family = \"Wilm\", role = \"ctb\", comment = \"src/biblatexin.c, src/bltypes.c\"), person(\"R Core Team\", role = \"ctb\", comment = \"base R's bibentry and bibstyle implementation\") )", + "Description": "Read and write 'Bibtex' files. Convert between bibliography formats, including 'Bibtex', 'Biblatex', 'PubMed', 'Endnote', and 'Bibentry'. Includes a port of the 'bibutils' utilities by Chris Putnam . Supports all bibliography formats and character encodings implemented in 'bibutils'.", + "License": "GPL-2", + "URL": "https://geobosh.github.io/rbibutils/ (doc), https://github.com/GeoBosh/rbibutils (devel)", + "BugReports": "https://github.com/GeoBosh/rbibutils/issues", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "utils", + "tools" + ], + "Suggests": [ + "testthat" + ], + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Config/Needs/memcheck": "devtools, rcmdcheck", + "Author": "Georgi N. Boshnakov [aut, cre] (R port, R code, new C code and modifications to bibutils' C code, conversion to Bibentry (R and C code)), Chris Putman [aut] (src/*, author of the bibutils libraries, https://sourceforge.net/projects/bibutils/), Richard Mathar [ctb] (src/addsout.c), Johannes Wilm [ctb] (src/biblatexin.c, src/bltypes.c), R Core Team [ctb] (base R's bibentry and bibstyle implementation)", + "Maintainer": "Georgi N. Boshnakov ", + "Repository": "CRAN" }, - "png": { - "Package": "png", - "Version": "0.1-8", + "reformulas": { + "Package": "reformulas", + "Version": "0.4.1", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R" + "Title": "Machinery for Processing Random Effect Formulas", + "Authors@R": "person(given = \"Ben\", family = \"Bolker\", role = c(\"aut\", \"cre\"), email = \"bolker@mcmaster.ca\", comment=c(ORCID=\"0000-0002-2127-0443\"))", + "Description": "Takes formulas including random-effects components (formatted as in 'lme4', 'glmmTMB', etc.) and processes them. Includes various helper functions.", + "URL": "https://github.com/bbolker/reformulas", + "License": "GPL-3", + "Encoding": "UTF-8", + "Imports": [ + "stats", + "methods", + "Matrix", + "Rdpack" + ], + "RdMacros": "Rdpack", + "Suggests": [ + "lme4", + "tinytest", + "glmmTMB" ], - "Hash": "bd54ba8a0a5faded999a7aab6e46b374" + "RoxygenNote": "7.3.2.9000", + "NeedsCompilation": "no", + "Author": "Ben Bolker [aut, cre] (ORCID: )", + "Maintainer": "Ben Bolker ", + "Repository": "CRAN" }, "renv": { "Package": "renv", - "Version": "1.0.5", + "Version": "1.1.4", "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ + "Type": "Package", + "Title": "Project Environments", + "Authors@R": "c( person(\"Kevin\", \"Ushey\", role = c(\"aut\", \"cre\"), email = \"kevin@rstudio.com\", comment = c(ORCID = \"0000-0003-2880-7407\")), person(\"Hadley\", \"Wickham\", role = c(\"aut\"), email = \"hadley@rstudio.com\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A dependency management toolkit for R. Using 'renv', you can create and manage project-local R libraries, save the state of these libraries to a 'lockfile', and later restore your library as required. Together, these tools can help make your projects more isolated, portable, and reproducible.", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/renv/, https://github.com/rstudio/renv", + "BugReports": "https://github.com/rstudio/renv/issues", + "Imports": [ "utils" ], - "Hash": "32c3f93e8360f667ca5863272ec8ba6a" + "Suggests": [ + "BiocManager", + "cli", + "compiler", + "covr", + "cpp11", + "devtools", + "gitcreds", + "jsonlite", + "jsonvalidate", + "knitr", + "miniUI", + "modules", + "packrat", + "pak", + "R6", + "remotes", + "reticulate", + "rmarkdown", + "rstudioapi", + "shiny", + "testthat", + "uuid", + "waldo", + "yaml", + "webfakes" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "bioconductor,python,install,restore,snapshot,retrieve,remotes", + "NeedsCompilation": "no", + "Author": "Kevin Ushey [aut, cre] (), Hadley Wickham [aut] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Kevin Ushey ", + "Repository": "CRAN" + }, + "reshape2": { + "Package": "reshape2", + "Version": "1.4.4", + "Source": "Repository", + "Title": "Flexibly Reshape Data: A Reboot of the Reshape Package", + "Author": "Hadley Wickham ", + "Maintainer": "Hadley Wickham ", + "Description": "Flexibly restructure and aggregate data using just two functions: melt and 'dcast' (or 'acast').", + "License": "MIT + file LICENSE", + "URL": "https://github.com/hadley/reshape", + "BugReports": "https://github.com/hadley/reshape/issues", + "Depends": [ + "R (>= 3.1)" + ], + "Imports": [ + "plyr (>= 1.8.1)", + "Rcpp", + "stringr" + ], + "Suggests": [ + "covr", + "lattice", + "testthat (>= 0.8.0)" + ], + "LinkingTo": [ + "Rcpp" + ], + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.1.0", + "NeedsCompilation": "yes", + "Repository": "CRAN" }, "rhdf5": { "Package": "rhdf5", - "Version": "2.46.1", + "Version": "2.50.2", "Source": "Bioconductor", - "Requirements": [ - "R", - "Rhdf5lib", - "S4Vectors", - "methods", - "rhdf5filters" + "Type": "Package", + "Title": "R Interface to HDF5", + "Authors@R": "c(person(\"Bernd\", \"Fischer\", role = c(\"aut\")), person(\"Mike\", \"Smith\", role=c(\"aut\", \"cre\"), email = \"mike.smith@embl.de\", comment = c(ORCID = \"0000-0002-7800-3848\") ), person(\"Gregoire\", \"Pau\", role=\"aut\"), person(\"Martin\", \"Morgan\", role = \"ctb\"), person(\"Daniel\", \"van Twisk\", role = \"ctb\"))", + "Description": "This package provides an interface between HDF5 and R. HDF5's main features are the ability to store and access very large and/or complex datasets and a wide variety of metadata on mass storage (disk) through a completely portable file format. The rhdf5 package is thus suited for the exchange of large and/or complex datasets between R and other software package, and for letting R applications work on datasets that are larger than the available RAM.", + "License": "Artistic-2.0", + "URL": "https://github.com/grimbough/rhdf5", + "BugReports": "https://github.com/grimbough/rhdf5/issues", + "LazyLoad": "true", + "VignetteBuilder": "knitr", + "Imports": [ + "Rhdf5lib (>= 1.13.4)", + "rhdf5filters (>= 1.15.5)" + ], + "Depends": [ + "R (>= 4.0.0)", + "methods" + ], + "Suggests": [ + "bit64", + "BiocStyle", + "knitr", + "rmarkdown", + "testthat", + "bench", + "dplyr", + "ggplot2", + "mockery", + "BiocParallel" + ], + "LinkingTo": [ + "Rhdf5lib" ], - "Hash": "b0a244022c3427cd8213c33804c6b5de" + "SystemRequirements": "GNU make", + "biocViews": "Infrastructure, DataImport", + "Encoding": "UTF-8", + "Roxygen": "list(markdown = TRUE)", + "RoxygenNote": "7.3.2", + "git_url": "https://git.bioconductor.org/packages/rhdf5", + "git_branch": "RELEASE_3_20", + "git_last_commit": "65c4deb", + "git_last_commit_date": "2025-01-08", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Bernd Fischer [aut], Mike Smith [aut, cre] (), Gregoire Pau [aut], Martin Morgan [ctb], Daniel van Twisk [ctb]", + "Maintainer": "Mike Smith " }, "rhdf5filters": { "Package": "rhdf5filters", - "Version": "1.14.1", + "Version": "1.18.1", "Source": "Bioconductor", - "Requirements": [ + "Type": "Package", + "Title": "HDF5 Compression Filters", + "Authors@R": "c(person(\"Mike\", \"Smith\", role=c(\"aut\", \"cre\"), email = \"grimbough@gmail.com\", comment = c(ORCID = \"0000-0002-7800-3848\")) )", + "Description": "Provides a collection of additional compression filters for HDF5 datasets. The package is intended to provide seemless integration with rhdf5, however the compiled filters can also be used with external applications.", + "License": "BSD_2_clause + file LICENSE", + "LazyLoad": "true", + "VignetteBuilder": "knitr", + "Suggests": [ + "BiocStyle", + "knitr", + "rmarkdown", + "tinytest", + "rhdf5 (>= 2.47.7)" + ], + "SystemRequirements": "GNU make", + "URL": "https://github.com/grimbough/rhdf5filters", + "BugReports": "https://github.com/grimbough/rhdf5filters", + "LinkingTo": [ "Rhdf5lib" ], - "Hash": "d27a2f6a89def6388fad5b0aae026220" + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "biocViews": "Infrastructure, DataImport", + "git_url": "https://git.bioconductor.org/packages/rhdf5filters", + "git_branch": "RELEASE_3_20", + "git_last_commit": "00e74d9", + "git_last_commit_date": "2025-03-05", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Mike Smith [aut, cre] ()", + "Maintainer": "Mike Smith " }, "rjson": { "Package": "rjson", - "Version": "0.2.21", + "Version": "0.2.23", "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R" + "Title": "JSON for R", + "Author": "Alex Couture-Beil [aut, cre]", + "Authors@R": "person(given = \"Alex\", family = \"Couture-Beil\", role = c(\"aut\", \"cre\"), email = \"rjson_pkg@mofo.ca\")", + "Maintainer": "Alex Couture-Beil ", + "Depends": [ + "R (>= 4.0.0)" ], - "Hash": "f9da75e6444e95a1baf8ca24909d63b9" + "Description": "Converts R object into JSON objects and vice-versa.", + "URL": "https://github.com/alexcb/rjson", + "License": "GPL-2", + "Repository": "CRAN", + "NeedsCompilation": "yes" }, "rlang": { "Package": "rlang", - "Version": "1.1.3", + "Version": "1.1.6", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", + "Title": "Functions for Base Types and Core R and 'Tidyverse' Features", + "Description": "A toolbox for working with base types, core R features like the condition system, and core 'Tidyverse' features like tidy evaluation.", + "Authors@R": "c( person(\"Lionel\", \"Henry\", ,\"lionel@posit.co\", c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", ,\"hadley@posit.co\", \"aut\"), person(given = \"mikefc\", email = \"mikefc@coolbutuseless.com\", role = \"cph\", comment = \"Hash implementation based on Mike's xxhashlite\"), person(given = \"Yann\", family = \"Collet\", role = \"cph\", comment = \"Author of the embedded xxHash library\"), person(given = \"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "License": "MIT + file LICENSE", + "ByteCompile": "true", + "Biarch": "true", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ "utils" ], - "Hash": "42548638fae05fd9a9b5f3f437fbbbe2" + "Suggests": [ + "cli (>= 3.1.0)", + "covr", + "crayon", + "desc", + "fs", + "glue", + "knitr", + "magrittr", + "methods", + "pillar", + "pkgload", + "rmarkdown", + "stats", + "testthat (>= 3.2.0)", + "tibble", + "usethis", + "vctrs (>= 0.2.3)", + "withr" + ], + "Enhances": [ + "winch" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "URL": "https://rlang.r-lib.org, https://github.com/r-lib/rlang", + "BugReports": "https://github.com/r-lib/rlang/issues", + "Config/build/compilation-database": "true", + "Config/testthat/edition": "3", + "Config/Needs/website": "dplyr, tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Author": "Lionel Henry [aut, cre], Hadley Wickham [aut], mikefc [cph] (Hash implementation based on Mike's xxhashlite), Yann Collet [cph] (Author of the embedded xxHash library), Posit, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.29", + "Source": "Repository", + "Type": "Package", + "Title": "Dynamic Documents for R", + "Authors@R": "c( person(\"JJ\", \"Allaire\", , \"jj@posit.co\", role = \"aut\"), person(\"Yihui\", \"Xie\", , \"xie@yihui.name\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Jonathan\", \"McPherson\", , \"jonathan@posit.co\", role = \"aut\"), person(\"Javier\", \"Luraschi\", role = \"aut\"), person(\"Kevin\", \"Ushey\", , \"kevin@posit.co\", role = \"aut\"), person(\"Aron\", \"Atkins\", , \"aron@posit.co\", role = \"aut\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"aut\"), person(\"Richard\", \"Iannone\", , \"rich@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Andrew\", \"Dunning\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0464-5036\")), person(\"Atsushi\", \"Yasumoto\", role = c(\"ctb\", \"cph\"), comment = c(ORCID = \"0000-0002-8335-495X\", cph = \"Number sections Lua filter\")), person(\"Barret\", \"Schloerke\", role = \"ctb\"), person(\"Carson\", \"Sievert\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Devon\", \"Ryan\", , \"dpryan79@gmail.com\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8549-0971\")), person(\"Frederik\", \"Aust\", , \"frederik.aust@uni-koeln.de\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4900-788X\")), person(\"Jeff\", \"Allen\", , \"jeff@posit.co\", role = \"ctb\"), person(\"JooYoung\", \"Seo\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4064-6012\")), person(\"Malcolm\", \"Barrett\", role = \"ctb\"), person(\"Rob\", \"Hyndman\", , \"Rob.Hyndman@monash.edu\", role = \"ctb\"), person(\"Romain\", \"Lesur\", role = \"ctb\"), person(\"Roy\", \"Storey\", role = \"ctb\"), person(\"Ruben\", \"Arslan\", , \"ruben.arslan@uni-goettingen.de\", role = \"ctb\"), person(\"Sergio\", \"Oller\", role = \"ctb\"), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(, \"jQuery UI contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery UI library; authors listed in inst/rmd/h/jqueryui/AUTHORS.txt\"), person(\"Mark\", \"Otto\", role = \"ctb\", comment = \"Bootstrap library\"), person(\"Jacob\", \"Thornton\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Alexander\", \"Farkas\", role = c(\"ctb\", \"cph\"), comment = \"html5shiv library\"), person(\"Scott\", \"Jehl\", role = c(\"ctb\", \"cph\"), comment = \"Respond.js library\"), person(\"Ivan\", \"Sagalaev\", role = c(\"ctb\", \"cph\"), comment = \"highlight.js library\"), person(\"Greg\", \"Franko\", role = c(\"ctb\", \"cph\"), comment = \"tocify library\"), person(\"John\", \"MacFarlane\", role = c(\"ctb\", \"cph\"), comment = \"Pandoc templates\"), person(, \"Google, Inc.\", role = c(\"ctb\", \"cph\"), comment = \"ioslides library\"), person(\"Dave\", \"Raggett\", role = \"ctb\", comment = \"slidy library\"), person(, \"W3C\", role = \"cph\", comment = \"slidy library\"), person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"), comment = \"Font-Awesome\"), person(\"Ben\", \"Sperry\", role = \"ctb\", comment = \"Ionicons\"), person(, \"Drifty\", role = \"cph\", comment = \"Ionicons\"), person(\"Aidan\", \"Lister\", role = c(\"ctb\", \"cph\"), comment = \"jQuery StickyTabs\"), person(\"Benct Philip\", \"Jonsson\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\"), person(\"Albert\", \"Krewinkel\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\") )", + "Description": "Convert R Markdown documents into a variety of formats.", + "License": "GPL-3", + "URL": "https://github.com/rstudio/rmarkdown, https://pkgs.rstudio.com/rmarkdown/", + "BugReports": "https://github.com/rstudio/rmarkdown/issues", + "Depends": [ + "R (>= 3.0)" + ], + "Imports": [ + "bslib (>= 0.2.5.1)", + "evaluate (>= 0.13)", + "fontawesome (>= 0.5.0)", + "htmltools (>= 0.5.1)", + "jquerylib", + "jsonlite", + "knitr (>= 1.43)", + "methods", + "tinytex (>= 0.31)", + "tools", + "utils", + "xfun (>= 0.36)", + "yaml (>= 2.1.19)" + ], + "Suggests": [ + "digest", + "dygraphs", + "fs", + "rsconnect", + "downlit (>= 0.4.0)", + "katex (>= 1.4.0)", + "sass (>= 0.4.0)", + "shiny (>= 1.6.0)", + "testthat (>= 3.0.3)", + "tibble", + "vctrs", + "cleanrmd", + "withr (>= 2.4.2)", + "xml2" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "rstudio/quillt, pkgdown", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "SystemRequirements": "pandoc (>= 1.14) - http://pandoc.org", + "NeedsCompilation": "no", + "Author": "JJ Allaire [aut], Yihui Xie [aut, cre] (), Christophe Dervieux [aut] (), Jonathan McPherson [aut], Javier Luraschi [aut], Kevin Ushey [aut], Aron Atkins [aut], Hadley Wickham [aut], Joe Cheng [aut], Winston Chang [aut], Richard Iannone [aut] (), Andrew Dunning [ctb] (), Atsushi Yasumoto [ctb, cph] (, Number sections Lua filter), Barret Schloerke [ctb], Carson Sievert [ctb] (), Devon Ryan [ctb] (), Frederik Aust [ctb] (), Jeff Allen [ctb], JooYoung Seo [ctb] (), Malcolm Barrett [ctb], Rob Hyndman [ctb], Romain Lesur [ctb], Roy Storey [ctb], Ruben Arslan [ctb], Sergio Oller [ctb], Posit Software, PBC [cph, fnd], jQuery UI contributors [ctb, cph] (jQuery UI library; authors listed in inst/rmd/h/jqueryui/AUTHORS.txt), Mark Otto [ctb] (Bootstrap library), Jacob Thornton [ctb] (Bootstrap library), Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Alexander Farkas [ctb, cph] (html5shiv library), Scott Jehl [ctb, cph] (Respond.js library), Ivan Sagalaev [ctb, cph] (highlight.js library), Greg Franko [ctb, cph] (tocify library), John MacFarlane [ctb, cph] (Pandoc templates), Google, Inc. [ctb, cph] (ioslides library), Dave Raggett [ctb] (slidy library), W3C [cph] (slidy library), Dave Gandy [ctb, cph] (Font-Awesome), Ben Sperry [ctb] (Ionicons), Drifty [cph] (Ionicons), Aidan Lister [ctb, cph] (jQuery StickyTabs), Benct Philip Jonsson [ctb, cph] (pagebreak Lua filter), Albert Krewinkel [ctb, cph] (pagebreak Lua filter)", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "rstatix": { + "Package": "rstatix", + "Version": "0.7.2", + "Source": "Repository", + "Type": "Package", + "Title": "Pipe-Friendly Framework for Basic Statistical Tests", + "Authors@R": "c( person(\"Alboukadel\", \"Kassambara\", role = c(\"aut\", \"cre\"), email = \"alboukadel.kassambara@gmail.com\"))", + "Description": "Provides a simple and intuitive pipe-friendly framework, coherent with the 'tidyverse' design philosophy, for performing basic statistical tests, including t-test, Wilcoxon test, ANOVA, Kruskal-Wallis and correlation analyses. The output of each test is automatically transformed into a tidy data frame to facilitate visualization. Additional functions are available for reshaping, reordering, manipulating and visualizing correlation matrix. Functions are also included to facilitate the analysis of factorial experiments, including purely 'within-Ss' designs (repeated measures), purely 'between-Ss' designs, and mixed 'within-and-between-Ss' designs. It's also possible to compute several effect size metrics, including \"eta squared\" for ANOVA, \"Cohen's d\" for t-test and 'Cramer V' for the association between categorical variables. The package contains helper functions for identifying univariate and multivariate outliers, assessing normality and homogeneity of variances.", + "License": "GPL-2", + "Encoding": "UTF-8", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "stats", + "utils", + "tidyr (>= 1.0.0)", + "purrr", + "broom (>= 0.7.4)", + "rlang (>= 0.3.1)", + "tibble (>= 2.1.3)", + "dplyr (>= 0.7.1)", + "magrittr", + "corrplot", + "tidyselect (>= 1.2.0)", + "car", + "generics (>= 0.0.2)" + ], + "Suggests": [ + "knitr", + "rmarkdown", + "ggpubr", + "graphics", + "emmeans", + "coin", + "boot", + "testthat", + "spelling" + ], + "URL": "https://rpkgs.datanovia.com/rstatix/", + "BugReports": "https://github.com/kassambara/rstatix/issues", + "RoxygenNote": "7.2.3", + "Collate": "'utilities.R' 'add_significance.R' 'adjust_pvalue.R' 'factorial_design.R' 'utilities_two_sample_test.R' 'anova_summary.R' 'anova_test.R' 'as_cor_mat.R' 'binom_test.R' 'box_m.R' 'chisq_test.R' 'cochran_qtest.R' 'cohens_d.R' 'cor_as_symbols.R' 'replace_triangle.R' 'pull_triangle.R' 'cor_mark_significant.R' 'cor_mat.R' 'cor_plot.R' 'cor_reorder.R' 'cor_reshape.R' 'cor_select.R' 'cor_test.R' 'counts_to_cases.R' 'cramer_v.R' 'df.R' 'doo.R' 't_test.R' 'dunn_test.R' 'emmeans_test.R' 'eta_squared.R' 'factors.R' 'fisher_test.R' 'freq_table.R' 'friedman_test.R' 'friedman_effsize.R' 'games_howell_test.R' 'get_comparisons.R' 'get_manova_table.R' 'get_mode.R' 'get_pvalue_position.R' 'get_summary_stats.R' 'get_test_label.R' 'kruskal_effesize.R' 'kruskal_test.R' 'levene_test.R' 'mahalanobis_distance.R' 'make_clean_names.R' 'mcnemar_test.R' 'multinom_test.R' 'outliers.R' 'p_value.R' 'prop_test.R' 'prop_trend_test.R' 'reexports.R' 'remove_ns.R' 'sample_n_by.R' 'shapiro_test.R' 'sign_test.R' 'tukey_hsd.R' 'utils-manova.R' 'utils-pipe.R' 'welch_anova_test.R' 'wilcox_effsize.R' 'wilcox_test.R'", + "Language": "en-US", + "NeedsCompilation": "no", + "Author": "Alboukadel Kassambara [aut, cre]", + "Maintainer": "Alboukadel Kassambara ", + "Repository": "CRAN" }, "rsvd": { "Package": "rsvd", "Version": "1.0.5", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "Matrix", - "R" + "Type": "Package", + "Title": "Randomized Singular Value Decomposition", + "Date": "2021-04-11", + "Authors@R": "c(person(\"N. Benjamin\", \"Erichson\", role = c(\"aut\", \"cre\"), email = \"erichson@berkeley.edu\"))", + "Author": "N. Benjamin Erichson [aut, cre]", + "Maintainer": "N. Benjamin Erichson ", + "Description": "Low-rank matrix decompositions are fundamental tools and widely used for data analysis, dimension reduction, and data compression. Classically, highly accurate deterministic matrix algorithms are used for this task. However, the emergence of large-scale data has severely challenged our computational ability to analyze big data. The concept of randomness has been demonstrated as an effective strategy to quickly produce approximate answers to familiar problems such as the singular value decomposition (SVD). The rsvd package provides several randomized matrix algorithms such as the randomized singular value decomposition (rsvd), randomized principal component analysis (rpca), randomized robust principal component analysis (rrpca), randomized interpolative decomposition (rid), and the randomized CUR decomposition (rcur). In addition several plot functions are provided.", + "Depends": [ + "R (>= 4.0.0)" + ], + "Imports": [ + "Matrix" + ], + "License": "GPL (>= 3)", + "LazyData": "TRUE", + "LazyDataCompression": "xz", + "URL": "https://github.com/erichson/rSVD", + "BugReports": "https://github.com/erichson/rSVD/issues", + "Suggests": [ + "ggplot2", + "testthat" + ], + "RoxygenNote": "7.1.1", + "NeedsCompilation": "no", + "Encoding": "UTF-8", + "Repository": "CRAN" + }, + "sass": { + "Package": "sass", + "Version": "0.4.10", + "Source": "Repository", + "Type": "Package", + "Title": "Syntactically Awesome Style Sheets ('Sass')", + "Description": "An 'SCSS' compiler, powered by the 'LibSass' library. With this, R developers can use variables, inheritance, and functions to generate dynamic style sheets. The package uses the 'Sass CSS' extension language, which is stable, powerful, and CSS compatible.", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@rstudio.com\", \"aut\"), person(\"Timothy\", \"Mastny\", , \"tim.mastny@gmail.com\", \"aut\"), person(\"Richard\", \"Iannone\", , \"rich@rstudio.com\", \"aut\", comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Barret\", \"Schloerke\", , \"barret@rstudio.com\", \"aut\", comment = c(ORCID = \"0000-0001-9986-114X\")), person(\"Carson\", \"Sievert\", , \"carson@rstudio.com\", c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Christophe\", \"Dervieux\", , \"cderv@rstudio.com\", c(\"ctb\"), comment = c(ORCID = \"0000-0003-4474-2498\")), person(family = \"RStudio\", role = c(\"cph\", \"fnd\")), person(family = \"Sass Open Source Foundation\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Greter\", \"Marcel\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Mifsud\", \"Michael\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Hampton\", \"Catlin\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Natalie\", \"Weizenbaum\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Chris\", \"Eppstein\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Adams\", \"Joseph\", role = c(\"ctb\", \"cph\"), comment = \"json.cpp\"), person(\"Trifunovic\", \"Nemanja\", role = c(\"ctb\", \"cph\"), comment = \"utf8.h\") )", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/sass/, https://github.com/rstudio/sass", + "BugReports": "https://github.com/rstudio/sass/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "SystemRequirements": "GNU make", + "Imports": [ + "fs (>= 1.2.4)", + "rlang (>= 0.4.10)", + "htmltools (>= 0.5.1)", + "R6", + "rappdirs" + ], + "Suggests": [ + "testthat", + "knitr", + "rmarkdown", + "withr", + "shiny", + "curl" + ], + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut], Timothy Mastny [aut], Richard Iannone [aut] (), Barret Schloerke [aut] (), Carson Sievert [aut, cre] (), Christophe Dervieux [ctb] (), RStudio [cph, fnd], Sass Open Source Foundation [ctb, cph] (LibSass library), Greter Marcel [ctb, cph] (LibSass library), Mifsud Michael [ctb, cph] (LibSass library), Hampton Catlin [ctb, cph] (LibSass library), Natalie Weizenbaum [ctb, cph] (LibSass library), Chris Eppstein [ctb, cph] (LibSass library), Adams Joseph [ctb, cph] (json.cpp), Trifunovic Nemanja [ctb, cph] (utf8.h)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "scales": { + "Package": "scales", + "Version": "1.4.0", + "Source": "Repository", + "Title": "Scale Functions for Visualization", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Dana\", \"Seidel\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "Graphical scales map data to aesthetics, and provide methods for automatically determining breaks and labels for axes and legends.", + "License": "MIT + file LICENSE", + "URL": "https://scales.r-lib.org, https://github.com/r-lib/scales", + "BugReports": "https://github.com/r-lib/scales/issues", + "Depends": [ + "R (>= 4.1)" + ], + "Imports": [ + "cli", + "farver (>= 2.0.3)", + "glue", + "labeling", + "lifecycle", + "R6", + "RColorBrewer", + "rlang (>= 1.1.0)", + "viridisLite" + ], + "Suggests": [ + "bit64", + "covr", + "dichromat", + "ggplot2", + "hms (>= 0.5.0)", + "stringi", + "testthat (>= 3.0.0)" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2025-04-23", + "Encoding": "UTF-8", + "LazyLoad": "yes", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut], Thomas Lin Pedersen [cre, aut] (), Dana Seidel [aut], Posit Software, PBC [cph, fnd] (03wc8by49)", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" + }, + "segmented": { + "Package": "segmented", + "Version": "2.1-4", + "Source": "Repository", + "Type": "Package", + "Title": "Regression Models with Break-Points / Change-Points Estimation (with Possibly Random Effects)", + "Date": "2025-02-26", + "Authors@R": "c(person(given = c(\"Vito\",\"M.\",\"R.\"), family = \"Muggeo\", role = c(\"aut\", \"cre\"), email = \"vito.muggeo@unipa.it\", comment=c(ORCID=\"0000-0002-3386-4054\")))", + "Maintainer": "Vito M. R. Muggeo ", + "Description": "Fitting regression models where, in addition to possible linear terms, one or more covariates have segmented (i.e., broken-line or piece-wise linear) or stepmented (i.e. piece-wise constant) effects. Multiple breakpoints for the same variable are allowed. The estimation method is discussed in Muggeo (2003, ) and illustrated in Muggeo (2008, ). An approach for hypothesis testing is presented in Muggeo (2016, ), and interval estimation for the breakpoint is discussed in Muggeo (2017, ). Segmented mixed models, i.e. random effects in the change point, are discussed in Muggeo (2014, ). Estimation of piecewise-constant relationships and changepoints (mean-shift models) is discussed in Fasola et al. (2018, ).", + "Depends": [ + "R (>= 3.5.0)", + "MASS", + "nlme" ], - "Hash": "b462187d887abc519894874486dbd6fd" + "License": "GPL", + "NeedsCompilation": "no", + "Author": "Vito M. R. Muggeo [aut, cre] ()", + "RoxygenNote": "7.3.1", + "Repository": "CRAN" }, "snow": { "Package": "snow", "Version": "0.4-4", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", + "Title": "Simple Network of Workstations", + "Author": "Luke Tierney, A. J. Rossini, Na Li, H. Sevcikova", + "Description": "Support for simple parallel computing in R.", + "Maintainer": "Luke Tierney ", + "Suggests": [ + "rlecuyer" + ], + "Enhances": [ + "Rmpi" + ], + "License": "GPL", + "Depends": [ + "R (>= 2.13.1)", "utils" ], - "Hash": "40b74690debd20c57d93d8c246b305d4" + "NeedsCompilation": "no", + "Repository": "CRAN" }, "sparseMatrixStats": { "Package": "sparseMatrixStats", - "Version": "1.14.0", + "Version": "1.18.0", "Source": "Bioconductor", - "Requirements": [ - "Matrix", - "MatrixGenerics", + "Type": "Package", + "Title": "Summary Statistics for Rows and Columns of Sparse Matrices", + "Authors@R": "person(\"Constantin\", \"Ahlmann-Eltze\", email = \"artjom31415@googlemail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-3762-068X\"))", + "Description": "High performance functions for row and column operations on sparse matrices. For example: col / rowMeans2, col / rowMedians, col / rowVars etc. Currently, the optimizations are limited to data in the column sparse format. This package is inspired by the matrixStats package by Henrik Bengtsson.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "LinkingTo": [ + "Rcpp" + ], + "Imports": [ "Rcpp", - "matrixStats", + "Matrix", + "matrixStats (>= 0.60.0)", "methods" ], - "Hash": "49383d0f6c6152ff7cb594f254c23cc8" + "Depends": [ + "MatrixGenerics (>= 1.5.3)" + ], + "Suggests": [ + "testthat (>= 2.1.0)", + "knitr", + "bench", + "rmarkdown", + "BiocStyle" + ], + "SystemRequirements": "C++11", + "VignetteBuilder": "knitr", + "URL": "https://github.com/const-ae/sparseMatrixStats", + "BugReports": "https://github.com/const-ae/sparseMatrixStats/issues", + "biocViews": "Infrastructure, Software, DataRepresentation", + "git_url": "https://git.bioconductor.org/packages/sparseMatrixStats", + "git_branch": "RELEASE_3_20", + "git_last_commit": "172c63e", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes", + "Author": "Constantin Ahlmann-Eltze [aut, cre] ()", + "Maintainer": "Constantin Ahlmann-Eltze " + }, + "stringi": { + "Package": "stringi", + "Version": "1.8.7", + "Source": "Repository", + "Date": "2025-03-27", + "Title": "Fast and Portable Character String Processing Facilities", + "Description": "A collection of character string/text/natural language processing tools for pattern searching (e.g., with 'Java'-like regular expressions or the 'Unicode' collation algorithm), random string generation, case mapping, string transliteration, concatenation, sorting, padding, wrapping, Unicode normalisation, date-time formatting and parsing, and many more. They are fast, consistent, convenient, and - thanks to 'ICU' (International Components for Unicode) - portable across all locales and platforms. Documentation about 'stringi' is provided via its website at and the paper by Gagolewski (2022, ).", + "URL": "https://stringi.gagolewski.com/, https://github.com/gagolews/stringi, https://icu.unicode.org/", + "BugReports": "https://github.com/gagolews/stringi/issues", + "SystemRequirements": "ICU4C (>= 61, optional)", + "Type": "Package", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ + "tools", + "utils", + "stats" + ], + "Biarch": "TRUE", + "License": "file LICENSE", + "Authors@R": "c(person(given = \"Marek\", family = \"Gagolewski\", role = c(\"aut\", \"cre\", \"cph\"), email = \"marek@gagolewski.com\", comment = c(ORCID = \"0000-0003-0637-6028\")), person(given = \"Bartek\", family = \"Tartanus\", role = \"ctb\"), person(\"Unicode, Inc. and others\", role=\"ctb\", comment = \"ICU4C source code, Unicode Character Database\") )", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Marek Gagolewski [aut, cre, cph] (), Bartek Tartanus [ctb], Unicode, Inc. and others [ctb] (ICU4C source code, Unicode Character Database)", + "Maintainer": "Marek Gagolewski ", + "License_is_FOSS": "yes", + "Repository": "CRAN" + }, + "stringr": { + "Package": "stringr", + "Version": "1.5.1", + "Source": "Repository", + "Title": "Simple, Consistent Wrappers for Common String Operations", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\", \"cph\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A consistent, simple and easy to use set of wrappers around the fantastic 'stringi' package. All function and argument names (and positions) are consistent, all functions deal with \"NA\"'s and zero length vectors in the same way, and the output from one function is easy to feed into the input of another.", + "License": "MIT + file LICENSE", + "URL": "https://stringr.tidyverse.org, https://github.com/tidyverse/stringr", + "BugReports": "https://github.com/tidyverse/stringr/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli", + "glue (>= 1.6.1)", + "lifecycle (>= 1.0.3)", + "magrittr", + "rlang (>= 1.0.0)", + "stringi (>= 1.5.3)", + "vctrs (>= 0.4.0)" + ], + "Suggests": [ + "covr", + "dplyr", + "gt", + "htmltools", + "htmlwidgets", + "knitr", + "rmarkdown", + "testthat (>= 3.0.0)", + "tibble" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre, cph], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "survival": { + "Package": "survival", + "Version": "3.8-3", + "Source": "Repository", + "Title": "Survival Analysis", + "Priority": "recommended", + "Date": "2024-12-17", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "graphics", + "Matrix", + "methods", + "splines", + "stats", + "utils" + ], + "LazyData": "Yes", + "LazyDataCompression": "xz", + "ByteCompile": "Yes", + "Authors@R": "c(person(c(\"Terry\", \"M\"), \"Therneau\", email=\"therneau.terry@mayo.edu\", role=c(\"aut\", \"cre\")), person(\"Thomas\", \"Lumley\", role=c(\"ctb\", \"trl\"), comment=\"original S->R port and R maintainer until 2009\"), person(\"Atkinson\", \"Elizabeth\", role=\"ctb\"), person(\"Crowson\", \"Cynthia\", role=\"ctb\"))", + "Description": "Contains the core survival analysis routines, including definition of Surv objects, Kaplan-Meier and Aalen-Johansen (multi-state) curves, Cox models, and parametric accelerated failure time models.", + "License": "LGPL (>= 2)", + "URL": "https://github.com/therneau/survival", + "NeedsCompilation": "yes", + "Author": "Terry M Therneau [aut, cre], Thomas Lumley [ctb, trl] (original S->R port and R maintainer until 2009), Atkinson Elizabeth [ctb], Crowson Cynthia [ctb]", + "Maintainer": "Terry M Therneau ", + "Repository": "CRAN" }, "sys": { "Package": "sys", - "Version": "3.4.2", + "Version": "3.4.3", + "Source": "Repository", + "Type": "Package", + "Title": "Powerful and Reliable Tools for Running System Commands in R", + "Authors@R": "c(person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = \"ctb\"))", + "Description": "Drop-in replacements for the base system2() function with fine control and consistent behavior across platforms. Supports clean interruption, timeout, background tasks, and streaming STDIN / STDOUT / STDERR over binary or text connections. Arguments on Windows automatically get encoded and quoted to work on different locales.", + "License": "MIT + file LICENSE", + "URL": "https://jeroen.r-universe.dev/sys", + "BugReports": "https://github.com/jeroen/sys/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.1", + "Suggests": [ + "unix (>= 1.4)", + "spelling", + "testthat" + ], + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), Gábor Csárdi [ctb]", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "tibble": { + "Package": "tibble", + "Version": "3.3.0", + "Source": "Repository", + "Title": "Simple Data Frames", + "Authors@R": "c(person(given = \"Kirill\", family = \"M\\u00fcller\", role = c(\"aut\", \"cre\"), email = \"kirill@cynkra.com\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(given = \"Hadley\", family = \"Wickham\", role = \"aut\", email = \"hadley@rstudio.com\"), person(given = \"Romain\", family = \"Francois\", role = \"ctb\", email = \"romain@r-enthusiasts.com\"), person(given = \"Jennifer\", family = \"Bryan\", role = \"ctb\", email = \"jenny@rstudio.com\"), person(given = \"RStudio\", role = c(\"cph\", \"fnd\")))", + "Description": "Provides a 'tbl_df' class (the 'tibble') with stricter checking and better formatting than the traditional data frame.", + "License": "MIT + file LICENSE", + "URL": "https://tibble.tidyverse.org/, https://github.com/tidyverse/tibble", + "BugReports": "https://github.com/tidyverse/tibble/issues", + "Depends": [ + "R (>= 3.4.0)" + ], + "Imports": [ + "cli", + "lifecycle (>= 1.0.0)", + "magrittr", + "methods", + "pillar (>= 1.8.1)", + "pkgconfig", + "rlang (>= 1.0.2)", + "utils", + "vctrs (>= 0.5.0)" + ], + "Suggests": [ + "bench", + "bit64", + "blob", + "brio", + "callr", + "DiagrammeR", + "dplyr", + "evaluate", + "formattable", + "ggplot2", + "here", + "hms", + "htmltools", + "knitr", + "lubridate", + "nycflights13", + "pkgload", + "purrr", + "rmarkdown", + "stringi", + "testthat (>= 3.0.2)", + "tidyr", + "withr" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2.9000", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "vignette-formats, as_tibble, add, invariants", + "Config/autostyle/scope": "line_breaks", + "Config/autostyle/strict": "true", + "Config/autostyle/rmd": "false", + "Config/Needs/website": "tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Author": "Kirill Müller [aut, cre] (ORCID: ), Hadley Wickham [aut], Romain Francois [ctb], Jennifer Bryan [ctb], RStudio [cph, fnd]", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "tidyr": { + "Package": "tidyr", + "Version": "1.3.1", + "Source": "Repository", + "Title": "Tidy Messy Data", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = \"aut\"), person(\"Maximilian\", \"Girlich\", role = \"aut\"), person(\"Kevin\", \"Ushey\", , \"kevin@posit.co\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Tools to help to create tidy data, where each column is a variable, each row is an observation, and each cell contains a single value. 'tidyr' contains tools for changing the shape (pivoting) and hierarchy (nesting and 'unnesting') of a dataset, turning deeply nested lists into rectangular data frames ('rectangling'), and extracting values out of string columns. It also includes tools for working with missing values (both implicit and explicit).", + "License": "MIT + file LICENSE", + "URL": "https://tidyr.tidyverse.org, https://github.com/tidyverse/tidyr", + "BugReports": "https://github.com/tidyverse/tidyr/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli (>= 3.4.1)", + "dplyr (>= 1.0.10)", + "glue", + "lifecycle (>= 1.0.3)", + "magrittr", + "purrr (>= 1.0.1)", + "rlang (>= 1.1.1)", + "stringr (>= 1.5.0)", + "tibble (>= 2.1.1)", + "tidyselect (>= 1.2.0)", + "utils", + "vctrs (>= 0.5.2)" + ], + "Suggests": [ + "covr", + "data.table", + "knitr", + "readr", + "repurrrsive (>= 1.1.0)", + "rmarkdown", + "testthat (>= 3.0.0)" + ], + "LinkingTo": [ + "cpp11 (>= 0.4.0)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.3.0", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre], Davis Vaughan [aut], Maximilian Girlich [aut], Kevin Ushey [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "tidyselect": { + "Package": "tidyselect", + "Version": "1.2.1", + "Source": "Repository", + "Title": "Select from a Set of Strings", + "Authors@R": "c( person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A backend for the selecting functions of the 'tidyverse'. It makes it easy to implement select-like functions in your own packages in a way that is consistent with other 'tidyverse' interfaces for selection.", + "License": "MIT + file LICENSE", + "URL": "https://tidyselect.r-lib.org, https://github.com/r-lib/tidyselect", + "BugReports": "https://github.com/r-lib/tidyselect/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ + "cli (>= 3.3.0)", + "glue (>= 1.3.0)", + "lifecycle (>= 1.0.3)", + "rlang (>= 1.0.4)", + "vctrs (>= 0.5.2)", + "withr" + ], + "Suggests": [ + "covr", + "crayon", + "dplyr", + "knitr", + "magrittr", + "rmarkdown", + "stringr", + "testthat (>= 3.1.1)", + "tibble (>= 2.1.3)" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/testthat/edition": "3", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.0.9000", + "NeedsCompilation": "yes", + "Author": "Lionel Henry [aut, cre], Hadley Wickham [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.57", + "Source": "Repository", + "Type": "Package", + "Title": "Helper Functions to Install and Maintain TeX Live, and Compile LaTeX Documents", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"Christophe\", \"Dervieux\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Devon\", \"Ryan\", role = \"ctb\", email = \"dpryan79@gmail.com\", comment = c(ORCID = \"0000-0002-8549-0971\")), person(\"Ethan\", \"Heinzen\", role = \"ctb\"), person(\"Fernando\", \"Cagua\", role = \"ctb\"), person() )", + "Description": "Helper functions to install and maintain the 'LaTeX' distribution named 'TinyTeX' (), a lightweight, cross-platform, portable, and easy-to-maintain version of 'TeX Live'. This package also contains helper functions to compile 'LaTeX' documents, and install missing 'LaTeX' packages automatically.", + "Imports": [ + "xfun (>= 0.48)" + ], + "Suggests": [ + "testit", + "rstudioapi" + ], + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/tinytex", + "BugReports": "https://github.com/rstudio/tinytex/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre, cph] (), Posit Software, PBC [cph, fnd], Christophe Dervieux [ctb] (), Devon Ryan [ctb] (), Ethan Heinzen [ctb], Fernando Cagua [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "utf8": { + "Package": "utf8", + "Version": "1.2.6", "Source": "Repository", - "Repository": "RSPM", - "Hash": "3a1be13d68d47a8cd0bfd74739ca1555" + "Title": "Unicode Text Processing", + "Authors@R": "c(person(given = c(\"Patrick\", \"O.\"), family = \"Perry\", role = c(\"aut\", \"cph\")), person(given = \"Kirill\", family = \"M\\u00fcller\", role = \"cre\", email = \"kirill@cynkra.com\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(given = \"Unicode, Inc.\", role = c(\"cph\", \"dtc\"), comment = \"Unicode Character Database\"))", + "Description": "Process and print 'UTF-8' encoded international text (Unicode). Input, validate, normalize, encode, format, and display.", + "License": "Apache License (== 2.0) | file LICENSE", + "URL": "https://krlmlr.github.io/utf8/, https://github.com/krlmlr/utf8", + "BugReports": "https://github.com/krlmlr/utf8/issues", + "Depends": [ + "R (>= 2.10)" + ], + "Suggests": [ + "cli", + "covr", + "knitr", + "rlang", + "rmarkdown", + "testthat (>= 3.0.0)", + "withr" + ], + "VignetteBuilder": "knitr, rmarkdown", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2.9000", + "NeedsCompilation": "yes", + "Author": "Patrick O. Perry [aut, cph], Kirill Müller [cre] (ORCID: ), Unicode, Inc. [cph, dtc] (Unicode Character Database)", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" }, "vctrs": { "Package": "vctrs", "Version": "0.6.5", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "cli", + "Title": "Vector Helpers", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"aut\"), person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = c(\"aut\", \"cre\")), person(\"data.table team\", role = \"cph\", comment = \"Radix sort based on data.table's forder() and their contribution to R's order()\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Defines new notions of prototype and size that are used to provide tools for consistent and well-founded type-coercion and size-recycling, and are in turn connected to ideas of type- and size-stability useful for analysing function interfaces.", + "License": "MIT + file LICENSE", + "URL": "https://vctrs.r-lib.org/, https://github.com/r-lib/vctrs", + "BugReports": "https://github.com/r-lib/vctrs/issues", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "cli (>= 3.4.0)", "glue", - "lifecycle", - "rlang" + "lifecycle (>= 1.0.3)", + "rlang (>= 1.1.0)" + ], + "Suggests": [ + "bit64", + "covr", + "crayon", + "dplyr (>= 0.8.5)", + "generics", + "knitr", + "pillar (>= 1.4.4)", + "pkgdown (>= 2.0.1)", + "rmarkdown", + "testthat (>= 3.0.0)", + "tibble (>= 3.1.3)", + "waldo (>= 0.2.0)", + "withr", + "xml2", + "zeallot" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "Language": "en-GB", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut], Lionel Henry [aut], Davis Vaughan [aut, cre], data.table team [cph] (Radix sort based on data.table's forder() and their contribution to R's order()), Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN" + }, + "viridisLite": { + "Package": "viridisLite", + "Version": "0.4.2", + "Source": "Repository", + "Type": "Package", + "Title": "Colorblind-Friendly Color Maps (Lite Version)", + "Date": "2023-05-02", + "Authors@R": "c( person(\"Simon\", \"Garnier\", email = \"garnier@njit.edu\", role = c(\"aut\", \"cre\")), person(\"Noam\", \"Ross\", email = \"noam.ross@gmail.com\", role = c(\"ctb\", \"cph\")), person(\"Bob\", \"Rudis\", email = \"bob@rud.is\", role = c(\"ctb\", \"cph\")), person(\"Marco\", \"Sciaini\", email = \"sciaini.marco@gmail.com\", role = c(\"ctb\", \"cph\")), person(\"Antônio Pedro\", \"Camargo\", role = c(\"ctb\", \"cph\")), person(\"Cédric\", \"Scherer\", email = \"scherer@izw-berlin.de\", role = c(\"ctb\", \"cph\")) )", + "Maintainer": "Simon Garnier ", + "Description": "Color maps designed to improve graph readability for readers with common forms of color blindness and/or color vision deficiency. The color maps are also perceptually-uniform, both in regular form and also when converted to black-and-white for printing. This is the 'lite' version of the 'viridis' package that also contains 'ggplot2' bindings for discrete and continuous color and fill scales and can be found at .", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Depends": [ + "R (>= 2.10)" ], - "Hash": "c03fa420630029418f7e6da3667aac4a" + "Suggests": [ + "hexbin (>= 1.27.0)", + "ggplot2 (>= 1.0.1)", + "testthat", + "covr" + ], + "URL": "https://sjmgarnier.github.io/viridisLite/, https://github.com/sjmgarnier/viridisLite/", + "BugReports": "https://github.com/sjmgarnier/viridisLite/issues/", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Simon Garnier [aut, cre], Noam Ross [ctb, cph], Bob Rudis [ctb, cph], Marco Sciaini [ctb, cph], Antônio Pedro Camargo [ctb, cph], Cédric Scherer [ctb, cph]", + "Repository": "CRAN" + }, + "withr": { + "Package": "withr", + "Version": "3.0.2", + "Source": "Repository", + "Title": "Run Code 'With' Temporarily Modified Global State", + "Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = c(\"aut\", \"cre\")), person(\"Kirill\", \"Müller\", , \"krlmlr+r@mailbox.org\", role = \"aut\"), person(\"Kevin\", \"Ushey\", , \"kevinushey@gmail.com\", role = \"aut\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Winston\", \"Chang\", role = \"aut\"), person(\"Jennifer\", \"Bryan\", role = \"ctb\"), person(\"Richard\", \"Cotton\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A set of functions to run code 'with' safely and temporarily modified global state. Many of these functions were originally a part of the 'devtools' package, this provides a simple package with limited dependencies to provide access to these functions.", + "License": "MIT + file LICENSE", + "URL": "https://withr.r-lib.org, https://github.com/r-lib/withr#readme", + "BugReports": "https://github.com/r-lib/withr/issues", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "graphics", + "grDevices" + ], + "Suggests": [ + "callr", + "DBI", + "knitr", + "methods", + "rlang", + "rmarkdown (>= 2.12)", + "RSQLite", + "testthat (>= 3.0.0)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Collate": "'aaa.R' 'collate.R' 'connection.R' 'db.R' 'defer-exit.R' 'standalone-defer.R' 'defer.R' 'devices.R' 'local_.R' 'with_.R' 'dir.R' 'env.R' 'file.R' 'language.R' 'libpaths.R' 'locale.R' 'makevars.R' 'namespace.R' 'options.R' 'par.R' 'path.R' 'rng.R' 'seed.R' 'wrap.R' 'sink.R' 'tempfile.R' 'timezone.R' 'torture.R' 'utils.R' 'with.R'", + "NeedsCompilation": "no", + "Author": "Jim Hester [aut], Lionel Henry [aut, cre], Kirill Müller [aut], Kevin Ushey [aut], Hadley Wickham [aut], Winston Chang [aut], Jennifer Bryan [ctb], Richard Cotton [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "xfun": { + "Package": "xfun", + "Version": "0.52", + "Source": "Repository", + "Type": "Package", + "Title": "Supporting Functions for Packages Maintained by 'Yihui Xie'", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Wush\", \"Wu\", role = \"ctb\"), person(\"Daijiang\", \"Li\", role = \"ctb\"), person(\"Xianying\", \"Tan\", role = \"ctb\"), person(\"Salim\", \"Brüggemann\", role = \"ctb\", email = \"salim-b@pm.me\", comment = c(ORCID = \"0000-0002-5329-5987\")), person(\"Christophe\", \"Dervieux\", role = \"ctb\"), person() )", + "Description": "Miscellaneous functions commonly used in other packages maintained by 'Yihui Xie'.", + "Depends": [ + "R (>= 3.2.0)" + ], + "Imports": [ + "grDevices", + "stats", + "tools" + ], + "Suggests": [ + "testit", + "parallel", + "codetools", + "methods", + "rstudioapi", + "tinytex (>= 0.30)", + "mime", + "litedown (>= 0.4)", + "commonmark", + "knitr (>= 1.50)", + "remotes", + "pak", + "curl", + "xml2", + "jsonlite", + "magick", + "yaml", + "qs" + ], + "License": "MIT + file LICENSE", + "URL": "https://github.com/yihui/xfun", + "BugReports": "https://github.com/yihui/xfun/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "VignetteBuilder": "litedown", + "NeedsCompilation": "yes", + "Author": "Yihui Xie [aut, cre, cph] (, https://yihui.org), Wush Wu [ctb], Daijiang Li [ctb], Xianying Tan [ctb], Salim Brüggemann [ctb] (), Christophe Dervieux [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" }, "xtable": { "Package": "xtable", "Version": "1.8-4", "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", + "Date": "2019-04-08", + "Title": "Export Tables to LaTeX or HTML", + "Authors@R": "c(person(\"David B.\", \"Dahl\", role=\"aut\"), person(\"David\", \"Scott\", role=c(\"aut\",\"cre\"), email=\"d.scott@auckland.ac.nz\"), person(\"Charles\", \"Roosen\", role=\"aut\"), person(\"Arni\", \"Magnusson\", role=\"aut\"), person(\"Jonathan\", \"Swinton\", role=\"aut\"), person(\"Ajay\", \"Shah\", role=\"ctb\"), person(\"Arne\", \"Henningsen\", role=\"ctb\"), person(\"Benno\", \"Puetz\", role=\"ctb\"), person(\"Bernhard\", \"Pfaff\", role=\"ctb\"), person(\"Claudio\", \"Agostinelli\", role=\"ctb\"), person(\"Claudius\", \"Loehnert\", role=\"ctb\"), person(\"David\", \"Mitchell\", role=\"ctb\"), person(\"David\", \"Whiting\", role=\"ctb\"), person(\"Fernando da\", \"Rosa\", role=\"ctb\"), person(\"Guido\", \"Gay\", role=\"ctb\"), person(\"Guido\", \"Schulz\", role=\"ctb\"), person(\"Ian\", \"Fellows\", role=\"ctb\"), person(\"Jeff\", \"Laake\", role=\"ctb\"), person(\"John\", \"Walker\", role=\"ctb\"), person(\"Jun\", \"Yan\", role=\"ctb\"), person(\"Liviu\", \"Andronic\", role=\"ctb\"), person(\"Markus\", \"Loecher\", role=\"ctb\"), person(\"Martin\", \"Gubri\", role=\"ctb\"), person(\"Matthieu\", \"Stigler\", role=\"ctb\"), person(\"Robert\", \"Castelo\", role=\"ctb\"), person(\"Seth\", \"Falcon\", role=\"ctb\"), person(\"Stefan\", \"Edwards\", role=\"ctb\"), person(\"Sven\", \"Garbade\", role=\"ctb\"), person(\"Uwe\", \"Ligges\", role=\"ctb\"))", + "Maintainer": "David Scott ", + "Imports": [ "stats", "utils" ], - "Hash": "b8acdf8af494d9ec19ccb2481a9b11c2" + "Suggests": [ + "knitr", + "plm", + "zoo", + "survival" + ], + "VignetteBuilder": "knitr", + "Description": "Coerce data to LaTeX and HTML tables.", + "URL": "http://xtable.r-forge.r-project.org/", + "Depends": [ + "R (>= 2.10.0)" + ], + "License": "GPL (>= 2)", + "Repository": "CRAN", + "NeedsCompilation": "no", + "Author": "David B. Dahl [aut], David Scott [aut, cre], Charles Roosen [aut], Arni Magnusson [aut], Jonathan Swinton [aut], Ajay Shah [ctb], Arne Henningsen [ctb], Benno Puetz [ctb], Bernhard Pfaff [ctb], Claudio Agostinelli [ctb], Claudius Loehnert [ctb], David Mitchell [ctb], David Whiting [ctb], Fernando da Rosa [ctb], Guido Gay [ctb], Guido Schulz [ctb], Ian Fellows [ctb], Jeff Laake [ctb], John Walker [ctb], Jun Yan [ctb], Liviu Andronic [ctb], Markus Loecher [ctb], Martin Gubri [ctb], Matthieu Stigler [ctb], Robert Castelo [ctb], Seth Falcon [ctb], Stefan Edwards [ctb], Sven Garbade [ctb], Uwe Ligges [ctb]" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.10", + "Source": "Repository", + "Type": "Package", + "Title": "Methods to Convert R Data to YAML and Back", + "Date": "2024-07-22", + "Suggests": [ + "RUnit" + ], + "Author": "Shawn P Garbett [aut], Jeremy Stephens [aut, cre], Kirill Simonov [aut], Yihui Xie [ctb], Zhuoer Dong [ctb], Hadley Wickham [ctb], Jeffrey Horner [ctb], reikoch [ctb], Will Beasley [ctb], Brendan O'Connor [ctb], Gregory R. Warnes [ctb], Michael Quinn [ctb], Zhian N. Kamvar [ctb], Charlie Gao [ctb]", + "Maintainer": "Shawn Garbett ", + "License": "BSD_3_clause + file LICENSE", + "Description": "Implements the 'libyaml' 'YAML' 1.1 parser and emitter () for R.", + "URL": "https://github.com/vubiostat/r-yaml/", + "BugReports": "https://github.com/vubiostat/r-yaml/issues", + "NeedsCompilation": "yes", + "Repository": "CRAN" }, "zlibbioc": { "Package": "zlibbioc", - "Version": "1.48.2", + "Version": "1.52.0", "Source": "Bioconductor", - "Repository": "Bioconductor 3.18", - "Hash": "2344be62c2da4d9e9942b5d8db346e59" + "Type": "Package", + "Title": "An R packaged zlib-1.2.5", + "Author": "Martin Morgan", + "Maintainer": "Bioconductor Package Maintainer ", + "Description": "This package uses the source code of zlib-1.2.5 to create libraries for systems that do not have these available via other means (most Linux and Mac users should have system-level access to zlib, and no direct need for this package). See the vignette for instructions on use.", + "Suggests": [ + "BiocStyle", + "knitr" + ], + "biocViews": "Infrastructure", + "URL": "https://bioconductor.org/packages/zlibbioc", + "BugReports": "https://github.com/Bioconductor/zlibbioc/issues", + "License": "Artistic-2.0 + file LICENSE", + "LazyLoad": "yes", + "VignetteBuilder": "knitr", + "PackageStatus": "Deprecated", + "git_url": "https://git.bioconductor.org/packages/zlibbioc", + "git_branch": "RELEASE_3_20", + "git_last_commit": "88140a7", + "git_last_commit_date": "2024-10-29", + "Repository": "Bioconductor 3.20", + "NeedsCompilation": "yes" } } } diff --git a/renv/activate.R b/renv/activate.R index 9b2e7f1..90b251c 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,11 +2,13 @@ local({ # the requested version of renv - version <- "1.0.5" + version <- "1.1.4" attr(version, "sha") <- NULL # the project directory - project <- getwd() + project <- Sys.getenv("RENV_PROJECT") + if (!nzchar(project)) + project <- getwd() # use start-up diagnostics if enabled diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") @@ -40,7 +42,7 @@ local({ return(FALSE) # next, check environment variables - # TODO: prefer using the configuration one in the future + # prefer using the configuration one in the future envvars <- c( "RENV_CONFIG_AUTOLOADER_ENABLED", "RENV_AUTOLOADER_ENABLED", @@ -96,6 +98,66 @@ local({ unloadNamespace("renv") # load bootstrap tools + ansify <- function(text) { + if (renv_ansify_enabled()) + renv_ansify_enhanced(text) + else + renv_ansify_default(text) + } + + renv_ansify_enabled <- function() { + + override <- Sys.getenv("RENV_ANSIFY_ENABLED", unset = NA) + if (!is.na(override)) + return(as.logical(override)) + + pane <- Sys.getenv("RSTUDIO_CHILD_PROCESS_PANE", unset = NA) + if (identical(pane, "build")) + return(FALSE) + + testthat <- Sys.getenv("TESTTHAT", unset = "false") + if (tolower(testthat) %in% "true") + return(FALSE) + + iderun <- Sys.getenv("R_CLI_HAS_HYPERLINK_IDE_RUN", unset = "false") + if (tolower(iderun) %in% "false") + return(FALSE) + + TRUE + + } + + renv_ansify_default <- function(text) { + text + } + + renv_ansify_enhanced <- function(text) { + + # R help links + pattern <- "`\\?(renv::(?:[^`])+)`" + replacement <- "`\033]8;;x-r-help:\\1\a?\\1\033]8;;\a`" + text <- gsub(pattern, replacement, text, perl = TRUE) + + # runnable code + pattern <- "`(renv::(?:[^`])+)`" + replacement <- "`\033]8;;x-r-run:\\1\a\\1\033]8;;\a`" + text <- gsub(pattern, replacement, text, perl = TRUE) + + # return ansified text + text + + } + + renv_ansify_init <- function() { + + envir <- renv_envir_self() + if (renv_ansify_enabled()) + assign("ansify", renv_ansify_enhanced, envir = envir) + else + assign("ansify", renv_ansify_default, envir = envir) + + } + `%||%` <- function(x, y) { if (is.null(x)) y else x } @@ -129,8 +191,22 @@ local({ } - startswith <- function(string, prefix) { - substring(string, 1, nchar(prefix)) == prefix + heredoc <- function(text, leave = 0) { + + # remove leading, trailing whitespace + trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text) + + # split into lines + lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]] + + # compute common indent + indent <- regexpr("[^[:space:]]", lines) + common <- min(setdiff(indent, -1L)) - leave + text <- paste(substring(lines, common), collapse = "\n") + + # substitute in ANSI links for executable renv code + ansify(text) + } bootstrap <- function(version, library) { @@ -288,8 +364,11 @@ local({ quiet = TRUE ) - if ("headers" %in% names(formals(utils::download.file))) - args$headers <- renv_bootstrap_download_custom_headers(url) + if ("headers" %in% names(formals(utils::download.file))) { + headers <- renv_bootstrap_download_custom_headers(url) + if (length(headers) && is.character(headers)) + args$headers <- headers + } do.call(utils::download.file, args) @@ -368,10 +447,21 @@ local({ for (type in types) { for (repos in renv_bootstrap_repos()) { + # build arguments for utils::available.packages() call + args <- list(type = type, repos = repos) + + # add custom headers if available -- note that + # utils::available.packages() will pass this to download.file() + if ("headers" %in% names(formals(utils::download.file))) { + headers <- renv_bootstrap_download_custom_headers(repos) + if (length(headers) && is.character(headers)) + args$headers <- headers + } + # retrieve package database db <- tryCatch( as.data.frame( - utils::available.packages(type = type, repos = repos), + do.call(utils::available.packages, args), stringsAsFactors = FALSE ), error = identity @@ -453,6 +543,14 @@ local({ } + renv_bootstrap_github_token <- function() { + for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(envval) + } + } + renv_bootstrap_download_github <- function(version) { enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") @@ -460,16 +558,19 @@ local({ return(FALSE) # prepare download options - pat <- Sys.getenv("GITHUB_PAT") - if (nzchar(Sys.which("curl")) && nzchar(pat)) { + token <- renv_bootstrap_github_token() + if (is.null(token)) + token <- "" + + if (nzchar(Sys.which("curl")) && nzchar(token)) { fmt <- "--location --fail --header \"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "curl", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) - } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + } else if (nzchar(Sys.which("wget")) && nzchar(token)) { fmt <- "--header=\"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "wget", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) @@ -594,11 +695,19 @@ local({ } - renv_bootstrap_platform_prefix <- function() { + renv_bootstrap_platform_prefix_default <- function() { - # construct version prefix - version <- paste(R.version$major, R.version$minor, sep = ".") - prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") + # read version component + version <- Sys.getenv("RENV_PATHS_VERSION", unset = "R-%v") + + # expand placeholders + placeholders <- list( + list("%v", format(getRversion()[1, 1:2])), + list("%V", format(getRversion()[1, 1:3])) + ) + + for (placeholder in placeholders) + version <- gsub(placeholder[[1L]], placeholder[[2L]], version, fixed = TRUE) # include SVN revision for development versions of R # (to avoid sharing platform-specific artefacts with released versions of R) @@ -607,10 +716,19 @@ local({ identical(R.version[["nickname"]], "Unsuffered Consequences") if (devel) - prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") + version <- paste(version, R.version[["svn rev"]], sep = "-r") + + version + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- renv_bootstrap_platform_prefix_default() # build list of path components - components <- c(prefix, R.version$platform) + components <- c(version, R.version$platform) # include prefix if provided by user prefix <- renv_bootstrap_platform_prefix_impl() @@ -631,6 +749,9 @@ local({ # if the user has requested an automatic prefix, generate it auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (is.na(auto) && getRversion() >= "4.4.0") + auto <- "TRUE" + if (auto %in% c("TRUE", "True", "true", "1")) return(renv_bootstrap_platform_prefix_auto()) @@ -822,24 +943,23 @@ local({ # the loaded version of renv doesn't match the requested version; # give the user instructions on how to proceed - remote <- if (!is.null(description[["RemoteSha"]])) { + dev <- identical(description[["RemoteType"]], "github") + remote <- if (dev) paste("rstudio/renv", description[["RemoteSha"]], sep = "@") - } else { + else paste("renv", description[["Version"]], sep = "@") - } # display both loaded version + sha if available friendly <- renv_bootstrap_version_friendly( version = description[["Version"]], - sha = description[["RemoteSha"]] + sha = if (dev) description[["RemoteSha"]] ) - fmt <- paste( - "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", - "- Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", - "- Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", - sep = "\n" - ) + fmt <- heredoc(" + renv %1$s was loaded from project library, but this project is configured to use renv %2$s. + - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile. + - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library. + ") catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) FALSE @@ -847,8 +967,14 @@ local({ } renv_bootstrap_validate_version_dev <- function(version, description) { + expected <- description[["RemoteSha"]] - is.character(expected) && startswith(expected, version) + if (!is.character(expected)) + return(FALSE) + + pattern <- sprintf("^\\Q%s\\E", version) + grepl(pattern, expected, perl = TRUE) + } renv_bootstrap_validate_version_release <- function(version, description) { @@ -1028,10 +1154,10 @@ local({ renv_bootstrap_exec <- function(project, libpath, version) { if (!renv_bootstrap_load(project, libpath, version)) - renv_bootstrap_run(version, libpath) + renv_bootstrap_run(project, libpath, version) } - renv_bootstrap_run <- function(version, libpath) { + renv_bootstrap_run <- function(project, libpath, version) { # perform bootstrap bootstrap(version, libpath) @@ -1042,7 +1168,7 @@ local({ # try again to load if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { - return(renv::load(project = getwd())) + return(renv::load(project = project)) } # failed to download or load renv; warn the user @@ -1088,98 +1214,105 @@ local({ jsonlite::fromJSON(txt = text, simplifyVector = FALSE) } - renv_json_read_default <- function(file = NULL, text = NULL) { + renv_json_read_patterns <- function() { - # find strings in the JSON - text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") - pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - locs <- gregexpr(pattern, text, perl = TRUE)[[1]] + list( - # if any are found, replace them with placeholders - replaced <- text - strings <- character() - replacements <- character() + # objects + list("{", "\t\n\tobject(\t\n\t", TRUE), + list("}", "\t\n\t)\t\n\t", TRUE), - if (!identical(c(locs), -1L)) { + # arrays + list("[", "\t\n\tarray(\t\n\t", TRUE), + list("]", "\n\t\n)\n\t\n", TRUE), - # get the string values - starts <- locs - ends <- locs + attr(locs, "match.length") - 1L - strings <- substring(text, starts, ends) + # maps + list(":", "\t\n\t=\t\n\t", TRUE), - # only keep those requiring escaping - strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) + # newlines + list("\\u000a", "\n", FALSE) - # compute replacements - replacements <- sprintf('"\032%i\032"', seq_along(strings)) + ) - # replace the strings - mapply(function(string, replacement) { - replaced <<- sub(string, replacement, replaced, fixed = TRUE) - }, strings, replacements) + } - } + renv_json_read_envir <- function() { - # transform the JSON into something the R parser understands - transformed <- replaced - transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) - transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) - transformed <- gsub("[]}]", ")", transformed, perl = TRUE) - transformed <- gsub(":", "=", transformed, fixed = TRUE) - text <- paste(transformed, collapse = "\n") + envir <- new.env(parent = emptyenv()) - # parse it - json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] + envir[["+"]] <- `+` + envir[["-"]] <- `-` - # construct map between source strings, replaced strings - map <- as.character(parse(text = strings)) - names(map) <- as.character(parse(text = replacements)) + envir[["object"]] <- function(...) { + result <- list(...) + names(result) <- as.character(names(result)) + result + } - # convert to list - map <- as.list(map) + envir[["array"]] <- list - # remap strings in object - remapped <- renv_json_read_remap(json, map) + envir[["true"]] <- TRUE + envir[["false"]] <- FALSE + envir[["null"]] <- NULL - # evaluate - eval(remapped, envir = baseenv()) + envir } - renv_json_read_remap <- function(json, map) { + renv_json_read_remap <- function(object, patterns) { - # fix names - if (!is.null(names(json))) { - lhs <- match(names(json), names(map), nomatch = 0L) - rhs <- match(names(map), names(json), nomatch = 0L) - names(json)[rhs] <- map[lhs] - } + # repair names if necessary + if (!is.null(names(object))) { + + nms <- names(object) + for (pattern in patterns) + nms <- gsub(pattern[[2L]], pattern[[1L]], nms, fixed = TRUE) + names(object) <- nms - # fix values - if (is.character(json)) - return(map[[json]] %||% json) - - # handle true, false, null - if (is.name(json)) { - text <- as.character(json) - if (text == "true") - return(TRUE) - else if (text == "false") - return(FALSE) - else if (text == "null") - return(NULL) } - # recurse - if (is.recursive(json)) { - for (i in seq_along(json)) { - json[i] <- list(renv_json_read_remap(json[[i]], map)) - } + # repair strings if necessary + if (is.character(object)) { + for (pattern in patterns) + object <- gsub(pattern[[2L]], pattern[[1L]], object, fixed = TRUE) } - json + # recurse for other objects + if (is.recursive(object)) + for (i in seq_along(object)) + object[i] <- list(renv_json_read_remap(object[[i]], patterns)) + + # return remapped object + object } + + renv_json_read_default <- function(file = NULL, text = NULL) { + + # read json text + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + + # convert into something the R parser will understand + patterns <- renv_json_read_patterns() + transformed <- text + for (pattern in patterns) + transformed <- gsub(pattern[[1L]], pattern[[2L]], transformed, fixed = TRUE) + + # parse it + rfile <- tempfile("renv-json-", fileext = ".R") + on.exit(unlink(rfile), add = TRUE) + writeLines(transformed, con = rfile) + json <- parse(rfile, keep.source = FALSE, srcfile = NULL)[[1L]] + + # evaluate in safe environment + result <- eval(json, envir = renv_json_read_envir()) + + # fix up strings if necessary -- do so only with reversible patterns + patterns <- Filter(function(pattern) pattern[[3L]], patterns) + renv_json_read_remap(result, patterns) + + } + # load the renv profile, if any renv_bootstrap_profile_load(project) diff --git a/renv/settings.json b/renv/settings.json index ffdbb32..0715690 100644 --- a/renv/settings.json +++ b/renv/settings.json @@ -1,5 +1,5 @@ { - "bioconductor.version": null, + "bioconductor.version": "3.20", "external.libraries": [], "ignored.packages": [], "package.dependency.fields": [ diff --git a/scripts/calculate_scores.py b/scripts/calculate_scores.py deleted file mode 100644 index b8874e9..0000000 --- a/scripts/calculate_scores.py +++ /dev/null @@ -1,101 +0,0 @@ -import json -import sys - -import numpy as np -import pandas as pd -from time import time - -from enrichment_auc.metrics import ( - aucell, - cerno, - gsea, - ratio, - svd, - jasmine, - vision, - z, - mean, -) - -if __name__ == "__main__": - inpath = sys.argv[1] - outpath = sys.argv[2] - datatype = sys.argv[3] - outpath = outpath + "/" + datatype - # load genesets - with open(inpath + "/filtered_genesets_genes.json") as file: - genesets = json.load(file) - gs_names = list(genesets.keys()) - # load gene expressions - gene_expr = pd.read_csv(inpath + "/" + datatype + "_filtered_data.csv", index_col=0) - patients_names = gene_expr.columns.to_list() - genes = gene_expr.index.tolist() - gene_expr = gene_expr.to_numpy().astype(float) - - # get scores with single output: - scores_functions = [ - ratio.RATIO, - svd.SVD, - svd.sparse_PCA, - vision.VISION, - mean.MEAN, - jasmine.JASMINE, - cerno.AUC, - aucell.AUCELL, - gsea.GSVA, - gsea.SSGSEA, - ] - scores_names = [ - "ratios", - "svd", - "sparse_pca", - "vision", - "mean", - "jasmine", - "auc", - "aucell", - "gsva", - "ssgsea", - "cerno", - "z", - ] - - elapsed_times = np.zeros(len(scores_names)) - for i in range(len(scores_functions)): - t = time() - score = scores_functions[i](genesets, gene_expr, genes) - elapsed = time() - t - elapsed_times[i] = elapsed - df_score = pd.DataFrame( - data=score, index=list(genesets.keys()), columns=patients_names - ) - df_score.to_csv(outpath + "/" + scores_names[i] + ".csv") - - # z - z_names = ["pvals_005", "qvals_005", "z"] - t = time() - output = z.Z(genesets, gene_expr, genes, alpha=0.05) - elapsed = time() - t - elapsed_times[scores_names.index("z")] = elapsed - for i in range(len(z_names)): - df = pd.DataFrame( - data=output[i], index=list(genesets.keys()), columns=patients_names - ) - df.to_csv(outpath + "/" + z_names[i] + ".csv") - - # cerno - cerno_names = ["cerno", "pvals_cerno005", "qvals_cerno005"] - t = time() - output = cerno.FISHER(genesets, gene_expr, genes, alpha=0.05) - elapsed = time() - t - elapsed_times[scores_names.index("cerno")] += elapsed - for i in range(len(cerno_names)): - df = pd.DataFrame( - data=output[i], index=list(genesets.keys()), columns=patients_names - ) - df.to_csv(outpath + "/" + cerno_names[i] + ".csv") - - elapsed_times = pd.DataFrame( - data=elapsed_times, index=scores_names, columns=["times"] - ) - elapsed_times.to_csv(outpath + "/times.csv") diff --git a/scripts/calculate_scores.sh b/scripts/calculate_scores.sh deleted file mode 100755 index 6261e60..0000000 --- a/scripts/calculate_scores.sh +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/bash -# declare -a data_types=('seurat' 'row') -declare -a data_types=('seurat') -inpath="/mnt/pmanas/Ania/scrna-seq/data/BreastCancer" -outpath="/mnt/pmanas/Ania/scrna-seq/results/BreastCancer" -# Iterate the string array using for loop -for data_type in ${data_types[@]}; do - python scripts/calculate_scores.py $inpath $outpath $data_type -done diff --git a/scripts/escript.py b/scripts/escript.py deleted file mode 100644 index 03f9ae2..0000000 --- a/scripts/escript.py +++ /dev/null @@ -1,213 +0,0 @@ -import json -import os -import sys -from time import time - -import numpy as np -import pandas as pd -from tqdm import tqdm - -from enrichment_auc.gmm.distributions import find_distribution -from enrichment_auc.gmm.thresholds import correct_via_kmeans, find_thresholds -from enrichment_auc.plot.plot_distributed_data import plot_mixtures -from enrichment_auc.plot.plot_scatter_flow import plot_flow - - -def pipeline_for_dist(score, geneset_name, score_name, save_dir): - score = np.nan_to_num(score) - # get mixtures and thresholds - distributions = find_distribution(score, geneset_name) - thresholds_gmm = find_thresholds(distributions, score, geneset_name) - thresholds_kmeans = correct_via_kmeans(distributions, thresholds_gmm) - - if score.max() - score.min() > 10 ** (-20): - thr_gmm = score.max() - thr_kmeans = score.max() - if thresholds_gmm.shape[0] != 0: - thr_gmm = thresholds_gmm[-1] - if thresholds_kmeans.shape[0] != 0: - thr_kmeans = thresholds_kmeans[-1] - plot_mixtures( - geneset_name, - distributions, - score, - thr_gmm, - thresholds_gmm, - score_name, - save_dir=save_dir + "/top1", - file_only=True, - ) - plot_mixtures( - geneset_name, - distributions, - score, - thr_kmeans, - thresholds_kmeans, - score_name, - save_dir=save_dir + "/kmeans", - file_only=True, - ) - return (thresholds_gmm, thresholds_kmeans, distributions) - - -def evaluate_pas( - scores, - gs_names, - geneset_info, - res_folder, - data_type, - score_name, - embed=None, - labels_arr=None, -): - print(score_name) - scores_thr = pd.DataFrame(0, index=gs_names, columns=np.arange(1)) - scores_thr_kmeans = pd.DataFrame(0, index=gs_names, columns=np.arange(1)) - scores_dist = [] - gmm_thrs = {} - kmeans_thrs = {} - - for i, gs_name in tqdm(enumerate(gs_names), total=len(gs_names)): - gs_title = geneset_info.Title.where(geneset_info.ID == gs_name, gs_name).max() - score = scores[i, :] - ( - thresholds_gmm, - thresholds_kmeans, - distributions, - ) = pipeline_for_dist(score, gs_title, score_name, save_dir) - distributions["weights"] = (distributions["weights"]).tolist() - distributions["mu"] = (distributions["mu"]).tolist() - distributions["sigma"] = (distributions["sigma"]).tolist() - if embed is not None and labels_arr is not None and score.max() - score.min() > 10 ** (-20): - plot_flow( - embed, - score, - thresholds_kmeans, - labels_arr, - name=score_name, - gs_name=gs_name, - embed_name="t-SNE", - save_dir=save_dir + "/kmeans/flow/", - ) - plot_flow( - embed, - score, - thresholds_gmm, - labels_arr, - name=score_name, - gs_name=gs_name, - embed_name="t-SNE", - save_dir=save_dir + "/top1/flow/", - ) - - if all(thresholds_gmm.shape): - scores_thr.loc[gs_name] = thresholds_gmm[-1] - else: - scores_thr.loc[gs_name] = np.nan - if all(thresholds_kmeans.shape): - scores_thr_kmeans.loc[gs_name] = thresholds_kmeans[-1] - else: - scores_thr_kmeans.loc[gs_name] = np.nan - scores_dist.append(distributions) - - gmm_thrs[gs_name] = thresholds_gmm.tolist() - kmeans_thrs[gs_name] = thresholds_kmeans.tolist() - - scores_thr.to_csv(res_folder + data_type + "/gmm_thr/" + score_name + "_thr.csv") - scores_thr_kmeans.to_csv( - res_folder + data_type + "/kmeans_thr/" + score_name + "_thr.csv" - ) - - with open(res_folder + data_type + "/" + score_name + "_dist.json", "w") as fout: - json.dump(scores_dist, fout) - - with open( - res_folder + data_type + "/gmm_thr/" + score_name + "_thrs.json", - "w", - ) as fout: - json.dump(gmm_thrs, fout) - with open( - res_folder + data_type + "/kmeans_thr/" + score_name + "_thrs.json", - "w", - ) as fout: - json.dump(kmeans_thrs, fout) - - -score_names = [ - "z", - "gsva", - "auc", - "cerno", - "ratios", - "vision", - "aucell", - "svd", - "sparse_pca", - "ssgsea", - "jasmine", - "mean", - "vae", - "vae_corr", -] # all scores to run for each data type - -if __name__ == "__main__": - data_type = sys.argv[1] - res_folder = sys.argv[2] - save_dir = sys.argv[3] - data_folder = sys.argv[4] - save_dir = save_dir + "/" + data_type - print(data_type) - geneset_info = pd.read_csv( - data_folder + "filtered_genesets_modules.csv", index_col=0 - ) - embed = None - labels_arr = None - if os.path.isfile(data_folder + "vae.csv"): - embed = pd.read_csv(data_folder + "vae.csv") - embed = embed.select_dtypes(["number"]).to_numpy().astype(float) - if os.path.isfile(data_folder + "true_labels.csv"): - labels_arr = pd.read_csv(data_folder + "true_labels.csv", index_col=0) - labels_arr = labels_arr["CellType"].to_numpy() - - if not os.path.isdir(save_dir + "/kmeans/flow/"): - os.makedirs(save_dir + "/kmeans/flow/") - if not os.path.isdir(save_dir + "/top1/flow/"): - os.makedirs(save_dir + "/top1/flow/") - - if not os.path.isdir(res_folder + data_type + "/gmm_thr/"): - os.makedirs(res_folder + data_type + "/gmm_thr/") - if not os.path.isdir(res_folder + data_type + "/kmeans_thr/"): - os.makedirs(res_folder + data_type + "/kmeans_thr/") - - for score_name in tqdm(score_names): - # get scores - scores = pd.read_csv( - res_folder + data_type + "/" + score_name + ".csv", - index_col=0, - ) - gs_names = scores.index.values.tolist() - scores = scores.to_numpy() - - evaluate_pas( - scores, - gs_names, - geneset_info, - res_folder, - data_type, - score_name, - embed, - labels_arr, - ) - - if score_name in ["svd", "sparse_pca", "z", "vision"]: - scores = np.abs(scores) - evaluate_pas( - scores, - gs_names, - geneset_info, - res_folder, - data_type, - score_name + "_abs", - embed, - labels_arr, - ) diff --git a/scripts/estimate_classif.py b/scripts/estimate_classif.py deleted file mode 100644 index 82a482d..0000000 --- a/scripts/estimate_classif.py +++ /dev/null @@ -1,114 +0,0 @@ -import os -import sys -import pandas as pd - -from enrichment_auc.evaluate_classification import Scores - - -scorenames = [ - "aucell", - "auc", - "cerno", - "jasmine", - "ratios", - "mean", - "vision", - "vision_abs", - "z", - "z_abs", - "svd", - "svd_abs", - "sparse_pca", - "sparse_pca_abs", - "gsva", - "ssgsea", - "vae", - "vae_corr", -] - -names = [ - "Balanced_accuracy_", - "ARI_", - "F1_", - "Recall_", - "Matthews_", - "Jaccard_", - "Hamming_", - "Precision_", - "FDR_", -] - - -if __name__ == "__main__": - tissue = sys.argv[1] - norm = sys.argv[2] - clustertype = sys.argv[3] - datafolder = sys.argv[4] - resfolder = sys.argv[5] + tissue + "/" + norm + "/" - - plottype = clustertype - if clustertype == "gmm": - plottype = "top1" - - if not os.path.isdir(resfolder + "confusion_matrix_" + plottype): - os.makedirs(resfolder + "confusion_matrix_" + plottype) - - paths = pd.read_csv(datafolder + "chosen_paths.txt", sep="\t", index_col=0) - geneset_info = pd.read_csv( - datafolder + tissue + "/filtered_genesets_modules.csv", index_col=0 - ) - dataset_specific = paths[paths["ID"].isin(geneset_info["ID"])] - dataset_specific.loc[:, "Celltype"] = dataset_specific["Celltype"].str.replace( - ";", " +" - ) - to_save = dataset_specific[["ID", "Title", "Celltype"]] - - true_labels = pd.read_csv(datafolder + tissue + "/true_labels.csv", index_col=0) - not_pre_B = ~true_labels["CellType"].isin(["precursor B cell", "pro-B cell"]) - true_labels = true_labels[not_pre_B] - true_labels.loc[ - true_labels["CellType"].isin(["CD4+ T cell", "Cytotoxic T cell"]), "CellType" - ] = "T cell" - true_labels.loc[ - true_labels["CellType"].isin(["mature B cell"]), "CellType" - ] = "B cell" - true_labels.loc[ - true_labels["CellType"].isin(["Natural killer cell", "natural killer cell"]), - "CellType", - ] = "NK cell" - true_labels.loc[ - ~true_labels["CellType"].isin(["NK cell", "T cell", "B cell"]), "CellType" - ] = "other" - - to_save_ = to_save[ - to_save.Celltype.str.contains("|".join(true_labels.CellType.unique())) - ] - - for scorename in scorenames: - if scorename.endswith("_abs"): - scores = pd.read_csv(resfolder + scorename[:-4] + ".csv", index_col=0) - scores = scores.abs() - else: - scores = pd.read_csv(resfolder + scorename + ".csv", index_col=0) - scores = scores.loc[:, not_pre_B] - thresholds = pd.read_csv( - resfolder + "/" + clustertype + "_thr/" + scorename + "_thr.csv", - index_col=0, - ) - eval = Scores() - for index, row in to_save_.iterrows(): - gs_score = scores.loc[row["ID"]] - thr = thresholds.loc[row["ID"]].max() - preds = gs_score > thr - preds = preds.astype(int) - true_labels["label"] = true_labels.CellType.isin( - row["Celltype"].split(" + ") - ).astype(int) - eval.get_classification_scores(true_labels["label"], preds) - eval.save_confusion_matrix( - true_labels["label"], preds, resfolder, plottype, scorename, row["ID"] - ) - for i, cls_score in enumerate(eval.scores): - to_save_.loc[:, eval.names[i] + scorename] = cls_score - - to_save_.to_csv(resfolder + "classification_scores_" + plottype + ".csv") diff --git a/scripts/estimate_classif.sh b/scripts/estimate_classif.sh deleted file mode 100755 index 6d11d40..0000000 --- a/scripts/estimate_classif.sh +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/bash -norm='seurat' -declare -a data_types=("PBMC" "Liver" "COVID" "BM") -declare -a cluster_types=('gmm' 'kmeans' 'AUCell') - -data_folder="/mnt/pmanas/Ania/scrna-seq/data/" -res_folder="/mnt/pmanas/Ania/scrna-seq/results/" - -for data_type in ${data_types[@]}; do - for cluster_type in ${cluster_types[@]}; do - python scripts/estimate_classif.py $data_type $norm $cluster_type $data_folder $res_folder - done -done diff --git a/scripts/plot_classif.py b/scripts/plot_classif.py deleted file mode 100644 index 4267437..0000000 --- a/scripts/plot_classif.py +++ /dev/null @@ -1,107 +0,0 @@ -import os -from itertools import combinations - -import pandas as pd - -from enrichment_auc.plot.plot_boxplots import visualize_difference, visualize_methods - -datafolder = "/mnt/pmanas/Ania/scrna-seq/data/" -resfolder = "/mnt/pmanas/Ania/scrna-seq/results/" -plotfolder = "/mnt/pmanas/Ania/scrna-seq/plots/" - -tissues = ["PBMC", "COVID", "BM", "Liver"] -norm = "seurat" -plottypes = ["top1", "kmeans", "AUCell"] - -names = [ - "Balanced_accuracy_", - "ARI_", - "F1_", - "Recall_", - "Matthews_", - "Jaccard_", - "Hamming_", - "Precision_", - "FDR_", -] -data = {} -merged = {} -cols = ["ID", "Title", "Celltype"] - -for tissue in tissues: - print(tissue) - data[tissue] = {} - for plottype in plottypes: - # do violin plots of each thr method per dataset - plot_folder = ( - plotfolder + tissue + "/" + norm + "/" + plottype + "/classification/" - ) - res_folder = resfolder + tissue + "/" + norm + "/" - if not os.path.isdir(plot_folder): - os.makedirs(plot_folder) - df = pd.read_csv( - res_folder + "classification_scores_" + plottype + ".csv", index_col=0 - ) - data[tissue][plottype] = df - groups = df.groupby(["Celltype"])["Celltype"].count() - celltypes = groups[groups > 2].keys().tolist() - visualize_methods(df, celltypes, names, plot_folder) - # do violin plots of differences between thr methods per dataset - for x, y in list(combinations(plottypes, 2)): - plot_folder = plotfolder + tissue + "/" + norm + "/" + x + "_" + y + "/" - if not os.path.isdir(plot_folder): - os.makedirs(plot_folder) - for celltype in celltypes: - subfolder = plot_folder + celltype + "/" - if not os.path.isdir(subfolder): - os.makedirs(subfolder) - df1 = data[tissue][x].loc[data[tissue][x]["Celltype"] == celltype] - df2 = data[tissue][y].loc[data[tissue][y]["Celltype"] == celltype] - visualize_difference( - df1.drop(columns=cols), df2.drop(columns=cols), names, subfolder, x, y - ) - visualize_difference( - data[tissue][x].drop(columns=cols), - data[tissue][y].drop(columns=cols), - names, - plot_folder, - x, - y, - ) - -print("merged") -# do violin plots of each thr method per whole -for plottype in plottypes: - plot_folder = plotfolder + "/merged/" + norm + "/" + plottype + "/" - if not os.path.isdir(plot_folder): - os.makedirs(plot_folder) - merged[plottype] = pd.concat([data[tissue][plottype] for tissue in tissues]) - groups = merged[plottype].groupby(["Celltype"])["Celltype"].count() - celltypes = groups[groups > 2].keys().tolist() - visualize_methods(merged[plottype], celltypes, names, plot_folder) - df = merged[plottype].copy(deep=True) - df["Celltype"] = "merged" - visualize_methods(df, ["merged"], names, plot_folder) - -# do violin plots of differences between thr methods per whole -for x, y in list(combinations(plottypes, 2)): - plot_folder = plotfolder + "/merged/" + norm + "/" + x + "_" + y + "/" - if not os.path.isdir(plot_folder): - os.makedirs(plot_folder) - for celltype in celltypes: - subfolder = plot_folder + celltype + "/" - if not os.path.isdir(subfolder): - os.makedirs(subfolder) - df1 = merged[x].loc[merged[x]["Celltype"] == celltype] - df2 = merged[y].loc[merged[y]["Celltype"] == celltype] - visualize_difference( - df1.drop(columns=cols), df2.drop(columns=cols), names, subfolder, x, y - ) - visualize_difference( - merged[x].drop(columns=cols), - merged[y].drop(columns=cols), - names, - plot_folder, - x, - y, - ) diff --git a/scripts/small-vae.py b/scripts/small-vae.py deleted file mode 100644 index 0c11746..0000000 --- a/scripts/small-vae.py +++ /dev/null @@ -1,95 +0,0 @@ -import os -import sys -import numpy as np -import pandas as pd -from argparse import ArgumentParser -import tensorflow as tf -import json -from tqdm import tqdm - -from enrichment_auc.metrics.vae import VAE - -tissues = ["PBMC", "COVID", "BM", "Liver"] -norm = "seurat" - -if __name__ == "__main__": - parser = ArgumentParser() - parser.add_argument("--test_case", default="layer_size", type=str) - parser.add_argument("--intermediate_dim", nargs="+", type=int) - parser.add_argument("--lr", default=10e-3, type=float) - parser.add_argument("--epochs", default=1000, type=int) - parser.add_argument("--reg", default=0.0, type=float) - parser.add_argument("--GPU", default=0, type=str) - - args = parser.parse_args() - test_case = args.test_case - intermediate_dim = tuple(args.intermediate_dim) - learning_rate = args.lr - epochs = args.epochs - verbose = 0 - batch_size = 2048 - reg = args.reg - data_folder = "/mnt/pmanas/Ania/scrna-seq/data/" - paths = pd.read_csv(data_folder + "chosen_paths.txt", sep="\t", index_col=0) - - with tf.device("/device:GPU:{}".format(args.GPU)): - for tissue in tissues: - print(tissue) - datafolder = data_folder + tissue + "/" - resfolder = ( - "/mnt/pmanas/Ania/scrna-seq/results/" - + tissue - + "/pas_vae/" - + test_case - + "/" - ) - - gene_expr = pd.read_csv( - datafolder + norm + "_filtered_data.csv", index_col=0 - ) - genes = gene_expr.index.tolist() - patients_names = gene_expr.columns.to_list() - gene_expr = gene_expr.to_numpy().astype(float) - with open(datafolder + "filtered_genesets_genes.json") as file: - genesets = json.load(file) - gs_names = list(genesets.keys()) - - if not os.path.isdir(resfolder): - os.makedirs(resfolder) - - filenames = os.listdir(resfolder) - filenames = [ - filename for filename in filenames if filename.endswith(".txt") - ] - trial = len(filenames) - - with open(resfolder + "config{}.txt".format(trial), "a") as myfile: - myfile.write(str(intermediate_dim)) - myfile.write("\n") - myfile.write(str(learning_rate)) - myfile.write("\n") - myfile.write(str(epochs)) - myfile.write("\n") - myfile.write(str(reg)) - - for i in tqdm(range(10)): - pas = np.empty((paths.shape[0], gene_expr.shape[1])) - j = 0 - for gs_name, geneset_genes in genesets.items(): - if paths["ID"].str.contains(gs_name).any(): - genes_in_ds = [gene in geneset_genes for gene in genes] - in_gs = gene_expr[genes_in_ds, :] - vae_f = VAE( - latent_dim=1, - verbose=verbose, - intermediate_dim=intermediate_dim, - learning_rate=learning_rate, - epochs=epochs, - batch_size=batch_size, - ).fit(in_gs.T) - pas[j] = vae_f.transform(in_gs.T).flatten() - j += 1 - df = pd.DataFrame( - data=pas, index=list(paths["ID"]), columns=patients_names - ) - df.to_csv(resfolder + "pas_trial{}_{}.csv".format(trial, i)) diff --git a/scripts/thr.sh b/scripts/thr.sh deleted file mode 100755 index 38402c8..0000000 --- a/scripts/thr.sh +++ /dev/null @@ -1,23 +0,0 @@ -#! /bin/bash -# poetry install -# poetry build -norm='seurat' -declare -a data_types=('PBMC' 'Liver' 'BM' 'COVID') - -# Iterate the string array using for loop -for data_type in ${data_types[@]}; do - data_folder="/mnt/pmanas/Ania/scrna-seq/data/${data_type}/" - res_folder="/mnt/pmanas/Ania/scrna-seq/results/${data_type}/" - plot_folder="/mnt/pmanas/Ania/scrna-seq/plots/${data_type}" - python scripts/escript.py $norm $res_folder $plot_folder $data_folder - # zip results - # cd $"${res_folder}${norm}" - # zip "${norm}.zip" *.json - # zip -r "${norm}.zip" kmeans_thr/ gmm_thr/ - # zip -r "${norm}.zip" times_thrs.csv - # cd $"../../../${plot_folder}/${norm}" - # zip -r "${norm}.zip" kmeans/ top1/ - # find . -type f -iname \*.png -delete - # find . -type f -iname \*.html -delete - # cd ../../../ -done diff --git a/scripts/upregulate_vae.py b/scripts/upregulate_vae.py deleted file mode 100644 index b7cf847..0000000 --- a/scripts/upregulate_vae.py +++ /dev/null @@ -1,33 +0,0 @@ -import os -import json -import numpy as np -import pandas as pd -import sys - - -import enrichment_auc.metrics.vae as vae - -if __name__ == "__main__": - tissue = sys.argv[1] - norm = sys.argv[2] - data_folder = os.path.join(sys.argv[3], tissue) - res_folder = os.path.join(sys.argv[4], tissue, norm) - - gene_expr = pd.read_csv( - os.path.join(data_folder, norm + "_filtered_data.csv"), index_col=0 - ) - genes = gene_expr.index.tolist() - patients_names = gene_expr.columns.to_list() - gene_expr = gene_expr.to_numpy().astype(float) - - with open(os.path.join(data_folder, "filtered_genesets_genes.json")) as file: - genesets = json.load(file) - gs_names = list(genesets.keys()) - pas = pd.read_csv(os.path.join(res_folder, "vae.csv"), index_col=0) - genesets = dict((k, genesets[k]) for k in list(pas.index)) - gs_names = list(genesets.keys()) - pas_corr = vae.correct_order( - gene_expr, genesets, genes, pas.to_numpy().astype(float) - ) - df = pd.DataFrame(data=pas_corr, index=pas.index, columns=patients_names) - df.to_csv(os.path.join(res_folder, "vae_corr.csv")) diff --git a/scripts/upregulate_vae.sh b/scripts/upregulate_vae.sh deleted file mode 100644 index 4d59e3b..0000000 --- a/scripts/upregulate_vae.sh +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/bash -norm='seurat' -declare -a data_types=("PBMC" "Liver" "COVID" "BM") -data_folder="/mnt/pmanas/Ania/scrna-seq/data/" -res_folder="/mnt/pmanas/Ania/scrna-seq/results/" - -for data_type in ${data_types[@]}; do - python scripts/upregulate_vae.py $data_type $norm $data_folder $res_folder -done \ No newline at end of file diff --git a/scripts/vae-tf-gpu-msc.py b/scripts/vae-tf-gpu-msc.py deleted file mode 100644 index 08113b2..0000000 --- a/scripts/vae-tf-gpu-msc.py +++ /dev/null @@ -1,96 +0,0 @@ -import os - -# os.environ["CUDA_VISIBLE_DEVICES"]="0" -from argparse import ArgumentParser -import numpy as np -import pandas as pd -import plotly.express as px -import plotly.graph_objects as go -from sklearn.manifold import TSNE -from sklearn.metrics import silhouette_score -from tqdm import tqdm -import tensorflow as tf - -import enrichment_auc -from enrichment_auc.metrics.vae import VAE - -tissues = [ - # "Pancreas", - "PBMC", - "COVID", - # "BreastCancer", - "BM", - "Liver", -] -norm = "seurat" - -if __name__ == "__main__": - parser = ArgumentParser() - parser.add_argument("--intermediate_dim", nargs="+", type=int) - parser.add_argument("--lr", default=10e-3, type=float) - parser.add_argument("--epochs", default=1000, type=int) - parser.add_argument("--reg", default=0.0, type=float) - parser.add_argument("--GPU", default=1, type=str) - - args = parser.parse_args() - intermediate_dim = tuple(args.intermediate_dim) - learning_rate = args.lr - epochs = args.epochs - verbose = 0 - batch_size = 2048 - reg = args.reg - - with tf.device("/device:GPU:{}".format(args.GPU)): - for tissue in tissues: - print(tissue) - datafolder = "/mnt/pmanas/Ania/scrna-seq/data/" + tissue + "/" - resfolder = "results/" + tissue + "/vae/" - - gene_expr = pd.read_csv( - datafolder + norm + "_filtered_data.csv", index_col=0 - ) - labels = pd.read_csv(datafolder + "true_labels.csv", index_col=0) - labels = labels["CellType"].to_numpy() - - if not os.path.isdir(resfolder): - os.makedirs(resfolder) - gene_expr = gene_expr.to_numpy().astype(float) - - # VAE + t-SNE - max_sil = -1.1 - for i in tqdm(range(10)): - vae = VAE( - latent_dim=50, - verbose=verbose, - intermediate_dim=intermediate_dim, - learning_rate=learning_rate, - epochs=epochs, - # random_state=42, - batch_size=batch_size, - ).fit(gene_expr.T) - embed = vae.transform(gene_expr.T) - tsne = TSNE(n_components=2, perplexity=35, n_iter=1500, angle=0.5) - embed1 = tsne.fit_transform(embed, labels) - s = silhouette_score(embed1, labels) - if s > max_sil: - max_sil = s - fig = px.scatter( - x=embed1[:, 0], - y=embed1[:, 1], - color=labels, - color_discrete_sequence=px.colors.qualitative.Alphabet, - title="Visualization of " - + tissue - + " dataset using VAE and t-SNE" - + "
Silhouette score: " - + str(round(s, 3)), - labels={"x": "t-SNE 1", "y": "t-SNE 2", "color": "Cell Type"}, - width=1200, - height=700, - ) - fig.update_layout(template="plotly_white") - fig.write_html(resfolder + "vae{}.html".format(intermediate_dim)) - dataset = pd.DataFrame( - {"tsne1": embed1[:, 0], "tsne2": embed1[:, 1]} - ) - dataset.to_csv(resfolder + "vae{}.csv".format(intermediate_dim)) diff --git a/scripts/vae-tf-gpu.py b/scripts/vae-tf-gpu.py deleted file mode 100644 index 2786f82..0000000 --- a/scripts/vae-tf-gpu.py +++ /dev/null @@ -1,171 +0,0 @@ -import os - -# os.environ["CUDA_VISIBLE_DEVICES"]="0" -from argparse import ArgumentParser -import numpy as np -import pandas as pd -import plotly.express as px -import plotly.graph_objects as go -from sklearn.manifold import TSNE -from sklearn.metrics import silhouette_score -from sklearn.metrics import davies_bouldin_score -from tqdm import tqdm -import tensorflow as tf - -import enrichment_auc -from enrichment_auc.metrics.vae import VAE -from enrichment_auc.preprocess.filter import filter - -tissues = ["Pancreas", "PBMC", "COVID", "BreastCancer", "BM", "Liver"] -norm = "seurat" - -if __name__ == "__main__": - parser = ArgumentParser() - parser.add_argument("--test_case", default="layer_size", type=str) - parser.add_argument("--intermediate_dim", nargs="+", type=int) - parser.add_argument("--lr", default=10e-3, type=float) - parser.add_argument("--epochs", default=1000, type=int) - parser.add_argument("--reg", default=0.0, type=float) - parser.add_argument("--GPU", default=0, type=str) - - args = parser.parse_args() - test_case = args.test_case - intermediate_dim = tuple(args.intermediate_dim) - learning_rate = args.lr - epochs = args.epochs - verbose = 0 - batch_size = 2048 - reg = args.reg - - with tf.device("/device:GPU:{}".format(args.GPU)): - for tissue in tissues: - print(tissue) - datafolder = "data/" + tissue + "/" - resfolder = "results/" + tissue + "/vae/" + test_case + "/" - - gene_expr = pd.read_csv( - datafolder + norm + "_filtered_data.csv", index_col=0 - ) - labels = pd.read_csv(datafolder + "true_labels.csv", index_col=0) - labels = labels["CellType"].to_numpy() - - if not os.path.isdir(resfolder): - os.makedirs(resfolder) - - filtered = filter(gene_expr, 0.2) - filtered = filtered.to_numpy().astype(float) - gene_expr = gene_expr.to_numpy().astype(float) - - filenames = os.listdir(resfolder) - filenames = [ - filename for filename in filenames if filename.endswith(".txt") - ] - trial = len(filenames) - - s1 = [] - s2 = [] - s3 = [] - s4 = [] - s5 = [] - db1 = [] - db2 = [] - db3 = [] - db4 = [] - db5 = [] - - with open(resfolder + "config{}.txt".format(trial), "a") as myfile: - myfile.write(str(intermediate_dim)) - myfile.write("\n") - myfile.write(str(learning_rate)) - myfile.write("\n") - myfile.write(str(epochs)) - myfile.write("\n") - myfile.write(str(reg)) - - # filtered VAE only - for i in tqdm(range(10)): - vae_f = VAE( - latent_dim=2, - verbose=verbose, - intermediate_dim=intermediate_dim, - learning_rate=learning_rate, - epochs=epochs, - # random_state=42, - batch_size=batch_size, - ).fit(filtered.T) - embed_f = vae_f.transform(filtered.T) - s = silhouette_score(embed_f, labels) - s1.append(s) - s = davies_bouldin_score(embed_f, labels) - db1.append(s) - - # filtered VAE + t-SNE - for i in tqdm(range(10)): - vae_f_t = VAE( - latent_dim=50, - verbose=verbose, - intermediate_dim=intermediate_dim, - learning_rate=learning_rate, - epochs=epochs, - # random_state=42, - batch_size=batch_size, - ).fit(filtered.T) - embed_f_t = vae_f_t.transform(filtered.T) - s = silhouette_score(embed_f_t, labels) - s2.append(s) - s = davies_bouldin_score(embed_f_t, labels) - db2.append(s) - tsne = TSNE(n_components=2, perplexity=35, n_iter=1500, angle=0.5) - embed1_f = tsne.fit_transform(embed_f_t, labels) - s = silhouette_score(embed1_f, labels) - s3.append(s) - s = davies_bouldin_score(embed1_f, labels) - db3.append(s) - - # VAE + t-SNE - for i in tqdm(range(10)): - vae = VAE( - latent_dim=50, - verbose=verbose, - intermediate_dim=intermediate_dim, - learning_rate=learning_rate, - epochs=epochs, - # random_state=42, - batch_size=batch_size, - ).fit(gene_expr.T) - embed = vae.transform(gene_expr.T) - s = silhouette_score(embed, labels) - s4.append(s) - s = davies_bouldin_score(embed, labels) - db4.append(s) - tsne = TSNE(n_components=2, perplexity=35, n_iter=1500, angle=0.5) - embed1 = tsne.fit_transform(embed, labels) - s = silhouette_score(embed1, labels) - s5.append(s) - s = davies_bouldin_score(embed1, labels) - db5.append(s) - - d = [s1, s2, s3, s4, s5] - df = pd.DataFrame( - data=d, - index=[ - "filtered_vae_2D", - "filtered_vae_50D", - "filtered_vae_tsne", - "vae_50D", - "vae_tsne", - ], - ) - df.to_csv(resfolder + "trial{}_silhouette.csv".format(trial)) - d = [db1, db2, db3, db4, db5] - df = pd.DataFrame( - data=d, - index=[ - "filtered_vae_2D", - "filtered_vae_50D", - "filtered_vae_tsne", - "vae_50D", - "vae_tsne", - ], - ) - df.to_csv(resfolder + "trial{}_db.csv".format(trial)) diff --git a/scripts/visualize_aucell.py b/scripts/visualize_aucell.py deleted file mode 100644 index 4ffe9af..0000000 --- a/scripts/visualize_aucell.py +++ /dev/null @@ -1,118 +0,0 @@ -import json -import os -import sys -from time import time - -import numpy as np -import pandas as pd -from tqdm import tqdm - -from enrichment_auc.plot.plot_scatter_flow import plot_flow - -def evaluate_pas( - scores, - thrs, - gs_names, - geneset_info, - data_type, - score_name, - embed=None, - labels_arr=None, -): - print(score_name) - - for i, gs_name in tqdm(enumerate(gs_names), total=len(gs_names)): - gs_title = geneset_info.Title.where(geneset_info.ID == gs_name, gs_name).max() - score = scores[i, :] - thr = [thrs.loc[gs_name]] - if embed is not None and labels_arr is not None and score.max() - score.min() > 10 ** (-20): - plot_flow( - embed, - score, - thr, - labels_arr, - name=score_name, - gs_name=gs_name, - embed_name="t-SNE", - save_dir=save_dir + "/AUCell/flow/", - ) - -score_names = [ - "z", - "gsva", - "auc", - "cerno", - "ratios", - "vision", - "aucell", - "svd", - "sparse_pca", - "ssgsea", - "jasmine", - "mean", - "vae", - "vae_corr", -] # all scores to run for each data type - -if __name__ == "__main__": - data_type = sys.argv[1] - res_folder = sys.argv[2] - save_dir = sys.argv[3] - data_folder = sys.argv[4] - save_dir = save_dir + "/" + data_type - print(data_type) - geneset_info = pd.read_csv( - data_folder + "filtered_genesets_modules.csv", index_col=0 - ) - embed = None - labels_arr = None - if os.path.isfile(data_folder + "vae.csv"): - embed = pd.read_csv(data_folder + "vae.csv") - embed = embed.select_dtypes(["number"]).to_numpy().astype(float) - if os.path.isfile(data_folder + "true_labels.csv"): - labels_arr = pd.read_csv(data_folder + "true_labels.csv", index_col=0) - labels_arr = labels_arr["CellType"].to_numpy() - - if not os.path.isdir(save_dir + "/AUCell/flow/"): - os.makedirs(save_dir + "/AUCell/flow/") - - for score_name in tqdm(score_names): - # get scores - # AUCell_thr - thrs = pd.read_csv( - res_folder + data_type + "/AUCell_thr/" + score_name + "_thr.csv", - index_col=0, - ) - scores = pd.read_csv( - res_folder + data_type + "/" + score_name + ".csv", - index_col=0, - ) - gs_names = scores.index.values.tolist() - scores = scores.to_numpy() - evaluate_pas( - scores, - thrs, - gs_names, - geneset_info, - data_type, - score_name, - embed, - labels_arr, - ) - - if score_name in ["svd", "sparse_pca", "z", "vision"]: - thrs = pd.read_csv( - res_folder + data_type + "/AUCell_thr/" + score_name + "_abs_thr.csv", - index_col=0, - ) - scores = np.abs(scores) - evaluate_pas( - scores, - thrs, - gs_names, - geneset_info, - data_type, - score_name + "_abs", - embed, - labels_arr, - ) diff --git a/scripts/visualize_aucell.sh b/scripts/visualize_aucell.sh deleted file mode 100644 index 6b05d51..0000000 --- a/scripts/visualize_aucell.sh +++ /dev/null @@ -1,23 +0,0 @@ -#! /bin/bash -# poetry install -# poetry build -norm='seurat' -declare -a data_types=('Liver') # 'Liver' - -# Iterate the string array using for loop -for data_type in ${data_types[@]}; do - data_folder="/mnt/pmanas/Ania/scrna-seq/data/${data_type}/" - res_folder="/mnt/pmanas/Ania/scrna-seq/results/${data_type}/" - plot_folder="/mnt/pmanas/Ania/scrna-seq/plots/${data_type}" - python scripts/visualize_aucell.py $norm $res_folder $plot_folder $data_folder - # zip results - # cd $"${res_folder}${norm}" - # zip "${norm}.zip" *.json - # zip -r "${norm}.zip" kmeans_thr/ gmm_thr/ - # zip -r "${norm}.zip" times_thrs.csv - # cd $"../../../${plot_folder}/${norm}" - # zip -r "${norm}.zip" kmeans/ top1/ - # find . -type f -iname \*.png -delete - # find . -type f -iname \*.html -delete - # cd ../../../ -done diff --git a/setup_docker_compatible_renv.R b/setup_docker_compatible_renv.R new file mode 100644 index 0000000..c7e9904 --- /dev/null +++ b/setup_docker_compatible_renv.R @@ -0,0 +1,143 @@ +#!/usr/bin/env Rscript + +# Docker-compatible R package installation using renv +# Use renv for version control, then copy to site-library for multi-stage builds + +cat("Setting up R environment using renv for Docker compatibility...\n") + +# Install renv if not available +if (!require("renv", quietly = TRUE)) { + install.packages("renv", repos = "https://cran.r-project.org") +} + +# Initialize renv in current directory if renv.lock exists +if (file.exists("renv.lock")) { + cat("Found renv.lock, initializing renv...\n") + renv::init(bare = TRUE) + + # Restore packages from renv.lock + cat("Restoring packages from renv.lock...\n") + renv::restore(confirm = FALSE) + + cat("✓ renv restore completed\n") + # Set Bioconductor version for R 4.4 + if (!requireNamespace("BiocManager", quietly = TRUE)) { + install.packages("BiocManager", repos = "https://cran.r-project.org") + } + BiocManager::install(version = "3.20", ask = FALSE, update = TRUE) +} else { + cat("No renv.lock found, setting up fresh renv environment...\n") + renv::init(bare = TRUE) + + # Install essential packages + essential_packages <- c("BiocManager", "rjson", "GSVA", "remotes", "AUCell") + + cat("Installing essential packages via renv...\n") + renv::install("BiocManager") + renv::install("rjson") + renv::install("bioc::GSVA") + renv::install("remotes") + renv::install("bioc::AUCell") + + # Install dpGMM from GitHub + cat("Installing dpGMM from GitHub...\n") + renv::install("ZAEDPolSl/dpGMM") + + # Create snapshot + cat("Creating renv snapshot...\n") + renv::snapshot() + # Set Bioconductor version for R 4.4 + if (!requireNamespace("BiocManager", quietly = TRUE)) { + install.packages("BiocManager", repos = "https://cran.r-project.org") + } + BiocManager::install(version = "3.20", ask = FALSE, update = TRUE) +} + +# Now copy packages from renv library to site-library for Docker multi-stage +cat("\nCopying packages from renv to site-library...\n") + +# Find renv library path +renv_lib <- renv::paths$library() +cat("renv library path:", renv_lib, "\n") + +# Create site-library path +site_lib <- "/usr/local/lib/R/site-library" +dir.create(site_lib, recursive = TRUE, showWarnings = FALSE) + +# Get list of installed packages in renv +installed_pkgs <- installed.packages(lib.loc = renv_lib) +pkg_names <- rownames(installed_pkgs) + +cat("Copying", length(pkg_names), "packages to site-library...\n") + +# Copy each package +copy_count <- 0 +for (pkg in pkg_names) { + src_path <- file.path(renv_lib, pkg) + dst_path <- file.path(site_lib, pkg) + + if (dir.exists(src_path)) { + # Check if it's a symlink and resolve it + if (Sys.readlink(src_path) != "") { + # It's a symlink, follow it to get the actual path + actual_path <- Sys.readlink(src_path) + if (file.exists(actual_path)) { + # Copy from the actual path, not the symlink + result <- system2("cp", args = c("-rL", actual_path, dst_path), stdout = FALSE, stderr = FALSE) + if (result == 0) { + copy_count <- copy_count + 1 + cat(" Copied", pkg, "from", actual_path, "\n") + } else { + cat("Warning: Failed to copy", pkg, "from", actual_path, "\n") + } + } else { + cat("Warning: Symlink target does not exist for", pkg, "->", actual_path, "\n") + } + } else { + # It's a regular directory, copy normally + result <- system2("cp", args = c("-r", src_path, dst_path), stdout = FALSE, stderr = FALSE) + if (result == 0) { + copy_count <- copy_count + 1 + cat(" Copied", pkg, "(regular directory)\n") + } else { + cat("Warning: Failed to copy", pkg, "\n") + } + } + } +} + +cat("✓ Copied", copy_count, "packages to site-library\n") + +# Update library paths to include site-library +.libPaths(c(site_lib, .libPaths())) +cat("Updated library paths:", .libPaths(), "\n") + +# Verify essential packages are available +essential_packages <- c("BiocManager", "rjson", "GSVA", "dpGMM", "AUCell") +cat("\nVerifying essential packages:\n") +for (pkg in essential_packages) { + if (require(pkg, quietly = TRUE, character.only = TRUE)) { + version_info <- tryCatch( + { + as.character(packageVersion(pkg)) + }, + error = function(e) "unknown" + ) + cat(sprintf(" ✓ %s (%s)\n", pkg, version_info)) + } else { + cat(sprintf(" ✗ %s (failed)\n", pkg)) + } +} + +# List contents of site-library +cat("\nContents of site-library:\n") +if (dir.exists(site_lib)) { + contents <- list.dirs(site_lib, full.names = FALSE, recursive = FALSE) + for (item in sort(contents)) { + if (item != "") { + cat(sprintf(" - %s\n", item)) + } + } +} + +cat("\nrenv packages successfully copied to site-library for Docker multi-stage build!\n") diff --git a/test/test_gmm/test_data.csv b/test/test_gmm/test_data.csv deleted file mode 100644 index 3a3ab6f..0000000 --- a/test/test_gmm/test_data.csv +++ /dev/null @@ -1,1501 +0,0 @@ -"","x" -"1",-25.8802542443628 -"2",-25.380949112989 -"3",-25.1420758089452 -"4",-24.8324984322475 -"5",-24.4387214711768 -"6",-23.9900090795357 -"7",-23.7523012194546 -"8",-23.6387759674181 -"9",-23.2631497295985 -"10",-23.1610018607415 -"11",-22.8035653712967 -"12",-22.7775383313012 -"13",-22.5956078713008 -"14",-22.5746529631518 -"15",-22.4408966738208 -"16",-22.3171029034146 -"17",-22.1107270204961 -"18",-21.9261363333791 -"19",-21.9017029100407 -"20",-21.8958766146948 -"21",-21.7497427148949 -"22",-21.7039145523488 -"23",-21.4137496765271 -"24",-21.4132264483681 -"25",-21.4020138208681 -"26",-21.3658670274995 -"27",-21.3579113820148 -"28",-21.2859295335389 -"29",-21.2091766744734 -"30",-21.1964932904243 -"31",-20.981323724298 -"32",-20.8480244524363 -"33",-20.7913325611244 -"34",-20.6061229911343 -"35",-20.5439688517748 -"36",-20.5241883601575 -"37",-20.5234012077248 -"38",-20.4227697758163 -"39",-20.4120937278488 -"40",-20.2269649747593 -"41",-20.1789261267054 -"42",-20.1461848195148 -"43",-20.1348736665686 -"44",-20.1238294358537 -"45",-20.1146009710709 -"46",-20.0468528226787 -"47",-19.9662771251942 -"48",-19.9234378305139 -"49",-19.8854642352261 -"50",-19.8472028325806 -"51",-19.824781909501 -"52",-19.7795764597889 -"53",-19.7792081201881 -"54",-19.7369816809347 -"55",-19.6082231147942 -"56",-19.504426142587 -"57",-19.4750954650989 -"58",-19.4732902991312 -"59",-19.3801819188294 -"60",-19.3121892670729 -"61",-19.2540803529877 -"62",-19.0774857901206 -"63",-19.0205016318907 -"64",-19.0052124848503 -"65",-18.9363839099971 -"66",-18.9018301057155 -"67",-18.9000911027051 -"68",-18.895194308823 -"69",-18.8790826730256 -"70",-18.8209184563739 -"71",-18.8011185394974 -"72",-18.7739112287119 -"73",-18.7054467187291 -"74",-18.7004758538595 -"75",-18.6765487234572 -"76",-18.6453107342279 -"77",-18.6067287883562 -"78",-18.6026863530648 -"79",-18.5243335656677 -"80",-18.4414017545917 -"81",-18.427342639382 -"82",-18.4266054473573 -"83",-18.4208796338616 -"84",-18.3180078916628 -"85",-18.2853568271808 -"86",-18.2611751355917 -"87",-18.2370744089479 -"88",-18.200670669913 -"89",-18.1962208284407 -"90",-18.1820426196702 -"91",-18.1715723465952 -"92",-18.158464364755 -"93",-18.1472702220544 -"94",-18.1247419401454 -"95",-18.1007423611671 -"96",-18.0486678343559 -"97",-18.0331155233663 -"98",-18.0285194430758 -"99",-17.9990948223777 -"100",-17.9101949020868 -"101",-17.9037618255884 -"102",-17.8956619598551 -"103",-17.8639100260226 -"104",-17.8597227828027 -"105",-17.7685815840377 -"106",-17.7634490889 -"107",-17.754395480501 -"108",-17.7460573029293 -"109",-17.672066859536 -"110",-17.6427383137406 -"111",-17.6283238560797 -"112",-17.611669311188 -"113",-17.6115415044756 -"114",-17.6061359874924 -"115",-17.5942714456536 -"116",-17.5517552966736 -"117",-17.5379371733374 -"118",-17.5166785495521 -"119",-17.5051167884566 -"120",-17.4825474375475 -"121",-17.4766095669411 -"122",-17.4681864970823 -"123",-17.4569910878086 -"124",-17.4382026434987 -"125",-17.425636853912 -"126",-17.3794578600109 -"127",-17.3789791196693 -"128",-17.3661148468199 -"129",-17.366111161109 -"130",-17.3361648546886 -"131",-17.3017752669583 -"132",-17.2828185863511 -"133",-17.2609301825529 -"134",-17.2489754859335 -"135",-17.2331051706273 -"136",-17.1887776937146 -"137",-17.1813048760678 -"138",-17.1778431617221 -"139",-17.0955272510065 -"140",-17.0924765047518 -"141",-17.0867905151614 -"142",-17.0813066882486 -"143",-17.074438245459 -"144",-17.0671556048615 -"145",-17.0612613092821 -"146",-17.0484527672247 -"147",-17.0435118523953 -"148",-17.029169232599 -"149",-17.0081674859119 -"150",-17.0068298080752 -"151",-17.0047378490751 -"152",-16.9980711762334 -"153",-16.9873539356025 -"154",-16.9858954040788 -"155",-16.9829835312091 -"156",-16.9637722196767 -"157",-16.9514106911874 -"158",-16.9512664737138 -"159",-16.9504704389187 -"160",-16.9446072344653 -"161",-16.9167658642178 -"162",-16.8816996994193 -"163",-16.8806530335502 -"164",-16.853322066784 -"165",-16.8381754113339 -"166",-16.8368287331273 -"167",-16.8274899358326 -"168",-16.8029654929467 -"169",-16.7811710676319 -"170",-16.7564993676429 -"171",-16.7435319866424 -"172",-16.7342807966305 -"173",-16.7325081056824 -"174",-16.7280648204385 -"175",-16.7174577876669 -"176",-16.702424697808 -"177",-16.6901407933238 -"178",-16.6895931735592 -"179",-16.6249446705019 -"180",-16.6195024161661 -"181",-16.6101527748923 -"182",-16.6046527074487 -"183",-16.6036704977062 -"184",-16.6009940881747 -"185",-16.5870370600943 -"186",-16.5705275524016 -"187",-16.5484207476809 -"188",-16.5439589304792 -"189",-16.5435372285033 -"190",-16.5306226062474 -"191",-16.521628276883 -"192",-16.5096285578174 -"193",-16.5079785831528 -"194",-16.504227474871 -"195",-16.496252412338 -"196",-16.4680211973984 -"197",-16.4540685057624 -"198",-16.4492021574866 -"199",-16.391039152156 -"200",-16.3877977086441 -"201",-16.3646264619813 -"202",-16.3491113450794 -"203",-16.3377840303225 -"204",-16.302571667317 -"205",-16.2905632037707 -"206",-16.2805407862449 -"207",-16.2732347922476 -"208",-16.2558425512213 -"209",-16.2316506608285 -"210",-16.219939793237 -"211",-16.216026423385 -"212",-16.2142831297992 -"213",-16.202389976158 -"214",-16.1888254251608 -"215",-16.1758228416377 -"216",-16.1409291351519 -"217",-16.1192505126986 -"218",-16.1190753808676 -"219",-16.1103801486065 -"220",-16.0965559389931 -"221",-16.0862620120059 -"222",-16.07990167094 -"223",-16.0594029542219 -"224",-16.0589909908467 -"225",-16.0064364796472 -"226",-15.9980910136081 -"227",-15.9885454219338 -"228",-15.976813514661 -"229",-15.9597219201846 -"230",-15.9313404831361 -"231",-15.924250193265 -"232",-15.9039319018908 -"233",-15.8915824881346 -"234",-15.843211771669 -"235",-15.843205668804 -"236",-15.8425357099191 -"237",-15.8203329956961 -"238",-15.8067367361134 -"239",-15.7816274544648 -"240",-15.7727248855523 -"241",-15.7692823642276 -"242",-15.7502748448541 -"243",-15.7375721893196 -"244",-15.732031082488 -"245",-15.7237996497376 -"246",-15.719392029572 -"247",-15.7097179513246 -"248",-15.7094754818909 -"249",-15.7086261788806 -"250",-15.6982791656679 -"251",-15.6964885980351 -"252",-15.6843878525304 -"253",-15.6830521171755 -"254",-15.6824725453062 -"255",-15.6743905486411 -"256",-15.6664766868767 -"257",-15.6604602308805 -"258",-15.6542329940971 -"259",-15.6435696198978 -"260",-15.6303767448927 -"261",-15.6288515424489 -"262",-15.6261632318476 -"263",-15.6207551164911 -"264",-15.6035099741134 -"265",-15.5991008074069 -"266",-15.5878213526649 -"267",-15.579257886214 -"268",-15.5781992919316 -"269",-15.5750010594522 -"270",-15.5633510532327 -"271",-15.5407590485734 -"272",-15.5289906671741 -"273",-15.5229835361884 -"274",-15.4940321729644 -"275",-15.4393423653867 -"276",-15.4276572365372 -"277",-15.424998428451 -"278",-15.4120392738777 -"279",-15.4077845083587 -"280",-15.3980411055076 -"281",-15.3974427029976 -"282",-15.3865235705911 -"283",-15.3800762371539 -"284",-15.3762127091184 -"285",-15.3703328178652 -"286",-15.3662399533855 -"287",-15.3549914524551 -"288",-15.3458426236969 -"289",-15.3438131534369 -"290",-15.3367919202854 -"291",-15.3264008015254 -"292",-15.3206617409706 -"293",-15.3195480685911 -"294",-15.2912997926319 -"295",-15.2888677668949 -"296",-15.2704703947471 -"297",-15.2664681731564 -"298",-15.2634776920816 -"299",-15.2627427268718 -"300",-15.2403537146272 -"301",-15.2223504777764 -"302",-15.2202405971083 -"303",-15.2196948692046 -"304",-15.2073696183237 -"305",-15.2040238045438 -"306",-15.1874851989864 -"307",-15.1765463941407 -"308",-15.148529154564 -"309",-15.138848091588 -"310",-15.1378752639036 -"311",-15.1375871871653 -"312",-15.1334728677257 -"313",-15.1220490866786 -"314",-15.1211869827894 -"315",-15.1167854190948 -"316",-15.1132013896257 -"317",-15.1058444676295 -"318",-15.0961447936203 -"319",-15.0890566200395 -"320",-15.0821838960994 -"321",-15.0766768793675 -"322",-15.0724441354339 -"323",-15.0325335000744 -"324",-15.0317680514366 -"325",-15.0213770487029 -"326",-15.0186692804351 -"327",-15.0161789054879 -"328",-15.0148175478177 -"329",-14.9743913641706 -"330",-14.9694103384784 -"331",-14.9596742310785 -"332",-14.9354704472086 -"333",-14.9291396938819 -"334",-14.8930272108834 -"335",-14.8907152403045 -"336",-14.8710620999935 -"337",-14.8704639544875 -"338",-14.865103485774 -"339",-14.8545340908468 -"340",-14.8278788482252 -"341",-14.8208734698854 -"342",-14.802494649217 -"343",-14.7860334337008 -"344",-14.7803496170826 -"345",-14.7755904060954 -"346",-14.7213602507968 -"347",-14.7194968816925 -"348",-14.7096381819875 -"349",-14.7091110600464 -"350",-14.6930164744896 -"351",-14.6748401092549 -"352",-14.6737969916934 -"353",-14.6729873787595 -"354",-14.6698200719862 -"355",-14.6623527916619 -"356",-14.6619252115489 -"357",-14.6568969027483 -"358",-14.6459800094253 -"359",-14.6054234690155 -"360",-14.5964321145718 -"361",-14.5931655476609 -"362",-14.5906040990132 -"363",-14.5755509708271 -"364",-14.5701783819694 -"365",-14.5693037898595 -"366",-14.5587826829317 -"367",-14.5578406865048 -"368",-14.5533817861193 -"369",-14.5271383462663 -"370",-14.5163658610972 -"371",-14.4918237945116 -"372",-14.4798531970735 -"373",-14.4600048763179 -"374",-14.4221125709755 -"375",-14.4209350628586 -"376",-14.4088950445243 -"377",-14.4068441283564 -"378",-14.3914535409896 -"379",-14.388792451971 -"380",-14.3763049268495 -"381",-14.3720599927124 -"382",-14.370076507353 -"383",-14.3629003333746 -"384",-14.3106459687142 -"385",-14.2940272907465 -"386",-14.2881516134164 -"387",-14.2777439671896 -"388",-14.2543737490603 -"389",-14.2276749897263 -"390",-14.2173549262086 -"391",-14.2142524555762 -"392",-14.2046164077263 -"393",-14.1832368672468 -"394",-14.1515228901261 -"395",-14.1405385640684 -"396",-14.1277621574294 -"397",-14.1012534937972 -"398",-14.0972464429011 -"399",-14.0912538683659 -"400",-14.0851897419191 -"401",-14.0830496729485 -"402",-14.0812365834122 -"403",-14.0689328378579 -"404",-14.0609481514444 -"405",-14.060684159367 -"406",-14.0449420591124 -"407",-14.0364703787537 -"408",-14.0290225987002 -"409",-14.0138449217422 -"410",-14.0056120202057 -"411",-14.0020327726465 -"412",-14.0010688851913 -"413",-13.9811379315543 -"414",-13.9760109055129 -"415",-13.9743274304517 -"416",-13.9719313031485 -"417",-13.9711945085368 -"418",-13.9649127258011 -"419",-13.964088632067 -"420",-13.9561539951906 -"421",-13.9535701318797 -"422",-13.9345218939209 -"423",-13.9328819854081 -"424",-13.9160662122817 -"425",-13.907654396641 -"426",-13.9002027817683 -"427",-13.8993119751752 -"428",-13.8833179066088 -"429",-13.8830926670813 -"430",-13.8728800133917 -"431",-13.861581807076 -"432",-13.8563468578405 -"433",-13.8513468952282 -"434",-13.8497450651657 -"435",-13.8164154637899 -"436",-13.8154270695971 -"437",-13.7914144475671 -"438",-13.7904790346335 -"439",-13.7770398741331 -"440",-13.771592718311 -"441",-13.7640548150817 -"442",-13.7633091349238 -"443",-13.7576740629619 -"444",-13.7506033597929 -"445",-13.7272267404565 -"446",-13.7100909803695 -"447",-13.7093884124666 -"448",-13.6938406923455 -"449",-13.6929792484899 -"450",-13.6905963430219 -"451",-13.6864495051771 -"452",-13.6845809220497 -"453",-13.6844786719164 -"454",-13.6781765885636 -"455",-13.6695932989448 -"456",-13.6684400395428 -"457",-13.6658493505739 -"458",-13.6475373657325 -"459",-13.6450201016227 -"460",-13.6426110006269 -"461",-13.6008981209324 -"462",-13.5909469290892 -"463",-13.5894698565885 -"464",-13.5853841889271 -"465",-13.5802411579345 -"466",-13.5777889486181 -"467",-13.5721142501682 -"468",-13.5549609130555 -"469",-13.5240619910476 -"470",-13.4846141799508 -"471",-13.4842652840539 -"472",-13.4764348643016 -"473",-13.47269788657 -"474",-13.4567386559125 -"475",-13.447694176717 -"476",-13.4443050192854 -"477",-13.4441399914949 -"478",-13.442770499166 -"479",-13.4351300381848 -"480",-13.4154205287097 -"481",-13.4046087180452 -"482",-13.4024216068117 -"483",-13.3975755442184 -"484",-13.3799839542609 -"485",-13.3689120731514 -"486",-13.3557212153976 -"487",-13.350676329042 -"488",-13.3260932561325 -"489",-13.3258348524092 -"490",-13.3222353648017 -"491",-13.3215820863244 -"492",-13.3213890204666 -"493",-13.3141816016611 -"494",-13.3101608836113 -"495",-13.3078270389404 -"496",-13.297749268602 -"497",-13.2925703266938 -"498",-13.277715000265 -"499",-13.2775792525711 -"500",-13.2716372077389 -"501",-13.2691905950028 -"502",-13.2593915686103 -"503",-13.2567815242099 -"504",-13.2391862709678 -"505",-13.2386426576235 -"506",-13.212066703086 -"507",-13.2097693337647 -"508",-13.1998387601652 -"509",-13.1650294660534 -"510",-13.1447887061541 -"511",-13.1412911047165 -"512",-13.1383511116729 -"513",-13.1219527089384 -"514",-13.1125352573577 -"515",-13.1093961031487 -"516",-13.1043484914855 -"517",-13.1033420354621 -"518",-13.0986441648708 -"519",-13.0884507804496 -"520",-13.0851266547903 -"521",-13.0625654792864 -"522",-13.0474548876693 -"523",-13.0421939343866 -"524",-13.0419238870168 -"525",-13.037132668509 -"526",-13.0303529264916 -"527",-13.028975171896 -"528",-13.0247310813251 -"529",-13.0230610975496 -"530",-12.9787551005744 -"531",-12.9772226979021 -"532",-12.9733167139138 -"533",-12.9406175522692 -"534",-12.9397595732481 -"535",-12.9279152813305 -"536",-12.8863442125141 -"537",-12.8748470833375 -"538",-12.8705420839059 -"539",-12.8638842300109 -"540",-12.849724631486 -"541",-12.8455602833229 -"542",-12.8365269938898 -"543",-12.8364631222446 -"544",-12.8340802724638 -"545",-12.8324464650752 -"546",-12.8232925103144 -"547",-12.7921625848162 -"548",-12.7843132885066 -"549",-12.7321966968165 -"550",-12.6865930373391 -"551",-12.6715944347085 -"552",-12.6400191108457 -"553",-12.6202816438824 -"554",-12.6121811877155 -"555",-12.6007407013269 -"556",-12.5944682959885 -"557",-12.5827729081917 -"558",-12.5467560782305 -"559",-12.5220940256875 -"560",-12.5127526465258 -"561",-12.4987945562413 -"562",-12.496859215676 -"563",-12.4856764188089 -"564",-12.4797250439475 -"565",-12.4790785437735 -"566",-12.4777873138861 -"567",-12.4669601292433 -"568",-12.4630694539927 -"569",-12.4579344744768 -"570",-12.4501051954062 -"571",-12.4228327270376 -"572",-12.4176333959405 -"573",-12.3945778392082 -"574",-12.3575448222584 -"575",-12.3562458547562 -"576",-12.3451164904447 -"577",-12.3062532637403 -"578",-12.2937009175378 -"579",-12.2932523997004 -"580",-12.2882609956882 -"581",-12.2689622995142 -"582",-12.2622516991766 -"583",-12.2557513416802 -"584",-12.2276490359956 -"585",-12.2126628788762 -"586",-12.2037533064144 -"587",-12.2037014638495 -"588",-12.1625788628962 -"589",-12.1456297803753 -"590",-12.1371016550677 -"591",-12.1254600036905 -"592",-12.1066880914457 -"593",-12.1038438371454 -"594",-12.0952475262124 -"595",-12.0933854182174 -"596",-12.066870021371 -"597",-12.0611654624792 -"598",-12.0425548396277 -"599",-12.0309974982939 -"600",-12.0000361272555 -"601",-11.9954293957487 -"602",-11.9910259071686 -"603",-11.9661162347724 -"604",-11.9346278914377 -"605",-11.9221442748867 -"606",-11.9208598819908 -"607",-11.920779718471 -"608",-11.913458349971 -"609",-11.9121381393644 -"610",-11.9007984127354 -"611",-11.8981936400697 -"612",-11.8829626371759 -"613",-11.87002835973 -"614",-11.8551142517715 -"615",-11.8396524261664 -"616",-11.8220249319511 -"617",-11.8203683517365 -"618",-11.8159497180852 -"619",-11.79801426065 -"620",-11.7963484251967 -"621",-11.7880625962795 -"622",-11.776702290455 -"623",-11.7602151633328 -"624",-11.7559884509275 -"625",-11.7118076345226 -"626",-11.6609589983335 -"627",-11.6421089740541 -"628",-11.6130376153275 -"629",-11.6016432505524 -"630",-11.5974387277214 -"631",-11.5918922766184 -"632",-11.5814332140432 -"633",-11.576774845606 -"634",-11.5756622491381 -"635",-11.5667128134962 -"636",-11.5601121849212 -"637",-11.5546578203844 -"638",-11.5464707148685 -"639",-11.5422817715034 -"640",-11.5032597043338 -"641",-11.4346334690664 -"642",-11.4198168777934 -"643",-11.4181773460119 -"644",-11.3746959114646 -"645",-11.3665114255039 -"646",-11.3274149446155 -"647",-11.3221978272979 -"648",-11.276094920444 -"649",-11.2709873034533 -"650",-11.2605025704377 -"651",-11.25902887818 -"652",-11.2409347602156 -"653",-11.2304950386317 -"654",-11.2193328233196 -"655",-11.2053231645898 -"656",-11.1833927721182 -"657",-11.1816742193413 -"658",-11.1813849851232 -"659",-11.1681672152449 -"660",-11.1332746864955 -"661",-11.1329066809524 -"662",-11.1135944835572 -"663",-11.091799701992 -"664",-11.0745804757979 -"665",-11.0557181092608 -"666",-11.0425267625423 -"667",-11.011777057178 -"668",-10.9976088375447 -"669",-10.983585241461 -"670",-10.9613738698998 -"671",-10.9579174206943 -"672",-10.9484889886192 -"673",-10.9412157031002 -"674",-10.9240695624156 -"675",-10.8550772592155 -"676",-10.831922967506 -"677",-10.8249304887325 -"678",-10.7965884586253 -"679",-10.7753578450432 -"680",-10.7520410695566 -"681",-10.751295665376 -"682",-10.7468121561378 -"683",-10.7440729522376 -"684",-10.7143110238806 -"685",-10.7001433106051 -"686",-10.6928469690567 -"687",-10.6678897539999 -"688",-10.6530092585265 -"689",-10.6374128613921 -"690",-10.6249660072467 -"691",-10.6195372843494 -"692",-10.6015098223745 -"693",-10.5958916270516 -"694",-10.589468259746 -"695",-10.5306787172363 -"696",-10.528359093635 -"697",-10.4142730840151 -"698",-10.3866927305816 -"699",-10.3859391842756 -"700",-10.3675456064798 -"701",-10.3356782507289 -"702",-10.3206699029045 -"703",-10.2837329343624 -"704",-10.2787199103305 -"705",-10.2785318086649 -"706",-10.2416184884606 -"707",-10.2095266219006 -"708",-10.2052676075833 -"709",-10.1965223835294 -"710",-10.1739323866236 -"711",-10.1614215299287 -"712",-10.1459653841934 -"713",-10.0783313872674 -"714",-10.0757828288928 -"715",-10.0600268394839 -"716",-10.0518767398994 -"717",-10.0492072849865 -"718",-10.0433844201293 -"719",-10.0356355086956 -"720",-9.99173043148437 -"721",-9.94896065443293 -"722",-9.93333862019731 -"723",-9.88597465940264 -"724",-9.88297910842593 -"725",-9.85001130469458 -"726",-9.83882640432387 -"727",-9.83821202353755 -"728",-9.83194595792553 -"729",-9.82226556374453 -"730",-9.81982508746656 -"731",-9.78480540104367 -"732",-9.75023414338085 -"733",-9.62865060706389 -"734",-9.6157609722398 -"735",-9.55780608271658 -"736",-9.54407339819132 -"737",-9.5366929228496 -"738",-9.53442129829487 -"739",-9.47869120901274 -"740",-9.47147434427379 -"741",-9.42943303923302 -"742",-9.40878689746764 -"743",-9.40075127623196 -"744",-9.39022008281005 -"745",-9.38775439275425 -"746",-9.38668461322802 -"747",-9.3804869310103 -"748",-9.34698981443989 -"749",-9.32130464563309 -"750",-9.32046993813873 -"751",-9.2321796689534 -"752",-9.22532165283546 -"753",-9.22372360535929 -"754",-9.20701965160319 -"755",-9.19044797554979 -"756",-9.17750875149135 -"757",-9.15660464113243 -"758",-9.14352416390932 -"759",-9.13046508114208 -"760",-9.1162375345649 -"761",-9.06310609602582 -"762",-9.04351146095618 -"763",-9.02119472023437 -"764",-9.01523660731094 -"765",-9.00359797453567 -"766",-9.00288787651626 -"767",-9.0011042817753 -"768",-8.95653273009221 -"769",-8.93905474680549 -"770",-8.92268668714257 -"771",-8.91617697033018 -"772",-8.88594681534863 -"773",-8.87166217323299 -"774",-8.86849855710715 -"775",-8.84566740208057 -"776",-8.84340922627165 -"777",-8.83923247737475 -"778",-8.82873770011765 -"779",-8.82760667277471 -"780",-8.75803856966086 -"781",-8.73464336371626 -"782",-8.7297911141881 -"783",-8.71412178162553 -"784",-8.71218835580368 -"785",-8.67247997536763 -"786",-8.63199937571711 -"787",-8.63153420181122 -"788",-8.58508714608263 -"789",-8.55473611593832 -"790",-8.5502434448294 -"791",-8.54813963076293 -"792",-8.53452418073047 -"793",-8.52604725842326 -"794",-8.50951844995501 -"795",-8.47744833874268 -"796",-8.47464478029965 -"797",-8.47459608730558 -"798",-8.46761775440331 -"799",-8.41094557419503 -"800",-8.40124722173578 -"801",-8.39438827143982 -"802",-8.38295438874536 -"803",-8.29667825719713 -"804",-8.29501290491493 -"805",-8.25250244980369 -"806",-8.24752368340137 -"807",-8.24142820287989 -"808",-8.23516254310745 -"809",-8.18142143077608 -"810",-8.15219461182369 -"811",-8.14581476465883 -"812",-8.12739715398368 -"813",-8.07820234666118 -"814",-8.07218107420425 -"815",-8.01938852049604 -"816",-8.01371649628964 -"817",-8.01244695031934 -"818",-8.00606079472956 -"819",-7.99425302109379 -"820",-7.98107998905961 -"821",-7.97593085545139 -"822",-7.97487126984638 -"823",-7.97385877918172 -"824",-7.94165254516459 -"825",-7.93138385321498 -"826",-7.92955618614671 -"827",-7.91141505718211 -"828",-7.9102761556656 -"829",-7.87866752863676 -"830",-7.86754900063721 -"831",-7.85057037313458 -"832",-7.84953144037812 -"833",-7.82058467456918 -"834",-7.76347258388479 -"835",-7.76294254843448 -"836",-7.75489095330816 -"837",-7.74371111658966 -"838",-7.7434711012403 -"839",-7.716909174411 -"840",-7.71688346094987 -"841",-7.70144542993327 -"842",-7.69701429912063 -"843",-7.66088657711575 -"844",-7.65220356993888 -"845",-7.63975125598429 -"846",-7.60702491718701 -"847",-7.59329888515391 -"848",-7.57139989435531 -"849",-7.54105738422713 -"850",-7.53890315710469 -"851",-7.5364375491769 -"852",-7.50838618678303 -"853",-7.49093482967768 -"854",-7.4644986216918 -"855",-7.45143895358609 -"856",-7.43817622959995 -"857",-7.41487496557553 -"858",-7.40142699773015 -"859",-7.38211380390822 -"860",-7.34285462767634 -"861",-7.34223904804004 -"862",-7.33684809827681 -"863",-7.32760663143596 -"864",-7.32418750834185 -"865",-7.24263155745986 -"866",-7.22157274618512 -"867",-7.2202873963459 -"868",-7.20348512908352 -"869",-7.15669276850928 -"870",-7.13594395409833 -"871",-7.10728811995693 -"872",-7.10368321722202 -"873",-7.09492358779953 -"874",-7.03653888189554 -"875",-6.99071624503965 -"876",-6.97918249334461 -"877",-6.97592565772133 -"878",-6.97550480499736 -"879",-6.97188888817695 -"880",-6.95223684489544 -"881",-6.93430824936166 -"882",-6.92461627586389 -"883",-6.91054912276516 -"884",-6.90967353579993 -"885",-6.90923502681767 -"886",-6.89735226620159 -"887",-6.88565558176189 -"888",-6.86436953463151 -"889",-6.859118226932 -"890",-6.82800489193525 -"891",-6.80988694589814 -"892",-6.79534545065767 -"893",-6.78462921396095 -"894",-6.74890591554677 -"895",-6.73134215433123 -"896",-6.72734432335813 -"897",-6.7194417413986 -"898",-6.6719981348337 -"899",-6.6641293726541 -"900",-6.65274817393911 -"901",-6.64980109904844 -"902",-6.64391859581526 -"903",-6.6427267039065 -"904",-6.61288227351264 -"905",-6.60065866258231 -"906",-6.59579170159478 -"907",-6.57398979445132 -"908",-6.52206535447106 -"909",-6.50884147118177 -"910",-6.50802712403448 -"911",-6.48563341360067 -"912",-6.47510413241905 -"913",-6.47081557178586 -"914",-6.46018944792403 -"915",-6.44700352286047 -"916",-6.42443806136662 -"917",-6.34585182592943 -"918",-6.32137737009852 -"919",-6.29631103443385 -"920",-6.25041947820153 -"921",-6.2306219259455 -"922",-6.23058277061223 -"923",-6.22840026968685 -"924",-6.21299454709797 -"925",-6.21170997887377 -"926",-6.20997671522482 -"927",-6.19936017153764 -"928",-6.19509389948308 -"929",-6.16970026969519 -"930",-6.16370298698599 -"931",-6.12791152234883 -"932",-6.11356191495016 -"933",-6.10133045077491 -"934",-6.08992935750733 -"935",-6.07945188648852 -"936",-6.06390789839233 -"937",-6.06289910067429 -"938",-6.05992428704055 -"939",-6.03331681506999 -"940",-6.01751434754819 -"941",-5.94239931838851 -"942",-5.94173772246377 -"943",-5.92496524860853 -"944",-5.89047598107827 -"945",-5.85825809462909 -"946",-5.85408875065221 -"947",-5.84519925506287 -"948",-5.82403968100185 -"949",-5.81293949878282 -"950",-5.80658152404052 -"951",-5.76459003470073 -"952",-5.7190046446227 -"953",-5.71898843260509 -"954",-5.71489980738066 -"955",-5.65684998358859 -"956",-5.64817021752773 -"957",-5.60199048804431 -"958",-5.56159394877575 -"959",-5.55717350733595 -"960",-5.51066488483595 -"961",-5.49144173582311 -"962",-5.48276584594181 -"963",-5.48029249832609 -"964",-5.44725736366439 -"965",-5.39060664948611 -"966",-5.38475663656071 -"967",-5.37427802158599 -"968",-5.36610597079737 -"969",-5.35033994283373 -"970",-5.3358114625574 -"971",-5.32103637053055 -"972",-5.2547907840562 -"973",-5.23322907873747 -"974",-5.21616122223604 -"975",-5.17946671124454 -"976",-5.17109708263807 -"977",-5.15387467133347 -"978",-5.13352415708953 -"979",-5.12098505157 -"980",-5.11623589250102 -"981",-5.10176153921816 -"982",-5.05539336624451 -"983",-5.04292348550201 -"984",-4.96699393959736 -"985",-4.96346988991658 -"986",-4.91845177914145 -"987",-4.91330372745945 -"988",-4.90087349477118 -"989",-4.88507879710418 -"990",-4.87881084507727 -"991",-4.82448343820553 -"992",-4.82125306703356 -"993",-4.81357719930759 -"994",-4.81268683304808 -"995",-4.81134686688343 -"996",-4.80717887890136 -"997",-4.7620807860848 -"998",-4.75979665110312 -"999",-4.73893156147107 -"1000",-4.67358047976961 -"1001",-4.67074978336363 -"1002",-4.66295626338547 -"1003",-4.64904107545826 -"1004",-4.64484559584056 -"1005",-4.64319468199025 -"1006",-4.62546565227372 -"1007",-4.62543366459879 -"1008",-4.59609841341489 -"1009",-4.58519128455598 -"1010",-4.58027935328347 -"1011",-4.57070864738962 -"1012",-4.55456621557653 -"1013",-4.51331642334308 -"1014",-4.50372454839763 -"1015",-4.47298852628407 -"1016",-4.46980830992988 -"1017",-4.45807715708397 -"1018",-4.45406137957354 -"1019",-4.36610795635331 -"1020",-4.36006748607961 -"1021",-4.34749895087826 -"1022",-4.34324974043103 -"1023",-4.33116598124241 -"1024",-4.32597730330045 -"1025",-4.31137831955402 -"1026",-4.29397253541425 -"1027",-4.27292821201622 -"1028",-4.27246284181158 -"1029",-4.27202031862558 -"1030",-4.26208482767148 -"1031",-4.23897606863458 -"1032",-4.21287045783937 -"1033",-4.19425578888815 -"1034",-4.16177685202163 -"1035",-4.15409580842133 -"1036",-4.10716649919354 -"1037",-4.072448431545 -"1038",-4.05534565335838 -"1039",-4.04967793062465 -"1040",-4.04963532119687 -"1041",-4.00322967225213 -"1042",-3.97913303644217 -"1043",-3.93848218445317 -"1044",-3.92896345601467 -"1045",-3.92129627729577 -"1046",-3.88873319656924 -"1047",-3.86460266970345 -"1048",-3.85592592335636 -"1049",-3.83806231438826 -"1050",-3.83646213170794 -"1051",-3.8358184097366 -"1052",-3.79687908142136 -"1053",-3.75949352880268 -"1054",-3.75259605784343 -"1055",-3.74990880094352 -"1056",-3.73544998144412 -"1057",-3.72526578646015 -"1058",-3.71518999634407 -"1059",-3.71331985199256 -"1060",-3.71099342724066 -"1061",-3.68863537833326 -"1062",-3.63867971957114 -"1063",-3.61616122923801 -"1064",-3.57558256759437 -"1065",-3.56703124354166 -"1066",-3.51619437209777 -"1067",-3.514906939665 -"1068",-3.50855781646648 -"1069",-3.50759104327018 -"1070",-3.50643933081537 -"1071",-3.49547808400832 -"1072",-3.47147360669847 -"1073",-3.47087329364612 -"1074",-3.46796889820745 -"1075",-3.45146511096799 -"1076",-3.44031608467071 -"1077",-3.43744191635976 -"1078",-3.40482480373609 -"1079",-3.38702758901487 -"1080",-3.38397441121381 -"1081",-3.37469772885609 -"1082",-3.35353665698488 -"1083",-3.34622593481475 -"1084",-3.30486592571477 -"1085",-3.29415127679213 -"1086",-3.28760492144145 -"1087",-3.28146261751984 -"1088",-3.26370511064366 -"1089",-3.25291805251271 -"1090",-3.24733287130236 -"1091",-3.24075679063325 -"1092",-3.23916148172611 -"1093",-3.23802011373731 -"1094",-3.23546241472571 -"1095",-3.22961025737516 -"1096",-3.21369819107273 -"1097",-3.2080203518895 -"1098",-3.1717577038152 -"1099",-3.17115094663317 -"1100",-3.16082585626425 -"1101",-3.13975833796136 -"1102",-3.13967958658723 -"1103",-3.13098128267803 -"1104",-3.12533143377261 -"1105",-3.12430453329657 -"1106",-3.11359628409605 -"1107",-3.10500994088662 -"1108",-3.05913409650067 -"1109",-3.03977661610826 -"1110",-3.02478375627226 -"1111",-3.01351356395688 -"1112",-3.01115817688416 -"1113",-2.99274684628785 -"1114",-2.97168935437248 -"1115",-2.95338504513677 -"1116",-2.95078645255541 -"1117",-2.94558346196136 -"1118",-2.94389730927521 -"1119",-2.93380272049453 -"1120",-2.93372788484735 -"1121",-2.92919537584195 -"1122",-2.927562490982 -"1123",-2.88922884595025 -"1124",-2.86395726017872 -"1125",-2.86328167229641 -"1126",-2.85149218376096 -"1127",-2.79805655011131 -"1128",-2.79633649577517 -"1129",-2.78182164147526 -"1130",-2.77899144223565 -"1131",-2.76067309061198 -"1132",-2.73780823215393 -"1133",-2.73499351454062 -"1134",-2.68785073145104 -"1135",-2.66773454737477 -"1136",-2.66336933895585 -"1137",-2.66011047459638 -"1138",-2.63885233577802 -"1139",-2.62612698740485 -"1140",-2.61336104779104 -"1141",-2.6133587686391 -"1142",-2.60791875345905 -"1143",-2.60654697921832 -"1144",-2.5744643823515 -"1145",-2.57217489404221 -"1146",-2.56936604463082 -"1147",-2.55356883801252 -"1148",-2.55351914058116 -"1149",-2.54678474541055 -"1150",-2.52931520778204 -"1151",-2.50624358397314 -"1152",-2.4985375295391 -"1153",-2.49337084027061 -"1154",-2.48443816364949 -"1155",-2.46293150498177 -"1156",-2.44046606539955 -"1157",-2.43615892235278 -"1158",-2.42456409579672 -"1159",-2.41602762536988 -"1160",-2.37460650990177 -"1161",-2.37118364554108 -"1162",-2.34598476523624 -"1163",-2.34126723656182 -"1164",-2.33973834551296 -"1165",-2.32053256611806 -"1166",-2.31067205361681 -"1167",-2.30217030325852 -"1168",-2.30159789883975 -"1169",-2.30055658148869 -"1170",-2.30050806363551 -"1171",-2.28524732961517 -"1172",-2.28494002044336 -"1173",-2.27685276999872 -"1174",-2.25846816258377 -"1175",-2.21857115034181 -"1176",-2.19450038782556 -"1177",-2.15704673766984 -"1178",-2.10301967386743 -"1179",-2.07851344707624 -"1180",-2.07291699872229 -"1181",-2.0694732626526 -"1182",-2.03954300860696 -"1183",-2.03134545678299 -"1184",-2.01625695535361 -"1185",-2.0141959144617 -"1186",-1.96198282005531 -"1187",-1.94893470382248 -"1188",-1.94598978475808 -"1189",-1.93740165185172 -"1190",-1.92935154117062 -"1191",-1.92925192404029 -"1192",-1.9249004994644 -"1193",-1.90194026729433 -"1194",-1.87522704043098 -"1195",-1.85795922791494 -"1196",-1.83381142182691 -"1197",-1.81734433403341 -"1198",-1.79956696349429 -"1199",-1.78489760264089 -"1200",-1.77109545824763 -"1201",-1.76435079813053 -"1202",-1.74235502103488 -"1203",-1.73873061096926 -"1204",-1.73372031479097 -"1205",-1.70364823452868 -"1206",-1.63715556193075 -"1207",-1.62303777078962 -"1208",-1.6151007340412 -"1209",-1.61470386200643 -"1210",-1.60764822786972 -"1211",-1.56388695693306 -"1212",-1.51734643128995 -"1213",-1.51010886348633 -"1214",-1.4924271028925 -"1215",-1.45102921640088 -"1216",-1.42281204746262 -"1217",-1.40961988428345 -"1218",-1.39724711166854 -"1219",-1.3751229494509 -"1220",-1.34735199629611 -"1221",-1.34665630880847 -"1222",-1.31661323477437 -"1223",-1.29102317399403 -"1224",-1.2909665661719 -"1225",-1.28735720691896 -"1226",-1.27032203264638 -"1227",-1.25762559676906 -"1228",-1.2474608100006 -"1229",-1.23485423219078 -"1230",-1.20812874043426 -"1231",-1.19030742716296 -"1232",-1.18835091256684 -"1233",-1.18079236729587 -"1234",-1.16924848981269 -"1235",-1.15143203638053 -"1236",-1.11721605745765 -"1237",-1.10962250716519 -"1238",-1.06153702750663 -"1239",-1.03768342632643 -"1240",-0.990734873078454 -"1241",-0.987495515445725 -"1242",-0.980496983724418 -"1243",-0.967406252178631 -"1244",-0.964736821820279 -"1245",-0.958971189311424 -"1246",-0.917217705486607 -"1247",-0.911599968953608 -"1248",-0.907127676077755 -"1249",-0.906114135398459 -"1250",-0.905458497625125 -"1251",-0.885190041156612 -"1252",-0.864606456004144 -"1253",-0.862874661132899 -"1254",-0.85074683388423 -"1255",-0.838385474118007 -"1256",-0.826043576140558 -"1257",-0.793589071850188 -"1258",-0.777950714528501 -"1259",-0.775621934054336 -"1260",-0.764157895605006 -"1261",-0.752127022142413 -"1262",-0.738311099338011 -"1263",-0.73022785137652 -"1264",-0.723105770386657 -"1265",-0.700306093965757 -"1266",-0.677985319557844 -"1267",-0.671894072946635 -"1268",-0.669324463916245 -"1269",-0.659305287552685 -"1270",-0.64012182961096 -"1271",-0.511736400201803 -"1272",-0.510290593677162 -"1273",-0.47763642346347 -"1274",-0.4709129894533 -"1275",-0.422944732882306 -"1276",-0.421044829674486 -"1277",-0.41710145102206 -"1278",-0.398196680679435 -"1279",-0.376156861207413 -"1280",-0.359233140365665 -"1281",-0.351732968641867 -"1282",-0.350647522014086 -"1283",-0.34517523086895 -"1284",-0.329326017933566 -"1285",-0.305943787046829 -"1286",-0.301545344439256 -"1287",-0.285084919793592 -"1288",-0.253729278940678 -"1289",-0.252700972522357 -"1290",-0.248919196626028 -"1291",-0.223291164100578 -"1292",-0.192185016529437 -"1293",-0.19161262631585 -"1294",-0.185045212286402 -"1295",-0.181919905749595 -"1296",-0.179034846876549 -"1297",-0.173287297503079 -"1298",-0.141525677518977 -"1299",-0.101840033226218 -"1300",-0.0970407112949778 -"1301",-0.0492548738995504 -"1302",-0.023513720010627 -"1303",0.0162604541839939 -"1304",0.0375336136823221 -"1305",0.0733184046974609 -"1306",0.0953001645455718 -"1307",0.120962160398074 -"1308",0.190017953406675 -"1309",0.218435442079588 -"1310",0.241821214281903 -"1311",0.250528389372194 -"1312",0.276196142322868 -"1313",0.27977948499051 -"1314",0.285500971890792 -"1315",0.287149100792679 -"1316",0.290112026146568 -"1317",0.29344080494716 -"1318",0.311908165392787 -"1319",0.322407584155402 -"1320",0.324182447301489 -"1321",0.383432755983119 -"1322",0.384485734764277 -"1323",0.386187025198377 -"1324",0.420618592768143 -"1325",0.447082184945172 -"1326",0.523803974388128 -"1327",0.529405611964534 -"1328",0.532998341099874 -"1329",0.534442031740709 -"1330",0.547379194123583 -"1331",0.561613960077787 -"1332",0.564318023626945 -"1333",0.570529840222415 -"1334",0.620360710219788 -"1335",0.64739563047546 -"1336",0.663207191480517 -"1337",0.670694252878435 -"1338",0.715555030597569 -"1339",0.716149392327277 -"1340",0.761846900496129 -"1341",0.810107808666224 -"1342",0.817334097946477 -"1343",0.820967302667451 -"1344",0.840173003211939 -"1345",0.852575696317977 -"1346",0.857150467934862 -"1347",0.859705945846018 -"1348",0.921459182277204 -"1349",0.926354072357387 -"1350",1.00885014220406 -"1351",1.03817313675617 -"1352",1.10984734260489 -"1353",1.15666208645111 -"1354",1.16142385573106 -"1355",1.17684070861746 -"1356",1.18385231612666 -"1357",1.1966950001691 -"1358",1.19741241523336 -"1359",1.20714296776668 -"1360",1.20888132109442 -"1361",1.21806302190688 -"1362",1.22884953986699 -"1363",1.24100478694269 -"1364",1.26761920472975 -"1365",1.28241249721386 -"1366",1.28336131776346 -"1367",1.31105660601415 -"1368",1.3170984001378 -"1369",1.33205504760875 -"1370",1.3344708438213 -"1371",1.38842889305729 -"1372",1.41575569616497 -"1373",1.41806626849728 -"1374",1.42708949372361 -"1375",1.46335663370264 -"1376",1.48398983615317 -"1377",1.50024384616022 -"1378",1.52065637752297 -"1379",1.5350986579673 -"1380",1.5605408381491 -"1381",1.58136979576822 -"1382",1.58623535161859 -"1383",1.66073941412552 -"1384",1.67455105203824 -"1385",1.69381716431386 -"1386",1.69852774224818 -"1387",1.73608161180673 -"1388",1.76103648112034 -"1389",1.77631065622266 -"1390",1.80425407719392 -"1391",1.81964072490539 -"1392",1.85554535705992 -"1393",1.8661352537373 -"1394",1.88787711923617 -"1395",1.89124446183704 -"1396",1.96759781922435 -"1397",1.97495194081412 -"1398",1.9773030062156 -"1399",1.99373675532775 -"1400",2.07720644159012 -"1401",2.09346332249502 -"1402",2.09555207626821 -"1403",2.1081331170213 -"1404",2.12113094978127 -"1405",2.12921502941589 -"1406",2.19414642417817 -"1407",2.20833629825387 -"1408",2.29333085208933 -"1409",2.32146884661582 -"1410",2.34505587392079 -"1411",2.36716783782891 -"1412",2.36976472015509 -"1413",2.41026723162849 -"1414",2.45804560298582 -"1415",2.4658541236074 -"1416",2.46612738765523 -"1417",2.48402543224341 -"1418",2.48411646664486 -"1419",2.53365172641323 -"1420",2.58817208275532 -"1421",2.62014303375104 -"1422",2.62782136922093 -"1423",2.62994468436115 -"1424",2.64204991920359 -"1425",2.64487083145706 -"1426",2.69526320013593 -"1427",2.74884598500507 -"1428",2.76192633578605 -"1429",2.82889272705632 -"1430",2.83892863508244 -"1431",2.85103842928921 -"1432",2.87652738820834 -"1433",2.88156277959989 -"1434",2.92047538708288 -"1435",2.92279651591474 -"1436",2.96637465937715 -"1437",3.00229612982986 -"1438",3.1065752776847 -"1439",3.1096498524862 -"1440",3.1407858182916 -"1441",3.14778479146946 -"1442",3.15343766601476 -"1443",3.18621126973117 -"1444",3.19811258758023 -"1445",3.20339899013596 -"1446",3.20410472854698 -"1447",3.22763035928729 -"1448",3.22848313361068 -"1449",3.24102825945565 -"1450",3.24138676238149 -"1451",3.26076393964278 -"1452",3.27282459362951 -"1453",3.2782587174085 -"1454",3.28456893310964 -"1455",3.29400515682231 -"1456",3.30100935005595 -"1457",3.39270071884497 -"1458",3.39692025651198 -"1459",3.41105471844293 -"1460",3.41217138060693 -"1461",3.42838146589016 -"1462",3.4425611070255 -"1463",3.45303326240453 -"1464",3.55178557268323 -"1465",3.56771353241915 -"1466",3.56846158219832 -"1467",3.86562973015187 -"1468",3.9011382272038 -"1469",3.91509586523911 -"1470",3.98468199214966 -"1471",3.98569379524452 -"1472",4.00519989930215 -"1473",4.0744703725391 -"1474",4.14250851343156 -"1475",4.16463619990869 -"1476",4.22643028443218 -"1477",4.26175416210141 -"1478",4.26902672497017 -"1479",4.28236491069222 -"1480",4.32306263259395 -"1481",4.43479075075663 -"1482",4.46251148961556 -"1483",4.46884432695762 -"1484",4.50019908651606 -"1485",4.53572436441097 -"1486",4.56592949690097 -"1487",4.57617569678174 -"1488",4.59836928747722 -"1489",4.63884242357687 -"1490",5.13999198643694 -"1491",5.26770967957216 -"1492",5.48175475871867 -"1493",5.51968954748753 -"1494",5.57259211210671 -"1495",5.57934964290803 -"1496",6.73061011495482 -"1497",7.07652340897122 -"1498",7.19236031365089 -"1499",9.58194214766505 -"1500",10.3950985695437 diff --git a/test/test_gmm/test_distributions.py b/test/test_gmm/test_distributions.py deleted file mode 100644 index d93a459..0000000 --- a/test/test_gmm/test_distributions.py +++ /dev/null @@ -1,60 +0,0 @@ -import numpy as np - -import enrichment_auc.gmm.distributions as dist - - -def test_find_dist_zero_var(): - scores = np.ones(100) - dist_found = dist.find_distribution(scores, "") - assert dist_found["weights"].shape[0] == 0 - assert dist_found["mu"].shape[0] == 0 - assert dist_found["sigma"].shape[0] == 0 - - -def test_merge_gmm_retains_dists(): - mu = np.array([0, 5, 10, 15]) - sigma = np.array([1, 2, 3, 4]) - weights = np.array([0.25, 0.25, 0.25, 0.25]) - dists = { - "sigma": sigma, - "mu": mu, - "weights": weights, - } - pred_dist = dist._merge_gmm(dists) - np.testing.assert_array_equal(mu, pred_dist["mu"]) - np.testing.assert_array_equal(weights, pred_dist["weights"]) - np.testing.assert_array_equal(sigma, pred_dist["sigma"]) - - -def test_merge_gmm_merges_dists_sigma(): - mu = np.array([0.0, 9.5, 10.0, 15]) - sigma = np.array([1.0, 2.0, 3, 4]) - weights = np.array([0.25, 0.25, 0.25, 0.25]) - dists = { - "sigma": sigma, - "mu": mu, - "weights": weights, - } - pred_dist = dist._merge_gmm(dists) - np.testing.assert_array_almost_equal(np.array([0, 9.75, 15]), pred_dist["mu"]) - np.testing.assert_array_equal(np.array([0.25, 0.5, 0.25]), pred_dist["weights"]) - np.testing.assert_array_almost_equal( - np.array([1.0, 2.56173769, 4]), pred_dist["sigma"] - ) - - -def test_merge_gmm_merges_dists_alpha(): - mu = np.array([-5.0, 0.0, 10.0, 15]) - sigma = np.array([2.0, 1.0, 3, 4]) - weights = np.array([0.4999, 0.0001, 0.25, 0.25]) - dists = { - "sigma": sigma, - "mu": mu, - "weights": weights, - } - pred_dist = dist._merge_gmm(dists) - np.testing.assert_array_almost_equal(np.array([-4.999, 10, 15]), pred_dist["mu"]) - np.testing.assert_array_equal(np.array([0.5, 0.25, 0.25]), pred_dist["weights"]) - np.testing.assert_array_almost_equal( - np.array([2.0010994478036324, 3, 4]), pred_dist["sigma"] - ) diff --git a/test/test_gmm/test_thresholds.py b/test/test_gmm/test_thresholds.py deleted file mode 100644 index 5052db0..0000000 --- a/test/test_gmm/test_thresholds.py +++ /dev/null @@ -1,205 +0,0 @@ -import numpy as np -import pandas as pd -import pytest - -import enrichment_auc.gmm.thresholds as thr_tools - - -def test_categorize_by_thresholds_no_thr(): - # check if all data is non significant and in one group when no thr is found - scores = np.random.normal(0, 1, 100) - labels = np.zeros(100) - thresholds = np.array([]) - groupings = thr_tools.categorize_by_thresholds(scores, thresholds) - np.testing.assert_array_equal(groupings, labels) - - -def test_correct_via_kmeans_skips_smaller_than_2(): - distributions_0 = { - "mu": np.array([]), - "sigma": np.array([]), - "weights": np.array([]), - } - distributions_1 = { - "mu": np.array([0]), - "sigma": np.array([1.0]), - "weights": np.array([1.0]), - } - distributions_2 = { - "mu": np.array([0, 1]), - "sigma": np.array([1, 1]), - "weights": np.array([0.5, 0.5]), - } - thresholds_0 = np.array([]) - thresholds_1 = np.array([]) - thresholds_2 = np.array([0.5]) - thr_found_0 = thr_tools.correct_via_kmeans(distributions_0, thresholds_0) - thr_found_1 = thr_tools.correct_via_kmeans(distributions_1, thresholds_1) - thr_found_2 = thr_tools.correct_via_kmeans(distributions_2, thresholds_2) - np.testing.assert_array_equal(thr_found_0, thresholds_0) - np.testing.assert_array_equal(thr_found_1, thresholds_1) - np.testing.assert_array_equal(thr_found_2, thresholds_2) - - -def test_correct_via_kmeans_skips_missing_thrs(): - distributions = { - "mu": np.array([0, 1, 2]), - "sigma": np.array([1, 1, 1]), - "weights": np.array([0.25, 0.25, 0.5]), - } - thresholds = np.array([0.5]) - thr_found = thr_tools.correct_via_kmeans(distributions, thresholds) - np.testing.assert_array_equal(thr_found, thresholds) - - -def test_correct_via_kmeans_scales_correctly(): - distributions = { - "mu": np.array( - [0.25, 0.5, 0.75], - ), - "sigma": np.array([0.1, 0.1, 0.1]), - "weights": np.array([1.0 / 3, 1.0 / 3, 1.0 / 3]), - } - thresholds = np.array([0.4, 0.6]) - try: - _ = thr_tools.correct_via_kmeans(distributions, thresholds) - except ValueError: - pytest.fail("unexpected ValueError") - - -def test_filter_thresholds_retains_thresholds(): - localizer = np.array([0, 1, 2]) - mu = np.array([0, 1, 2]) - thresholds = np.array([0.5, 1.5]) - thr_found = thr_tools._filter_thresholds(localizer, mu, thresholds) - np.testing.assert_array_equal(thr_found, thresholds) - - -def test_filter_thresholds_retains_thresholds_mixed_up(): - localizer = np.array([0, 1, 0]) - mu = np.array([0, 1, 2]) - thresholds = np.array([0.5, 1.5]) - thr_found = thr_tools._filter_thresholds(localizer, mu, thresholds) - np.testing.assert_array_equal(thr_found, thresholds) - - -def test_filter_thresholds_removes_single_thresholds(): - localizer = np.array([1, 1, 0]) - mu = np.array([0, 1, 2]) - thresholds = np.array([0.5, 1.5]) - thr_found = thr_tools._filter_thresholds(localizer, mu, thresholds) - np.testing.assert_array_equal(thr_found, np.array([1.5])) - - -def test_filter_thresholds_removes_multiple_thresholds_one_label(): - localizer = np.array([0, 1, 1, 1]) - mu = np.array([0, 1, 2, 3]) - thresholds = np.array([0.5, 1.5, 2.5]) - thr_found = thr_tools._filter_thresholds(localizer, mu, thresholds) - np.testing.assert_array_equal(thr_found, np.array([0.5])) - - -def test_filter_thresholds_removes_multiple_thresholds_diff_label(): - localizer = np.array([0, 0, 1, 1]) - mu = np.array([0, 1, 2, 3]) - thresholds = np.array([0.5, 1.5, 2.5]) - thr_found = thr_tools._filter_thresholds(localizer, mu, thresholds) - np.testing.assert_array_equal(thr_found, np.array([1.5])) - - -def test_detect_noncrossing(): - f1 = np.array([[0, 1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [0, 1, 2, 4, 2, 0]]) - f2 = np.array([[1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5], [0, 0.5, 1, 6, 7, 1]]) - expected = np.array([0, 1]) - np.testing.assert_array_equal(thr_tools._detect_noncrossing(f1, f2)[0], expected) - - -def test_restrict_thr_ranges(): - ranges = np.array([0.1, 0.9]) - x_temp = np.array([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]) - pdfs = np.array( - [ - [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], - [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], - [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], - ] - ) - x_expected = np.array([0.3, 0.4, 0.5, 0.6, 0.7]) - pdfs_expected = np.array( - [ - [0.3, 0.4, 0.5, 0.6, 0.7], - [0.3, 0.4, 0.5, 0.6, 0.7], - [0.3, 0.4, 0.5, 0.6, 0.7], - ] - ) - x_restricted, pdfs_restricted = thr_tools._restrict_thr_ranges(ranges, x_temp, pdfs) - np.testing.assert_array_equal(x_restricted, x_expected) - np.testing.assert_array_equal(pdfs_restricted, pdfs_expected) - - -def test_find_closest_location(): - x_temp = np.array([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]) - f1 = np.array( - [ - [0.02, 0.05, 0.1, 0.2, 0.3, 0.35, 0.3, 0.2, 0.1, 0.05, 0.02], - [0.02, 0.05, 0.17, 0.2, 0.3, 0.35, 0.3, 0.2, 0.1, 0.05, 0.02], - ] - ) - f2 = np.array( - [ - [0.2, 0.15, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.001, 0.0001, 0.00001], - [0.2, 0.07, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.001, 0.0001, 0.00001], - ] - ) - x_expected = np.array([0.2, 1]) - x_found = thr_tools._find_closest_location(f1, f2, x_temp) - np.testing.assert_array_equal(x_found, x_expected) - - -def test_find_thr_by_dist_2(): - distributions = { - "mu": np.array( - [0.25, 0.75], - ), - "sigma": np.array([0.25, 0.25]), - "weights": np.array([0.5, 0.5]), - } - x_temp = np.array([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]) - pdfs = thr_tools.find_pdfs( - distributions["mu"], distributions["sigma"], distributions["weights"], x_temp - ) - thr_expected = np.array([0.5]) - thr_found = thr_tools._find_thr_by_dist(distributions, x_temp, pdfs) - np.testing.assert_array_almost_equal(thr_found, thr_expected) - - -def test_find_thr_by_dist_more(): - distributions = { - "mu": np.array( - [0.25, 0.5, 0.75], - ), - "sigma": np.array([0.1, 0.1, 0.1]), - "weights": np.array([1.0 / 3, 1.0 / 3, 1.0 / 3]), - } - x_temp = np.array([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]) - pdfs = thr_tools.find_pdfs( - distributions["mu"], distributions["sigma"], distributions["weights"], x_temp - ) - thr_expected = np.array([0.4, 0.6]) - thr_found = thr_tools._find_thr_by_dist(distributions, x_temp, pdfs) - np.testing.assert_array_almost_equal(thr_found, thr_expected) - - -def test_find_thresholds(): - df = pd.read_csv("test/test_gmm/test_data.csv", index_col=0) - scores = df.to_numpy().flatten() - distributions = { - "mu": np.array( - [-20.965105, -14.611753, -5.064705, 1.029677], - ), - "sigma": np.array([2.267210, 2.414377, 4.526973, 2.267210]), - "weights": np.array([0.03698616, 0.38945294, 0.46400648, 0.10955443]), - } - thr_expected = np.array([-19.9026174, -10.785832, 0.5642248]) - thr_found = thr_tools.find_thresholds(distributions, scores, "") - np.testing.assert_array_almost_equal(thr_found, thr_expected, decimal=2) diff --git a/test/test_gmmdecomp.py b/test/test_gmmdecomp.py new file mode 100644 index 0000000..dd01125 --- /dev/null +++ b/test/test_gmmdecomp.py @@ -0,0 +1,463 @@ +""" +Test module for GMMdecomp implementation. +""" + +import numpy as np +import pandas as pd +import pytest +from typing import Dict, Any + +import pytest + +from pyfuncella.GMMdecomp import ( + GMMdecomp, + _check_r_available, + _check_dpgmm_installed, +) + + +class TestGMMdecomp: + """Test class for GMMdecomp functionality.""" + + def test_r_available(self): + """Test that R is available through rpy2.""" + assert _check_r_available(), "R is not available through rpy2" + + def test_dpgmm_installed(self): + """Test that dpGMM package is installed in R.""" + assert _check_dpgmm_installed(), "dpGMM package is not installed" + + def test_gmmdecomp_basic_functionality(self): + """Test basic GMMdecomp functionality with pandas DataFrame input.""" + # Create test data + np.random.seed(42) + + # Create some bimodal data for testing + pathway1 = np.concatenate( + [ + np.random.normal(0.2, 0.1, 10), # Low activity component + np.random.normal(0.8, 0.1, 10), # High activity component + ] + ) + + pathway2 = np.random.normal(0.5, 0.2, 20) # Unimodal data + + # Create DataFrame more concisely + test_data = pd.DataFrame( + [pathway1, pathway2], + index=["pathway_bimodal", "pathway_unimodal"], + columns=[f"sample_{i}" for i in range(20)], + ) + + # Run GMM decomposition + results = GMMdecomp(test_data, K=3, verbose=False) + + # Check results structure + assert isinstance(results, dict), "Results should be a dictionary" + assert len(results) == 2, "Should have results for 2 pathways" + assert "pathway_bimodal" in results, "Should have results for pathway_bimodal" + assert "pathway_unimodal" in results, "Should have results for pathway_unimodal" + + def test_gmmdecomp_result_structure(self): + """Test that GMMdecomp results have the correct structure.""" + np.random.seed(42) + + pathway1_data = np.concatenate( + [ + np.random.normal(-1, 0.3, 10), # First mode + np.random.normal(1, 0.3, 10), # Second mode + ] + ) + pathway2_data = np.concatenate( + [ + np.random.normal(0, 0.2, 10), # Single mode + np.random.normal(2, 0.2, 10), # Second mode + ] + ) + + test_data = pd.DataFrame( + [pathway1_data, pathway2_data], + index=["pathway_1", "pathway_2"], + columns=[f"sample_{i}" for i in range(20)], + ) + + results = GMMdecomp(test_data, K=2, verbose=False) + + # Check each pathway result structure + for pathway_name, result in results.items(): + assert isinstance( + result, dict + ), f"Result for {pathway_name} should be a dictionary" + assert ( + "model" in result + ), f"Result for {pathway_name} should have 'model' key" + assert ( + "thresholds" in result + ), f"Result for {pathway_name} should have 'thresholds' key" + + # Check model structure + model = result["model"] + assert isinstance( + model, dict + ), f"Model for {pathway_name} should be a dictionary" + assert "alpha" in model, f"Model for {pathway_name} should have 'alpha' key" + assert "mu" in model, f"Model for {pathway_name} should have 'mu' key" + assert "sigma" in model, f"Model for {pathway_name} should have 'sigma' key" + + # Check model components are numpy arrays + assert isinstance( + model["alpha"], np.ndarray + ), f"Alpha for {pathway_name} should be numpy array" + assert isinstance( + model["mu"], np.ndarray + ), f"Mu for {pathway_name} should be numpy array" + assert isinstance( + model["sigma"], np.ndarray + ), f"Sigma for {pathway_name} should be numpy array" + + # Check thresholds is a numpy array + assert isinstance( + result["thresholds"], np.ndarray + ), f"Thresholds for {pathway_name} should be numpy array" + + # Check that all model components have the same length + if len(model["alpha"]) > 0: + assert len(model["alpha"]) == len( + model["mu"] + ), f"Alpha and mu should have same length for {pathway_name}" + assert len(model["alpha"]) == len( + model["sigma"] + ), f"Alpha and sigma should have same length for {pathway_name}" + + # Check that alpha values sum to approximately 1 (mixture weights) + assert ( + np.abs(np.sum(model["alpha"]) - 1.0) < 1e-10 + ), f"Alpha values should sum to 1 for {pathway_name}, got sum={np.sum(model['alpha'])}" + else: + # For empty components (failed GMM), all should be empty but still valid + assert ( + len(model["mu"]) == 0 + ), f"Mu should also be empty when alpha is empty for {pathway_name}" + assert ( + len(model["sigma"]) == 0 + ), f"Sigma should also be empty when alpha is empty for {pathway_name}" + # This is acceptable - GMM can fail for various reasons + print( + f"Note: GMM failed for {pathway_name} - this can happen with difficult data" + ) + + def test_gmmdecomp_value_validation(self): + """Test that GMMdecomp produces reasonable values.""" + np.random.seed(42) + + # Create bimodal and unimodal data + pathway1 = np.concatenate( + [np.random.normal(0.2, 0.1, 10), np.random.normal(0.8, 0.1, 10)] + ) + pathway2 = np.random.normal(0.5, 0.2, 20) + + test_data = pd.DataFrame( + [pathway1, pathway2], + index=["pathway_bimodal", "pathway_unimodal"], + columns=[f"sample_{i}" for i in range(20)], + ) + + results = GMMdecomp(test_data, K=3, verbose=False) + + bimodal_result = results["pathway_bimodal"] + unimodal_result = results["pathway_unimodal"] + + # Check threshold values are within reasonable range + bimodal_data = test_data.loc["pathway_bimodal"] + unimodal_data = test_data.loc["pathway_unimodal"] + + # For bimodal data, check thresholds if any exist + bimodal_range = bimodal_data.max() - bimodal_data.min() + bimodal_min_extended = bimodal_data.min() - 0.5 * bimodal_range + bimodal_max_extended = bimodal_data.max() + 0.5 * bimodal_range + + bimodal_thresholds = bimodal_result["thresholds"] + if len(bimodal_thresholds) > 0: + for threshold in bimodal_thresholds: + assert ( + bimodal_min_extended <= threshold <= bimodal_max_extended + ), f"Bimodal threshold {threshold} should be within extended range [{bimodal_min_extended}, {bimodal_max_extended}]" + + # For unimodal data, check thresholds if any exist + unimodal_range = unimodal_data.max() - unimodal_data.min() + unimodal_min_extended = unimodal_data.min() - 0.5 * unimodal_range + unimodal_max_extended = unimodal_data.max() + 0.5 * unimodal_range + + unimodal_thresholds = unimodal_result["thresholds"] + if len(unimodal_thresholds) > 0: + for threshold in unimodal_thresholds: + assert ( + unimodal_min_extended <= threshold <= unimodal_max_extended + ), f"Unimodal threshold {threshold} should be within extended range [{unimodal_min_extended}, {unimodal_max_extended}]" + + # Check that component means are reasonable + for pathway_name, result in results.items(): + pathway_data = test_data.loc[pathway_name] + model = result["model"] + + # All component means should be within expanded data range + data_range = pathway_data.max() - pathway_data.min() + data_min = pathway_data.min() - 0.5 * data_range + data_max = pathway_data.max() + 0.5 * data_range + + for mu in model["mu"]: + assert ( + data_min <= mu <= data_max + ), f"Component mean {mu} should be within reasonable range for {pathway_name}" + + # Check that all sigma values are positive (or zero for constant data) + for pathway_name, result in results.items(): + model = result["model"] + assert np.all( + model["sigma"] >= 0 + ), f"All sigma values should be non-negative for {pathway_name}" + + def test_gmmdecomp_bimodal_detection(self): + """Test that GMMdecomp can detect bimodal patterns.""" + np.random.seed(42) + + # Create clearly bimodal and unimodal data + pathway1 = np.concatenate( + [np.random.normal(0.2, 0.1, 10), np.random.normal(0.8, 0.1, 10)] + ) + pathway2 = np.random.normal(0.5, 0.2, 20) + + test_data = pd.DataFrame( + [pathway1, pathway2], + index=["pathway_bimodal", "pathway_unimodal"], + columns=[f"sample_{i}" for i in range(20)], + ) + + results = GMMdecomp(test_data, K=3, verbose=False) + + bimodal_result = results["pathway_bimodal"] + unimodal_result = results["pathway_unimodal"] + + # Check that bimodal data likely has more components than unimodal + bimodal_components = len(bimodal_result["model"]["alpha"]) + unimodal_components = len(unimodal_result["model"]["alpha"]) + + # This is probabilistic, but with our designed data it should usually hold + assert ( + bimodal_components >= unimodal_components + ), "Bimodal data should generally have at least as many components as unimodal" + + def test_gmmdecomp_with_numpy_array(self): + """Test GMMdecomp with numpy array input.""" + np.random.seed(42) + + # Create test data as numpy array + test_data = np.random.randn(2, 10) + + # Run GMM decomposition + results = GMMdecomp(test_data, K=2, verbose=False) + + # Check results structure + assert isinstance(results, dict), "Results should be a dictionary" + assert len(results) == 2, "Should have results for 2 pathways" + assert "pathway_0" in results, "Should have results for pathway_0" + assert "pathway_1" in results, "Should have results for pathway_1" + + def test_gmmdecomp_parameter_validation_k(self): + """Test K parameter validation in GMMdecomp.""" + np.random.seed(42) + test_data = pd.DataFrame(np.random.randn(2, 10)) + + # Test invalid K + with pytest.raises(ValueError, match="K must be a positive integer"): + GMMdecomp(test_data, K=0, verbose=False) + + with pytest.raises(ValueError, match="K must be a positive integer"): + GMMdecomp(test_data, K=-1, verbose=False) + + def test_gmmdecomp_parameter_validation_types(self): + """Test type validation for boolean parameters in GMMdecomp.""" + np.random.seed(42) + test_data = pd.DataFrame(np.random.randn(2, 10)) + + # Test invalid multiply + with pytest.raises(ValueError, match="multiply must be a boolean value"): + GMMdecomp(test_data, multiply="true", verbose=False) # type: ignore + + # Test invalid parallel + with pytest.raises(ValueError, match="parallel must be a boolean value"): + GMMdecomp(test_data, parallel="false", verbose=False) # type: ignore + + def test_gmmdecomp_parameter_validation_ic(self): + """Test IC parameter validation in GMMdecomp.""" + np.random.seed(42) + test_data = pd.DataFrame(np.random.randn(2, 10)) + + # Test invalid IC + with pytest.raises(ValueError, match="IC must be one of"): + GMMdecomp(test_data, IC="INVALID", verbose=False) + + def test_gmmdecomp_parameter_validation_input(self): + """Test input data validation in GMMdecomp.""" + # Test empty DataFrame + empty_df = pd.DataFrame() + with pytest.raises(ValueError, match="Input data X cannot be empty"): + GMMdecomp(empty_df, verbose=False) + + # Test invalid input type + with pytest.raises( + ValueError, match="X must be a pandas DataFrame or numpy array" + ): + GMMdecomp([1, 2, 3], verbose=False) # type: ignore + + def test_gmmdecomp_different_ic_criteria(self): + """Test GMMdecomp with different IC criteria.""" + np.random.seed(42) + test_data = pd.DataFrame(np.random.randn(1, 20), index=["pathway_test"]) + + ic_criteria = ["AIC", "AICc", "BIC", "ICL-BIC", "LR"] + + for ic in ic_criteria: + results = GMMdecomp(test_data, K=2, IC=ic, verbose=False) + assert isinstance( + results, dict + ), f"Results should be a dictionary for IC={ic}" + assert len(results) == 1, f"Should have results for 1 pathway for IC={ic}" + assert ( + "pathway_test" in results + ), f"Should have results for pathway_test for IC={ic}" + + def test_gmmdecomp_multiply_equivalence(self): + """Test that multiply parameter produces equivalent results.""" + np.random.seed(42) + test_data = pd.DataFrame(np.random.randn(1, 20), index=["pathway_test"]) + + # Test with multiply=True + results_multiply = GMMdecomp(test_data, K=2, multiply=True, verbose=False) + + # Test with multiply=False + results_no_multiply = GMMdecomp(test_data, K=2, multiply=False, verbose=False) + + # Both should return valid results + assert isinstance( + results_multiply, dict + ), "Results with multiply=True should be a dictionary" + assert isinstance( + results_no_multiply, dict + ), "Results with multiply=False should be a dictionary" + assert ( + len(results_multiply) == 1 + ), "Should have results for 1 pathway with multiply=True" + assert ( + len(results_no_multiply) == 1 + ), "Should have results for 1 pathway with multiply=False" + + # Check that results are equivalent (multiply should not change final results) + # Since we scale and then unscale, the final results should be very similar + result_mult = results_multiply["pathway_test"] + result_no_mult = results_no_multiply["pathway_test"] + + # Thresholds should be similar (allowing for small numerical differences) + thresholds_mult = result_mult["thresholds"] + thresholds_no_mult = result_no_mult["thresholds"] + + assert len(thresholds_mult) == len( + thresholds_no_mult + ), "Number of thresholds should be equal" + + if len(thresholds_mult) > 0: + np.testing.assert_allclose( + thresholds_mult, + thresholds_no_mult, + rtol=1e-4, + atol=1e-4, + err_msg="Thresholds should be equivalent regardless of multiply parameter", + ) + + # Component means should be similar + np.testing.assert_allclose( + result_mult["model"]["mu"], + result_no_mult["model"]["mu"], + rtol=1e-4, + atol=1e-4, + err_msg="Component means should be equivalent regardless of multiply parameter", + ) + + # Component standard deviations should be similar + np.testing.assert_allclose( + result_mult["model"]["sigma"], + result_no_mult["model"]["sigma"], + rtol=1e-4, + atol=1e-4, + err_msg="Component sigmas should be equivalent regardless of multiply parameter", + ) + + def test_gmmdecomp_edge_case_constant_data(self): + """Test GMMdecomp with constant data (all same values).""" + np.random.seed(42) + + # Test with constant data (all same values) + constant_data = pd.DataFrame(np.full((1, 20), 0.5), index=["pathway_constant"]) + results_constant = GMMdecomp(constant_data, K=2, verbose=False) + + # Should still work, likely with 1 component + assert isinstance(results_constant, dict) + assert len(results_constant) == 1 + assert "pathway_constant" in results_constant + + # For constant data, should have no thresholds (single component) + constant_result = results_constant["pathway_constant"] + assert ( + len(constant_result["thresholds"]) == 0 + ), "Constant data should have no thresholds (single component)" + + # The single component should be centered around the constant value + assert ( + len(constant_result["model"]["mu"]) == 1 + ), "Should have exactly one component for constant data" + assert ( + abs(constant_result["model"]["mu"][0] - 0.5) < 0.1 + ), "Component mean should be near the constant value" + + def test_gmmdecomp_edge_case_small_range(self): + """Test GMMdecomp with very small data range.""" + np.random.seed(42) + + # Test with very small data range + small_range_data = pd.DataFrame( + np.random.normal(0.5, 0.001, (1, 20)), index=["pathway_small_range"] + ) + results_small = GMMdecomp(small_range_data, K=2, verbose=False) + + assert isinstance(results_small, dict) + assert len(results_small) == 1 + assert "pathway_small_range" in results_small + + def test_gmmdecomp_edge_case_extreme_values(self): + """Test GMMdecomp with extreme values.""" + np.random.seed(42) + + # Test with extreme values + extreme_data = pd.DataFrame( + np.concatenate( + [ + np.full(10, -100), # Very negative values + np.full(10, 100), # Very positive values + ] + ).reshape(1, -1), + index=["pathway_extreme"], + ) + results_extreme = GMMdecomp(extreme_data, K=2, verbose=False) + + assert isinstance(results_extreme, dict) + assert len(results_extreme) == 1 + assert "pathway_extreme" in results_extreme + + # Thresholds should be somewhere between the extremes if any exist + extreme_result = results_extreme["pathway_extreme"] + thresholds = extreme_result["thresholds"] + if len(thresholds) > 0: + for threshold in thresholds: + assert ( + -100 <= threshold <= 100 + ), f"Threshold {threshold} should be between extremes" diff --git a/test/test_kmeans_search.py b/test/test_kmeans_search.py new file mode 100644 index 0000000..66238c4 --- /dev/null +++ b/test/test_kmeans_search.py @@ -0,0 +1,106 @@ +import numpy as np +import pytest + +from pyfuncella.utils.kmeans_search import last_consecutive_true, km_search + + +@pytest.mark.parametrize( + "arr,expected", + [ + ([False, True, True, False, True, True, True], [4, 5, 6]), + ([False, False, False], None), + ([False, False, True], [2]), + ([True, True, False, False], [0, 1]), + ([False, False, True, True], [2, 3]), + ([True, True, True], [0, 1, 2]), + ([False, True, False, True, False, True], [5]), + ([True], [0]), + ([False], None), + ([True, False, True, True, False, True, True, True], [5, 6, 7]), + ], +) +def test_last_consecutive_true_various(arr, expected): + assert last_consecutive_true(arr) == expected + + +def test_km_search_edge_cases(): + # 1 component + gmm_result = { + "model": { + "mu": np.array([1.0]), + "sigma": np.array([0.1]), + "alpha": np.array([1.0]), + }, + "thresholds": np.array([]), + } + assert np.isnan(km_search(gmm_result)) + + # 2 components + gmm_result = { + "model": { + "mu": np.array([1.0, 2.0]), + "sigma": np.array([0.1, 0.2]), + "alpha": np.array([0.5, 0.5]), + }, + "thresholds": np.array([1.5]), + } + assert km_search(gmm_result) == 1.5 + + # No valid params + gmm_result = { + "model": {"mu": np.array([]), "sigma": np.array([]), "alpha": np.array([])}, + "thresholds": np.array([]), + } + assert np.isnan(km_search(gmm_result)) + + # Final component not in target cluster (simulate by shifting means) + gmm_result = { + "model": { + "mu": np.array([10.0, 20.0, 5.0]), + "sigma": np.array([0.1, 0.2, 0.3]), + "alpha": np.array([0.3, 0.3, 0.4]), + }, + "thresholds": np.array([1.5, 2.5]), + } + result = km_search(gmm_result) + assert result == 2.5 + + # All components their own cluster (simulate by making all params unique) + gmm_result = { + "model": { + "mu": np.array([1.0, 2.0, 3.0]), + "sigma": np.array([0.1, 0.2, 0.3]), + "alpha": np.array([0.3, 0.2, 0.5]), + }, + "thresholds": np.array([1.5, 2.5]), + } + result = km_search(gmm_result) + assert result == 2.5 + + # Normal case: last run of TRUEs is not at start + gmm_result = { + "model": { + "mu": np.array([1.0, 2.0, 3.0]), + "sigma": np.array([0.1, 0.2, 0.3]), + "alpha": np.array([0.3, 0.3, 0.4]), + }, + "thresholds": np.array([1.5, 2.5]), + } + result = km_search(gmm_result) + assert isinstance(result, float) + + +def test_km_search_randomized(): + # Randomized test: 5 components, thresholds + rng = np.random.default_rng(42) + mu = rng.normal(0, 1, 5) + sigma = rng.uniform(0.1, 1.0, 5) + alpha = rng.dirichlet(np.ones(5)) + thrs = np.sort(rng.uniform(-2, 2, 4)) + gmm_result = { + "model": {"mu": mu, "sigma": sigma, "alpha": alpha}, + "thresholds": thrs, + } + result = km_search(gmm_result) + assert isinstance(result, float) + assert thrs[0] <= result <= thrs[-1] diff --git a/test/test_metrics/aucell_test.py b/test/test_metrics/aucell_test.py index fcf0fc4..841b28d 100644 --- a/test/test_metrics/aucell_test.py +++ b/test/test_metrics/aucell_test.py @@ -1,6 +1,6 @@ import numpy as np -import enrichment_auc.metrics.aucell as aucell +import pyfuncella.metrics.aucell as aucell def test_aucell(): @@ -46,6 +46,6 @@ def test_aucell_sets_ranks(): [0.0, 0.5, 0.4, 0.3, 0.2, 0.1], ] ) - score = aucell.AUCELL(genesets, data, genes) + score = aucell.AUCELL(genesets, data, genes, thr=0.25) score_expected = np.array([1, 0, 1.0 / 3, 2.0 / 3, 1, 1]) assert np.isclose(score_expected, score, atol=10e-4).all() diff --git a/test/test_metrics/cerno_test.py b/test/test_metrics/cerno_test.py index d5d53a4..011a216 100644 --- a/test/test_metrics/cerno_test.py +++ b/test/test_metrics/cerno_test.py @@ -1,7 +1,7 @@ import numpy as np from statsmodels.stats.multitest import multipletests -import enrichment_auc.metrics.cerno as cerno +import pyfuncella.metrics.cerno as cerno def test_auc(): diff --git a/test/test_metrics/ft_test.py b/test/test_metrics/ft_test.py index a5e5e81..6b8a1cc 100644 --- a/test/test_metrics/ft_test.py +++ b/test/test_metrics/ft_test.py @@ -1,7 +1,7 @@ import numpy as np import pytest -import enrichment_auc.normalize.freeman_tukey as ft +import pyfuncella.normalize.freeman_tukey as ft def test_ft(): diff --git a/test/test_metrics/means_test.py b/test/test_metrics/means_test.py index 04fe666..06944e7 100644 --- a/test/test_metrics/means_test.py +++ b/test/test_metrics/means_test.py @@ -1,6 +1,6 @@ import numpy as np -import enrichment_auc.metrics.mean as mean +import pyfuncella.metrics.mean as mean def test_mean(): diff --git a/test/test_metrics/pca_test.py b/test/test_metrics/pca_test.py index 48b80a2..0839278 100644 --- a/test/test_metrics/pca_test.py +++ b/test/test_metrics/pca_test.py @@ -1,6 +1,6 @@ import numpy as np -import enrichment_auc.metrics.svd as svd +import pyfuncella.metrics.svd as svd def test_svd(): diff --git a/test/test_metrics/rank_test.py b/test/test_metrics/rank_test.py index 13a3815..f45e223 100644 --- a/test/test_metrics/rank_test.py +++ b/test/test_metrics/rank_test.py @@ -1,6 +1,6 @@ import numpy as np -import enrichment_auc.metrics.rank as rank +import pyfuncella.metrics.rank as rank def test_rank_genes(): diff --git a/test/test_metrics/ratio_test.py b/test/test_metrics/ratio_test.py index 5f36cac..0423b87 100644 --- a/test/test_metrics/ratio_test.py +++ b/test/test_metrics/ratio_test.py @@ -1,6 +1,6 @@ import numpy as np -import enrichment_auc.metrics.ratio as ratio +import pyfuncella.metrics.bina as bina def test_ratio(): @@ -17,17 +17,21 @@ def test_ratio(): [0, 5, 0, 5, 0], ] ) - res = ratio._ratio(geneset["geneset"], data, genes) + res = bina._ratio(geneset["geneset"], data, genes) assert np.array_equal(expected, res) -def test_calculate_ratio(): +def test_calculate_bina(): genes = ["a", "b", "c", "d", "e"] genesets = {"geneset": ["a", "b", "e", "f"], "geneset1": ["a", "b", "c"]} - expected = np.array( + # Raw ratios that would be calculated + ratios = np.array( [[2 / 3, 2 / 3, 1 / 3, 1.0, 0.0], [2 / 3, 2 / 3, 2 / 3, 3 / 3, 0 / 3]] ) + # Transform to BINA scores: log((DR + 0.1) / (1 - DR + 0.1)) + expected = np.log((ratios + 0.1) / (1 - ratios + 0.1)) + data = np.array( [ [1.0, 2, 0, 4, 0], @@ -37,5 +41,5 @@ def test_calculate_ratio(): [0, 5, 0, 5, 0], ] ) - res = ratio.RATIO(genesets, data, genes) + res = bina.BINA(genesets, data, genes) assert np.array_equal(expected, res) diff --git a/test/test_metrics/test_jasmine.py b/test/test_metrics/test_jasmine.py index fc7eec9..0a1b2a8 100644 --- a/test/test_metrics/test_jasmine.py +++ b/test/test_metrics/test_jasmine.py @@ -1,6 +1,7 @@ import numpy as np +import pytest -from enrichment_auc.metrics import jasmine +from pyfuncella.metrics import jasmine def test_ranks(): @@ -51,7 +52,7 @@ def test_full_jasmine(): [[0.1, 0.7, 0.9], [0.8, 0.6, 0.2], [0.0, 0.3, 0.5], [0.7, 0.0, 0.1]] ) res_expected = np.array([[1.0 / 3, 1, 0.0], [1, 0, 3.0 / 8]]) - jasmine_ = jasmine.JASMINE(genesets, data, genes) + jasmine_ = jasmine.JASMINE(genesets, data, genes, use_effect_size=False) assert np.isclose(res_expected, jasmine_, atol=10e-4).all() @@ -62,7 +63,7 @@ def test_full_jasmine_ties(): [[0.1, 0.7, 0.9], [0.8, 0.6, 0.2], [0.0, 0.3, 0.5], [0.1, 0.0, 0.1]] ) res_expected = np.array([[1.0 / 3, 1, 0.0], [1, 0, 1.0 / 2]]) - jasmine_ = jasmine.JASMINE(genesets, data, genes) + jasmine_ = jasmine.JASMINE(genesets, data, genes, use_effect_size=False) assert np.isclose(res_expected, jasmine_, atol=10e-4).all() @@ -73,5 +74,117 @@ def test_jasmine_is_0_robust(): [[0.1, 0.7, 0.0], [0.8, 0.6, 0.0], [0.0, 0.3, 0.0], [0.7, 0.0, 0.0]] ) res_expected = np.array([[0.8, 1.0, 0.0], [1.0, 0, 0.0]]) - jasmine_ = jasmine.JASMINE(genesets, data, genes) + jasmine_ = jasmine.JASMINE(genesets, data, genes, use_effect_size=False) assert np.isclose(res_expected, jasmine_, atol=10e-4).all() + + +def test_scale_minmax(): + """Test min-max normalization function""" + x = np.array([1, 2, 3, 4, 5]) + expected = np.array([0.0, 0.25, 0.5, 0.75, 1.0]) + result = jasmine.scale_minmax(x) + assert np.allclose(result, expected) + + # Test with constant values + x_constant = np.array([2, 2, 2, 2]) + result_constant = jasmine.scale_minmax(x_constant) + assert np.allclose(result_constant, np.zeros(4)) + + +def test_calc_odds_ratio(): + """Test odds ratio calculation""" + genes = ["a", "b", "c", "d"] + geneset_genes = ["a", "b"] + data = np.array([[1, 0, 1], [1, 1, 0], [0, 1, 1], [1, 0, 0]]) + + result = jasmine.calc_odds_ratio(data, geneset_genes, genes) + assert len(result) == 3 # Should have one value per sample + assert all(result >= 0) # Odds ratios should be non-negative + + +def test_calc_likelihood(): + """Test likelihood ratio calculation""" + genes = ["a", "b", "c", "d"] + geneset_genes = ["a", "b"] + data = np.array([[1, 0, 1], [1, 1, 0], [0, 1, 1], [1, 0, 0]]) + + result = jasmine.calc_likelihood(data, geneset_genes, genes) + assert len(result) == 3 # Should have one value per sample + assert all(result >= 0) # Likelihood ratios should be non-negative + + +def test_jasmine_with_effect_size(): + """Test JASMINE method with effect size""" + genes = ["a", "b", "c", "d"] + genesets = {"geneset": ["a", "b", "d"], "geneset1": ["d"]} + data = np.array( + [[0.1, 0.7, 0.9], [0.8, 0.6, 0.2], [0.0, 0.3, 0.5], [0.7, 0.0, 0.1]] + ) + + # Test with odds ratio + jasmine_odds = jasmine.JASMINE( + genesets, data, genes, use_effect_size=True, effect_size="oddsratio" + ) + assert jasmine_odds.shape == (2, 3) + assert np.all(jasmine_odds >= 0) + + # Test with likelihood + jasmine_likelihood = jasmine.JASMINE( + genesets, data, genes, use_effect_size=True, effect_size="likelihood" + ) + assert jasmine_likelihood.shape == (2, 3) + assert np.all(jasmine_likelihood >= 0) + + +def test_jasmine_backward_compatibility(): + """Test that original method still works as before""" + genes = ["a", "b", "c", "d"] + genesets = {"geneset": ["a", "b", "d"], "geneset1": ["d"]} + data = np.array( + [[0.1, 0.7, 0.9], [0.8, 0.6, 0.2], [0.0, 0.3, 0.5], [0.7, 0.0, 0.1]] + ) + + # Test original method (explicitly set to False) + jasmine_original = jasmine.JASMINE(genesets, data, genes, use_effect_size=False) + + # Test with effect size (default behavior) + jasmine_enhanced = jasmine.JASMINE(genesets, data, genes) + + # They should have same shape but potentially different values + assert jasmine_original.shape == jasmine_enhanced.shape + + +def test_jasmine_edge_cases(): + """Test edge cases for JASMINE function""" + genes = ["a", "b", "c", "d"] + genesets = {"empty_geneset": []} + data = np.array( + [[0.1, 0.7, 0.9], [0.8, 0.6, 0.2], [0.0, 0.3, 0.5], [0.7, 0.0, 0.1]] + ) + + # Test with empty geneset + jasmine_empty = jasmine.JASMINE(genesets, data, genes, use_effect_size=True) + assert jasmine_empty.shape == (1, 3) + + # Test with non-existent genes in geneset + genesets_missing = {"geneset": ["x", "y", "z"]} + jasmine_missing = jasmine.JASMINE( + genesets_missing, data, genes, use_effect_size=True + ) + assert jasmine_missing.shape == (1, 3) + + +def test_jasmine_parameter_validation(): + """Test that invalid parameters work as expected""" + genes = ["a", "b", "c", "d"] + genesets = {"geneset": ["a", "b", "d"]} + data = np.array( + [[0.1, 0.7, 0.9], [0.8, 0.6, 0.2], [0.0, 0.3, 0.5], [0.7, 0.0, 0.1]] + ) + + # Test invalid effect_size (should default to zeros) + jasmine_invalid = jasmine.JASMINE( + genesets, data, genes, use_effect_size=True, effect_size="invalid_effect" + ) + assert jasmine_invalid.shape == (1, 3) + # Should still work, just use zeros for effect size diff --git a/test/test_metrics/vae_correct_test.py b/test/test_metrics/vae_correct_test.py deleted file mode 100644 index 56bbde1..0000000 --- a/test/test_metrics/vae_correct_test.py +++ /dev/null @@ -1,64 +0,0 @@ -import numpy as np - -import enrichment_auc.metrics.vae as vae - - -def test_find_most_enriched(): - genes = ["a", "b", "c", "d", "e"] - genesets = {"geneset": ["a", "b", "e", "f"], "geneset1": ["a", "b", "c"]} - - expected = np.array([3, 3]) - data = np.array( - [ - [1.0, 2, 0, 4, 0], - [6, 0, 6, 2, 0], - [0.0, 7, 3, 6, 0], - [0, 9, 9, 0, 0], - [0, 5, 0, 5, 0], - ] - ) - res = vae.find_most_enriched(genesets, data, genes) - assert np.array_equal(expected, res) - - -def test_leaves_correct_order(): - enriched_idx = 3 - expected = np.array([7.0 / 3, 7.0 / 3, 6.0 / 3, 11.0 / 3, 0.0]) - res = vae.correct_pas(expected, enriched_idx) - assert np.array_equal(expected, res) - - -def test_reverts_order(): - enriched_idx = 4 - pas = np.array([7.0 / 3, 7.0 / 3, 6.0 / 3, 11.0 / 3, 0.0]) - expected = np.array([-7.0 / 3, -7.0 / 3, -6.0 / 3, -11.0 / 3, 0.0]) - res = vae.correct_pas(pas, enriched_idx) - assert np.array_equal(expected, res) - - -def test_corrects_order(): - genes = ["a", "b", "c", "d", "e"] - genesets = {"geneset": ["a", "b", "e", "f"], "geneset1": ["a", "b", "c"]} - data = np.array( - [ - [1.0, 2, 0, 4, 0], - [6, 0, 6, 2, 0], - [0.0, 7, 3, 6, 0], - [0, 9, 9, 0, 0], - [0, 5, 0, 5, 0], - ] - ) - pas = np.array( - [ - [7.0 / 3, 7.0 / 3, 6.0 / 3, 11.0 / 3, 0.0], - [7.0 / 3, 7.0 / 3, 9.0 / 3, -1.0 / 3, 11.0], - ] - ) - expected = np.array( - [ - [7.0 / 3, 7.0 / 3, 6.0 / 3, 11.0 / 3, 0.0], - [-7.0 / 3, -7.0 / 3, -9.0 / 3, 1.0 / 3, -11.0], - ] - ) - res = vae.correct_order(data, genesets, genes, pas) - assert np.array_equal(expected, res) diff --git a/test/test_metrics/vae_test.py b/test/test_metrics/vae_test.py deleted file mode 100644 index ddbc2d9..0000000 --- a/test/test_metrics/vae_test.py +++ /dev/null @@ -1,137 +0,0 @@ -import io - -import pickle -import numpy as np -from sklearn.base import clone -from sklearn.datasets import make_blobs - -from enrichment_auc.metrics.vae import VAE - - -def dataset(): - """ - prepare exemplary test data - """ - data = make_blobs(n_samples=10000, n_features=20, centers=2, random_state=42)[0] - data = data - np.min(data) - return data - - -def test_VAE_compresses_data(): - data = dataset() - vae = VAE( - intermediate_dim=2, - latent_dim=5, - epochs=2, - learning_rate=1e-6, - normalize=True, - random_state=42, - verbose=0, - ) - vae.fit(data) - encoded = vae.transform(data) - assert encoded.shape == (10000, 5) - - -def test_VAE_reconstructs_data_shape(): - data = dataset() - vae = VAE( - intermediate_dim=2, - latent_dim=5, - epochs=2, - learning_rate=1e-6, - normalize=True, - random_state=42, - verbose=0, - ) - vae.fit(data) - recon = vae.vae_.predict(data) - assert recon.shape == (10000, 20) - - -def test_VAE_yields_stable_results_without_training(): - data = dataset() - vae1 = VAE( - intermediate_dim=2, - latent_dim=5, - epochs=0, - learning_rate=1e-6, - normalize=True, - random_state=42, - verbose=0, - ) - vae1.fit(data) - embed1 = vae1.transform(data) - recon1 = vae1.vae_.predict(data) - - vae2 = VAE( - intermediate_dim=2, - latent_dim=5, - epochs=0, - learning_rate=1e-6, - normalize=True, - random_state=42, - verbose=0, - ) - vae2.fit(data) - embed2 = vae2.transform(data) - recon2 = vae2.vae_.predict(data) - - np.testing.assert_array_equal(embed1, embed2) - np.testing.assert_array_equal(recon1, recon2) - - -def test_VAE_yields_stable_results_with_training(): - data = dataset() - vae1 = VAE( - intermediate_dim=2, - latent_dim=5, - epochs=2, - learning_rate=1e-6, - normalize=True, - random_state=42, - verbose=0, - ) - vae1.fit(data) - embed1 = vae1.transform(data) - recon1 = vae1.vae_.predict(data) - - vae2 = VAE( - intermediate_dim=2, - latent_dim=5, - epochs=2, - learning_rate=1e-6, - normalize=True, - random_state=42, - verbose=0, - ) - vae2.fit(data) - embed2 = vae2.transform(data) - recon2 = vae2.vae_.predict(data) - - np.testing.assert_array_equal(embed1, embed2) - np.testing.assert_array_equal(recon1, recon2) - - -def test_VAE_is_clonable(): - data = dataset() - vae1 = VAE( - intermediate_dim=2, - latent_dim=5, - epochs=2, - learning_rate=1e-6, - normalize=True, - random_state=42, - verbose=0, - ) - vae1.fit(data) - embed1 = vae1.transform(data) - recon1 = vae1.vae_.predict(data) - - vae2 = clone(vae1) - vae2.fit(data) - embed2 = vae2.transform(data) - recon2 = vae2.vae_.predict(data) - - np.testing.assert_array_equal(embed1, embed2) - np.testing.assert_array_equal(recon1, recon2) diff --git a/test/test_metrics/vision_test.py b/test/test_metrics/vision_test.py index 3a873bf..46b058b 100644 --- a/test/test_metrics/vision_test.py +++ b/test/test_metrics/vision_test.py @@ -1,7 +1,7 @@ import numpy as np import pytest -import enrichment_auc.metrics.vision as vision +import pyfuncella.metrics.vision as vision def test_gs_generator_raises_exception(): diff --git a/test/test_preprocess/test_clean_geneset.py b/test/test_preprocess/test_clean_geneset.py index 7efbae6..b1fb397 100644 --- a/test/test_preprocess/test_clean_geneset.py +++ b/test/test_preprocess/test_clean_geneset.py @@ -1,4 +1,4 @@ -from enrichment_auc.preprocess.clean_geneset import remove_redundant_genesets +from pyfuncella.preprocess.clean_geneset import remove_redundant_genesets def test_remove_geneset(): diff --git a/test/test_preprocess/test_entrez2genes.py b/test/test_preprocess/test_entrez2genes.py index 8a1a3fe..549106d 100644 --- a/test/test_preprocess/test_entrez2genes.py +++ b/test/test_preprocess/test_entrez2genes.py @@ -2,7 +2,7 @@ import pandas as pd import pytest -from enrichment_auc.preprocess import entrez2genes +from pyfuncella.preprocess import entrez2genes def test_drops_nan_genes(): diff --git a/test/test_preprocess/test_filter.py b/test/test_preprocess/test_filter.py index 75df567..7a6ed90 100644 --- a/test/test_preprocess/test_filter.py +++ b/test/test_preprocess/test_filter.py @@ -1,7 +1,7 @@ import numpy as np import pandas as pd -from enrichment_auc.preprocess import filter +from pyfuncella.preprocess import filter def test_thresholds_on_1(): @@ -46,3 +46,80 @@ def test_filters_out(): expected = pd.DataFrame(data=d1, index=[0, 2, 3]) filtered = filter.filter(cells, 0.75) assert filtered.equals(expected) + + +def test_filter_size(): + # Test pathway size filtering + genesets = { + "small": ["gene1", "gene2"], # size 2 + "medium": ["gene1", "gene2", "gene3", "gene4", "gene5"], # size 5 + "large": [ + "gene1", + "gene2", + "gene3", + "gene4", + "gene5", + "gene6", + "gene7", + "gene8", + ], # size 8 + } + + # Filter with min_size=3, max_size=6 + filtered = filter.filter_size(genesets, min_size=3, max_size=6) + + # Should only keep "medium" pathway + assert len(filtered) == 1 + assert "medium" in filtered + assert "small" not in filtered + assert "large" not in filtered + + +def test_filter_coverage(): + # Test pathway coverage filtering + genesets = { + "high_coverage": ["gene1", "gene2", "gene3"], # 3/3 = 100% coverage + "medium_coverage": ["gene1", "gene2", "missing1"], # 2/3 = 67% coverage + "low_coverage": ["missing1", "missing2", "gene1"], # 1/3 = 33% coverage + } + genes = ["gene1", "gene2", "gene3", "gene4"] # Available genes + + # Filter with min_coverage=0.5 (50%) + filtered = filter.filter_coverage(genesets, genes, min_coverage=0.5) + + # Should keep pathways with >= 50% coverage + assert len(filtered) == 2 + assert "high_coverage" in filtered + assert "medium_coverage" in filtered + assert "low_coverage" not in filtered + + +def test_filter_coverage_zero_threshold(): + # Test that zero coverage threshold returns all pathways + genesets = { + "pathway1": ["gene1", "missing1"], + "pathway2": ["missing1", "missing2"], + } + genes = ["gene1", "gene2"] + + filtered = filter.filter_coverage(genesets, genes, min_coverage=0.0) + + # Should return all pathways when threshold is 0 + assert len(filtered) == len(genesets) + assert filtered == genesets + + +def test_filter_size_edge_cases(): + # Test edge cases for size filtering + genesets = { + "exactly_min": ["gene1", "gene2", "gene3"], # size 3 + "exactly_max": ["gene1", "gene2", "gene3", "gene4", "gene5"], # size 5 + } + + # Filter with min_size=3, max_size=5 (inclusive) + filtered = filter.filter_size(genesets, min_size=3, max_size=5) + + # Should keep both pathways (inclusive boundaries) + assert len(filtered) == 2 + assert "exactly_min" in filtered + assert "exactly_max" in filtered diff --git a/test/test_thr_AUCell.py b/test/test_thr_AUCell.py new file mode 100644 index 0000000..0e89cdf --- /dev/null +++ b/test/test_thr_AUCell.py @@ -0,0 +1,72 @@ +import numpy as np +import pandas as pd +import pytest + +from pyfuncella.thr_AUCell import thr_AUCell, _check_aucell_installed +from pyfuncella.utils.r_executor import check_r_available + + +class TestThrAUCell: + """Test class for thr_AUCell functionality.""" + + def test_r_available(self): + """Test that R is available through process-based execution.""" + assert check_r_available(), "R is not available. Please install R to run tests." + + def test_aucell_installed(self): + """Test that AUCell package is installed in R.""" + assert _check_aucell_installed(), "AUCell R package is not installed" + + def test_thr_AUCell_numpy(self): + np.random.seed(42) + # Unimodal (normal), bimodal (mixture), and reversed + unimodal = np.random.normal(0.5, 0.1, 20) + bimodal = np.concatenate( + [np.random.normal(0.2, 0.05, 10), np.random.normal(0.8, 0.05, 10)] + ) + reversed = unimodal[::-1] + arr = np.stack([unimodal, bimodal, reversed]) + pathway_names = ["unimodal", "bimodal", "reversed"] + thresholds = thr_AUCell(arr, pathway_names=pathway_names) + assert isinstance(thresholds, dict) + assert set(thresholds.keys()) == set(pathway_names) + for k, v in thresholds.items(): + assert isinstance(v, float), f"Threshold for {k} should be float" + idx = pathway_names.index(k) + min_val, max_val = arr[idx].min(), arr[idx].max() + # Threshold can be outside min/max, so just check it's finite + assert np.isfinite(v), f"Threshold for {k} should be finite" + + def test_thr_AUCell_dataframe(self): + np.random.seed(123) + # Unimodal, bimodal, constant + unimodal = np.random.normal(0.5, 0.1, 10) + bimodal = np.concatenate( + [np.random.normal(0.2, 0.05, 5), np.random.normal(0.8, 0.05, 5)] + ) + constant = np.full(10, 0.7) + df = pd.DataFrame( + [unimodal, bimodal, constant], + index=["unimodal", "bimodal", "constant"], + columns=[f"sample{i}" for i in range(10)], + ) + thresholds = thr_AUCell(df) + assert isinstance(thresholds, dict) + assert set(thresholds.keys()) == set(df.index) + for k, v in thresholds.items(): + assert isinstance(v, float), f"Threshold for {k} should be float" + # Threshold can be outside min/max, so just check it's finite + assert np.isfinite(v), f"Threshold for {k} should be finite" + + def test_thr_AUCell_value_validation(self): + np.random.seed(321) + # Small range, large range, negative values + small_range = np.random.normal(0.5, 0.001, 10) + large_range = np.concatenate([np.full(5, -100), np.full(5, 100)]) + negative = np.random.normal(-1, 0.1, 10) + arr = np.stack([small_range, large_range, negative]) + pathway_names = ["small_range", "large_range", "negative"] + thresholds = thr_AUCell(arr, pathway_names=pathway_names) + for k, v in thresholds.items(): + assert isinstance(v, float) + assert np.isfinite(v), f"Threshold for {k} should be finite" diff --git a/test/test_thr_GMM.py b/test/test_thr_GMM.py new file mode 100644 index 0000000..20210ff --- /dev/null +++ b/test/test_thr_GMM.py @@ -0,0 +1,76 @@ +import numpy as np + +from pyfuncella.thr_GMM import thr_GMM + + +def test_thr_GMM_basic(): + gmms = { + "pathway1": { + "thresholds": np.array([1.0, 2.0, np.nan, 3.0]), + "model": { + "mu": np.array([0.5, 1.5, 2.5, 3.5, 4.5]), + "sigma": np.array([0.1, 0.2, 0.3, 0.4, 0.5]), + "alpha": np.array([0.2, 0.2, 0.2, 0.2, 0.2]), + }, + }, + "pathway2": { + "thresholds": np.array([np.nan]), + "model": { + "mu": np.array([1.0, 2.0]), + "sigma": np.array([0.1, 0.2]), + "alpha": np.array([0.5, 0.5]), + }, + }, + "pathway3": { + "thresholds": np.array([1.5]), + "model": { + "mu": np.array([1.0, 2.0]), + "sigma": np.array([0.1, 0.2]), + "alpha": np.array([0.5, 0.5]), + }, + }, + "pathway4": { + "thresholds": np.array([]), + "model": { + "mu": np.array([1.0]), + "sigma": np.array([0.1]), + "alpha": np.array([1.0]), + }, + }, + } + result = thr_GMM(gmms) + # pathway1: thresholds after nan removal [1.0, 2.0, 3.0], Top1_thr=3.0, All_thr=[1.0,2.0,3.0] + assert result["pathway1"]["Top1_thr"] == 3.0 + assert result["pathway1"]["All_thr"] == [1.0, 2.0, 3.0] + assert isinstance(result["pathway1"]["Kmeans_thr"], float) + # pathway2: thresholds after nan removal [], Top1_thr=nan, All_thr=[] + assert np.isnan(result["pathway2"]["Top1_thr"]) + assert result["pathway2"]["All_thr"] == [] + assert result["pathway2"]["Kmeans_thr"] == float("-inf") + # pathway3: thresholds [1.5], Top1_thr=1.5, All_thr=[1.5], Kmeans_thr=1.5 (2 components) + assert result["pathway3"]["Top1_thr"] == 1.5 + assert result["pathway3"]["All_thr"] == [1.5] + assert result["pathway3"]["Kmeans_thr"] == 1.5 + # pathway4: no thresholds, Top1_thr=nan, All_thr=[], Kmeans_thr=-inf + assert np.isnan(result["pathway4"]["Top1_thr"]) + assert result["pathway4"]["All_thr"] == [] + assert result["pathway4"]["Kmeans_thr"] == float("-inf") + + +def test_thr_GMM_edge_cases(): + # thresholds off by one from components + gmms = { + "p": { + "thresholds": np.array([1.0, 2.0]), + "model": { + "mu": np.array([1.0, 2.0, 3.0, 4.0]), + "sigma": np.array([0.1, 0.2, 0.3, 0.4]), + "alpha": np.array([0.25, 0.25, 0.25, 0.25]), + }, + } + } + result = thr_GMM(gmms) + # Should fallback to Top1_thr + assert result["p"]["Kmeans_thr"] == result["p"]["Top1_thr"] + assert result["p"]["All_thr"] == [1.0, 2.0] + assert result["p"]["Top1_thr"] == 2.0