install
source · Clone the upstream repo
git clone https://github.com/mdbabumiamssm/LLMs-Universal-Life-Science-and-Clinical-Skills-
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/mdbabumiamssm/LLMs-Universal-Life-Science-and-Clinical-Skills- "$T" && mkdir -p ~/.claude/skills && cp -r "$T/Skills/Hematology/Flow_Cytometry/compensation-transformation" ~/.claude/skills/mdbabumiamssm-llms-universal-life-science-and-clinical-skills-compensation-trans && rm -rf "$T"
manifest:
Skills/Hematology/Flow_Cytometry/compensation-transformation/SKILL.mdsource content
<!--
# COPYRIGHT NOTICE
# This file is part of the "Universal Biomedical Skills" project.
# Copyright (c) 2026 MD BABU MIA, PhD <md.babu.mia@mssm.edu>
# All Rights Reserved.
#
# This code is proprietary and confidential.
# Unauthorized copying of this file, via any medium is strictly prohibited.
#
# Provenance: Authenticated by MD BABU MIA
-->
name: bio-flow-cytometry-compensation-transformation description: Spillover compensation and data transformation for flow cytometry. Covers compensation matrix calculation, application, and biexponential/arcsinh transforms. Use when correcting spectral overlap between fluorophores or transforming data for analysis. tool_type: r primary_tool: flowCore measurable_outcome: Execute skill workflow successfully with valid output within 15 minutes. allowed-tools:
- read_file
- run_shell_command
Compensation and Transformation
Load Compensation Matrix
library(flowCore) # From FCS file keywords fcs <- read.FCS('sample.fcs', transformation = FALSE) comp_matrix <- keyword(fcs)$`$SPILLOVER` # Or from CSV file comp_matrix <- as.matrix(read.csv('compensation.csv', row.names = 1))
Apply Compensation
# Create compensation object comp <- compensation(comp_matrix) # Apply to flowFrame fcs_comp <- compensate(fcs, comp) # Apply to flowSet fs_comp <- compensate(fs, comp)
Calculate Compensation from Controls
library(flowStats) # Single-stained controls controls <- read.flowSet(list.files('controls', pattern = '\\.fcs$', full.names = TRUE)) # Calculate spillover matrix spillover <- spillover(controls, unstained = 'Unstained.fcs', fsc = 'FSC-A', ssc = 'SSC-A', patt = '-A$', # Channel pattern stain_match = 'regexpr') # The result is a list; extract matrix comp_matrix <- spillover$comp
Transformation: Biexponential (Logicle)
# Logicle transformation (standard for flow) library(flowWorkspace) # Auto-estimate parameters lgcl <- estimateLogicle(fcs, colnames(fcs)[3:10]) # Apply fcs_trans <- transform(fcs, lgcl) # Manual logicle parameters lgcl_manual <- logicleTransform( w = 0.5, # Linearization width t = 262144, # Top of scale m = 4.5, # Decades of data a = 0 # Additional negative range )
Transformation: Arcsinh (CyTOF)
# Arcsinh transformation for CyTOF arcsinh_transform <- function(x, cofactor = 5) { asinh(x / cofactor) } # Apply to expression matrix expr <- exprs(fcs) expr_trans <- apply(expr[, marker_channels], 2, arcsinh_transform, cofactor = 5) # Or using transformList asinhTrans <- arcsinhTransform(transformationId = 'arcsinh', a = 0, b = 1/5) trans_list <- transformList(marker_channels, asinhTrans) fcs_trans <- transform(fcs, trans_list)
Transformation: Log
# Simple log transformation logTrans <- logTransform(transformationId = 'log10', logbase = 10, r = 1, d = 1) trans_list <- transformList(marker_channels, logTrans) fcs_trans <- transform(fcs, trans_list)
View Before/After Compensation
library(ggcyto) # Before compensation p1 <- autoplot(fcs, 'FITC-A', 'PE-A') + ggtitle('Before Compensation') # After compensation p2 <- autoplot(fcs_comp, 'FITC-A', 'PE-A') + ggtitle('After Compensation') library(patchwork) p1 + p2
Complete Preprocessing Pipeline
preprocess_flow <- function(fcs, comp_matrix, marker_channels) { # 1. Compensation comp <- compensation(comp_matrix) fcs <- compensate(fcs, comp) # 2. Transformation (logicle for flow, arcsinh for CyTOF) lgcl <- estimateLogicle(fcs, marker_channels) fcs <- transform(fcs, lgcl) return(fcs) } # Apply to flowSet fs_processed <- fsApply(fs, function(f) { preprocess_flow(f, comp_matrix, marker_channels) })
CATALYST Preprocessing (CyTOF)
library(CATALYST) library(SingleCellExperiment) # Create SingleCellExperiment from flowSet sce <- prepData(fs, panel = panel, # data.frame with columns: fcs_colname, antigen, marker_class md = sample_info, # sample metadata transform = TRUE, # Apply arcsinh cofactor = 5, FACS = FALSE) # TRUE for flow, FALSE for CyTOF
Panel File Format (CATALYST)
# panel.csv panel <- data.frame( fcs_colname = c('Yb176Di', 'Er168Di', 'Nd142Di'), antigen = c('CD45', 'CD3', 'CD4'), marker_class = c('type', 'type', 'type') # 'type' for phenotyping, 'state' for functional )
Save Preprocessed Data
# Write transformed FCS write.FCS(fcs_trans, 'sample_preprocessed.fcs') # Save transformation for reproducibility saveRDS(list(comp = comp_matrix, transform = lgcl), 'preprocessing_params.rds')
Related Skills
- fcs-handling - Load FCS files first
- gating-analysis - Gate after preprocessing
- clustering-phenotyping - Cluster transformed data