Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
38dbfec
Add Shiny dependencies to Suggests for unified visualization app
psychemistz Mar 28, 2026
314bd33
Add shared Shiny app helpers (utils_viz.R)
psychemistz Mar 28, 2026
9251d7b
Add global.R app config with dependency checks
psychemistz Mar 28, 2026
0d8d85f
Add spatial visualization Shiny module (mod_spatial.R)
psychemistz Mar 28, 2026
1692b12
Add app.R entry point for unified SecAct Shiny app
psychemistz Mar 28, 2026
c748257
Add runSecActApp() launcher function
psychemistz Mar 28, 2026
b69e80c
Add README for unified SecAct Shiny app
psychemistz Mar 28, 2026
bcc1310
Add Visium support: Space Ranger loading, SecAct inference, demo dataset
psychemistz Mar 28, 2026
8e8edbe
Fix review issues: temp cleanup, missing return, extract swap helper
psychemistz Mar 28, 2026
88aa026
Add inference tab: upload expression data and run SecAct analysis
psychemistz Mar 28, 2026
9317589
Add CosMx and Xenium upload tabs to spatial module
psychemistz Mar 29, 2026
1345e16
Add single-cell tab with SC inference and activity visualization
psychemistz Mar 29, 2026
2e75c9d
Extract extract_platform_zip() helper, deduplicate 3 zip handlers
psychemistz Mar 29, 2026
c96fdab
Add Bulk tab with activity change and cohort survival workflows
psychemistz Mar 29, 2026
5cda006
Fix bugs and reduce technical debt across package
psychemistz Mar 28, 2026
3699a5d
Simplify: add input guard, fix naming, pre-allocate vectors
psychemistz Mar 28, 2026
9168319
Fix remaining bugs and remove unused imports
psychemistz Mar 28, 2026
806be60
Add drop=FALSE to signaling.pattern.gene subsetting
psychemistz Mar 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
.Rhistory
.RData
.Ruserdata
.DS_Store
src/*.o
src/*.so
16 changes: 13 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,27 @@ Imports:
Matrix,
ggplot2,
reshape2,
patchwork,
NMF,
akima,
gganimate,
metap,
circlize,
ggalluvial,
networkD3,
survival,
survminer,
parallel,
ComplexHeatmap
ComplexHeatmap,
RANN
Suggests:
shiny,
shinyWidgets,
bslib,
DT,
SeuratObject,
SeuratDisk,
png,
base64enc,
shinyjs,
shinyFeedback
biocViews:
ComplexHeatmap
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Generated by roxygen2: do not edit by hand

import(ggplot2)
importFrom(ggalluvial,geom_alluvium)
importFrom(ggalluvial,geom_stratum)
importFrom(ggalluvial,to_lodes_form)

export(SecAct.CCC.circle)
export(SecAct.CCC.dot)
export(SecAct.CCC.heatmap)
Expand All @@ -20,4 +25,5 @@ export(SecAct.signaling.pattern.gene)
export(SecAct.signaling.velocity.scST)
export(SecAct.signaling.velocity.spotST)
export(SecAct.survival.plot)
export(runSecActApp)
useDynLib(SecAct, .registration=TRUE)
Binary file removed R/.DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions R/SecAct-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
## usethis namespace: start
## usethis namespace: end

#' @import ggplot2
#' @importFrom ggalluvial geom_alluvium geom_stratum to_lodes_form
#' @useDynLib SecAct, .registration=TRUE

NULL
111 changes: 23 additions & 88 deletions R/activity.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,10 @@
#'
SecAct.inference.gsl <- function(Y, SigMat="SecAct", lambda=5e+05, nrand=1000)
{
if(SigMat=="SecAct")
{
Xfile<- file.path(system.file(package = "SecAct"), "extdata/SecAct.tsv.gz")
X <- read.table(Xfile,sep="\t",check.names=F)
}else{
X <- read.table(SigMat,sep="\t",check.names=F)
}
sig <- load_sig_matrix(SigMat, lambda)
X <- sig$X

olp <- intersect(row.names(Y),row.names(X))
olp <- intersect(rownames(Y),rownames(X))
X <- as.matrix(X[olp,,drop=F])
Y <- as.matrix(Y[olp,,drop=F])

Expand All @@ -50,14 +45,7 @@ SecAct.inference.gsl <- function(Y, SigMat="SecAct", lambda=5e+05, nrand=1000)
pvalue=double(p*m)
)

beta <- matrix(res$beta,byrow=T,ncol=m,dimnames=list(colnames(X),colnames(Y)))
se <- matrix(res$se,byrow=T,ncol=m,dimnames=list(colnames(X),colnames(Y)))
zscore <- matrix(res$zscore,byrow=T,ncol=m,dimnames=list(colnames(X),colnames(Y)))
pvalue <- matrix(res$pvalue,byrow=T,ncol=m,dimnames=list(colnames(X),colnames(Y)))

res <- list(beta=beta, se=se, zscore=zscore, pvalue=pvalue)

res
unpack_ridge_results(res, m, colnames(X), colnames(Y))
}

#' @title Secreted protein activity inference
Expand All @@ -79,15 +67,10 @@ SecAct.inference.gsl <- function(Y, SigMat="SecAct", lambda=5e+05, nrand=1000)
#'
SecAct.inference.r <- function(Y, SigMat="SecAct", lambda=5e+05, nrand=1000)
{
if(SigMat=="SecAct")
{
Xfile<- file.path(system.file(package = "SecAct"), "extdata/SecAct.tsv.gz")
X <- read.table(Xfile,sep="\t",check.names=F)
}else{
X <- read.table(SigMat,sep="\t",check.names=F)
}
sig <- load_sig_matrix(SigMat, lambda)
X <- sig$X

olp <- intersect(row.names(Y),row.names(X))
olp <- intersect(rownames(Y),rownames(X))
X <- as.matrix(X[olp,,drop=F])
Y <- as.matrix(Y[olp,,drop=F])

Expand Down Expand Up @@ -193,11 +176,11 @@ SecAct.activity.inference <- function(
nrand=1000
)
{
if(class(inputProfile)[1]=="SpaCET")
if(inherits(inputProfile, "SpaCET"))
{
stop("Please use 'SecAct.activity.inference.ST'.")
}
if(class(inputProfile)[1]=="Seurat")
if(inherits(inputProfile, "Seurat"))
{
stop("Please use 'SecAct.activity.inference.scRNAseq'.")
}
Expand Down Expand Up @@ -229,29 +212,13 @@ SecAct.activity.inference <- function(
}
}

if(sigMatrix=="SecAct")
{
Xfile <- file.path(system.file(package = "SecAct"), "extdata/SecAct.tsv.gz")
X <- read.table(Xfile,sep="\t",check.names=F)
if(is.null(lambda)) lambda <- 5e+05

}else if(grepl("SecAct-",sigMatrix,fixed=TRUE)){
Xfile <- paste0("https://hpc.nih.gov/~Jiang_Lab/SecAct_Package/",sigMatrix,"_filterByPan_ds3_vst.tsv")
X <- read.table(Xfile,sep="\t",check.names=F)
if(is.null(lambda)) lambda <- 5e+05

}else if(sigMatrix=="CytoSig"){
Xfile <- "https://raw.githubusercontent.com/data2intelligence/CytoSig/refs/heads/master/CytoSig/signature.centroid"
X <- read.table(Xfile,sep="\t",check.names=F)
if(is.null(lambda)) lambda <- 10000

}else{
X <- read.table(sigMatrix,sep="\t",check.names=F)
}
sig <- load_sig_matrix(sigMatrix, lambda)
X <- sig$X
lambda <- sig$lambda

if(is.filter.sig==TRUE)
{
X <- X[,colnames(X)%in%row.names(Y)]
X <- X[,colnames(X)%in%rownames(Y)]
}

if(is.group.sig==TRUE)
Expand All @@ -272,7 +239,7 @@ SecAct.activity.inference <- function(
X <- newsig
}

olp <- intersect(row.names(Y),row.names(X))
olp <- intersect(rownames(Y),rownames(X))

if(length(olp)<2) stop("The overlapped genes between your expression matrix and our signature matrix are too few!")

Expand Down Expand Up @@ -300,26 +267,15 @@ SecAct.activity.inference <- function(
pvalue=double(p*m)
)

beta <- matrix(res$beta,byrow=T,ncol=m,dimnames=list(colnames(X),colnames(Y)))
se <- matrix(res$se,byrow=T,ncol=m,dimnames=list(colnames(X),colnames(Y)))
zscore <- matrix(res$zscore,byrow=T,ncol=m,dimnames=list(colnames(X),colnames(Y)))
pvalue <- matrix(res$pvalue,byrow=T,ncol=m,dimnames=list(colnames(X),colnames(Y)))
res <- unpack_ridge_results(res, m, colnames(X), colnames(Y))

if(is.group.sig==TRUE)
{
beta <- expand_rows(beta)
se <- expand_rows(se)
zscore <- expand_rows(zscore)
pvalue <- expand_rows(pvalue)

beta <- beta[sort(rownames(beta)),,drop=F]
se <- se[sort(rownames(beta)),,drop=F]
zscore <- zscore[sort(rownames(beta)),,drop=F]
pvalue <- pvalue[sort(rownames(beta)),,drop=F]
for(nm in names(res)) res[[nm]] <- expand_rows(res[[nm]])
idx <- sort(rownames(res$beta))
for(nm in names(res)) res[[nm]] <- res[[nm]][idx,,drop=F]
}

res <- list(beta=beta, se=se, zscore=zscore, pvalue=pvalue)

res
}

Expand Down Expand Up @@ -351,7 +307,7 @@ SecAct.activity.inference.ST <- function(
nrand=1000
)
{
if(!class(inputProfile)[1]=="SpaCET")
if(!inherits(inputProfile, "SpaCET"))
{
stop("Please input a SpaCET object.")
}
Expand All @@ -362,33 +318,19 @@ SecAct.activity.inference.ST <- function(
rownames(expr) <- transferSymbol(rownames(expr))
expr <- rm_duplicates(expr)

# normalize to TPM
stats <- Matrix::colSums(expr)
expr <- sweep_sparse(expr,2,stats,"/")
expr@x <- expr@x * scale.factor

# transform to log space
expr@x <- log2(expr@x + 1)
expr <- normalize_log_sparse(expr, scale.factor)

if(is.null(inputProfile_control))
{
# normalized with the control samples
expr.diff <- expr - Matrix::rowMeans(expr)

}else{
# extract count matrix
expr_control <- inputProfile_control@input$counts
expr_control <- expr_control[Matrix::rowSums(expr_control)>0,]
rownames(expr_control) <- transferSymbol(rownames(expr_control))
expr_control <- rm_duplicates(expr_control)

# normalize to TPM
stats <- Matrix::colSums(expr_control)
expr_control <- sweep_sparse(expr_control,2,stats,"/")
expr_control@x <- expr_control@x * scale.factor

# transform to log space
expr_control@x <- log2(expr_control@x + 1)
expr_control <- normalize_log_sparse(expr_control, scale.factor)

olp <- intersect(rownames(expr), rownames(expr_control))
expr.diff <- expr[olp,] - Matrix::rowMeans(expr_control[olp,])
Expand Down Expand Up @@ -438,19 +380,12 @@ SecAct.activity.inference.scRNAseq <- function(
nrand=1000
)
{
if(!class(inputProfile)[1]=="Seurat")
if(!inherits(inputProfile, "Seurat"))
{
stop("Please input a Seurat object.")
}

if(class(inputProfile@assays$RNA)=="Assay5")
{
counts <- inputProfile@assays$RNA@layers$counts
colnames(counts) <- rownames(inputProfile@assays$RNA@cells)
rownames(counts) <- rownames(inputProfile@assays$RNA@features)
}else{
counts <- inputProfile@assays$RNA@counts
}
counts <- extract_seurat_counts(inputProfile)

rownames(counts) <- transferSymbol(rownames(counts))
counts <- rm_duplicates(counts)
Expand Down
Loading