EmbedSOM

Fast embedding for flow/mass cytometry data. Best used with FlowSOM (https://github.com/SofieVG/FlowSOM).

Installation of R module

Use devtools:

devtools::install_github('exaexa/EmbedSOM')

Usage

EmbedSOM works by aligning the cells to the FlowSOM-defined SOM (viewed as a smooth manifold). The main function EmbedSOM takes the SOM (present in the $map in FlowSOM objects) and returns a matrix with 2D cell coordinates on each row.

Quick way to get something out:

fs <- FlowSOM::ReadInput('Levine_13dim_cleaned.fcs', scale=TRUE, transform=TRUE, toTransform=c(1:13))
fs <- FlowSOM::BuildSOM(fs, xdim=16, ydim=16, colsToUse=c(1:13))
e <- EmbedSOM::EmbedSOM(fs) # compute 2D coordinates of cells
par(mfrow=c(2,1))
EmbedSOM::PlotEmbed(e, fsom=fs)

(The FCS file can be downloaded from EmbedSOM website at http://bioinfo.uochb.cas.cz/embedsom/)

EmbedSOM parameters

HOW-TOs

How to save an embedding to FCS file?

Use flowCore functionality to add any information to a FCS. The following template saves the scaled FlowSOM object data as-is, together with the embedding:

fs <- FlowSOM::ReadInput('original.fcs', scale=T, ...)
fs <- FlowSOM::BuildSOM(fs, ...)
e <- EmbedSOM::EmbedSOM(fs, ...)
flowCore::write.FCS(new('flowFrame',
    exprs=as.matrix(data.frame(fs$data,
                   embedsom1=e[,1],
                   embedsom2=e[,2]))),
    'original_with_embedding.fcs')

See flowCore documentation for information about advanced FCS-writing functionality, e.g. for column descriptions.

How to align the population positions in embedding of multiple files?

Train a SOM on an aggregate file, and use it to embed the individual files. It is important to always apply the same scaling and transformations on all input files.

fs <- FlowSOM::ReadInput(
    FlowSOM::AggregateFlowFrames(c('file1.fcs', 'file2.fcs', ...),
                     cTotal=100000),
    scale=T, transform=...)
n <- length(fs$scaled.scale)-2
map <- FlowSOM::SOM(fs)

fs1 <- FlowSOM::ReadInput('file1.fcs',
    scale=T,
    scaled.scale=fs$scaled.scale[1:n],
    scaled.center=fs$scaled.center[1:n],
    transform=...)
e1 <- EmbedSOM::EmbedSOM(fs1, map=map)
EmbedSOM::PlotEmbed(e1, fsom=fs1, xdim=10, ydim=10)
# repeat as needed for file2.fcs, etc.

What are the color parameters of PlotEmbed?

Please see documentation in ?PlotEmbed. By default, PlotEmbed plots a simple colored representation of cell density. If supplied with a FCS column name (or number), it uses the a color scale similar to ColorBrewer’s RdYlBu (with improvements for transparent stuff) to plot a single marker expression. Parameters red, green and blue can be used to set column names (or numbers) to mix RGB color from marker expressions.

PlotEmbed optionally accepts parameter col with a vector of R colors, which, if provided, is just forwarded to the internal plot function. For example, use col=rgb(0,0,0,0.2) for transparent black cells.

New! if you need to mix more nicer colors than just the default RGB, use ExprColors.

How to plot the gazillions of the tiny points faster?

How to reduce size (and loading time) of the PDFs that contain scatterplots?

Use scattermore: https://github.com/exaexa/scattermore

How to select cell subsets from the embedding?

First, a clustering method is needed to define the subsets. Supposing you already have a FlowSOM object fs with the SOM built, you can run e.g. the FlowSOM metaclustering to generate 10 clusters:

clusters <- FlowSOM::metaClustering_consensus(fs$map$codes, k=10)

After that, the metaclusters can be plotted in the embedding. Because the clustering is related to the small FlowSOM “pre-clusters” rather than cells, it is also necessary to use the information from fs$map$mapping for getting the cluster information to single cell level:

EmbedSOM::PlotEmbed(e, fsom=fs, clust=clusters[fs$map$mapping[,1]])

After you choose a metacluster in the embedding, use the color scale to find its number, then filter the cells in fs to the corresponding subset. This example selects the cell subset in metacluster number 5:

fs$data <- fs$data[clusters[fs$map$mapping[,1]]==5,]

Note that you must rebuild the SOM and re-embed the cells to work with the updated fs object.

How to produce and display a 3D embedding?

There is now support for 3D SOM grids and 3D embedding. You need the customized SOM function from EmbedSOM:

map <- EmbedSOM::SOM(someData, xdim=8, ydim=8, zdim=8)
e <- EmbedSOM::EmbedSOM(data=someData, map=map)

PlotEmbed and other functions do not work on 3D embed data, but you may use other libraries to display the plots. For example the plot3D library:

plot3D::scatter3D(x=e[,1], y=e[,2], z=e[,3])

Interactive rotatable and zoomable plots can be viewed using the rgl library:

rgl::points3d(x=e[,1], y=e[,2], z=e[,3])

What to do if embedding takes too long?

You may use parallelized versions of the algorithms. Several functions (SOM, GQTSOM, EmbedSOM) support setting parallel=T, which enables parallel processing; you may fine-tune the number of used CPUs by setting e.g. threads=5.

For SOM training, you need to explicitly switch to the parallelizable batch version, using batch=F.

How to activate the SIMD support? (i.e. how to get even more speed?)

Additionally, EmbedSOM has support for SIMD-assisted computation of both SOM and the embedding. If your CPU can work with SSE4 instructions (almost every amd64 (a.k.a. x64 a.k.a. x86_64) CPU built after around 2013 can do that), just tell R to compile your code with correct C++ flags, and SOM+EmbedSOM computation should get a bit faster! (in fact, usually at least around 3x faster, depending on the CPU and dataset shape).

First, add a correct line to the R Makevars config file:

 $ cat ~/.R/Makevars
CXXFLAGS += -O3 -march=native

After reinstalling EmbedSOM, SIMD code will be used by default. Note that only the SOM functions from EmbedSOM are affected, i.e. you will need to use EmbedSOM::SOM to get this speedup. FlowSOM::BuildSOM will not get accelerated.