diff --git a/DESCRIPTION b/DESCRIPTION
index 4e8f6028..f16be2df 100755
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,7 +1,7 @@
Type: Package
Package: Spectre
Title: High-dimensional cytometry and imaging analysis.
-Version: 1.2.0
+Version: 1.2.0-00
Date: 2023-11-12
Authors@R: c(
person("Thomas", "Ashhurst", , "thomas.ashhurst@sydney.edu.au", role = c("aut", "cre")),
diff --git a/R/do.add.masks.R b/R/do.add.masks.R
index 89d80f11..0f5ea329 100755
--- a/R/do.add.masks.R
+++ b/R/do.add.masks.R
@@ -34,7 +34,7 @@ do.add.masks <- function(dat, # list of spatial objects
require('raster')
require('rhdf5')
- require('HDF5Array')
+ # require('HDF5Array')
###
diff --git a/R/do.calculate.area.R b/R/do.calculate.area.R
index 7665de4a..ad977371 100755
--- a/R/do.calculate.area.R
+++ b/R/do.calculate.area.R
@@ -33,8 +33,17 @@ do.calculate.area <- function(dat,
poly.names <- dat[[i]]@MASKS[[region]]$polygons@data
- areas <- area(dat[[i]]@MASKS[[region]]$polygons)
- areas <- sqrt(areas)
+ # areas <- area(dat[[i]]@MASKS[[region]]$polygons)
+
+ res <- data.table()
+
+ for(i in c(1:length(dat[[i]]@MASKS[[region]]$polygons@polygons))){
+ x <- data.table('ID' = i, 'Area' = dat[[i]]@MASKS[[region]]$polygons@polygons[[i]]@area)
+ res <- rbindlist(list(res, x))
+ rm(x)
+ }
+
+ areas <- sqrt(res[,2])
areas <- as.data.table(t(areas))
names(areas) <- as.character(poly.names[[1]])
diff --git a/R/do.create.outlines.R b/R/do.create.outlines.R
index c025f059..475bc7ec 100755
--- a/R/do.create.outlines.R
+++ b/R/do.create.outlines.R
@@ -17,12 +17,14 @@ do.create.outlines <- function(dat,
#message("This is a developmental Spectre-spatial function that is still in testing phase with limited documentation. We recommend only using this function if you know what you are doing.")
+ require(s2)
+ require(sf)
require(raster)
require(tiff)
- require(rgeos)
require(tidyr)
require(ggplot2)
require(dplyr)
+ require(sp)
# polygons.name <- paste0(mask.name, "_polygons")
# outlines.name <- paste0(mask.name, "_outlines")
@@ -30,8 +32,8 @@ do.create.outlines <- function(dat,
### Initial warning
- os.deets <- devtools::session_info()
- if(grepl('Windows', os.deets$platform$os)){
+ os.deets <- sessionInfo()
+ if(grepl('Windows', os.deets$running)){
message("Warning: the generation of mask outlines may differ between Mac and Windows. See 'https://github.com/ImmuneDynamics/Spectre/issues/56' for more information.")
}
@@ -50,7 +52,7 @@ do.create.outlines <- function(dat,
}
if(method == 'gdal'){
- message("GDAL version not currently supportedb -- reverting to stars method")
+ message("GDAL version not currently supported -- reverting to stars method")
# if(length(Sys.which("gdal_polygonize.py")) > 1){
# message(paste0("Creating polygons, outlines, and centroids using GDAL -- this step may take some time, please be patient"))
# }
@@ -59,7 +61,7 @@ do.create.outlines <- function(dat,
### Run
for(i in names(dat)){
- # i <- names(spatial.dat)[[1]]
+ # i <- names(dat)[[1]]
start.time <- Sys.time()
mask <- dat[[i]]@MASKS[[mask.name]]$maskraster
@@ -78,7 +80,6 @@ do.create.outlines <- function(dat,
require(stars)
require(sf)
- require(sp)
require(s2)
names(mask) <- "TEMP_MASK"
@@ -120,7 +121,8 @@ do.create.outlines <- function(dat,
message(" ... outlines complete")
### Create centroids
- centroids <- gCentroid(polygon,byid=TRUE)
+ centroids <- sp::coordinates(polygon#,byid=TRUE
+ )
dat[[i]]@MASKS[[mask.name]][["centroids"]] <- centroids
message(" ... centroids complete")
}
diff --git a/R/do.extract.R b/R/do.extract.R
index 10faf5b5..c3bdb79e 100755
--- a/R/do.extract.R
+++ b/R/do.extract.R
@@ -17,10 +17,8 @@ do.extract <- function(dat, # spatial.data object
#message("This is a developmental Spectre-spatial function that is still in testing phase with limited documentation. We recommend only using this function if you know what you are doing.")
- require('rgeos')
require('sp')
require('sf')
- require('rgdal')
require('exactextractr')
require('data.table')
@@ -58,12 +56,24 @@ do.extract <- function(dat, # spatial.data object
ply.df <- as.data.frame(roi.poly)
ply.df
- ply.centroids <- gCentroid(roi.poly,byid=TRUE)
+ ply.centroids <- sp::coordinates(roi.poly)
+
ply.centroids.df <- as.data.frame(ply.centroids)
ply.centroids.df # mask number, with X and Y coordinates
- ply.centroids.df <- cbind(ply.centroids.df, as.data.frame(area(roi.poly)))
- names(ply.centroids.df)[3] <- "Area"
+ # ply.centroids.df <- cbind(ply.centroids.df, as.data.frame(area(roi.poly)))
+
+ res <- data.table()
+
+ for(i in c(1:length(roi.poly@polygons))){
+ x <- data.table('ID' = i, 'Area' = roi.poly@polygons[[i]]@area)
+ res <- rbindlist(list(res, x))
+ rm(x)
+ }
+
+ ply.centroids.df <- cbind(ply.centroids.df, res[,2])
+
+ names(ply.centroids.df) <- c("x", "y", "Area")
## RASTERS
diff --git a/R/make.spatial.plot.R b/R/make.spatial.plot.R
index 1916e356..bfc452da 100755
--- a/R/make.spatial.plot.R
+++ b/R/make.spatial.plot.R
@@ -211,11 +211,11 @@ make.spatial.plot <- function(dat, # spatial data object
outline <- dat[[roi]]@MASKS[[mask.outlines]]$outlines
centroids <- dat[[roi]]@MASKS[[mask.outlines]]$centroids
- centroid.xmin <- centroids@bbox[1]
- centroid.xmax <- centroids@bbox[3]
+ centroid.xmin <- min(centroids[,1])
+ centroid.xmax <- max(centroids[,1])
- centroid.ymin <- centroids@bbox[2]
- centroid.ymax <- centroids@bbox[4]
+ centroid.ymin <- min(centroids[,2])
+ centroid.ymax <- max(centroids[,2])
}
## Flip y-axis values
diff --git a/R/package.check.R b/R/package.check.R
index 31c3bde0..f115427d 100755
--- a/R/package.check.R
+++ b/R/package.check.R
@@ -216,11 +216,6 @@ package.check <- function(type = "general"){
message(' -- rhdf5 is required for SPATIAL analysis but is not installed')
res.list[['rhdf5']] <- 'rhdf5'
}
-
- if(!is.element('HDF5Array', installed.packages()[,1])) {
- message(' -- HDF5Array is required for SPATIAL analysis but is not installed')
- res.list[['HDF5Array']] <- 'HDF5Array'
- }
}
diff --git a/R/write.hdf5.R b/R/write.hdf5.R
index 6d84fec7..76e60ffe 100755
--- a/R/write.hdf5.R
+++ b/R/write.hdf5.R
@@ -49,7 +49,7 @@ write.hdf5 <- function(dat, # SpectreMAP object
require('data.table')
require('raster')
require('rhdf5')
- require('HDF5Array')
+ # require('HDF5Array')
### Testing
@@ -326,7 +326,7 @@ write.hdf5 <- function(dat, # SpectreMAP object
if(!is.null(random.crop.x)){
if(!is.null(random.crop.y)){
- if(!paste0(i, "_crop.h5") %in% list.files(getwd())){
+ if(paste0(i, "_crop.h5") %in% list.files(getwd())){
file.remove(paste0(i, "_crop.h5"))
}
@@ -347,7 +347,7 @@ write.hdf5 <- function(dat, # SpectreMAP object
} else {
- if(!paste0(i, ".h5") %in% list.files(getwd())){
+ if(paste0(i, ".h5") %in% list.files(getwd())){
file.remove(paste0(i, ".h5"))
}
diff --git a/README.md b/README.md
index 18dd0f76..f32e1c22 100755
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
A computational toolkit in R for the integration, exploration, and analysis of high-dimensional single-cell cytometry and imaging data.
-
+
-**Current version**: [`v1.2.0`](https://github.com/ImmuneDynamics/Spectre/releases)
+**Current version**: [`v1.2.0-beta`](https://github.com/ImmuneDynamics/Spectre/releases)
[![AppVeyor build status](https://ci.appveyor.com/api/projects/status/akhvb8wub6d6xhtd?svg=true)](https://ci.appveyor.com/project/tomashhurst/spectre)
@@ -12,83 +12,41 @@ A computational toolkit in R for the integration, exploration, and analysis of h
## About
-
-
-Spectre is an R package that enables comprehensive end-to-end integration and analysis of high-dimensional cytometry data from different batches or experiments. Spectre streamlines the analytical stages of raw data pre-processing, batch alignment, data integration, clustering, dimensionality reduction, visualisation and population labelling, as well as quantitative and statistical analysis. To manage large cytometry datasets, Spectre was built on the data.table framework – this simple table-like structure allows for fast and easy processing of large datasets in R. Critically, the design of Spectre allows for a simple, clear, and modular design of analysis workflows, that can be utilised by data and laboratory scientists. Recently we have extended the functionality of Spectre to support the analysis of Imaging Mass Cytometry (IMC) and scRNAseq data. For more information, please see our paper: [Ashhurst TM, Marsh-Wakefield F, Putri GH et al. (2021). Cytometry A. DOI: 10.1002/cyto.a.24350](https://doi.org/10.1002/cyto.a.24350).
+Spectre is an R package that enables comprehensive end-to-end integration and analysis of high-dimensional cytometry data from different batches or experiments. Spectre streamlines the analytical stages of raw data pre-processing, batch alignment, data integration, clustering, dimensionality reduction, visualisation and population labelling, as well as quantitative and statistical analysis. To manage large cytometry datasets, Spectre was built on the data.table framework -- this simple table-like structure allows for fast and easy processing of large datasets in R. Critically, the design of Spectre allows for a simple, clear, and modular design of analysis workflows, that can be utilised by data and laboratory scientists. Recently we have extended the functionality of Spectre to support the analysis of Imaging Mass Cytometry (IMC) and scRNAseq data. For more information, please see our paper: [Ashhurst TM, Marsh-Wakefield F, Putri GH et al. (2021). Cytometry A. DOI: 10.1002/cyto.a.24350](https://doi.org/10.1002/cyto.a.24350).
Spectre was developed by [Thomas Ashhurst](https://immunedynamics.github.io/thomas-ashhurst/), [Felix Marsh-Wakefield](https://immunedynamics.github.io/felix-marsh-wakefield/), and [Givanna Putri](https://immunedynamics.github.io/givanna-putri/).
## Citation
-If you use Spectre in your work, please consider citing [Ashhurst TM, Marsh-Wakefield F, Putri GH et al. (2021). Cytometry A. DOI: 10.1002/cyto.a.24350](https://doi.org/10.1002/cyto.a.24350). To continue providing open-source tools such as Spectre, it helps us if we can demonstrate that our efforts are contributing to analysis efforts in the community. Please also consider citing the authors of the individual packages or tools (e.g. CytoNorm, FlowSOM, tSNE, UMAP, etc) that are critical elements of your analysis work.
-
-
-## Instructions and protocols
-Usage instructions and protocols are available from [https://immunedynamics.github.io/spectre](https://immunedynamics.github.io/spectre).
+If you use Spectre in your work, please consider citing [Ashhurst TM, Marsh-Wakefield F, Putri GH et al. (2022). Cytometry A. DOI: 10.1002/cyto.a.24350](https://doi.org/10.1002/cyto.a.24350). To continue providing open-source tools such as Spectre, it helps us if we can demonstrate that our efforts are contributing to analysis efforts in the community. Please also consider citing the authors of the individual packages or tools (e.g. CytoNorm, FlowSOM, tSNE, UMAP, etc) that are critical elements of your analysis work.
-## Installing Spectre
-
-Detailed installation instructions are available from [https://immunedynamics.github.io/spectre/getting-started](https://immunedynamics.github.io/spectre/getting-started). Spectre can be installed in R directly, or can be used via a pre-compiled Docker image. Brief instructions below.
-
-_**In v1.1 and above we have removed the package dependencies `rgeos` and `rgdal` as these are no longer available on CRAN. The package should install fine without these dependencies, but some spatial functions may not work properly. If required, one can download the archived packages, unzip them, and then placed them in the R library location.**_
-
-
-
-### Option 1: Install Spectre in R
-
-Install and load the 'devtools' library.
+## Getting started
-```
-if(!require('remotes')) {install.packages('remotes')}
-library('remotes')
-```
+### Installation
-Subsequently, use the 'install_github' function to install and load the Spectre package. By default this will load the 'master' branch, which is the same as the latest stable release version (listed at https://github.com/immunedynamics/Spectre/releases). To install a specific release version, see https://cran.r-project.org/web/packages/githubinstall/vignettes/githubinstall.html.
+We recommend using Spectre with [R](https://cran.r-project.org/mirrors.html) and [RStudio](https://www.rstudio.com/products/rstudio/download/#download). Once R and RStudio are installed, run the following to install the Spectre package.
-```
-remotes::install_github(repo = "immunedynamics/spectre")
+```
+if(!require('remotes')) {install.packages('remotes')} # Installs the package 'remotes'
+remotes::install_github(repo = "immunedynamics/spectre") # Install the Spectre package
```
-You will see the following returned. We suggest selecting 'none' (in this example, by entering '3' and pressing return) to avoid updating other packages. You can update your packages after installation.
-```
-Downloading GitHub repo immunedynamics/spectre@master
-These packages have more recent versions available.
-Which would you like to update?
-
- 1: All
- 2: CRAN packages only
- 3: None
- 4: data.table (1.12.0 -> 1.12.2) [CRAN]
- ... etc
- ```
-
-If the package is sucessfully installed, you can load the library using:
-```
-library("Spectre")
-```
+If you are unfamiliar with using R and RStudio, check out our [R and Spectre basics guides](https://immunedynamics.io/spectre/install/#Basics_guide) for assistance. For detailed installation instructions, and instructions for installing Spectre via Docker, see our [installation guide](https://immunedynamics.io/spectre/install/).
-You can then check for whether all of the packages for Spectre have been loaded correctly using the following commands
-```
-## Check if all required packages have been installed
-Spectre::package.check()
-
-## Load all required packages
-Spectre::package.load()
-```
+### New to R or Spectre?
-Alternatively, you can go to releases (https://github.com/immunedynamics/spectre/releases) and download the latest stable release -- which can then be installed in R.
+New users can check out our [basics guides](https://immunedynamics.io/spectre/install/#Basics_guide) to get acquainted with using R and Spectre.
-
+### Workflows and protocols
-### Option 2: Install Spectre using Docker
+When you are ready to start analysis, check out our structured workflows and tutorials on the following pages:
-Install a 'container' version of Spectre using Docker, that contains a pre-built environment with all the required packages necessary to use Spectre. Please see [this page](https://wiki.centenary.org.au/display/SPECTRE/Install+from+Docker) for instructions.
+- Analysis of [high-dimensional cytometry](https://immunedynamics.github.io/spectre/cytometry) data
+- Analysis of [high-dimensional imaging/spatial](https://immunedynamics.github.io/spectre/spatial/) data
+- Analysis of [single-cell genomics](https://immunedynamics.github.io/spectre/single-cell/) data
-
-## Acknowledgements
-The Spectre package was constructed on the basis of the CAPX workflow in R (https://sydneycytometry.org.au/capx). Along with the various R packages used within Spectre, we would like to acknowledge the Seurat and cytofkit R packages from providing inspiration for elements of the package design.
diff --git a/workflows/CellProfiler segmentation/BasicSegmentation_MAC.cpproj b/workflows/CellProfiler segmentation/BasicSegmentation_MAC.cpproj
new file mode 100755
index 00000000..92806064
Binary files /dev/null and b/workflows/CellProfiler segmentation/BasicSegmentation_MAC.cpproj differ
diff --git a/workflows/CellProfiler segmentation/BasicSegmentation_WINDOWS.cpproj b/workflows/CellProfiler segmentation/BasicSegmentation_WINDOWS.cpproj
new file mode 100755
index 00000000..3a9d3e59
Binary files /dev/null and b/workflows/CellProfiler segmentation/BasicSegmentation_WINDOWS.cpproj differ
diff --git a/workflows/Ilastik multicut/Segmentation - process TIFFs.R b/workflows/Ilastik multicut/Segmentation - process TIFFs.R
new file mode 100755
index 00000000..dddc8347
--- /dev/null
+++ b/workflows/Ilastik multicut/Segmentation - process TIFFs.R
@@ -0,0 +1,139 @@
+###################################################################################
+### Segmentation 1 - process TIFFs
+###################################################################################
+
+ ### Load libraries
+
+ library('Spectre')
+
+ ### Extra packages
+
+ if(!require('raster')) {install.packages('raster')}
+ if(!require('tiff')) {install.packages('tiff')}
+ if(!require('rhdf5')) {BiocManager::install("rhdf5")}
+ if(!require('s2')) {install.packages('s2')}
+ if(!require('sf')) {install.packages('sf')}
+ if(!require('stars')) {install.packages('stars')}
+ if(!require('sp')) {install.packages('sp')}
+ if(!require('exactextractr')) {install.packages('exactextractr')}
+ if(!require('qs')) {install.packages('qs')}
+
+ ### Check and load packages
+
+ Spectre::package.check(type = 'spatial')
+ Spectre::package.load(type = 'spatial')
+
+ ### Set PrimaryDirectory
+
+ dirname(rstudioapi::getActiveDocumentContext()$path) # Finds the directory where this script is located
+ setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) # Sets the working directory to where the script is located
+ getwd()
+ PrimaryDirectory <- getwd()
+ PrimaryDirectory
+
+ ### Set InputDirectory
+
+ setwd(PrimaryDirectory)
+ dir.create('ROIs', showWarnings = FALSE)
+ setwd("ROIs/")
+ InputDirectory <- getwd()
+ InputDirectory
+
+ ### Create directory for Ilastik HDF5 files
+
+ setwd(PrimaryDirectory)
+ dir.create("masks")
+ setwd("masks")
+ MaskDirectory <- getwd()
+ MaskDirectory
+
+ ### Create directory for CROPPED Ilastik HDF5 files
+
+ setwd(PrimaryDirectory)
+ dir.create("cropped")
+ setwd("cropped")
+ CroppedDirectory <- getwd()
+ CroppedDirectory
+
+###################################################################################
+### Check ROIs and TIFFs
+###################################################################################
+
+ ### If you need the demo dataset, uncomment the following code (select all, CMD+SHIFT+C) and run to download
+
+ # setwd(PrimaryDirectory)
+ # getwd()
+ # download.file(url = "https://github.com/ImmuneDynamics/data/blob/main/spatialSimple.zip?raw=TRUE", destfile = 'spatialSimple.zip', mode = 'wb')
+ # unzip(zipfile = 'spatialSimple.zip')
+ # for(i in list.files('spatialSimple/data/ROIs/', full.names = TRUE)){
+ # file.rename(from = i, to = gsub('spatialSimple/data/', '', i))
+ # }
+ # unlink(c('spatialSimple/', 'spatialSimple.zip', '__MACOSX'), recursive = TRUE)
+
+ ### Initialise the spatial data object with channel TIFF files
+
+ setwd(InputDirectory)
+
+ rois <- list.dirs(full.names = FALSE, recursive = FALSE)
+ as.matrix(rois)
+
+ ### List of TIFF files
+
+ tiff.list <- list()
+
+ for(i in rois){
+ setwd(InputDirectory)
+ setwd(i)
+ tiff.list[[i]] <- list.files(getwd())
+ }
+
+ t(as.data.frame(tiff.list))
+
+###################################################################################
+### Read in TIFF files and create spatial objects
+###################################################################################
+
+ setwd(InputDirectory)
+
+ spatial.dat <- read.spatial.files(dir = getwd())
+
+ str(spatial.dat, 3)
+ spatial.dat[[1]]@RASTERS
+
+###################################################################################
+### Create HDF5 files for mask creation
+###################################################################################
+
+ nms <- names(spatial.dat[[1]]@RASTERS)
+
+ as.matrix(nms)
+ for.ilastik <- nms[c(1:8)]
+ as.matrix(for.ilastik)
+
+ as.matrix(for.ilastik)
+ merge.channels <- for.ilastik[c(1:6)]
+ as.matrix(merge.channels)
+
+ ## Whole ROIs for Ilastik
+
+ setwd(MaskDirectory)
+ write.hdf5(dat = spatial.dat,
+ channels = for.ilastik,
+ merge.channels = merge.channels,
+ plots = FALSE)
+
+ fwrite(data.table('Channels' = for.ilastik), 'ilastik.channels.csv')
+
+
+ ## Cropped ROIs to train Ilastik
+
+ setwd(CroppedDirectory)
+ write.hdf5(dat = spatial.dat,
+ channels = for.ilastik,
+ merge.channels = merge.channels,
+ random.crop.x = 350,
+ random.crop.y = 300,
+ plots = TRUE)
+
+ fwrite(data.table('Channels' = for.ilastik), 'ilastik.channels.csv')
+
diff --git a/workflows/Ilastik multicut/multicut_1_pixel.ilp b/workflows/Ilastik multicut/multicut_1_pixel.ilp
new file mode 100644
index 00000000..632e7a7f
Binary files /dev/null and b/workflows/Ilastik multicut/multicut_1_pixel.ilp differ
diff --git a/workflows/Ilastik multicut/multicut_2_segment.ilp b/workflows/Ilastik multicut/multicut_2_segment.ilp
new file mode 100644
index 00000000..cdfb4550
Binary files /dev/null and b/workflows/Ilastik multicut/multicut_2_segment.ilp differ
diff --git a/workflows/Ilastik multicut/multicut_3_cellClassification.ilp b/workflows/Ilastik multicut/multicut_3_cellClassification.ilp
new file mode 100644
index 00000000..bdf949ba
Binary files /dev/null and b/workflows/Ilastik multicut/multicut_3_cellClassification.ilp differ
diff --git a/workflows/Ilastik multicut/multicut_4_regionClassification.ilp b/workflows/Ilastik multicut/multicut_4_regionClassification.ilp
new file mode 100644
index 00000000..b82d231d
Binary files /dev/null and b/workflows/Ilastik multicut/multicut_4_regionClassification.ilp differ
diff --git a/workflows/Spectre chronoclust/ChronoClust.R b/workflows/Spectre chronoclust/ChronoClust.R
index 71f8c610..847a717d 100755
--- a/workflows/Spectre chronoclust/ChronoClust.R
+++ b/workflows/Spectre chronoclust/ChronoClust.R
@@ -16,7 +16,24 @@ Spectre::package.load() # If you do not have anaconda installed in your system,
primary.dir <- 'M:/givanna/spectre_paper/WNV CNS timecourse (channel value)/'
+### Set or create 'input' directory
+
+setwd(primary.dir)
+dir.create('../data', showWarnings = FALSE)
+setwd("../data/")
+InputDirectory <- getwd()
+setwd(primary.dir)
+
+### Set or create 'metadata' directory
+
+setwd(primary.dir)
+dir.create('../metadata', showWarnings = FALSE)
+setwd("../metadata/")
+MetaDirectory <- getwd()
+setwd(primary.dir)
+
## Create output directory
+setwd(primary.dir)
output.dir <- paste0(primary.dir, "/Output_Spectre_cc")
dir.create(output.dir, showWarnings = FALSE)
@@ -24,6 +41,21 @@ dir.create(output.dir, showWarnings = FALSE)
#### 2. Read and prepare data
##########################################################################################################
+### If you need the demo dataset, uncomment the following code (select all, CMD+SHIFT+C) and run to download
+
+ # setwd(primary.dir)
+ # setwd("../")
+ # getwd()
+ # download.file(url = "https://github.com/ImmuneDynamics/data/blob/main/timeSeries.zip?raw=TRUE", destfile = 'timeSeries.zip', mode = 'wb')
+ # unzip(zipfile = 'timeSeries.zip')
+ # for(i in list.files('timeSeries/data', full.names = TRUE)){
+ # file.rename(from = i, to = gsub('timeSeries/', '', i))
+ # }
+ # for(i in list.files('timeSeries/metadata', full.names = TRUE)){
+ # file.rename(from = i, to = gsub('timeSeries/', '', i))
+ # }
+ # unlink(c('timeSeries/', 'timeSeries.zip', '__MACOSX'), recursive = TRUE)
+
### Read SAMPLES (data) into workspace and review
## List of CSV files in input directory
diff --git a/workflows/Spectre rPCA/Spectre rPCA.R b/workflows/Spectre rPCA/Spectre rPCA.R
index 6693c801..c75ddb77 100644
--- a/workflows/Spectre rPCA/Spectre rPCA.R
+++ b/workflows/Spectre rPCA/Spectre rPCA.R
@@ -17,7 +17,7 @@
### Example:
- # CNS analysis
+ # BM analysis
# /data
# -- Contains data files, one CSV or FCS per sample
# /metadata
diff --git a/workflows/Spectre spatial (FlowJo)/TIFF to FCS.R b/workflows/Spectre spatial (FlowJo)/TIFF to FCS.R
index e336d903..5d47e13e 100755
--- a/workflows/Spectre spatial (FlowJo)/TIFF to FCS.R
+++ b/workflows/Spectre spatial (FlowJo)/TIFF to FCS.R
@@ -1,15 +1,47 @@
+##########################################################################################################
+#### Create a folder structure for your analysis run
+##########################################################################################################
+
+ ### Create a master folder with a meaningful name. Then inside that folder, insert the following:
+
+ # One folder called 'data' -- this will contain your 'ROIs' folder and 'masks' folder
+ # One folder called 'Spectre FlowJo' or similar -- place analysis scripts there
+
+ ### Example:
+
+ # Spleen analysis
+ # /data
+ # /ROIs -- contains one folder per ROI, filled with TIFF files (one per channel)
+ # /masks -- contains mask files (TIFFs). Can have multiple mask types (e.g. cell mask, region mask)
+ # /Spectre FlowJo
+ # -- TIFF to FCS.R
+
###################################################################################
### Spectre: TIFF to FCS
###################################################################################
-
- ### Load libraries
+
+ ### Load libraries
library('Spectre')
-
+
+ ### Extra packages
+
+ if(!require('raster')) {install.packages('raster')}
+ if(!require('tiff')) {install.packages('tiff')}
+ if(!require('rhdf5')) {BiocManager::install("rhdf5")}
+ if(!require('s2')) {install.packages('s2')}
+ if(!require('sf')) {install.packages('sf')}
+ if(!require('stars')) {install.packages('stars')}
+ if(!require('sp')) {install.packages('sp')}
+ if(!require('exactextractr')) {install.packages('exactextractr')}
+ if(!require('qs')) {install.packages('qs')}
+
+ ### Check and load packages
+
Spectre::package.check(type = 'spatial')
Spectre::package.load(type = 'spatial')
-
- ### Set PrimaryDirectory
+
+ ### Set PrimaryDirectory
dirname(rstudioapi::getActiveDocumentContext()$path) # Finds the directory where this script is located
setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) # Sets the working directory to where the script is located
@@ -17,21 +49,25 @@
PrimaryDirectory <- getwd()
PrimaryDirectory
- ### Set InputDirectory (ROI TIFFs)
+ ### Set InputDirectory (ROI TIFFs)
setwd(PrimaryDirectory)
+ dir.create('../data/', showWarnings = FALSE)
+ dir.create('../data/ROIs/', showWarnings = FALSE)
setwd("../data/ROIs/")
InputDirectory <- getwd()
InputDirectory
- ### Set MaskDirectory (ROI mask TIFFs)
+ ### Set MaskDirectory (ROI mask TIFFs)
setwd(PrimaryDirectory)
+ dir.create('../data/', showWarnings = FALSE)
+ dir.create('../data/masks/', showWarnings = FALSE)
setwd("../data/masks")
MaskDirectory <- getwd()
MaskDirectory
- ### Create output directory
+ ### Create output directory
setwd(PrimaryDirectory)
dir.create("Output - TIFF to FCS")
@@ -43,14 +79,26 @@
### Check ROIs and TIFFs
###################################################################################
- ### Initialise the spatial data object with channel TIFF files
+ ### If you need the demo dataset, uncomment the following code (select all, CMD+SHIFT+C) and run to download
+
+ # setwd(PrimaryDirectory)
+ # setwd("../")
+ # getwd()
+ # download.file(url = "https://github.com/ImmuneDynamics/data/blob/main/spatialFlowjo.zip?raw=TRUE", destfile = 'spatialFlowjo.zip', mode = 'wb')
+ # unzip(zipfile = 'spatialFlowjo.zip')
+ # for(i in list.files('spatialFlowjo/data', full.names = TRUE)){
+ # file.rename(from = i, to = gsub('spatialFlowjo/', '', i))
+ # }
+ # unlink(c('spatialFlowjo/', 'spatialFlowjo.zip', '__MACOSX'), recursive = TRUE)
+
+ ### Initialise the spatial data object with channel TIFF files
setwd(InputDirectory)
rois <- list.dirs(full.names = FALSE, recursive = FALSE)
as.matrix(rois)
- ### Check channel names
+ ### Check channel names
tiff.list <- list()
@@ -66,12 +114,12 @@
### Read in TIFF files and create spatial objects
###################################################################################
- ### Read in ROI channel TIFFs
+ ### Read in ROI channel TIFFs
setwd(InputDirectory)
spatial.dat <- read.spatial.files(dir = InputDirectory)
- ### Check results
+ ### Check results
str(spatial.dat, 3)
spatial.dat[[1]]@RASTERS
@@ -80,7 +128,7 @@
### Read in masks files
###################################################################################
- ### Define cell mask extension for different mask types
+ ### Define cell mask extension for different mask types
setwd(MaskDirectory)
@@ -92,7 +140,7 @@
'region' = '_ilastik_s2_Simple Segmentation.tif')
mask.types
- ### Read in masks
+ ### Read in masks
for(i in names(mask.types)){
spatial.dat <- do.add.masks(dat = spatial.dat,
@@ -108,7 +156,7 @@
### Rename rasters (if required)
###################################################################################
- ### Check channel names
+ ### Check channel names
channel.names <- list()
@@ -118,13 +166,13 @@
t(as.data.frame(channel.names))
- ### List of corrections (first entry is the 'correct' one)
+ ### List of corrections (first entry is the 'correct' one)
# corrections <- list(c('CD4','Cd4'),
# c('CD8','CD8a')
# )
- ### Replace the 'incorrect' names
+ ### Replace the 'incorrect' names
# for(i in names(spatial.dat)){
# # i <- names(spatial.dat)[[1]]
@@ -139,7 +187,7 @@
# }
# }
- ### Check channel names
+ ### Check channel names
# channel.names <- list()
#
@@ -153,14 +201,13 @@
### Generate polygons and outlines
###################################################################################
- ### Generate polygons and outlines
+ ### Generate polygons and outlines
for(i in names(spatial.dat[[1]]@MASKS)){
spatial.dat <- do.create.outlines(dat = spatial.dat, mask.name = i)
}
-
- ### Checks
+ ### Checks
str(spatial.dat, 3)
str(spatial.dat[[1]]@MASKS, 2)
@@ -169,7 +216,7 @@
### Mask QC plots
###################################################################################
- ### Mask plot setup
+ ### Mask plot setup
setwd(OutputDirectory)
dir.create('Plots - cell masks')
@@ -183,7 +230,7 @@
mask <- 'cell.mask'
mask
- ### Create plots
+ ### Create plots
for(i in names(spatial.dat)){
make.spatial.plot(dat = spatial.dat,
@@ -196,7 +243,7 @@
### Calculate cellular data and plot
###################################################################################
- ### Calculate cellular data for each cell mask (this step may take some time)
+ ### Calculate cellular data for each cell mask (this step may take some time)
spatial.dat <- do.extract(spatial.dat, 'cell.mask')
str(spatial.dat, 3)
@@ -210,16 +257,16 @@
### Save data
###################################################################################
- ### Output QS and CSV file
+ ### Output QS and CSV file
setwd(OutputDirectory)
dir.create('Data')
setwd('Data')
- qsave(spatial.dat, "spatial.dat.qs")
+ qs::qsave(spatial.dat, "spatial.dat.qs")
fwrite(all.dat, 'all.dat.csv')
- ### Pull cellular data and write FCS file from each ROI independently
+ ### Pull cellular data and write FCS file from each ROI independently
setwd(OutputDirectory)
dir.create('FCS files')
@@ -229,24 +276,24 @@
## Extract data and setup cols
- tmp <- list()
- tmp[[i]] <- spatial.dat[[i]]
-
- cell.dat <- do.pull.data(tmp, 'CellData')
- cell.dat <- do.asinh(cell.dat, names(spatial.dat[[i]]@RASTERS), cofactor = 1)
-
- ### Invert y axis
-
- all.neg <- function(test) -1*abs(test)
+ tmp <- list()
+ tmp[[i]] <- spatial.dat[[i]]
+
+ cell.dat <- do.pull.data(tmp, 'CellData')
+ cell.dat <- do.asinh(cell.dat, names(spatial.dat[[i]]@RASTERS), cofactor = 1)
+
+ ## Invert y axis
- y_invert <- cell.dat[['y']]
- y_invert <- all.neg(y_invert)
- cell.dat[['y_invert']] <- y_invert
+ all.neg <- function(test) -1*abs(test)
+
+ y_invert <- cell.dat[['y']]
+ y_invert <- all.neg(y_invert)
+ cell.dat[['y_invert']] <- y_invert
- ### Write FCS files
+ ## Write FCS files
- write.files(cell.dat, i, write.csv = FALSE, write.fcs = TRUE)
- rm(cell.dat)
- rm(i)
+ write.files(cell.dat, i, write.csv = FALSE, write.fcs = TRUE)
+ rm(cell.dat)
+ rm(i)
}
diff --git a/workflows/Spectre spatial (advanced)/Adv spatial 1 - add masks.R b/workflows/Spectre spatial (advanced)/Adv spatial 1 - add masks.R
index e48a8a9e..cdaa3401 100755
--- a/workflows/Spectre spatial (advanced)/Adv spatial 1 - add masks.R
+++ b/workflows/Spectre spatial (advanced)/Adv spatial 1 - add masks.R
@@ -1,80 +1,142 @@
+##########################################################################################################
+#### Create a folder structure for your analysis run
+##########################################################################################################
+
+ ### Create a master folder with a meaningful name. Then inside that folder, insert the following:
+
+ # One folder called 'data' -- this will contain your 'ROIs' folder and 'masks' folder
+ # One folder called 'metadata' -- this will contain a CSV containg your sample metadata
+ # One folder called 'Spectre advanced spatial' or similar -- place analysis scripts there
+
+ ### Example:
+
+ # Spleen analysis
+ # /data
+ # /ROIs -- contains one folder per ROI, filled with TIFF files (one per channel)
+ # /masks -- contains mask files (TIFFs). Can have multiple mask types (e.g. cell mask, region mask)
+ # /metadata
+ # -- Contains a CSV containing sample metadata (group, batch, etc)
+ # /Spectre advanced spatial
+ # -- Adv spatial 1- add masks.R
+
###################################################################################
### Spectre: spatial 1 - add masks and extract cellular data
###################################################################################
### Load libraries
- library('Spectre')
+ library('Spectre')
+
+ ### Extra packages
- Spectre::package.check(type = 'spatial')
- Spectre::package.load(type = 'spatial')
+ if(!require('raster')) {install.packages('raster')}
+ if(!require('tiff')) {install.packages('tiff')}
+ if(!require('rhdf5')) {BiocManager::install("rhdf5")}
+ if(!require('s2')) {install.packages('s2')}
+ if(!require('sf')) {install.packages('sf')}
+ if(!require('stars')) {install.packages('stars')}
+ if(!require('sp')) {install.packages('sp')}
+ if(!require('exactextractr')) {install.packages('exactextractr')}
+ if(!require('qs')) {install.packages('qs')}
+
+ ### Check and load packages
+
+ Spectre::package.check(type = 'spatial')
+ Spectre::package.load(type = 'spatial')
### Set PrimaryDirectory
- dirname(rstudioapi::getActiveDocumentContext()$path)
- setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
- getwd()
- PrimaryDirectory <- getwd()
- PrimaryDirectory
+ dirname(rstudioapi::getActiveDocumentContext()$path)
+ setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
+ getwd()
+ PrimaryDirectory <- getwd()
+ PrimaryDirectory
### Set InputDirectory (ROI TIFFs)
- setwd(PrimaryDirectory)
- setwd("../data/ROIs/")
- InputDirectory <- getwd()
- InputDirectory
+ setwd(PrimaryDirectory)
+ dir.create('../data/', showWarnings = FALSE)
+ dir.create('../data/ROIs/', showWarnings = FALSE)
+ setwd("../data/ROIs/")
+ InputDirectory <- getwd()
+ InputDirectory
### Set MaskDirectory (ROI mask TIFFs)
- setwd(PrimaryDirectory)
- setwd("../data/masks")
- MaskDirectory <- getwd()
- MaskDirectory
+ setwd(PrimaryDirectory)
+ dir.create('../data/', showWarnings = FALSE)
+ dir.create('../data/masks/', showWarnings = FALSE)
+ setwd("../data/masks")
+ MaskDirectory <- getwd()
+ MaskDirectory
+
+ ### Set metadata directory
+
+ setwd(PrimaryDirectory)
+ dir.create('../metadata/', showWarnings = FALSE)
+ setwd("../metadata/")
+ MetaDirectory <- getwd()
+ MetaDirectory
### Create output directory
- setwd(PrimaryDirectory)
- dir.create("Output 1 - add masks")
- setwd("Output 1 - add masks")
- OutputDirectory <- getwd()
- OutputDirectory
+ setwd(PrimaryDirectory)
+ dir.create("Output 1 - add masks")
+ setwd("Output 1 - add masks")
+ OutputDirectory <- getwd()
+ OutputDirectory
###################################################################################
### Check ROIs and TIFFs
###################################################################################
+ ### If you need the demo dataset, uncomment the following code (select all, CMD+SHIFT+C) and run to download
+
+ # setwd(PrimaryDirectory)
+ # setwd("../")
+ # getwd()
+ # download.file(url = "https://github.com/ImmuneDynamics/data/blob/main/spatialAdvanced.zip?raw=TRUE", destfile = 'spatialAdvanced.zip', mode = 'wb')
+ # unzip(zipfile = 'spatialAdvanced.zip')
+ # for(i in list.files('spatialAdvanced/data', full.names = TRUE)){
+ # file.rename(from = i, to = gsub('spatialAdvanced/', '', i))
+ # }
+ # for(i in list.files('spatialAdvanced/metadata', full.names = TRUE)){
+ # file.rename(from = i, to = gsub('spatialAdvanced/', '', i))
+ # }
+ # unlink(c('spatialAdvanced/', 'spatialAdvanced.zip', '__MACOSX'), recursive = TRUE)
+
### Initialise the spatial data object with channel TIFF files
- setwd(InputDirectory)
-
- rois <- list.dirs(full.names = FALSE, recursive = FALSE)
- as.matrix(rois)
+ setwd(InputDirectory)
+
+ rois <- list.dirs(full.names = FALSE, recursive = FALSE)
+ as.matrix(rois)
### Check channel names
- tiff.list <- list()
-
- for(i in rois){
- setwd(InputDirectory)
- setwd(i)
- tiff.list[[i]] <- list.files(getwd())
- }
-
- t(as.data.frame(tiff.list))
+ tiff.list <- list()
+
+ for(i in rois){
+ setwd(InputDirectory)
+ setwd(i)
+ tiff.list[[i]] <- list.files(getwd())
+ }
+
+ t(as.data.frame(tiff.list))
###################################################################################
### Read in TIFF files and create spatial objects
###################################################################################
### Read in ROI channel TIFFs
-
- setwd(InputDirectory)
- spatial.dat <- read.spatial.files(dir = InputDirectory)
+
+ setwd(InputDirectory)
+ spatial.dat <- read.spatial.files(dir = InputDirectory)
### Check results
- str(spatial.dat, 3)
- spatial.dat[[1]]@RASTERS
+ str(spatial.dat, 3)
+ spatial.dat[[1]]@RASTERS
###################################################################################
### Read in masks files
@@ -203,11 +265,11 @@
spatial.dat[[1]]@DATA
- ### Factor plot setup
+ ### Plot setup
setwd(OutputDirectory)
- dir.create('Plots - factors')
- setwd('Plots - factors')
+ dir.create('Plots - points')
+ setwd('Plots - points')
plot.rois <- names(spatial.dat)[c(1:2)]
plot.rois
@@ -222,12 +284,12 @@
plot.exp <- names(spatial.dat[[1]]@RASTERS)
plot.exp
- ### Make factor plots
+ ### Make plots
for(i in plot.rois){
setwd(OutputDirectory)
- setwd('Plots - factors')
+ setwd('Plots - points')
dir.create(i)
setwd(i)
@@ -248,7 +310,7 @@
for(i in plot.rois){
setwd(OutputDirectory)
- setwd('Plots - factors')
+ setwd('Plots - points')
dir.create(i)
setwd(i)
diff --git a/workflows/Spectre spatial (advanced)/Adv spatial 2 - cellular analysis.R b/workflows/Spectre spatial (advanced)/Adv spatial 2 - cellular analysis.R
index 17ccad21..0fca321f 100755
--- a/workflows/Spectre spatial (advanced)/Adv spatial 2 - cellular analysis.R
+++ b/workflows/Spectre spatial (advanced)/Adv spatial 2 - cellular analysis.R
@@ -27,7 +27,7 @@
### Set metadata directory
setwd(PrimaryDirectory)
- setwd("metadata")
+ setwd("../metadata")
MetaDirectory <- getwd()
MetaDirectory
@@ -80,7 +80,7 @@
as.matrix(names(cell.dat))
- to.asinh <- names(cell.dat)[c(8:20)]
+ to.asinh <- names(cell.dat)[c(6:13)]
to.asinh
### Arcsinh
@@ -101,14 +101,14 @@
as.matrix(names(cell.dat))
- cellular.cols <- names(cell.dat)[c(28:40)]
+ cellular.cols <- names(cell.dat)[c(29:36)]
cellular.cols
### Select clustering columns
as.matrix(names(cell.dat))
- cluster.cols <- names(cell.dat)[c(28:40)]
+ cluster.cols <- names(cell.dat)[c(29:34)]
cluster.cols
### Sample, group, etc columns
@@ -162,7 +162,7 @@
for(i in cellular.cols){
make.spatial.plot(spatial.dat,
image.roi = roi.plot,
- image.channel = gsub('_asinh', '', i),
+ image.channel = gsub('_asinh_rescaled', '', i),
mask.outlines = 'cell.mask',
cell.dat = cell.dat[cell.dat[['ROI']] == roi.plot],
cell.col = 'Annotated cell type',
@@ -197,7 +197,7 @@
### Multi plots
- make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', plot.by = cellular.cols, figure.title = 'Cellular cols')
+ make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', plot.by = cellular.cols, figure.title = 'Cellular cols', col.type = 'continuous')
make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', plot.by = cluster.cols, col.type = 'factor', figure.title = 'Clustering cols')
make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', 'Annotated cell type', 'ROI', col.type = 'factor', figure.title = 'FlowSOM_metacluster by ROI')
@@ -213,25 +213,28 @@
### Annotate clusters
###################################################################################
- # ### Cluster annotations
- #
- # cluster.annots <- list('T cells' = c(12,14,15),
- # 'B cells' = c(1,10,5,9))
- #
- # cluster.annots <- do.list.switch(cluster.annots)
- # names(cluster.annots) <- c('Values', 'Annotated metacluster')
- # cluster.annots
- #
- # ### Add annotations, fill in NAs
- #
- # cell.dat <- do.add.cols(cell.dat, 'FlowSOM_metacluster', cluster.annots, 'Values')
- # cell.dat[['Annotated metacluster']][is.na(cell.dat[['Annotated metacluster']])] <- 'Other'
- # cell.dat
- #
- # ### Extra plots
- #
- # make.colour.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', 'Annotated metacluster', 'factor', add.label = TRUE)
- # make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', 'Annotated metacluster', 'ROI', col.type = 'factor', figure.title = 'Annotated metacluster by ROI')
+ ### Cluster annotations
+
+ cluster.annots <- list('CD4 T cells' = c(14,15,13,8),
+ 'CD8 T cells' = c(11,12,10),
+ 'CD11b+ cells' = c(6,5),
+ 'B cells' = c(7,1,9)
+ )
+
+ cluster.annots <- do.list.switch(cluster.annots)
+ names(cluster.annots) <- c('Values', 'Annotated metacluster')
+ cluster.annots
+
+ ### Add annotations, fill in NAs
+
+ cell.dat <- do.add.cols(cell.dat, 'FlowSOM_metacluster', cluster.annots, 'Values')
+ cell.dat[['Annotated metacluster']][is.na(cell.dat[['Annotated metacluster']])] <- 'Other'
+ cell.dat
+
+ ### Extra plots
+
+ make.colour.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', 'Annotated metacluster', 'factor', add.label = TRUE)
+ make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', 'Annotated metacluster', 'ROI', col.type = 'factor', figure.title = 'Annotated metacluster by ROI')
###################################################################################
### Save data
@@ -244,6 +247,7 @@
### Save cellular data
fwrite(cell.dat, 'cell.dat.csv')
+ qsave(spatial.dat, 'spatial.dat.qs')
### FCS files
@@ -258,29 +262,17 @@
### Spatial plotting of cluster data
###################################################################################
- ### Clusters
-
- # setwd(OutputDirectory)
- # dir.create('Annotated clusters')
- # setwd('Annotated clusters')
- #
- # for(i in unique(cell.dat$ROI)){
- # temp <- cell.dat[cell.dat[['ROI']] == i,]
- # make.spatial.plot(spatial.dat, i, 'DNA1_Ir191', mask.outlines = 'cell.mask', temp, cell.col = 'Annotated metacluster', cell.col.type = 'factor')
- # }
-
- ### Cell type
+ ### Annotated metaclusters
setwd(OutputDirectory)
- dir.create('Annotated cell types')
- setwd('Annotated cell types')
-
+ dir.create('Annotated metaclusters')
+ setwd('Annotated metaclusters')
+
for(i in unique(cell.dat$ROI)){
temp <- cell.dat[cell.dat[['ROI']] == i,]
- make.spatial.plot(spatial.dat, i, 'DNA1_Ir191', mask.outlines = 'cell.mask', temp, cell.col = 'Annotated cell type', cell.col.type = 'factor')
+ make.spatial.plot(spatial.dat, i, 'DNA1_Ir191', mask.outlines = 'cell.mask', temp, cell.col = 'Annotated metacluster', cell.col.type = 'factor')
}
-
### Regions
setwd(OutputDirectory)
diff --git a/workflows/Spectre spatial (advanced)/Adv spatial 3 - quantitative analysis.R b/workflows/Spectre spatial (advanced)/Adv spatial 3 - quantitative analysis.R
index 7e261fc7..f44f9e20 100755
--- a/workflows/Spectre spatial (advanced)/Adv spatial 3 - quantitative analysis.R
+++ b/workflows/Spectre spatial (advanced)/Adv spatial 3 - quantitative analysis.R
@@ -77,7 +77,7 @@
group.col <- 'Group'
batch.col <- 'Batch'
- pop.col <- 'Annotated cell type'
+ pop.col <- 'Annotated metacluster'
region.col <- 'Annotated region'
### Some checks
diff --git a/workflows/Spectre spatial (simple)/Simple spatial 1 - add masks.R b/workflows/Spectre spatial (simple)/Simple spatial 1 - add masks.R
index a8e1df22..0ae01344 100755
--- a/workflows/Spectre spatial (simple)/Simple spatial 1 - add masks.R
+++ b/workflows/Spectre spatial (simple)/Simple spatial 1 - add masks.R
@@ -1,13 +1,48 @@
+##########################################################################################################
+#### Create a folder structure for your analysis run
+##########################################################################################################
+
+ ### Create a master folder with a meaningful name. Then inside that folder, insert the following:
+
+ # One folder called 'data' -- this will contain your 'ROIs' folder and 'masks' folder
+ # One folder called 'metadata' -- this will contain a CSV containg your sample metadata
+ # One folder called 'Spectre Simple spatial' or similar -- place analysis scripts there
+
+ ### Example:
+
+ # Spleen analysis
+ # /data
+ # /ROIs -- contains one folder per ROI, filled with TIFF files (one per channel)
+ # /masks -- contains mask files (TIFFs). Can have multiple mask types (e.g. cell mask, region mask)
+ # /metadata
+ # -- Contains a CSV containing sample metadata (group, batch, etc)
+ # /Spectre Simple spatial
+ # -- Simple spatial 1 - add masks.R
+
###################################################################################
### Spectre: spatial 1 - add masks and extract cellular data
###################################################################################
-
+
### Load libraries
- library('Spectre')
+ library('Spectre')
- Spectre::package.check(type = 'spatial')
- Spectre::package.load(type = 'spatial')
+ ### Extra packages
+
+ if(!require('raster')) {install.packages('raster')}
+ if(!require('tiff')) {install.packages('tiff')}
+ if(!require('rhdf5')) {BiocManager::install("rhdf5")}
+ if(!require('s2')) {install.packages('s2')}
+ if(!require('sf')) {install.packages('sf')}
+ if(!require('stars')) {install.packages('stars')}
+ if(!require('sp')) {install.packages('sp')}
+ if(!require('exactextractr')) {install.packages('exactextractr')}
+ if(!require('qs')) {install.packages('qs')}
+
+ ### Check and load packages
+
+ Spectre::package.check(type = 'spatial')
+ Spectre::package.load(type = 'spatial')
### Set PrimaryDirectory
@@ -20,6 +55,8 @@
### Set InputDirectory (ROI TIFFs)
setwd(PrimaryDirectory)
+ dir.create('../data/', showWarnings = FALSE)
+ dir.create('../data/ROIs/', showWarnings = FALSE)
setwd("../data/ROIs/")
InputDirectory <- getwd()
InputDirectory
@@ -27,10 +64,20 @@
### Set MaskDirectory (ROI mask TIFFs)
setwd(PrimaryDirectory)
+ dir.create('../data/', showWarnings = FALSE)
+ dir.create('../data/masks/', showWarnings = FALSE)
setwd("../data/masks")
MaskDirectory <- getwd()
MaskDirectory
+ ### Set metadata directory
+
+ setwd(PrimaryDirectory)
+ dir.create('../metadata/', showWarnings = FALSE)
+ setwd("../metadata/")
+ MetaDirectory <- getwd()
+ MetaDirectory
+
### Create output directory
setwd(PrimaryDirectory)
@@ -43,24 +90,39 @@
### Check ROIs and TIFFs
###################################################################################
+ ### If you need the demo dataset, uncomment the following code (select all, CMD+SHIFT+C) and run to download
+#
+# setwd(PrimaryDirectory)
+# setwd("../")
+# getwd()
+# download.file(url = "https://github.com/ImmuneDynamics/data/blob/main/spatialSimple.zip?raw=TRUE", destfile = 'spatialSimple.zip', mode = 'wb')
+# unzip(zipfile = 'spatialSimple.zip')
+# for(i in list.files('spatialSimple/data', full.names = TRUE)){
+# file.rename(from = i, to = gsub('spatialSimple/', '', i))
+# }
+# for(i in list.files('spatialSimple/metadata', full.names = TRUE)){
+# file.rename(from = i, to = gsub('spatialSimple/', '', i))
+# }
+# unlink(c('spatialSimple/', 'spatialSimple.zip', '__MACOSX'), recursive = TRUE)
+
### Initialise the spatial data object with channel TIFF files
-
- setwd(InputDirectory)
-
- rois <- list.dirs(full.names = FALSE, recursive = FALSE)
- as.matrix(rois)
+
+ setwd(InputDirectory)
+
+ rois <- list.dirs(full.names = FALSE, recursive = FALSE)
+ as.matrix(rois)
### Check channel names
+
+ tiff.list <- list()
- tiff.list <- list()
-
- for(i in rois){
- setwd(InputDirectory)
- setwd(i)
- tiff.list[[i]] <- list.files(getwd())
- }
-
- t(as.data.frame(tiff.list))
+ for(i in rois){
+ setwd(InputDirectory)
+ setwd(i)
+ tiff.list[[i]] <- list.files(getwd())
+ }
+
+ t(as.data.frame(tiff.list))
###################################################################################
### Read in TIFF files and create spatial objects
@@ -68,13 +130,13 @@
### Read in ROI channel TIFFs
- setwd(InputDirectory)
- spatial.dat <- read.spatial.files(dir = InputDirectory)
+ setwd(InputDirectory)
+ spatial.dat <- read.spatial.files(dir = InputDirectory)
### Check results
- str(spatial.dat, 3)
- spatial.dat[[1]]@RASTERS
+ str(spatial.dat, 3)
+ spatial.dat[[1]]@RASTERS
###################################################################################
### Read in masks files
@@ -88,7 +150,6 @@
as.matrix(all.masks)
mask.types <- list('cell.mask' = '_Cell_mask.tiff')
-
mask.types
### Read in masks
@@ -201,11 +262,11 @@
spatial.dat[[1]]@DATA
- ### Factor plot setup
+ ### Plot setup
setwd(OutputDirectory)
- dir.create('Plots - factors')
- setwd('Plots - factors')
+ dir.create('Plots - points')
+ setwd('Plots - points')
as.matrix(names(spatial.dat))
@@ -217,7 +278,7 @@
base
plot.factors <- names(spatial.dat[[1]]@MASKS)[-which('cell.mask' == names(spatial.dat[[1]]@MASKS))]
- plot.factors
+ plot.factors # might be empty if no other mask types present
plot.exp <- names(spatial.dat[[1]]@RASTERS)
plot.exp
@@ -227,7 +288,7 @@
for(i in plot.rois){
setwd(OutputDirectory)
- setwd('Plots - factors')
+ setwd('Plots - points')
dir.create(i)
setwd(i)
@@ -248,7 +309,7 @@
for(i in plot.rois){
setwd(OutputDirectory)
- setwd('Plots - factors')
+ setwd('Plots - points')
dir.create(i)
setwd(i)
diff --git a/workflows/Spectre spatial (simple)/Simple spatial 2 - cellular analysis.R b/workflows/Spectre spatial (simple)/Simple spatial 2 - cellular analysis.R
index 49f9ea3b..814837d3 100755
--- a/workflows/Spectre spatial (simple)/Simple spatial 2 - cellular analysis.R
+++ b/workflows/Spectre spatial (simple)/Simple spatial 2 - cellular analysis.R
@@ -108,7 +108,7 @@
as.matrix(names(cell.dat))
- cluster.cols <- names(cell.dat)[c(25:32)]
+ cluster.cols <- names(cell.dat)[c(25:30)]
cluster.cols
### Sample, group, etc columns
@@ -146,7 +146,7 @@
### Multi plots
- make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', plot.by = cellular.cols, figure.title = 'Cellular cols')
+ make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', plot.by = cellular.cols, figure.title = 'Cellular cols', col.type = 'continuous')
make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', plot.by = cluster.cols, col.type = 'factor', figure.title = 'Clustering cols')
make.multi.plot(cell.dat, 'FItSNE_X', 'FItSNE_Y', 'FlowSOM_metacluster', 'ROI', col.type = 'factor', figure.title = 'FlowSOM_metacluster by ROI')
@@ -164,10 +164,10 @@
### Cluster annotations
- cluster.annots <- list('CD4 T cells' = c(4,14,11,10),
- 'CD8 T cells' = c(2,15),
- 'CD11b+ cells' = c(5,9),
- 'B cells' = c(1,3,6)
+ cluster.annots <- list('CD4 T cells' = c(8,11,15),
+ 'CD8 T cells' = c(14,6),
+ 'CD11b+ cells' = c(1,3,5),
+ 'B cells' = c(9,4,2)
)
cluster.annots <- do.list.switch(cluster.annots)