1. load libraries

2. Load Data into Seurat

ss_Borcherding$sample <- recode(ss_Borcherding$sample, 
                                "Control" = "Normal CD4", 
                                "SS_Patient1" = "Malignant CD4")

table(ss_Borcherding$sample)

Malignant CD4    Normal CD4 
         3443          4437 

3. QC


VlnPlot(ss_Borcherding, features = c("nFeature_RNA", 
                                    "nCount_RNA", 
                                    "percent.mt"), 
                                      ncol = 3)
Warning: Default search for "data" layer in "RNA" assay yielded no results; utilizing "counts" layer instead.

VlnPlot(ss_Borcherding, features = c("nFeature_RNA", 
                                         "nCount_RNA", 
                                         "percent.mt",
                                         "percent.rb"), 
                            ncol = 4, pt.size = 0.1) & 
              theme(plot.title = element_text(size=10))
Warning: Default search for "data" layer in "RNA" assay yielded no results; utilizing "counts" layer instead.Warning: The following requested variables were not found: percent.rb

FeatureScatter(ss_Borcherding, 
               feature1 = "nCount_RNA", 
               feature2 = "nFeature_RNA") +
  geom_smooth(method = 'lm')

##FeatureScatter is typically used to visualize feature-feature relationships ##for anything calculated by the object, ##i.e. columns in object metadata, PC scores etc.


FeatureScatter(ss_Borcherding, 
               feature1 = "nCount_RNA", 
               feature2 = "percent.mt")+
  geom_smooth(method = 'lm')


FeatureScatter(ss_Borcherding, 
               feature1 = "nCount_RNA", 
               feature2 = "nFeature_RNA")+
  geom_smooth(method = 'lm')

4. Log-normalization (scale factor = 10,000)



ss_Borcherding <- NormalizeData(ss_Borcherding, normalization.method = "LogNormalize", scale.factor = 10000)
Normalizing layer: counts.SS_Patient1
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Normalizing layer: counts.Control
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|

5. Variable features & scaling



ss_Borcherding <- FindVariableFeatures(ss_Borcherding, selection.method = "vst", nfeatures = 2000)
Finding variable features for layer counts.SS_Patient1
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Finding variable features for layer counts.Control
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
ss_Borcherding <- ScaleData(ss_Borcherding, features = VariableFeatures(ss_Borcherding))
Centering and scaling data matrix

  |                                                                                                   
  |                                                                                             |   0%
  |                                                                                                   
  |==============================================                                               |  50%
  |                                                                                                   
  |=============================================================================================| 100%

6. PCA + UMAP



# PCA
ss_Borcherding <- RunPCA(ss_Borcherding, features = VariableFeatures(ss_Borcherding))
PC_ 1 
Positive:  TRBV14, TRBV21-1, S100A10, TRAV9-2, CRIP1, B2M, ITGB1, S100A6, S100A4, PLS3 
       HLA-C, S100A11, KLF6, CD70, MBP, KIR3DL2, PCSK1N, AHNAK, CD52, HACD1 
       LMNA, VIM, HPGD, GPR15, CCDC167, PTTG1, ANXA2, HLA-A, TSPAN2, KIR3DL1 
Negative:  RPS4Y1, RPS12, RPS6, TPT1, RPL3, MT-CO3, MT-ND3, RPL13, MT-CO1, TXNIP 
       RPSA, MT-ATP8, RPL35, C1orf162, RPS18, MT-CYB, ABLIM1, RPS19, RPLP1, SLC40A1 
       NUCB2, RPLP0, SATB1, HNRNPA1, AIF1, PCED1B, FYB, MBNL1, MT-CO2, VAMP5 
PC_ 2 
Positive:  TYROBP, CST3, LYZ, FCER1G, FCN1, S100A9, HLA-DRA, CYBB, S100A8, SERPINA1 
       CLEC12A, FGL2, VCAN, CSTA, LST1, FGR, MPEG1, SPI1, RAB31, DUSP6 
       MNDA, S100A12, CD68, SLC7A7, NCF2, CLEC7A, LGALS2, TNFAIP2, CD14, LYN 
Negative:  RPSA, RPL3, IFITM1, RPS18, RPLP0, RPL13, TCF7, LTB, LEF1, CD7 
       CCR7, IL7R, PTPRCAP, RPS12, IL32, RPS6, CD27, RPS19, TRBV14, TRBV21-1 
       MAL, ID3, ARHGAP15, TRAV9-2, STMN1, AES, CD3G, RPLP1, LRRN3, RGCC 
PC_ 3 
Positive:  PFN1, MIR4435-2HG, LINC00152, GZMA, CCL5, CST7, ANXA5, GZMK, HLA-DPA1, FAS 
       CTSC, CXCR3, C12orf75, CDCA7, PRDM1, SRGN, CD99, HLA-DRB5, PTPRCAP, KLRB1 
       SH3BGRL3, NKG7, FAM46C, HLA-DPB1, GBP5, ITGA4, CD74, JAKMIP1, ARHGDIB, CD2 
Negative:  TCF7, TRBV14, TRBV21-1, CCR7, LRRN3, FOS, LEF1, JUNB, SPINT2, TRAV9-2 
       RAB25, LINC01480, RHOB, KIR3DL2, RPL13, ESPN, PLS3, KIR3DL1, ID3, DNM3OS 
       COL6A2, TSPAN2, PCSK1N, RHBDL1, JUN, MAL, EPHX2, S100A9, AIF1, LYZ 
PC_ 4 
Positive:  MT-CO2, MT-CO1, MT-ND6, AHNAK, MT-CYB, MIR4435-2HG, FTH1, LINC00152, SH3BGRL3, S100A10 
       TTN, HIST1H1E, FOXP3, C12orf75, S100A4, TTC39C, LGALS3, VIM, NEAT1, MYO1F 
       SAMSN1, S100A6, KLF6, PREX1, TIGIT, PRDM1, CTLA4, HLA-DQA1, CDCA7, MT-ND3 
Negative:  HLA-B, CFL1, HLA-A, IFITM1, ITM2B, CALM2, CCR7, ARHGDIB, MYL12A, CD7 
       PGK1, HSP90AB1, ACTB, MYL6, RPL27A, IFITM2, TXNIP, CD3G, STMN1, RPS18 
       HLA-C, NOSIP, ANXA1, CORO1A, SELL, LEF1, RPL35, PRDX2, CALR, B2M 
PC_ 5 
Positive:  MALAT1, MT-ND3, PTPRC, CCR7, TTN, LEF1, MBNL1, MT-ATP8, MT-ATP6, MT-CYB 
       MT-CO2, SELL, IL6ST, FOXP1, ITK, MT-CO1, LINC00861, MT-CO3, MT-ND2, SPTBN1 
       SF3B1, FAM65B, DDX5, CLEC2D, SLFN5, GPR155, FCMR, IKZF2, SESN3, PDE3B 
Negative:  RPLP1, RPLP0, RPS18, RPL13, RPS19, RPSA, RPS12, SH3BGRL3, RPL35, TPT1 
       RPL36A, NME2, RPL3, TMSB10, S100A4, ATP5E, ACTG1, RPS6, S100A11, CRIP1 
       VIM, FTH1, GAPDH, S100A10, PFN1, ACTB, HNRNPA1, IFITM2, TMSB4X, TXN 
# Optional: Visualize elbow plot
ElbowPlot(ss_Borcherding, ndims = 20)


# Run JackStraw analysis properly
ss_Borcherding <- JackStraw(ss_Borcherding, num.replicate = 100)
Warning: The `slot` argument of `GetAssayData()` is deprecated as of SeuratObject 5.0.0.
Please use the `layer` argument instead.

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~04m 41s      
  |+                                                 | 2 % ~04m 04s      
  |++                                                | 3 % ~03m 48s      
  |++                                                | 4 % ~03m 39s      
  |+++                                               | 5 % ~03m 34s      
  |+++                                               | 6 % ~03m 32s      
  |++++                                              | 7 % ~03m 28s      
  |++++                                              | 8 % ~03m 25s      
  |+++++                                             | 9 % ~03m 21s      
  |+++++                                             | 10% ~03m 19s      
  |++++++                                            | 11% ~03m 16s      
  |++++++                                            | 12% ~03m 14s      
  |+++++++                                           | 13% ~03m 11s      
  |+++++++                                           | 14% ~03m 09s      
  |++++++++                                          | 15% ~03m 06s      
  |++++++++                                          | 16% ~03m 05s      
  |+++++++++                                         | 17% ~03m 02s      
  |+++++++++                                         | 18% ~03m 01s      
  |++++++++++                                        | 19% ~03m 01s      
  |++++++++++                                        | 20% ~02m 59s      
  |+++++++++++                                       | 21% ~02m 57s      
  |+++++++++++                                       | 22% ~02m 54s      
  |++++++++++++                                      | 23% ~02m 52s      
  |++++++++++++                                      | 24% ~02m 49s      
  |+++++++++++++                                     | 25% ~02m 47s      
  |+++++++++++++                                     | 26% ~02m 44s      
  |++++++++++++++                                    | 27% ~02m 41s      
  |++++++++++++++                                    | 28% ~02m 39s      
  |+++++++++++++++                                   | 29% ~02m 37s      
  |+++++++++++++++                                   | 30% ~02m 35s      
  |++++++++++++++++                                  | 31% ~02m 32s      
  |++++++++++++++++                                  | 32% ~02m 30s      
  |+++++++++++++++++                                 | 33% ~02m 27s      
  |+++++++++++++++++                                 | 34% ~02m 25s      
  |++++++++++++++++++                                | 35% ~02m 23s      
  |++++++++++++++++++                                | 36% ~02m 20s      
  |+++++++++++++++++++                               | 37% ~02m 18s      
  |+++++++++++++++++++                               | 38% ~02m 16s      
  |++++++++++++++++++++                              | 39% ~02m 13s      
  |++++++++++++++++++++                              | 40% ~02m 11s      
  |+++++++++++++++++++++                             | 41% ~02m 09s      
  |+++++++++++++++++++++                             | 42% ~02m 07s      
  |++++++++++++++++++++++                            | 43% ~02m 05s      
  |++++++++++++++++++++++                            | 44% ~02m 02s      
  |+++++++++++++++++++++++                           | 45% ~02m 00s      
  |+++++++++++++++++++++++                           | 46% ~01m 58s      
  |++++++++++++++++++++++++                          | 47% ~01m 56s      
  |++++++++++++++++++++++++                          | 48% ~01m 54s      
  |+++++++++++++++++++++++++                         | 49% ~01m 51s      
  |+++++++++++++++++++++++++                         | 50% ~01m 49s      
  |++++++++++++++++++++++++++                        | 51% ~01m 47s      
  |++++++++++++++++++++++++++                        | 52% ~01m 45s      
  |+++++++++++++++++++++++++++                       | 53% ~01m 43s      
  |+++++++++++++++++++++++++++                       | 54% ~01m 40s      
  |++++++++++++++++++++++++++++                      | 55% ~01m 39s      
  |++++++++++++++++++++++++++++                      | 56% ~01m 36s      
  |+++++++++++++++++++++++++++++                     | 57% ~01m 34s      
  |+++++++++++++++++++++++++++++                     | 58% ~01m 32s      
  |++++++++++++++++++++++++++++++                    | 59% ~01m 30s      
  |++++++++++++++++++++++++++++++                    | 60% ~01m 27s      
  |+++++++++++++++++++++++++++++++                   | 61% ~01m 25s      
  |+++++++++++++++++++++++++++++++                   | 62% ~01m 23s      
  |++++++++++++++++++++++++++++++++                  | 63% ~01m 21s      
  |++++++++++++++++++++++++++++++++                  | 64% ~01m 18s      
  |+++++++++++++++++++++++++++++++++                 | 65% ~01m 16s      
  |+++++++++++++++++++++++++++++++++                 | 66% ~01m 14s      
  |++++++++++++++++++++++++++++++++++                | 67% ~01m 12s      
  |++++++++++++++++++++++++++++++++++                | 68% ~01m 10s      
  |+++++++++++++++++++++++++++++++++++               | 69% ~01m 07s      
  |+++++++++++++++++++++++++++++++++++               | 70% ~01m 05s      
  |++++++++++++++++++++++++++++++++++++              | 71% ~01m 03s      
  |++++++++++++++++++++++++++++++++++++              | 72% ~01m 01s      
  |+++++++++++++++++++++++++++++++++++++             | 73% ~59s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~57s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~55s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~52s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~50s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~48s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~46s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~44s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~41s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~39s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~37s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~35s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~33s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~31s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~28s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~26s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~24s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~22s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~20s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~17s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~15s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~13s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~11s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~09s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~07s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=03m 39s

  |                                                  | 0 % ~calculating  
  |+++                                               | 5 % ~00s          
  |+++++                                             | 10% ~00s          
  |++++++++                                          | 15% ~00s          
  |++++++++++                                        | 20% ~00s          
  |+++++++++++++                                     | 25% ~00s          
  |+++++++++++++++                                   | 30% ~00s          
  |++++++++++++++++++                                | 35% ~00s          
  |++++++++++++++++++++                              | 40% ~00s          
  |+++++++++++++++++++++++                           | 45% ~00s          
  |+++++++++++++++++++++++++                         | 50% ~00s          
  |++++++++++++++++++++++++++++                      | 55% ~00s          
  |++++++++++++++++++++++++++++++                    | 60% ~00s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~00s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~00s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~00s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s  
ss_Borcherding <- ScoreJackStraw(ss_Borcherding, dims = 1:20)

# Visualize JackStraw scores
JackStrawPlot(ss_Borcherding, dims = 1:20)

7. PCA Visualization




# TEST-1
# given that the output of RunPCA is "pca"
# replace "so" by the name of your seurat object

pct <- ss_Borcherding[["pca"]]@stdev / sum(ss_Borcherding[["pca"]]@stdev) * 100
cumu <- cumsum(pct) # Calculate cumulative percents for each PC
# Determine the difference between variation of PC and subsequent PC
co2 <- sort(which((pct[-length(pct)] - pct[-1]) > 0.1), decreasing = T)[1] + 1
# last point where change of % of variation is more than 0.1%. -> co2
co2
[1] 12
# TEST-2
# get significant PCs
stdv <- ss_Borcherding[["pca"]]@stdev
sum.stdv <- sum(ss_Borcherding[["pca"]]@stdev)
percent.stdv <- (stdv / sum.stdv) * 100
cumulative <- cumsum(percent.stdv)
co1 <- which(cumulative > 90 & percent.stdv < 5)[1]
co2 <- sort(which((percent.stdv[1:length(percent.stdv) - 1] - 
                       percent.stdv[2:length(percent.stdv)]) > 0.1), 
              decreasing = T)[1] + 1
min.pc <- min(co1, co2)
min.pc
[1] 12
# Create a dataframe with values
plot_df <- data.frame(pct = percent.stdv, 
           cumu = cumulative, 
           rank = 1:length(percent.stdv))

# Elbow plot to visualize 
  ggplot(plot_df, aes(cumulative, percent.stdv, label = rank, color = rank > min.pc)) + 
  geom_text() + 
  geom_vline(xintercept = 90, color = "grey") + 
  geom_hline(yintercept = min(percent.stdv[percent.stdv > 5]), color = "grey") +
  theme_bw()

NA
NA
NA

8. Clustering (resolution = 1.2)

# Then find neighbors & clusters
ss_Borcherding <- FindNeighbors(ss_Borcherding, dims = 1:10)
Computing nearest neighbor graph
Computing SNN
ss_Borcherding <- FindClusters(ss_Borcherding, resolution = 1.2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 7880
Number of edges: 260091

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7903
Number of communities: 19
Elapsed time: 0 seconds
# run UMAP
ss_Borcherding <- RunUMAP(ss_Borcherding, dims = 1:10)
Warning: The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session16:36:34 UMAP embedding parameters a = 0.9922 b = 1.112
16:36:34 Read 7880 rows and found 10 numeric columns
16:36:34 Using Annoy for neighbor search, n_neighbors = 30
16:36:34 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
16:36:34 Writing NN index file to temp file /tmp/Rtmp8n5s4h/file14a79594363bc
16:36:34 Searching Annoy index using 1 thread, search_k = 3000
16:36:36 Annoy recall = 100%
16:36:36 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 30
16:36:38 Initializing from normalized Laplacian + noise (using RSpectra)
16:36:38 Commencing optimization for 500 epochs, with 322366 positive edges
16:36:38 Using rng type: pcg
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
16:36:44 Optimization finished
RunTSNE(object, dims.use = 1:10)
Error: object 'object' not found

9. Visualize UMAP with Clusters


DimPlot(ss_Borcherding, reduction = "umap",group.by = "sample", label = TRUE, pt.size = 0.6) +
  ggtitle("UMAP of Sézary Syndrome CD4+ T Cells")



DimPlot(ss_Borcherding, reduction = "umap", label = TRUE, pt.size = 0.6) +
  ggtitle("UMAP of Sézary Syndrome CD4+ T Cells")



DimPlot(ss_Borcherding, reduction = "tsne", label = TRUE, pt.size = 0.6) +
  ggtitle("TSNE of Sézary Syndrome CD4+ T Cells")

10. FeaturePlots for Top50 UP

top_50_up <- read.csv("top_50_upregulated.csv")        # or read.delim("top_50_up.tsv")
top_50_down <- read.csv("top_50_downregulated.csv")

Idents(ss_Borcherding) <- "sample"


FeaturePlot(ss_Borcherding, 
             features = top_50_up$gene[1:10], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)
Warning: The following requested variables were not found: PCLAF

FeaturePlot(ss_Borcherding, 
             features = top_50_up$gene[11:20], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)


FeaturePlot(ss_Borcherding, 
             features = top_50_up$gene[21:30], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)

FeaturePlot(ss_Borcherding, 
             features = top_50_up$gene[31:40], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)

FeaturePlot(ss_Borcherding, 
             features = top_50_up$gene[41:50], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)

11. FeaturePlots for Top50 DOWN


FeaturePlot(ss_Borcherding, 
             features = top_50_down$gene[1:10], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)
Warning: The following requested variables were not found: PCED1B-AS1, SNHG5

FeaturePlot(ss_Borcherding, 
             features = top_50_down$gene[11:20], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)
Warning: The following requested variables were not found: RIPOR2

FeaturePlot(ss_Borcherding, 
             features = top_50_down$gene[21:30], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)

FeaturePlot(ss_Borcherding, 
             features = top_50_down$gene[31:40], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)
Warning: The following requested variables were not found: LINC01578

FeaturePlot(ss_Borcherding, 
             features = top_50_down$gene[41:50], 
             reduction = "umap", 
             cols = c("lightblue", "red"),  # Custom color gradient from light blue to red
             label = TRUE)
Warning: The following requested variables were not found: AL138963.4

Visualization



DimPlot(ss_Borcherding, group.by = "seurat_clusters", label = T, label.box = T, repel = T, reduction = "umap")

NA
NA

Visualization of Potential biomarkers-Upregulated


Idents(ss_Borcherding) <- "sample"

# Vector of genes to plot
up_genes <- c("CLIC1", "COX5A","GTSF1", "MAD2L1","MYBL2","MYL6B","NME1","PLK1", "PYCR1", "SLC25A5", "SRI", "TUBA1C", "UBE2T", "YWHAH")

# DotPlot with custom firebrick-red gradient
DotPlot(ss_Borcherding, features = up_genes) +
  RotatedAxis() +
  scale_color_gradient2(low = "lightyellow", mid = "red", high = "firebrick", midpoint = 1) +
  ggtitle("Expression of Upregulated Genes in Sézary Syndrome") +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 12),
    axis.text.y = element_text(size = 12),
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14)
  )
Warning: Scaling data with a low number of groups may produce misleading resultsScale for colour is already present.
Adding another scale for colour, which will replace the existing scale.

Idents(ss_Borcherding) <- "seurat_clusters"

# Vector of genes to plot
up_genes <- c("CLIC1", "COX5A","GTSF1", "MAD2L1","MYBL2","MYL6B","NME1","PLK1", "PYCR1", "SLC25A5", "SRI", "TUBA1C", "UBE2T", "YWHAH")

# DotPlot with custom firebrick-red gradient
DotPlot(ss_Borcherding, features = up_genes) +
  RotatedAxis() +
  scale_color_gradient2(low = "lightyellow", mid = "red", high = "firebrick", midpoint = 1) +
  ggtitle("Expression of Upregulated Genes in Sézary Syndrome") +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 12),
    axis.text.y = element_text(size = 12),
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14)
  )
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.

Visualization of Potential biomarkers-Downregulated


Idents(ss_Borcherding) <- "sample"
# Downregulated genes
down_genes <- c("TXNIP", "RASA3", "RIPOR2", 
                "ZFP36", "ZFP36L1", "ZFP36L2",
                "PRMT2", "MAX", "PIK3IP1", 
                "BTG1", "CDKN1B")

# DotPlot with firebrick color for high expression
DotPlot(ss_Borcherding, features = down_genes) +
  RotatedAxis() +
  scale_color_gradient2(low = "lightyellow", mid = "red", high = "firebrick", midpoint = 1) +
  ggtitle("Expression of Downregulated Genes in Sézary Syndrome") +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 12),
    axis.text.y = element_text(size = 12),
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14)
  )
Warning: The following requested variables were not found: RIPOR2Warning: Scaling data with a low number of groups may produce misleading resultsScale for colour is already present.
Adding another scale for colour, which will replace the existing scale.

Idents(ss_Borcherding) <- "seurat_clusters"

# DotPlot with firebrick color for high expression
DotPlot(ss_Borcherding, features = down_genes) +
  RotatedAxis() +
  scale_color_gradient2(low = "lightyellow", mid = "red", high = "firebrick", midpoint = 1) +
  ggtitle("Expression of Downregulated Genes in Sézary Syndrome") +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 12),
    axis.text.y = element_text(size = 12),
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14)
  )
Warning: The following requested variables were not found: RIPOR2Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.

Save the Seurat object as an RDS



saveRDS(ss_Borcherding, file = "data/ss_Borcherding_Malignant_Normal.rds")
LS0tCnRpdGxlOiAiUG90ZW50aWFsIGJpb21hcmtlcnMgVmFsaWRhdGlvbiBvbiBQdWJsaWMgUGF0aWVudCBkYXRhX0JvcmNoZXJkaW5nXzFfTWFsaWduYW50X2FuZCBOb25tYWxpZ25hbnRfUGF0aWVudF9TYW1wbGUiCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgI3JtZGZvcm1hdHM6OnJlYWR0aGVkb3duCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCi0tLQoKIyAxLiBsb2FkIGxpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KFNldXJhdE9iamVjdCkKbGlicmFyeShTZXVyYXREYXRhKQpsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeShBemltdXRoKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJtYXJrZG93bikKbGlicmFyeSh0aW55dGV4KQoKCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZGl0dG9TZXEpCmxpYnJhcnkoZ2dyZXBlbCkKI2xpYnJhcnkoZ2d0cmVlKQpsaWJyYXJ5KHBhcmFsbGVsKQpsaWJyYXJ5KHBsb3RseSkgICMgM0QgcGxvdApsaWJyYXJ5KFNldXJhdCkgICMgSWRlbnRzKCkKbGlicmFyeShTZXVyYXREaXNrKSAgIyBTYXZlSDVTZXVyYXQoKQpsaWJyYXJ5KHRpYmJsZSkgICMgcm93bm5hbWVzX3RvX2NvbHVtbgpsaWJyYXJ5KGhhcm1vbnkpICMgUnVuSGFybW9ueSgpCiNvcHRpb25zKG1jLmNvcmVzID0gZGV0ZWN0Q29yZXMoKSAtIDEpCgpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShkYnBseXIpCmxpYnJhcnkocm1hcmtkb3duKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KHRpbnl0ZXgpCiNBemltdXRoIEFubm90YXRpb24gbGlicmFyaWVzCmxpYnJhcnkoQXppbXV0aCkKI1Byb2plY1RpbHMgQW5ub3RhdGlvbiBsaWJyYXJpZXMKbGlicmFyeShTVEFDQVMpCmxpYnJhcnkoUHJvamVjVElMcykKI3NpbmdsZVIgQW5ub3RhdGlvbiBsaWJyYXJpZXMKCmxpYnJhcnkoU2luZ2xlQ2VsbEV4cGVyaW1lbnQpCgpgYGAKCgojIDIuIExvYWQgRGF0YSBpbnRvIFNldXJhdApgYGB7ciBsb2FkX3NldXJhdH0KCiMgTG9hZCBTw6l6YXJ5IHN5bmRyb21lIG1hbGlnbmFudCBzYW1wbGUgKHBhdGllbnQpCnNzX2RpciA8LSAiZGF0YS9HU00zNDc4NzkxLyIKc3NfZGF0YSA8LSBSZWFkMTBYKGRhdGEuZGlyID0gc3NfZGlyKQpzcyA8LSBDcmVhdGVTZXVyYXRPYmplY3QoY291bnRzID0gc3NfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0ID0gIlNTX1BhdGllbnQxIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uY2VsbHMgPSAzLCAKICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5mZWF0dXJlcyA9IDIwMCkKc3Mkc2FtcGxlIDwtICJTU19QYXRpZW50MSIKCiMgTG9hZCBjb250cm9sIHNhbXBsZQpjb250cm9sX2RpciA8LSAiZGF0YS9Ob25fbWFsaWduYW50X3BhdGllbnRfQm9yY2hlcmRpbmdfMjAxOS8iICAjIEFkanVzdCB0byB0aGUgYWN0dWFsIGZvbGRlciBuYW1lIG9mIHlvdXIgY29udHJvbApjb250cm9sX2RhdGEgPC0gUmVhZDEwWChkYXRhLmRpciA9IGNvbnRyb2xfZGlyKQpjb250cm9sIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBjb250cm9sX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0ID0gIkNvbnRyb2wiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmNlbGxzID0gMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5mZWF0dXJlcyA9IDIwMCkKY29udHJvbCRzYW1wbGUgPC0gIkNvbnRyb2wiCgojIE1lcmdlIHBhdGllbnQgYW5kIGNvbnRyb2wgU2V1cmF0IG9iamVjdHMKc3NfQm9yY2hlcmRpbmcgPC0gbWVyZ2Uoc3MsIHkgPSBjb250cm9sLCBhZGQuY2VsbC5pZHMgPSBjKCJTUyIsICJDVFJMIiksIHByb2plY3QgPSAiU1NfdnNfQ29udHJvbCIpCgojIEJhc2ljIFFDIGFuZCBmaWx0ZXJpbmcKc3NfQm9yY2hlcmRpbmdbWyJwZXJjZW50Lm10Il1dIDwtIFBlcmNlbnRhZ2VGZWF0dXJlU2V0KHNzX0JvcmNoZXJkaW5nLCBwYXR0ZXJuID0gIl5NVC0iKQpzc19Cb3JjaGVyZGluZyA8LSBzdWJzZXQoc3NfQm9yY2hlcmRpbmcsIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IDIwMCAmIG5GZWF0dXJlX1JOQSA8IDM1MDAgJiBwZXJjZW50Lm10IDwgOSkKCnNzX0JvcmNoZXJkaW5nJHNhbXBsZSA8LSByZWNvZGUoc3NfQm9yY2hlcmRpbmckc2FtcGxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29udHJvbCIgPSAiTm9ybWFsIENENCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTU19QYXRpZW50MSIgPSAiTWFsaWduYW50IENENCIpCgp0YWJsZShzc19Cb3JjaGVyZGluZyRzYW1wbGUpCgoKCmBgYAojIDMuIFFDCmBgYHtyIFFDLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KClZsblBsb3Qoc3NfQm9yY2hlcmRpbmcsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuQ291bnRfUk5BIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwZXJjZW50Lm10IiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jb2wgPSAzKQoKVmxuUGxvdChzc19Cb3JjaGVyZGluZywgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibkNvdW50X1JOQSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwZXJjZW50Lm10IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGVyY2VudC5yYiIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jb2wgPSA0LCBwdC5zaXplID0gMC4xKSAmIAogICAgICAgICAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpCgpGZWF0dXJlU2NhdHRlcihzc19Cb3JjaGVyZGluZywgCiAgICAgICAgICAgICAgIGZlYXR1cmUxID0gIm5Db3VudF9STkEiLCAKICAgICAgICAgICAgICAgZmVhdHVyZTIgPSAibkZlYXR1cmVfUk5BIikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScpCgpgYGAKCiMjRmVhdHVyZVNjYXR0ZXIgaXMgdHlwaWNhbGx5IHVzZWQgdG8gdmlzdWFsaXplIGZlYXR1cmUtZmVhdHVyZSByZWxhdGlvbnNoaXBzCiMjZm9yIGFueXRoaW5nIGNhbGN1bGF0ZWQgYnkgdGhlIG9iamVjdCwgCiMjaS5lLiBjb2x1bW5zIGluIG9iamVjdCBtZXRhZGF0YSwgUEMgc2NvcmVzIGV0Yy4KCmBgYHtyIEZDLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCkZlYXR1cmVTY2F0dGVyKHNzX0JvcmNoZXJkaW5nLCAKICAgICAgICAgICAgICAgZmVhdHVyZTEgPSAibkNvdW50X1JOQSIsIAogICAgICAgICAgICAgICBmZWF0dXJlMiA9ICJwZXJjZW50Lm10IikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJykKCkZlYXR1cmVTY2F0dGVyKHNzX0JvcmNoZXJkaW5nLCAKICAgICAgICAgICAgICAgZmVhdHVyZTEgPSAibkNvdW50X1JOQSIsIAogICAgICAgICAgICAgICBmZWF0dXJlMiA9ICJuRmVhdHVyZV9STkEiKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nKQoKYGBgCiMgNC4gTG9nLW5vcm1hbGl6YXRpb24gKHNjYWxlIGZhY3RvciA9IDEwLDAwMCkKYGBge3IgUENBLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCgpzc19Cb3JjaGVyZGluZyA8LSBOb3JtYWxpemVEYXRhKHNzX0JvcmNoZXJkaW5nLCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJMb2dOb3JtYWxpemUiLCBzY2FsZS5mYWN0b3IgPSAxMDAwMCkKCgoKYGBgCgoKIyA1LiBWYXJpYWJsZSBmZWF0dXJlcyAmIHNjYWxpbmcKYGBge3IgLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCgpzc19Cb3JjaGVyZGluZyA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhzc19Cb3JjaGVyZGluZywgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwKQpzc19Cb3JjaGVyZGluZyA8LSBTY2FsZURhdGEoc3NfQm9yY2hlcmRpbmcsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhzc19Cb3JjaGVyZGluZykpCgoKCmBgYAoKIyA2LiBQQ0EgKyBVTUFQCmBgYHtyICwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgoKIyBQQ0EKc3NfQm9yY2hlcmRpbmcgPC0gUnVuUENBKHNzX0JvcmNoZXJkaW5nLCBmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMoc3NfQm9yY2hlcmRpbmcpKQoKCgoKIyBPcHRpb25hbDogVmlzdWFsaXplIGVsYm93IHBsb3QKRWxib3dQbG90KHNzX0JvcmNoZXJkaW5nLCBuZGltcyA9IDIwKQoKIyBSdW4gSmFja1N0cmF3IGFuYWx5c2lzIHByb3Blcmx5CnNzX0JvcmNoZXJkaW5nIDwtIEphY2tTdHJhdyhzc19Cb3JjaGVyZGluZywgbnVtLnJlcGxpY2F0ZSA9IDEwMCkKc3NfQm9yY2hlcmRpbmcgPC0gU2NvcmVKYWNrU3RyYXcoc3NfQm9yY2hlcmRpbmcsIGRpbXMgPSAxOjIwKQoKIyBWaXN1YWxpemUgSmFja1N0cmF3IHNjb3JlcwpKYWNrU3RyYXdQbG90KHNzX0JvcmNoZXJkaW5nLCBkaW1zID0gMToyMCkKCmBgYAoKIyA3LiBQQ0EgVmlzdWFsaXphdGlvbgpgYGB7ciBQQ0EtVEVTVDIsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQoKCgojIFRFU1QtMQojIGdpdmVuIHRoYXQgdGhlIG91dHB1dCBvZiBSdW5QQ0EgaXMgInBjYSIKIyByZXBsYWNlICJzbyIgYnkgdGhlIG5hbWUgb2YgeW91ciBzZXVyYXQgb2JqZWN0CgpwY3QgPC0gc3NfQm9yY2hlcmRpbmdbWyJwY2EiXV1Ac3RkZXYgLyBzdW0oc3NfQm9yY2hlcmRpbmdbWyJwY2EiXV1Ac3RkZXYpICogMTAwCmN1bXUgPC0gY3Vtc3VtKHBjdCkgIyBDYWxjdWxhdGUgY3VtdWxhdGl2ZSBwZXJjZW50cyBmb3IgZWFjaCBQQwojIERldGVybWluZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHZhcmlhdGlvbiBvZiBQQyBhbmQgc3Vic2VxdWVudCBQQwpjbzIgPC0gc29ydCh3aGljaCgocGN0Wy1sZW5ndGgocGN0KV0gLSBwY3RbLTFdKSA+IDAuMSksIGRlY3JlYXNpbmcgPSBUKVsxXSArIDEKIyBsYXN0IHBvaW50IHdoZXJlIGNoYW5nZSBvZiAlIG9mIHZhcmlhdGlvbiBpcyBtb3JlIHRoYW4gMC4xJS4gLT4gY28yCmNvMgoKIyBURVNULTIKIyBnZXQgc2lnbmlmaWNhbnQgUENzCnN0ZHYgPC0gc3NfQm9yY2hlcmRpbmdbWyJwY2EiXV1Ac3RkZXYKc3VtLnN0ZHYgPC0gc3VtKHNzX0JvcmNoZXJkaW5nW1sicGNhIl1dQHN0ZGV2KQpwZXJjZW50LnN0ZHYgPC0gKHN0ZHYgLyBzdW0uc3RkdikgKiAxMDAKY3VtdWxhdGl2ZSA8LSBjdW1zdW0ocGVyY2VudC5zdGR2KQpjbzEgPC0gd2hpY2goY3VtdWxhdGl2ZSA+IDkwICYgcGVyY2VudC5zdGR2IDwgNSlbMV0KY28yIDwtIHNvcnQod2hpY2goKHBlcmNlbnQuc3RkdlsxOmxlbmd0aChwZXJjZW50LnN0ZHYpIC0gMV0gLSAKICAgICAgICAgICAgICAgICAgICAgICBwZXJjZW50LnN0ZHZbMjpsZW5ndGgocGVyY2VudC5zdGR2KV0pID4gMC4xKSwgCiAgICAgICAgICAgICAgZGVjcmVhc2luZyA9IFQpWzFdICsgMQptaW4ucGMgPC0gbWluKGNvMSwgY28yKQptaW4ucGMKCiMgQ3JlYXRlIGEgZGF0YWZyYW1lIHdpdGggdmFsdWVzCnBsb3RfZGYgPC0gZGF0YS5mcmFtZShwY3QgPSBwZXJjZW50LnN0ZHYsIAogICAgICAgICAgIGN1bXUgPSBjdW11bGF0aXZlLCAKICAgICAgICAgICByYW5rID0gMTpsZW5ndGgocGVyY2VudC5zdGR2KSkKCiMgRWxib3cgcGxvdCB0byB2aXN1YWxpemUgCiAgZ2dwbG90KHBsb3RfZGYsIGFlcyhjdW11bGF0aXZlLCBwZXJjZW50LnN0ZHYsIGxhYmVsID0gcmFuaywgY29sb3IgPSByYW5rID4gbWluLnBjKSkgKyAKICBnZW9tX3RleHQoKSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDkwLCBjb2xvciA9ICJncmV5IikgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtaW4ocGVyY2VudC5zdGR2W3BlcmNlbnQuc3RkdiA+IDVdKSwgY29sb3IgPSAiZ3JleSIpICsKICB0aGVtZV9idygpCgogIAoKYGBgCgojIDguIENsdXN0ZXJpbmcgKHJlc29sdXRpb24gPSAxLjIpCmBgYHtyICwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CiMgVGhlbiBmaW5kIG5laWdoYm9ycyAmIGNsdXN0ZXJzCnNzX0JvcmNoZXJkaW5nIDwtIEZpbmROZWlnaGJvcnMoc3NfQm9yY2hlcmRpbmcsIGRpbXMgPSAxOjEwKQpzc19Cb3JjaGVyZGluZyA8LSBGaW5kQ2x1c3RlcnMoc3NfQm9yY2hlcmRpbmcsIHJlc29sdXRpb24gPSAxLjIpCgojIHJ1biBVTUFQCnNzX0JvcmNoZXJkaW5nIDwtIFJ1blVNQVAoc3NfQm9yY2hlcmRpbmcsIGRpbXMgPSAxOjEwKQoKc3NfQm9yY2hlcmRpbmcgPC1SdW5UU05FKHNzX0JvcmNoZXJkaW5nLCBkaW1zLnVzZSA9IDE6MTApCgpgYGAKCgojIDkuIFZpc3VhbGl6ZSBVTUFQIHdpdGggQ2x1c3RlcnMKYGBge3IgLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCkRpbVBsb3Qoc3NfQm9yY2hlcmRpbmcsIHJlZHVjdGlvbiA9ICJ1bWFwIixncm91cC5ieSA9ICJzYW1wbGUiLCBsYWJlbCA9IFRSVUUsIHB0LnNpemUgPSAwLjYpICsKICBnZ3RpdGxlKCJVTUFQIG9mIFPDqXphcnkgU3luZHJvbWUgQ0Q0KyBUIENlbGxzIikKCgpEaW1QbG90KHNzX0JvcmNoZXJkaW5nLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDAuNikgKwogIGdndGl0bGUoIlVNQVAgb2YgU8OpemFyeSBTeW5kcm9tZSBDRDQrIFQgQ2VsbHMiKQoKCkRpbVBsb3Qoc3NfQm9yY2hlcmRpbmcsIHJlZHVjdGlvbiA9ICJ0c25lIiwgbGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMC42KSArCiAgZ2d0aXRsZSgiVFNORSBvZiBTw6l6YXJ5IFN5bmRyb21lIENENCsgVCBDZWxscyIpCgpgYGAKCiMgMTAuICBGZWF0dXJlUGxvdHMgZm9yIFRvcDUwIFVQCmBgYHtyICwgZmlnLmhlaWdodD0xNiwgZmlnLndpZHRoPTIwfQp0b3BfNTBfdXAgPC0gcmVhZC5jc3YoInRvcF81MF91cHJlZ3VsYXRlZC5jc3YiKSAgICAgICAgIyBvciByZWFkLmRlbGltKCJ0b3BfNTBfdXAudHN2IikKdG9wXzUwX2Rvd24gPC0gcmVhZC5jc3YoInRvcF81MF9kb3ducmVndWxhdGVkLmNzdiIpCgpJZGVudHMoc3NfQm9yY2hlcmRpbmcpIDwtICJzYW1wbGUiCgoKRmVhdHVyZVBsb3Qoc3NfQm9yY2hlcmRpbmcsIAogICAgICAgICAgICAgZmVhdHVyZXMgPSB0b3BfNTBfdXAkZ2VuZVsxOjEwXSwgCiAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsIAogICAgICAgICAgICAgY29scyA9IGMoImxpZ2h0Ymx1ZSIsICJyZWQiKSwgICMgQ3VzdG9tIGNvbG9yIGdyYWRpZW50IGZyb20gbGlnaHQgYmx1ZSB0byByZWQKICAgICAgICAgICAgIGxhYmVsID0gVFJVRSkKCgpGZWF0dXJlUGxvdChzc19Cb3JjaGVyZGluZywgCiAgICAgICAgICAgICBmZWF0dXJlcyA9IHRvcF81MF91cCRnZW5lWzExOjIwXSwgCiAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsIAogICAgICAgICAgICAgY29scyA9IGMoImxpZ2h0Ymx1ZSIsICJyZWQiKSwgICMgQ3VzdG9tIGNvbG9yIGdyYWRpZW50IGZyb20gbGlnaHQgYmx1ZSB0byByZWQKICAgICAgICAgICAgIGxhYmVsID0gVFJVRSkKCkZlYXR1cmVQbG90KHNzX0JvcmNoZXJkaW5nLCAKICAgICAgICAgICAgIGZlYXR1cmVzID0gdG9wXzUwX3VwJGdlbmVbMjE6MzBdLCAKICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwgCiAgICAgICAgICAgICBjb2xzID0gYygibGlnaHRibHVlIiwgInJlZCIpLCAgIyBDdXN0b20gY29sb3IgZ3JhZGllbnQgZnJvbSBsaWdodCBibHVlIHRvIHJlZAogICAgICAgICAgICAgbGFiZWwgPSBUUlVFKQpGZWF0dXJlUGxvdChzc19Cb3JjaGVyZGluZywgCiAgICAgICAgICAgICBmZWF0dXJlcyA9IHRvcF81MF91cCRnZW5lWzMxOjQwXSwgCiAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsIAogICAgICAgICAgICAgY29scyA9IGMoImxpZ2h0Ymx1ZSIsICJyZWQiKSwgICMgQ3VzdG9tIGNvbG9yIGdyYWRpZW50IGZyb20gbGlnaHQgYmx1ZSB0byByZWQKICAgICAgICAgICAgIGxhYmVsID0gVFJVRSkKRmVhdHVyZVBsb3Qoc3NfQm9yY2hlcmRpbmcsIAogICAgICAgICAgICAgZmVhdHVyZXMgPSB0b3BfNTBfdXAkZ2VuZVs0MTo1MF0sIAogICAgICAgICAgICAgcmVkdWN0aW9uID0gInVtYXAiLCAKICAgICAgICAgICAgIGNvbHMgPSBjKCJsaWdodGJsdWUiLCAicmVkIiksICAjIEN1c3RvbSBjb2xvciBncmFkaWVudCBmcm9tIGxpZ2h0IGJsdWUgdG8gcmVkCiAgICAgICAgICAgICBsYWJlbCA9IFRSVUUpCgpgYGAKCgoKIyAxMS4gIEZlYXR1cmVQbG90cyBmb3IgVG9wNTAgRE9XTgpgYGB7ciAsIGZpZy5oZWlnaHQ9MTYsIGZpZy53aWR0aD0yMH0KCkZlYXR1cmVQbG90KHNzX0JvcmNoZXJkaW5nLCAKICAgICAgICAgICAgIGZlYXR1cmVzID0gdG9wXzUwX2Rvd24kZ2VuZVsxOjEwXSwgCiAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsIAogICAgICAgICAgICAgY29scyA9IGMoImxpZ2h0Ymx1ZSIsICJyZWQiKSwgICMgQ3VzdG9tIGNvbG9yIGdyYWRpZW50IGZyb20gbGlnaHQgYmx1ZSB0byByZWQKICAgICAgICAgICAgIGxhYmVsID0gVFJVRSkKCgpGZWF0dXJlUGxvdChzc19Cb3JjaGVyZGluZywgCiAgICAgICAgICAgICBmZWF0dXJlcyA9IHRvcF81MF9kb3duJGdlbmVbMTE6MjBdLCAKICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwgCiAgICAgICAgICAgICBjb2xzID0gYygibGlnaHRibHVlIiwgInJlZCIpLCAgIyBDdXN0b20gY29sb3IgZ3JhZGllbnQgZnJvbSBsaWdodCBibHVlIHRvIHJlZAogICAgICAgICAgICAgbGFiZWwgPSBUUlVFKQoKRmVhdHVyZVBsb3Qoc3NfQm9yY2hlcmRpbmcsIAogICAgICAgICAgICAgZmVhdHVyZXMgPSB0b3BfNTBfZG93biRnZW5lWzIxOjMwXSwgCiAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsIAogICAgICAgICAgICAgY29scyA9IGMoImxpZ2h0Ymx1ZSIsICJyZWQiKSwgICMgQ3VzdG9tIGNvbG9yIGdyYWRpZW50IGZyb20gbGlnaHQgYmx1ZSB0byByZWQKICAgICAgICAgICAgIGxhYmVsID0gVFJVRSkKRmVhdHVyZVBsb3Qoc3NfQm9yY2hlcmRpbmcsIAogICAgICAgICAgICAgZmVhdHVyZXMgPSB0b3BfNTBfZG93biRnZW5lWzMxOjQwXSwgCiAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsIAogICAgICAgICAgICAgY29scyA9IGMoImxpZ2h0Ymx1ZSIsICJyZWQiKSwgICMgQ3VzdG9tIGNvbG9yIGdyYWRpZW50IGZyb20gbGlnaHQgYmx1ZSB0byByZWQKICAgICAgICAgICAgIGxhYmVsID0gVFJVRSkKRmVhdHVyZVBsb3Qoc3NfQm9yY2hlcmRpbmcsIAogICAgICAgICAgICAgZmVhdHVyZXMgPSB0b3BfNTBfZG93biRnZW5lWzQxOjUwXSwgCiAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsIAogICAgICAgICAgICAgY29scyA9IGMoImxpZ2h0Ymx1ZSIsICJyZWQiKSwgICMgQ3VzdG9tIGNvbG9yIGdyYWRpZW50IGZyb20gbGlnaHQgYmx1ZSB0byByZWQKICAgICAgICAgICAgIGxhYmVsID0gVFJVRSkKYGBgCgojIyBWaXN1YWxpemF0aW9uCmBgYHtyICwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgoKRGltUGxvdChzc19Cb3JjaGVyZGluZywgZ3JvdXAuYnkgPSAic2V1cmF0X2NsdXN0ZXJzIiwgbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBULCByZXBlbCA9IFQsIHJlZHVjdGlvbiA9ICJ1bWFwIikKCgpgYGAKCiMjIFZpc3VhbGl6YXRpb24gb2YgUG90ZW50aWFsIGJpb21hcmtlcnMtVXByZWd1bGF0ZWQKYGBge3IgLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCklkZW50cyhzc19Cb3JjaGVyZGluZykgPC0gInNhbXBsZSIKCiMgVmVjdG9yIG9mIGdlbmVzIHRvIHBsb3QKdXBfZ2VuZXMgPC0gYygiQ0xJQzEiLCAiQ09YNUEiLCJHVFNGMSIsICJNQUQyTDEiLCJNWUJMMiIsIk1ZTDZCIiwiTk1FMSIsIlBMSzEiLCAiUFlDUjEiLCAiU0xDMjVBNSIsICJTUkkiLCAiVFVCQTFDIiwgIlVCRTJUIiwgIllXSEFIIikKCiMgRG90UGxvdCB3aXRoIGN1c3RvbSBmaXJlYnJpY2stcmVkIGdyYWRpZW50CkRvdFBsb3Qoc3NfQm9yY2hlcmRpbmcsIGZlYXR1cmVzID0gdXBfZ2VuZXMpICsKICBSb3RhdGVkQXhpcygpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gImxpZ2h0eWVsbG93IiwgbWlkID0gInJlZCIsIGhpZ2ggPSAiZmlyZWJyaWNrIiwgbWlkcG9pbnQgPSAxKSArCiAgZ2d0aXRsZSgiRXhwcmVzc2lvbiBvZiBVcHJlZ3VsYXRlZCBHZW5lcyBpbiBTw6l6YXJ5IFN5bmRyb21lIikgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkKICApCgpJZGVudHMoc3NfQm9yY2hlcmRpbmcpIDwtICJzZXVyYXRfY2x1c3RlcnMiCgojIFZlY3RvciBvZiBnZW5lcyB0byBwbG90CnVwX2dlbmVzIDwtIGMoIkNMSUMxIiwgIkNPWDVBIiwiR1RTRjEiLCAiTUFEMkwxIiwiTVlCTDIiLCJNWUw2QiIsIk5NRTEiLCJQTEsxIiwgIlBZQ1IxIiwgIlNMQzI1QTUiLCAiU1JJIiwgIlRVQkExQyIsICJVQkUyVCIsICJZV0hBSCIpCgojIERvdFBsb3Qgd2l0aCBjdXN0b20gZmlyZWJyaWNrLXJlZCBncmFkaWVudApEb3RQbG90KHNzX0JvcmNoZXJkaW5nLCBmZWF0dXJlcyA9IHVwX2dlbmVzKSArCiAgUm90YXRlZEF4aXMoKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQyKGxvdyA9ICJsaWdodHllbGxvdyIsIG1pZCA9ICJyZWQiLCBoaWdoID0gImZpcmVicmljayIsIG1pZHBvaW50ID0gMSkgKwogIGdndGl0bGUoIkV4cHJlc3Npb24gb2YgVXByZWd1bGF0ZWQgR2VuZXMgaW4gU8OpemFyeSBTeW5kcm9tZSIpICsKICB0aGVtZSgKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpCiAgKQoKCmBgYAoKCgojIyBWaXN1YWxpemF0aW9uIG9mIFBvdGVudGlhbCBiaW9tYXJrZXJzLURvd25yZWd1bGF0ZWQKYGBge3IgQzIsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQoKSWRlbnRzKHNzX0JvcmNoZXJkaW5nKSA8LSAic2FtcGxlIgojIERvd25yZWd1bGF0ZWQgZ2VuZXMKZG93bl9nZW5lcyA8LSBjKCJUWE5JUCIsICJSQVNBMyIsICJSSVBPUjIiLCAKICAgICAgICAgICAgICAgICJaRlAzNiIsICJaRlAzNkwxIiwgIlpGUDM2TDIiLAogICAgICAgICAgICAgICAgIlBSTVQyIiwgIk1BWCIsICJQSUszSVAxIiwgCiAgICAgICAgICAgICAgICAiQlRHMSIsICJDREtOMUIiKQoKIyBEb3RQbG90IHdpdGggZmlyZWJyaWNrIGNvbG9yIGZvciBoaWdoIGV4cHJlc3Npb24KRG90UGxvdChzc19Cb3JjaGVyZGluZywgZmVhdHVyZXMgPSBkb3duX2dlbmVzKSArCiAgUm90YXRlZEF4aXMoKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQyKGxvdyA9ICJsaWdodHllbGxvdyIsIG1pZCA9ICJyZWQiLCBoaWdoID0gImZpcmVicmljayIsIG1pZHBvaW50ID0gMSkgKwogIGdndGl0bGUoIkV4cHJlc3Npb24gb2YgRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBTw6l6YXJ5IFN5bmRyb21lIikgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkKICApCklkZW50cyhzc19Cb3JjaGVyZGluZykgPC0gInNldXJhdF9jbHVzdGVycyIKCiMgRG90UGxvdCB3aXRoIGZpcmVicmljayBjb2xvciBmb3IgaGlnaCBleHByZXNzaW9uCkRvdFBsb3Qoc3NfQm9yY2hlcmRpbmcsIGZlYXR1cmVzID0gZG93bl9nZW5lcykgKwogIFJvdGF0ZWRBeGlzKCkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAibGlnaHR5ZWxsb3ciLCBtaWQgPSAicmVkIiwgaGlnaCA9ICJmaXJlYnJpY2siLCBtaWRwb2ludCA9IDEpICsKICBnZ3RpdGxlKCJFeHByZXNzaW9uIG9mIERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gU8OpemFyeSBTeW5kcm9tZSIpICsKICB0aGVtZSgKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpCiAgKQpgYGAKCiMgU2F2ZSB0aGUgU2V1cmF0IG9iamVjdCBhcyBhbiBSRFMKYGBge3Igc2F2ZVJEU30KCgpzYXZlUkRTKHNzX0JvcmNoZXJkaW5nLCBmaWxlID0gImRhdGEvc3NfQm9yY2hlcmRpbmdfTWFsaWduYW50X05vcm1hbC5yZHMiKQoKCmBgYAoKCgo=