R/count_touching_cells.R
count_touching_cells.Rd
count_touching_cells
uses morphological analysis of nuclear and
membrane segmentation maps to find touching cells of paired phenotypes.
It reports the number of touching cells found and, optionally,
writes image files showing the touching cells.
count_touching_cells(
cell_seg_path,
pairs,
colors = NULL,
phenotype_rules = NULL,
categories = NULL,
write_images = !is.null(colors),
output_base = NULL
)
The path to the cell seg data file. The same directory
must also contain _memb_seg_map.tif
or _binary_seg_maps.tif
and, if
write_images
is true, a TIFF or JPEG composite image from inForm.
A list of pairs of phenotypes. Each entry is a two-element vector. The result will contain one line for each pair showing the number of cells and number of touches. Pairs must match two different sets of cells; in particular, touches of a phenotype to itself are not supported.
A named list of phenotype colors to use when drawing
the output. Only used when write_images
is TRUE
.
(Optional) A named list.
Item names are phenotype names and must match entries in pairs
.
Item values are selectors for select_rows.
If given, a vector or list of tissue category names. Categories not in the list will be excluded from the analysis.
If TRUE
, for each pair, write an image showing the
touching pairs. Requires colors
and a composite image in the same
directory as the cell seg table.
Base path for image output.
If NULL
, output will be to the same
directory as the cell table.
Returns a tibble
with one row for each pair in
pairs
, containing these columns:
slide_id
Slide ID from the data file, if available.
source
Base file name of the source file with
_cell_seg_data.txt
stripped off for brevity.
phenotype1
The name of the first phenotype in the touching pair.
phenotype2
The name of the second phenotype in the touching pair.
total1
The total number of phenotype1
cells
in the image.
total2
The total number of phenotype2
cells
in the image.
p1_touch_p2
The number of phenotype1
cells
touching a phenotype2
cell.
p2_touch_p1
The number of phenotype2
cells
touching a phenotype1
cell.
touch_mutual
The number of mutually touching pairs.
This function requires a cell seg data file and a matching
segmentation map file. If write_images
is true,
a composite image is required.
If the cell seg data uses micron units, a composite data file is also
required.
Cells are considered to touch if they have any amount of common membrane as determined by the inForm membrane segmentation. Cells which meet only at a corner, like black squares on a checkerboard, are not counted as touching.
The number of touching cells is reported in three ways. For a pair of phenotypes A and B, this function reports the number of A touching a B, the number of B touching an A, and the number of mutually touching pairs. Note that the number of mutual touches is often larger than the count of either "A touching B" or "B touching A" because a single touching cell may be part of multiple pairs.
The image files written show cells of the selected phenotypes on a background of the composite. Touching cells are filled in the provided color; cells which are not touching the other phenotype are outlined. Image files are written as TIFF files to preserve the fine detail of cell boundaries.
Images are only written when both phenotypes of the pair are represented.
See the tutorial
Selecting cells within a cell segmentation table
for more on
the use of pairs
and phenotype_rules
.
Other distance functions:
compute_all_nearest_distance()
,
count_within_batch()
,
count_within_many()
,
count_within()
,
distance_matrix()
,
find_nearest_distance()
,
spatial_distribution_report()
,
subset_distance_matrix()
if (FALSE) {
# This example creates an image in a subdirectory of the
# current user's directory.
cell_seg_path <- sample_cell_seg_path()
pairs <- list(c("CD68+", "CD8+"))
colors <- c("CD68+"='magenta', "CD8+"='yellow')
output_base <- path.expand('~/touches')
count_touching_cells(cell_seg_path, pairs, colors,
output_base=output_base)
# This example will count and image all files in the `base_path` directory.
base_path <- '/path/to/data'
output_base <- file.path(base_path, 'touches')
files <- list_cell_seg_files(base_path)
# The phenotype pairs to locate. This will find CD8 cells touching
# tumor cells, and, separately, CD8 cells touching CD68 cells.
pairs <- list(c("CD8+", "CK+"),
c("CD8+", "CD68+"))
# Colors for all the phenotypes mentioned in pairs
colors <- list(
'CD8+' = 'yellow',
'CK+' = 'cyan',
'CD68+' = 'magenta'
)
# Count and visualize touching cells
touch_counts <- purrr::map_df(files, function(path) {
cat('Processing', path, '\n')
count_touching_cells(path, pairs, colors, output_base=output_base)
})
# Save the result
touches_path <- file.path(output_base, 'TouchCounts.csv')
readr::write_csv(touch_counts, touches_path)
# The phenotype definitions can be more complex. The default is to use
# the names in `pairs`. Using `phenotype_rules`, the definition can be
# anything allowed by select_rows().
# You can also limit the tissue category.
# For example, find all touches between lymphocytes and tumor cells
# within the tumor:
pairs <- list(c('Tumor', 'Lymphocyte'))
colors <- list(Tumor='cyan', Lymphocyte='yellow')
phenotype_rules <- list(
Lymphocyte=c('CD8+', 'FoxP3+')
)
touch_counts <- map_df(files, function(path) {
cat('Processing', path, '\n')
count_touching_cells(path, pairs, colors, phenotype_rules,
categories='tumor',
output_base=output_base)
})
# Then write the results as above.
}