diff --git a/scripts/object_conversion/seurat/generate_SCP_files.Rmd b/scripts/object_conversion/seurat/generate_SCP_files.Rmd new file mode 100644 index 0000000..4c54872 --- /dev/null +++ b/scripts/object_conversion/seurat/generate_SCP_files.Rmd @@ -0,0 +1,156 @@ +--- +title: "Create SCP files" +output: html_notebook +--- +## Setup +This R notebook uses [code written by Velina Kozareva](https://github.com/vkozareva/single_cell_portal/blob/object-conversion-scripts/scripts/object_conversion/seurat/seurat_scp_convenience.R) with the following change: +line 159 was +} else if (s_version == 3) { +Velina's code was written before Seurat v4 existed so the line now needs to be +} else if (s_version >= 3) { + +Example precomputed Seurat object downloaded from https://www.dropbox.com/s/63gnlw45jf7cje8/pbmc3k_final.rds?dl=1 +(reference: https://satijalab.org/seurat/archive/v3.0/de_vignette.html) + +Save the modified code as a file in the same directory as your Seurat object file (in this case, pbmc3k_final.rds; replace in the code block below with the name of your Seurat object file) and call the file with the modified version of Velina's code: seurat_scp_convenience_v2.R + +Save this Rmd file in the same directory. This should allow you to source Velina's code and read your Seurat object by using the code below. If you encounter an message indicating "cannot open the connection", try replacing the filename in the command with the full path to the file. + +### Adapt the following code to generate SCP files from your Seurat object +##### Name the output directory where you would like your SCP files to be written + +```{r} +source("seurat_scp_convenience_v2.R") +library(Seurat) +data <- readRDS(file = "pbmc3k_final.rds") +outdir <- "SCP_files" +if (!dir.exists(outdir)) {dir.create(outdir)} +#if you don't want a prefix, set it to the empty string "" +prefix = "expt1" +``` + +### General information about the Seurat object, confirm the object is as expected +```{r} +data +``` + +### Use this block to add a prefix to your cells if renaming ALL cells +####### This is useful if multiple runs have identical cell barcodes +##### The following code would need to be modified if SUBSETs of cells need to be differentially prefixed. +```{r} +if (length(prefix)) { + # add.cell.id puts underscore between prefix and original cell name + #data <- RenameCells(data, add.cell.id = prefix) + # set up the following to put a hyphen, rather than underscore, as separator + # which separator you choose is up to you, both are acceptable + data <- RenameCells(data, new.names = paste0(prefix, "-", colnames(data))) + head(colnames(data)) +} +``` + +## The code in this notebook assumes: +## - raw counts in the "counts" slot under @assays in the Seurat Object +## - processed counts in the "data" slot under @assays in the Seurat Object +## - metadata under @meta.data in the Seurat Object +## - "umap" calculation under @reductions in the Seurat Object +### if your data is not stored as described above, please modify the code to reflect your Seurat object's layout + +### Show details of the Seurat object +##### including the analysis commands that have been run on the data +```{r} +str(data) +``` +### Update the Seurat object, if needed +##### This notebook should still work with Seurat v2 but has not been tested +```{r} +s_version <- packageVersion('Seurat')$major + if (s_version == 2) { + stop ('Portions of this notebook may need updating for Seurat v2, proceed with caution.') + } else if (s_version >= 3) { + data <- UpdateSeuratObject(object = data) + } else { + stop ('Seurat v1 objects are not supported.') + } +``` + +### Generate a cluster file +##### Many reduction.use options are possible, **replace "umap" with the dimensionality reduction option used in the analysis**. Refer to the output of str(data) if unfamiliar with how the data was analyzed (look under @reductions) +```{r} +cluster_name <- paste0(outdir, "/", prefix, "-", "cluster.tsv") +generateClusterFile(data, cluster_name, reduction.use = "umap") +``` + + +### Generate raw and processed count matrices +##### files generated have fixed names (matrix.mtx, barcodes.tsv, genes.tsv) +##### SCP expects raw and processed matrices to have different file names, rename one set of matrices prior to upload +```{r} +raw_dir <- paste0(outdir, "/", "raw") +# create raw count MTX IF using conventional Seurat slot naming +generateExpressionMatrix(data, raw_dir, slot.use = "counts", compress.files = T) + +proc_dir <- paste0(outdir, "/", "processed") +# create processed count MTX IF using conventional Seurat slot naming +generateExpressionMatrix(data, proc_dir, slot.use = "data", compress.files = T) +``` + +### Add SCP required metadata to your Seurat object +##### Use the interactive metadata option to add metadata that are consistent across ALL cells +###### metadata that vary by groups of cells cannot be annotated using this script (eg. if you have multiple biosamples, diease vs control; or multiple donors, mouse1, mouse2 ... mouseN) +##### Many SCP required metadata are ontology-based, look up ontology ID values using the links found at https://singlecell.zendesk.com/hc/en-us/articles/360060609852-Required-Metadata +##### ontology labels are the human-readable text that accompany ontology IDs +###### SCP uses the ontology_label to validate that the provided ontology ID is the intended term and not mis-entered +##### For example: For the metadata "species", NCBITaxon_9606 is a valid ontology ID +##### Homo sapiens is the corresponding value for "species__ontology_label" + +#### **When prompted to "Enter columns you wish to add" provide the following metadata columns as they are also SCP required metadata** +##### species__ontology_label disease__ontology_label organ__ontology_label library_preparation_protocol__ontology_label +```{r} +#Velina's script does not add the required ontology label columns +#use the "add optional metadata" feature in addConsistentMetadataColumns + +data = addConsistentMetadataColumns(data, return.object = T) +``` +###### If you use Excel to add metadata that varies by groups of cells, take care that Excel copy/paste does not automagically increment the pasted value (ie. NCBITaxon_9606, NCBITaxon_9607, NCBITaxon_9608 etc) + + + +### Review existing metadata and identify metadata to exclude +##### ie. any metadata unique to all cells OR metadata not useful for analysis +#### **use the generated string of column names in the next (Generate metadata file) block** +```{r} +metadata = data@meta.data +#Edit this string to rename metadata or exclude metadata +dput(colnames(metadata)) +``` + +### Generate metadata file +##### cols.use can be used to omit metadata columns or to re-order the columns +##### use the string in the block above to manipulate the metadata file you will generate +##### column order in cols.use determines the order the metadata are listed in the annotations dropdown +### **column names can only have only alphanumeric characters and underscore characters** +##### new.col.names can be used to rename columns such as "percent.mt" which have characters that are disallowed +###### for this example, metadata names with "." separators were replaced with "_" +###### if a metadata (for example, orig.ident) was not useful, it can be omitted from both cols.use and new.col.names and that metadata will be omitted from the output file. +##### spacing in generateMetadataFile command was added for readability, the string from the prior block can be cut and paste as-is and does not need to resemble the block below. +```{r} +metadata_name <- paste0(outdir, "/", prefix, "-", "metadata.tsv") +# generate metadata file omitting "orig.ident" +generateMetadataFile(data, metadata_name, + cols.use = c( "seurat_clusters", "biosample_id", "donor_id", + "species", "disease", "organ", "library_preparation_protocol", + "sex", "biosample_type", "species__ontology_label", + "disease__ontology_label", "organ__ontology_label", + "library_preparation_protocol__ontology_label", + "orig.ident", "nCount_RNA", "nFeature_RNA", + "percent.mt","RNA_snn_res.0.5"), + new.col.names = c( "seurat_clusters", "biosample_id", "donor_id", + "species", "disease", "organ", "library_preparation_protocol", + "sex", "biosample_type", "species__ontology_label", + "disease__ontology_label", "organ__ontology_label", + "library_preparation_protocol__ontology_label", + "orig_ident", "nCount_RNA", "nFeature_RNA", + "percent_mt", "RNA_snn_res_0_5") +) +``` + diff --git a/scripts/object_conversion/seurat/generate_SCP_files.nb.html b/scripts/object_conversion/seurat/generate_SCP_files.nb.html new file mode 100644 index 0000000..9027d22 --- /dev/null +++ b/scripts/object_conversion/seurat/generate_SCP_files.nb.html @@ -0,0 +1,990 @@ + + + + + + + + + + + + + +Create SCP files + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+

Setup

+

This R notebook uses code written by Velina Kozareva with the following change:
+line 159 was
+} else if (s_version == 3) {
+Velina’s code was written before Seurat v4 existed so the line now needs to be
+} else if (s_version >= 3) {

+

Example precomputed Seurat object downloaded from https://www.dropbox.com/s/63gnlw45jf7cje8/pbmc3k_final.rds?dl=1 (reference: https://satijalab.org/seurat/archive/v3.0/de_vignette.html)

+

Save the modified code as a file in the same directory as your Seurat object file (in this case, pbmc3k_final.rds; replace in the code block below with the name of your Seurat object file) and call the file with the modified version of Velina’s code: seurat_scp_convenience_v2.R

+

Save this Rmd file in the same directory. This should allow you to source Velina’s code and read your Seurat object by using the code below. If you encounter an message indicating “cannot open the connection”, try replacing the filename in the command with the full path to the file.

+
+

Adapt the following code to generate SCP files from your Seurat object

+
+
Name the output directory where you would like your SCP files to be written
+ + + +
source("seurat_scp_convenience_v2.R")
+library(Seurat)
+ + +
Registered S3 method overwritten by 'data.table':
+  method           from
+  print.data.table     
+Registered S3 method overwritten by 'htmlwidgets':
+  method           from         
+  print.htmlwidget tools:rstudio
+Attaching SeuratObject
+ + +
data <- readRDS(file = "pbmc3k_final.rds")
+outdir <- "SCP_files"
+if (!dir.exists(outdir)) {dir.create(outdir)}
+#if you don't want a prefix, set it to the empty string ""
+prefix = "expt1"
+ + + +
+
+
+

General information about the Seurat object, confirm the object is as expected

+ + + +
data
+ + +
An object of class Seurat 
+13714 features across 2638 samples within 1 assay 
+Active assay: RNA (13714 features, 2000 variable features)
+ 2 dimensional reductions calculated: pca, umap
+ + + +
+
+

Use this block to add a prefix to your cells if renaming ALL cells

+
+

This is useful if multiple runs have identical cell barcodes

+
+
+
The following code would need to be modified if SUBSETs of cells need to be differentially prefixed.
+ + + +
if (length(prefix)) {
+  # add.cell.id puts underscore between prefix and original cell name
+  #data <- RenameCells(data, add.cell.id = prefix)
+  # set up the following to put a hyphen, rather than underscore, as separator
+  # which separator you choose is up to you, both are acceptable
+  data <- RenameCells(data, new.names = paste0(prefix, "-", colnames(data)))
+  head(colnames(data))
+}
+ + +
Warning: Adding a Graph without an assay associated with it
+Warning: Adding a Graph without an assay associated with it
+Warning: Adding a Graph without an assay associated with it
+Warning: Adding a Graph without an assay associated with it
+ + +
[1] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" "expt1-AAACCGTGTATGCG"
+[6] "expt1-AAACGCACTGGTAC"
+ + + +
+
+
+
+

The code in this notebook assumes:

+
+
+

- raw counts in the “counts” slot under @assays in the Seurat Object

+
+
+

- processed counts in the “data” slot under @assays in the Seurat Object

+
+
+

- metadata under @meta.data in the Seurat Object

+
+
+

- “umap” calculation under @reductions in the Seurat Object

+
+

if your data is not stored as described above, please modify the code to reflect your Seurat object’s layout

+
+
+

Show details of the Seurat object

+
+
including the analysis commands that have been run on the data
+ + + +
str(data)
+ + +
Formal class 'Seurat' [package "SeuratObject"] with 13 slots
+  ..@ assays      :List of 1
+  .. ..$ RNA:Formal class 'Assay' [package "Seurat"] with 8 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.orig" for this object of class "Assay"
+ + +
  .. .. .. ..@ counts       :Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
+  .. .. .. .. .. ..@ i       : int [1:2238732] 29 73 80 148 163 184 186 227 229 230 ...
+  .. .. .. .. .. ..@ p       : int [1:2639] 0 779 2131 3260 4220 4741 5522 6304 7094 7626 ...
+  .. .. .. .. .. ..@ Dim     : int [1:2] 13714 2638
+  .. .. .. .. .. ..@ Dimnames:List of 2
+  .. .. .. .. .. .. ..$ : chr [1:13714] "AL627309.1" "AP006222.2" "RP11-206L10.2" "RP11-206L10.9" ...
+  .. .. .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. .. .. ..@ x       : num [1:2238732] 1 1 2 1 1 1 1 41 1 1 ...
+  .. .. .. .. .. ..@ factors : list()
+  .. .. .. ..@ data         :Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
+  .. .. .. .. .. ..@ i       : int [1:2238732] 29 73 80 148 163 184 186 227 229 230 ...
+  .. .. .. .. .. ..@ p       : int [1:2639] 0 779 2131 3260 4220 4741 5522 6304 7094 7626 ...
+  .. .. .. .. .. ..@ Dim     : int [1:2] 13714 2638
+  .. .. .. .. .. ..@ Dimnames:List of 2
+  .. .. .. .. .. .. ..$ : chr [1:13714] "AL627309.1" "AP006222.2" "RP11-206L10.2" "RP11-206L10.9" ...
+  .. .. .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. .. .. ..@ x       : num [1:2238732] 1.64 1.64 2.23 1.64 1.64 ...
+  .. .. .. .. .. ..@ factors : list()
+  .. .. .. ..@ scale.data   : num [1:13714, 1:2638] -0.0581 -0.0336 -0.0417 -0.0336 -0.0822 ...
+  .. .. .. .. ..- attr(*, "dimnames")=List of 2
+  .. .. .. .. .. ..$ : chr [1:13714] "AL627309.1" "AP006222.2" "RP11-206L10.2" "RP11-206L10.9" ...
+  .. .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. ..@ key          : chr "rna_"
+  .. .. .. ..@ var.features : chr [1:2000] "PPBP" "LYZ" "S100A9" "IGLL5" ...
+  .. .. .. ..@ meta.features:'data.frame':  13714 obs. of  4 variables:
+  .. .. .. .. ..$ mean                 : num [1:13714] 0.00341 0.00114 0.0019 0.00114 0.00682 ...
+  .. .. .. .. ..$ variance             : num [1:13714] 0.0034 0.00114 0.00189 0.00114 0.00678 ...
+  .. .. .. .. ..$ variance.expected    : num [1:13714] 0.00365 0.00114 0.00197 0.00114 0.00748 ...
+  .. .. .. .. ..$ variance.standardized: num [1:13714] 0.933 0.992 0.963 0.992 0.906 ...
+  .. .. .. ..@ misc         : symbol NULL
+  .. .. .. ..@ NA           : NULL
+  ..@ meta.data   :'data.frame':    2638 obs. of  6 variables:
+  .. ..$ orig.ident     : Factor w/ 1 level "pbmc3k": 1 1 1 1 1 1 1 1 1 1 ...
+  .. ..$ nCount_RNA     : num [1:2638] 2419 4903 3147 2639 980 ...
+  .. ..$ nFeature_RNA   : int [1:2638] 779 1352 1129 960 521 781 782 790 532 550 ...
+  .. ..$ percent.mt     : num [1:2638] 3.02 3.79 0.89 1.74 1.22 ...
+  .. ..$ RNA_snn_res.0.5: Factor w/ 9 levels "0","1","2","3",..: 2 4 2 3 7 2 5 5 1 6 ...
+  .. ..$ seurat_clusters: Factor w/ 9 levels "0","1","2","3",..: 2 4 2 3 7 2 5 5 1 6 ...
+  ..@ active.assay: chr "RNA"
+  ..@ active.ident: Factor w/ 9 levels "Naive CD4 T",..: 2 4 2 3 7 2 5 5 1 6 ...
+  .. ..- attr(*, "names")= chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  ..@ graphs      :List of 2
+  .. ..$ RNA_nn :Formal class 'Graph' [package "Seurat"] with 7 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "Graph"
+ + +
  .. .. .. ..@ i       : int [1:52760] 0 6 102 203 292 421 451 511 547 618 ...
+  .. .. .. ..@ p       : int [1:2639] 0 37 55 78 95 102 113 150 173 184 ...
+  .. .. .. ..@ Dim     : int [1:2] 2638 2638
+  .. .. .. ..@ Dimnames:List of 2
+  .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. ..@ x       : num [1:52760] 1 1 1 1 1 1 1 1 1 1 ...
+  .. .. .. ..@ factors : list()
+  .. .. .. ..@ NA      : NULL
+  .. ..$ RNA_snn:Formal class 'Graph' [package "Seurat"] with 7 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "Graph"
+ + +
  .. .. .. ..@ i       : int [1:194704] 0 6 76 102 167 171 187 203 229 292 ...
+  .. .. .. ..@ p       : int [1:2639] 0 80 145 197 252 299 367 463 523 573 ...
+  .. .. .. ..@ Dim     : int [1:2] 2638 2638
+  .. .. .. ..@ Dimnames:List of 2
+  .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. ..@ x       : num [1:194704] 1 0.1111 0.0811 0.2121 0.0811 ...
+  .. .. .. ..@ factors : list()
+  .. .. .. ..@ NA      : NULL
+  ..@ neighbors   : list()
+  ..@ reductions  :List of 2
+  .. ..$ pca :Formal class 'DimReduc' [package "SeuratObject"] with 9 slots
+  .. .. .. ..@ cell.embeddings           : num [1:2638, 1:50] -4.73 -0.517 -3.189 12.793 -3.129 ...
+  .. .. .. .. ..- attr(*, "dimnames")=List of 2
+  .. .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. .. .. ..$ : chr [1:50] "PC_1" "PC_2" "PC_3" "PC_4" ...
+  .. .. .. ..@ feature.loadings          : num [1:2000, 1:50] 0.01099 0.11623 0.11541 -0.00799 -0.01524 ...
+  .. .. .. .. ..- attr(*, "dimnames")=List of 2
+  .. .. .. .. .. ..$ : chr [1:2000] "PPBP" "LYZ" "S100A9" "IGLL5" ...
+  .. .. .. .. .. ..$ : chr [1:50] "PC_1" "PC_2" "PC_3" "PC_4" ...
+  .. .. .. ..@ feature.loadings.projected: num[0 , 0 ] 
+  .. .. .. ..@ assay.used                : chr "RNA"
+  .. .. .. ..@ global                    : logi FALSE
+  .. .. .. ..@ stdev                     : num [1:50] 7.1 4.5 3.87 3.75 3.17 ...
+  .. .. .. ..@ key                       : chr "PC_"
+  .. .. .. ..@ jackstraw                 :Formal class 'JackStrawData' [package "Seurat"] with 4 slots
+  .. .. .. .. .. ..@ empirical.p.values     : num [1:2000, 1:20] 0.0005 0 0 0.0035 0 0 0.0045 0 0.006 0 ...
+  .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
+  .. .. .. .. .. .. .. ..$ : chr [1:2000] "PPBP" "LYZ" "S100A9" "IGLL5" ...
+  .. .. .. .. .. .. .. ..$ : chr [1:20] "PC1" "PC2" "PC3" "PC4" ...
+  .. .. .. .. .. ..@ fake.reduction.scores  : num [1:2000, 1:20] 0.004436 0.001927 0.003784 0.000461 -0.000823 ...
+  .. .. .. .. .. ..@ empirical.p.values.full: logi [1, 1] NA
+  .. .. .. .. .. ..@ overall.p.values       : num [1:20, 1:2] 1 2 3 4 5 6 7 8 9 10 ...
+  .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
+  .. .. .. .. .. .. .. ..$ : NULL
+  .. .. .. .. .. .. .. ..$ : chr [1:2] "PC" "Score"
+  .. .. .. ..@ misc                      :List of 1
+  .. .. .. .. ..$ total.variance: num 1734
+  .. ..$ umap:Formal class 'DimReduc' [package "SeuratObject"] with 9 slots
+  .. .. .. ..@ cell.embeddings           : num [1:2638, 1:2] 10.6 15.6 13 26.7 13.4 ...
+  .. .. .. .. ..- attr(*, "dimnames")=List of 2
+  .. .. .. .. .. ..$ : chr [1:2638] "expt1-AAACATACAACCAC" "expt1-AAACATTGAGCTAC" "expt1-AAACATTGATCAGC" "expt1-AAACCGTGCTTCCG" ...
+  .. .. .. .. .. ..$ : chr [1:2] "UMAP_1" "UMAP_2"
+  .. .. .. ..@ feature.loadings          : num[0 , 0 ] 
+  .. .. .. ..@ feature.loadings.projected: num[0 , 0 ] 
+  .. .. .. ..@ assay.used                : chr "RNA"
+  .. .. .. ..@ global                    : logi FALSE
+  .. .. .. ..@ stdev                     : num(0) 
+  .. .. .. ..@ key                       : chr "UMAP_"
+  .. .. .. ..@ jackstraw                 :Formal class 'JackStrawData' [package "Seurat"] with 4 slots
+  .. .. .. .. .. ..@ empirical.p.values     : num[0 , 0 ] 
+  .. .. .. .. .. ..@ fake.reduction.scores  : num[0 , 0 ] 
+  .. .. .. .. .. ..@ empirical.p.values.full: num[0 , 0 ] 
+  .. .. .. .. .. ..@ overall.p.values       : num[0 , 0 ] 
+  .. .. .. ..@ misc                      : list()
+  ..@ images      : list()
+  ..@ project.name: chr "pbmc3k"
+  ..@ misc        : list()
+  ..@ version     :Classes 'package_version', 'numeric_version'  hidden list of 1
+  .. ..$ : int [1:4] 3 0 0 9150
+  ..@ commands    :List of 9
+  .. ..$ NormalizeData.RNA       :Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "NormalizeData.RNA"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:29:22"
+  .. .. .. ..@ call.string: chr [1:2] "NormalizeData(object = pbmc, normalization.method = \"LogNormalize\", " "    scale.factor = 10000)"
+  .. .. .. ..@ params     :List of 5
+  .. .. .. .. ..$ assay               : chr "RNA"
+  .. .. .. .. ..$ normalization.method: chr "LogNormalize"
+  .. .. .. .. ..$ scale.factor        : num 10000
+  .. .. .. .. ..$ margin              : num 1
+  .. .. .. .. ..$ verbose             : logi TRUE
+  .. .. .. ..@ NA         : NULL
+  .. ..$ FindVariableFeatures.RNA:Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "FindVariableFeatures.RNA"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:29:23"
+  .. .. .. ..@ call.string: chr [1:2] "FindVariableFeatures(object = pbmc, selection.method = \"vst\", " "    nfeatures = 2000)"
+  .. .. .. ..@ params     :List of 12
+  .. .. .. .. ..$ assay              : chr "RNA"
+  .. .. .. .. ..$ selection.method   : chr "vst"
+  .. .. .. .. ..$ loess.span         : num 0.3
+  .. .. .. .. ..$ clip.max           : chr "auto"
+  .. .. .. .. ..$ mean.function      :function (mat, display_progress)  
+  .. .. .. .. ..$ dispersion.function:function (mat, display_progress)  
+  .. .. .. .. ..$ num.bin            : num 20
+  .. .. .. .. ..$ binning.method     : chr "equal_width"
+  .. .. .. .. ..$ nfeatures          : num 2000
+  .. .. .. .. ..$ mean.cutoff        : num [1:2] 0.1 8
+  .. .. .. .. ..$ dispersion.cutoff  : num [1:2] 1 Inf
+  .. .. .. .. ..$ verbose            : logi TRUE
+  .. .. .. ..@ NA         : NULL
+  .. ..$ ScaleData.RNA           :Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "ScaleData.RNA"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:29:29"
+  .. .. .. ..@ call.string: chr "ScaleData(object = pbmc, features = all.genes)"
+  .. .. .. ..@ params     :List of 10
+  .. .. .. .. ..$ features          : chr [1:13714] "AL627309.1" "AP006222.2" "RP11-206L10.2" "RP11-206L10.9" ...
+  .. .. .. .. ..$ assay             : chr "RNA"
+  .. .. .. .. ..$ model.use         : chr "linear"
+  .. .. .. .. ..$ use.umi           : logi FALSE
+  .. .. .. .. ..$ do.scale          : logi TRUE
+  .. .. .. .. ..$ do.center         : logi TRUE
+  .. .. .. .. ..$ scale.max         : num 10
+  .. .. .. .. ..$ block.size        : num 1000
+  .. .. .. .. ..$ min.cells.to.block: num 2638
+  .. .. .. .. ..$ verbose           : logi TRUE
+  .. .. .. ..@ NA         : NULL
+  .. ..$ RunPCA.RNA              :Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "RunPCA.RNA"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:29:31"
+  .. .. .. ..@ call.string: chr "RunPCA(object = pbmc, features = VariableFeatures(object = pbmc))"
+  .. .. .. ..@ params     :List of 11
+  .. .. .. .. ..$ assay          : chr "RNA"
+  .. .. .. .. ..$ features       : chr [1:2000] "PPBP" "LYZ" "S100A9" "IGLL5" ...
+  .. .. .. .. ..$ npcs           : num 50
+  .. .. .. .. ..$ rev.pca        : logi FALSE
+  .. .. .. .. ..$ weight.by.var  : logi TRUE
+  .. .. .. .. ..$ verbose        : logi TRUE
+  .. .. .. .. ..$ ndims.print    : int [1:5] 1 2 3 4 5
+  .. .. .. .. ..$ nfeatures.print: num 30
+  .. .. .. .. ..$ reduction.name : chr "pca"
+  .. .. .. .. ..$ reduction.key  : chr "PC_"
+  .. .. .. .. ..$ seed.use       : num 42
+  .. .. .. ..@ NA         : NULL
+  .. ..$ JackStraw.RNA.pca       :Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "JackStraw.RNA.pca"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:30:30"
+  .. .. .. ..@ call.string: chr "JackStraw(object = pbmc, num.replicate = 100)"
+  .. .. .. ..@ params     :List of 7
+  .. .. .. .. ..$ reduction    : chr "pca"
+  .. .. .. .. ..$ assay        : chr "RNA"
+  .. .. .. .. ..$ dims         : num 20
+  .. .. .. .. ..$ num.replicate: num 100
+  .. .. .. .. ..$ prop.freq    : num 0.01
+  .. .. .. .. ..$ verbose      : logi TRUE
+  .. .. .. .. ..$ maxit        : num 1000
+  .. .. .. ..@ NA         : NULL
+  .. ..$ ScoreJackStraw          :Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "ScoreJackStraw"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:30:31"
+  .. .. .. ..@ call.string: chr "ScoreJackStraw(object = pbmc, dims = 1:20)"
+  .. .. .. ..@ params     :List of 4
+  .. .. .. .. ..$ reduction   : chr "pca"
+  .. .. .. .. ..$ dims        : int [1:20] 1 2 3 4 5 6 7 8 9 10 ...
+  .. .. .. .. ..$ score.thresh: num 1e-05
+  .. .. .. .. ..$ do.plot     : logi FALSE
+  .. .. .. ..@ NA         : NULL
+  .. ..$ FindNeighbors.RNA.pca   :Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "FindNeighbors.RNA.pca"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:30:33"
+  .. .. .. ..@ call.string: chr "FindNeighbors(object = pbmc, dims = 1:10)"
+  .. .. .. ..@ params     :List of 11
+  .. .. .. .. ..$ reduction   : chr "pca"
+  .. .. .. .. ..$ dims        : int [1:10] 1 2 3 4 5 6 7 8 9 10
+  .. .. .. .. ..$ assay       : chr "RNA"
+  .. .. .. .. ..$ k.param     : num 20
+  .. .. .. .. ..$ compute.SNN : logi TRUE
+  .. .. .. .. ..$ prune.SNN   : num 0.0667
+  .. .. .. .. ..$ nn.eps      : num 0
+  .. .. .. .. ..$ verbose     : logi TRUE
+  .. .. .. .. ..$ force.recalc: logi FALSE
+  .. .. .. .. ..$ do.plot     : logi FALSE
+  .. .. .. .. ..$ graph.name  : chr [1:2] "RNA_nn" "RNA_snn"
+  .. .. .. ..@ NA         : NULL
+  .. ..$ FindClusters            :Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "FindClusters"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:30:33"
+  .. .. .. ..@ call.string: chr "FindClusters(object = pbmc, resolution = 0.5)"
+  .. .. .. ..@ params     :List of 8
+  .. .. .. .. ..$ graph.name    : chr "RNA_snn"
+  .. .. .. .. ..$ modularity.fxn: num 1
+  .. .. .. .. ..$ resolution    : num 0.5
+  .. .. .. .. ..$ algorithm     : num 1
+  .. .. .. .. ..$ n.start       : num 10
+  .. .. .. .. ..$ n.iter        : num 10
+  .. .. .. .. ..$ random.seed   : num 0
+  .. .. .. .. ..$ verbose       : logi TRUE
+  .. .. .. ..@ NA         : NULL
+  .. ..$ RunUMAP.RNA.pca         :Formal class 'SeuratCommand' [package "Seurat"] with 5 slots
+ + +
Warning: Not a validObject(): no slot of name "assay.used" for this object of class "SeuratCommand"
+ + +
  .. .. .. ..@ name       : chr "RunUMAP.RNA.pca"
+  .. .. .. ..@ time.stamp : POSIXct[1:1], format: "2019-04-29 09:30:52"
+  .. .. .. ..@ call.string: chr "RunUMAP(object = pbmc, dims = 1:10)"
+  .. .. .. ..@ params     :List of 18
+  .. .. .. .. ..$ dims                : int [1:10] 1 2 3 4 5 6 7 8 9 10
+  .. .. .. .. ..$ reduction           : chr "pca"
+  .. .. .. .. ..$ assay               : chr "RNA"
+  .. .. .. .. ..$ n.neighbors         : int 30
+  .. .. .. .. ..$ n.components        : int 2
+  .. .. .. .. ..$ metric              : chr "correlation"
+  .. .. .. .. ..$ learning.rate       : num 1
+  .. .. .. .. ..$ min.dist            : num 0.3
+  .. .. .. .. ..$ spread              : num 1
+  .. .. .. .. ..$ set.op.mix.ratio    : num 1
+  .. .. .. .. ..$ local.connectivity  : int 1
+  .. .. .. .. ..$ repulsion.strength  : num 1
+  .. .. .. .. ..$ negative.sample.rate: int 5
+  .. .. .. .. ..$ seed.use            : int 42
+  .. .. .. .. ..$ angular.rp.forest   : logi FALSE
+  .. .. .. .. ..$ verbose             : logi TRUE
+  .. .. .. .. ..$ reduction.name      : chr "umap"
+  .. .. .. .. ..$ reduction.key       : chr "UMAP_"
+  .. .. .. ..@ NA         : NULL
+  ..@ tools       : list()
+ + + +
+
+
+

Update the Seurat object, if needed

+
+
This notebook should still work with Seurat v2 but has not been tested
+ + + +
s_version <- packageVersion('Seurat')$major
+  if (s_version == 2) {
+    stop ('Portions of this notebook may need updating for Seurat v2, proceed with caution.')
+  } else if (s_version >= 3) {
+    data <- UpdateSeuratObject(object = data)
+  } else {
+    stop ('Seurat v1 objects are not supported.')
+  }
+ + +
Validating object structure
+Updating object slots
+Ensuring keys are in the proper strucutre
+Ensuring feature names don't have underscores or pipes
+Updating slots in RNA
+Updating slots in RNA_nn
+Setting default assay of RNA_nn to RNA
+Updating slots in RNA_snn
+Setting default assay of RNA_snn to RNA
+Updating slots in pca
+Updating slots in umap
+Setting umap DimReduc to global
+Setting assay used for NormalizeData.RNA to RNA
+Setting assay used for FindVariableFeatures.RNA to RNA
+Setting assay used for ScaleData.RNA to RNA
+Setting assay used for RunPCA.RNA to RNA
+Setting assay used for JackStraw.RNA.pca to RNA
+No assay information could be found for ScoreJackStraw
+Warning: Adding a command log without an assay associated with it
+Setting assay used for FindNeighbors.RNA.pca to RNA
+No assay information could be found for FindClusters
+Warning: Adding a command log without an assay associated with it
+Setting assay used for RunUMAP.RNA.pca to RNA
+Object representation is consistent with the most current Seurat version
+ + + +
+
+
+

Generate a cluster file

+
+
Many reduction.use options are possible, replace “umap” with the dimensionality reduction option used in the analysis. Refer to the output of str(data) if unfamiliar with how the data was analyzed (look under @reductions)
+ + + +
cluster_name <- paste0(outdir, "/", prefix, "-", "cluster.tsv")
+generateClusterFile(data, cluster_name, reduction.use = "umap")
+ + +
Finished writing SCP_files/expt1-cluster.tsv
+ + + +
+
+
+

Generate raw and processed count matrices

+
+
files generated have fixed names (matrix.mtx, barcodes.tsv, genes.tsv)
+
+
+
SCP expects raw and processed matrices to have different file names, rename one set of matrices prior to upload
+ + + +
raw_dir <- paste0(outdir, "/", "raw")
+# create raw count MTX IF using conventional Seurat slot naming
+generateExpressionMatrix(data, raw_dir, slot.use = "counts", compress.files = T)
+ + +
Finished writing SCP_files/raw/expression_matrix.mtx
+Finished compressing SCP_files/raw/expression_matrix.mtx
+Finished writing SCP_files/raw/barcodes.tsv.gz
+Finished writing SCP_files/raw/genes.tsv.gz
+ + +
proc_dir <- paste0(outdir, "/", "processed")
+# create processed count MTX IF using conventional Seurat slot naming
+generateExpressionMatrix(data, proc_dir, slot.use = "data", compress.files = T)
+ + +
Finished writing SCP_files/processed/expression_matrix.mtx
+Finished compressing SCP_files/processed/expression_matrix.mtx
+Finished writing SCP_files/processed/barcodes.tsv.gz
+Finished writing SCP_files/processed/genes.tsv.gz
+ + + +
+
+
+

Add SCP required metadata to your Seurat object

+
+
Use the interactive metadata option to add metadata that are consistent across ALL cells
+
+
metadata that vary by groups of cells cannot be annotated using this script (eg. if you have multiple biosamples, diease vs control; or multiple donors, mouse1, mouse2 … mouseN)
+
+
+ +
+
ontology labels are the human-readable text that accompany ontology IDs
+
+
SCP uses the ontology_label to validate that the provided ontology ID is the intended term and not mis-entered
+
+
+
+
For example: For the metadata “species”, NCBITaxon_9606 is a valid ontology ID
+
+
+
Homo sapiens is the corresponding value for “species__ontology_label”
+
+
+

When prompted to “Enter columns you wish to add” provide the following metadata columns as they are also SCP required metadata

+
+
species__ontology_label disease__ontology_label organ__ontology_label library_preparation_protocol__ontology_label
+ + + +
#Velina's script does not add the required ontology label columns 
+#use the "add optional metadata" feature in addConsistentMetadataColumns
+
+data = addConsistentMetadataColumns(data, return.object = T)
+ + +
Note that your object metadata is missing the following required columns:
+biosample_id, donor_id, species, disease, organ, library_preparation_protocol, sex, biosample_type
+You will be prompted for corresponding values for each of these columns.
+You can skip columns for which your dataset isn't constant by typing 'skip'.
+Type 'quit' to exit this function at any point.
+Are there any other (optional) consistent columns you want to add?
+ + +
species__ontology_label disease__ontology_label organ__ontology_label library_preparation_protocol__ontology_label
+sample1
+ + +
Warning: closing unused connection 8 (SCP_files/processed/genes.tsv.gz)
+Warning: closing unused connection 7 (SCP_files/processed/barcodes.tsv.gz)
+Warning: closing unused connection 6 (SCP_files/processed/expression_matrix.mtx)
+Warning: closing unused connection 5 (SCP_files/raw/genes.tsv.gz)
+Warning: closing unused connection 4 (SCP_files/raw/barcodes.tsv.gz)
+Warning: closing unused connection 3 (SCP_files/raw/expression_matrix.mtx)
+ + +
donor1
+NCBITaxon_9606
+PATO_0000461
+UBERON_0000178
+EFO_0009899
+ + +
The next metadata column, sex has a list of controlled values. The values are:
+male, female, mixed, unknown
+ + +
unknown
+ + +
The next metadata column, biosample_type has a list of controlled values. The values are:
+CellLine, DerivedType_Organoid, DerivedType_InVitroDifferentiated, DerivedType_InducedPluripotentStemCell, PrimaryBioSample, PrimaryBioSample_BodyFluid, PrimaryBioSample_CellFreeDNA, PrimaryBioSample_PrimaryCell, PrimaryBioSample_PrimaryCulture, PrimaryBioSample_Stool, PrimaryBioSample_Tissue
+ + +
PrimaryBioSample_BodyFluid
+Homo sapiens
+normal
+blood
+10x 3' v2
+ + + +
+
If you use Excel to add metadata that varies by groups of cells, take care that Excel copy/paste does not automagically increment the pasted value (ie. NCBITaxon_9606, NCBITaxon_9607, NCBITaxon_9608 etc)
+
+
+
+
+
+

Review existing metadata and identify metadata to exclude

+
+
ie. any metadata unique to all cells OR metadata not useful for analysis
+
+
+

use the generated string of column names in the next (Generate metadata file) block

+ + + +
metadata = data@meta.data
+#Edit this string to rename metadata or exclude metadata
+dput(colnames(metadata))
+ + +
c("orig.ident", "nCount_RNA", "nFeature_RNA", "percent.mt", "RNA_snn_res.0.5", 
+"seurat_clusters", "biosample_id", "donor_id", "species", "disease", 
+"organ", "library_preparation_protocol", "sex", "biosample_type", 
+"species__ontology_label", "disease__ontology_label", "organ__ontology_label", 
+"library_preparation_protocol__ontology_label")
+ + + +
+
+
+

Generate metadata file

+
+
cols.use can be used to omit metadata columns or to re-order the columns
+
+
+
use the string in the block above to manipulate the metadata file you will generate
+
+
+
column order in cols.use determines the order the metadata are listed in the annotations dropdown
+
+
+
+

column names can only have only alphanumeric characters and underscore characters

+
+
new.col.names can be used to rename columns such as “percent.mt” which have characters that are disallowed
+
+
for this example, metadata names with “.” separators were replaced with “_”
+
+
+
if a metadata (for example, orig.ident) was not useful, it can be omitted from both cols.use and new.col.names and that metadata will be omitted from the output file.
+
+
+
+
spacing in generateMetadataFile command was added for readability, the string from the prior block can be cut and paste as-is and does not need to resemble the block below.
+ + + +
metadata_name <- paste0(outdir, "/", prefix, "-", "metadata.tsv")
+# generate metadata file omitting "orig.ident"
+generateMetadataFile(data, metadata_name, 
+    cols.use = c( "seurat_clusters", "biosample_id", "donor_id", 
+      "species", "disease", "organ", "library_preparation_protocol", 
+      "sex", "biosample_type", "species__ontology_label", 
+      "disease__ontology_label", "organ__ontology_label", 
+      "library_preparation_protocol__ontology_label", 
+      "orig.ident", "nCount_RNA", "nFeature_RNA", 
+      "percent.mt","RNA_snn_res.0.5"),
+    new.col.names = c( "seurat_clusters", "biosample_id", "donor_id", 
+      "species", "disease", "organ", "library_preparation_protocol", 
+      "sex", "biosample_type", "species__ontology_label", 
+      "disease__ontology_label", "organ__ontology_label", 
+      "library_preparation_protocol__ontology_label", 
+      "orig_ident", "nCount_RNA", "nFeature_RNA", 
+      "percent_mt", "RNA_snn_res_0_5")
+)
+ + +
Finished writing SCP_files/expt1-metadata.tsv
+ + + + +
+
+
+ +
LS0tCnRpdGxlOiAiQ3JlYXRlIFNDUCBmaWxlcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQojIyBTZXR1cApUaGlzIFIgbm90ZWJvb2sgdXNlcyBbY29kZSB3cml0dGVuIGJ5IFZlbGluYSBLb3phcmV2YV0oaHR0cHM6Ly9naXRodWIuY29tL3Zrb3phcmV2YS9zaW5nbGVfY2VsbF9wb3J0YWwvYmxvYi9vYmplY3QtY29udmVyc2lvbi1zY3JpcHRzL3NjcmlwdHMvb2JqZWN0X2NvbnZlcnNpb24vc2V1cmF0L3NldXJhdF9zY3BfY29udmVuaWVuY2UuUikgd2l0aCB0aGUgZm9sbG93aW5nIGNoYW5nZTogIApsaW5lIDE1OSB3YXMgIAp9IGVsc2UgaWYgKHNfdmVyc2lvbiA9PSAzKSB7ICAKVmVsaW5hJ3MgY29kZSB3YXMgd3JpdHRlbiBiZWZvcmUgU2V1cmF0IHY0IGV4aXN0ZWQgc28gdGhlIGxpbmUgbm93IG5lZWRzIHRvIGJlICAKfSBlbHNlIGlmIChzX3ZlcnNpb24gPj0gMykgeyAgCgpFeGFtcGxlIHByZWNvbXB1dGVkIFNldXJhdCBvYmplY3QgZG93bmxvYWRlZCBmcm9tIGh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3MvNjNnbmx3NDVqZjdjamU4L3BibWMza19maW5hbC5yZHM/ZGw9MQoocmVmZXJlbmNlOiBodHRwczovL3NhdGlqYWxhYi5vcmcvc2V1cmF0L2FyY2hpdmUvdjMuMC9kZV92aWduZXR0ZS5odG1sKQoKU2F2ZSB0aGUgbW9kaWZpZWQgY29kZSBhcyBhIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHlvdXIgU2V1cmF0IG9iamVjdCBmaWxlIChpbiB0aGlzIGNhc2UsIHBibWMza19maW5hbC5yZHM7IHJlcGxhY2UgaW4gdGhlIGNvZGUgYmxvY2sgYmVsb3cgd2l0aCB0aGUgbmFtZSBvZiB5b3VyIFNldXJhdCBvYmplY3QgZmlsZSkgYW5kIGNhbGwgdGhlIGZpbGUgd2l0aCB0aGUgbW9kaWZpZWQgdmVyc2lvbiBvZiBWZWxpbmEncyBjb2RlOiBzZXVyYXRfc2NwX2NvbnZlbmllbmNlX3YyLlIKClNhdmUgdGhpcyBSbWQgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuIFRoaXMgc2hvdWxkIGFsbG93IHlvdSB0byBzb3VyY2UgVmVsaW5hJ3MgY29kZSBhbmQgcmVhZCB5b3VyIFNldXJhdCBvYmplY3QgYnkgdXNpbmcgdGhlIGNvZGUgYmVsb3cuIElmIHlvdSBlbmNvdW50ZXIgYW4gbWVzc2FnZSBpbmRpY2F0aW5nICJjYW5ub3Qgb3BlbiB0aGUgY29ubmVjdGlvbiIsIHRyeSByZXBsYWNpbmcgdGhlIGZpbGVuYW1lIGluIHRoZSBjb21tYW5kIHdpdGggdGhlIGZ1bGwgcGF0aCB0byB0aGUgZmlsZS4KCiMjIyBBZGFwdCB0aGUgZm9sbG93aW5nIGNvZGUgdG8gZ2VuZXJhdGUgU0NQIGZpbGVzIGZyb20geW91ciBTZXVyYXQgb2JqZWN0CiMjIyMjIE5hbWUgdGhlIG91dHB1dCBkaXJlY3Rvcnkgd2hlcmUgeW91IHdvdWxkIGxpa2UgeW91ciBTQ1AgZmlsZXMgdG8gYmUgd3JpdHRlbgoKYGBge3J9CnNvdXJjZSgic2V1cmF0X3NjcF9jb252ZW5pZW5jZV92Mi5SIikKbGlicmFyeShTZXVyYXQpCmRhdGEgPC0gcmVhZFJEUyhmaWxlID0gInBibWMza19maW5hbC5yZHMiKQpvdXRkaXIgPC0gIlNDUF9maWxlcyIKaWYgKCFkaXIuZXhpc3RzKG91dGRpcikpIHtkaXIuY3JlYXRlKG91dGRpcil9CiNpZiB5b3UgZG9uJ3Qgd2FudCBhIHByZWZpeCwgc2V0IGl0IHRvIHRoZSBlbXB0eSBzdHJpbmcgIiIKcHJlZml4ID0gImV4cHQxIgpgYGAKCiMjIyBHZW5lcmFsIGluZm9ybWF0aW9uIGFib3V0IHRoZSBTZXVyYXQgb2JqZWN0LCBjb25maXJtIHRoZSBvYmplY3QgaXMgYXMgZXhwZWN0ZWQKYGBge3J9CmRhdGEKYGBgCgojIyMgVXNlIHRoaXMgYmxvY2sgdG8gYWRkIGEgcHJlZml4IHRvIHlvdXIgY2VsbHMgaWYgcmVuYW1pbmcgQUxMIGNlbGxzCiMjIyMjIyMgVGhpcyBpcyB1c2VmdWwgaWYgbXVsdGlwbGUgcnVucyBoYXZlIGlkZW50aWNhbCBjZWxsIGJhcmNvZGVzCiMjIyMjIFRoZSBmb2xsb3dpbmcgY29kZSB3b3VsZCBuZWVkIHRvIGJlIG1vZGlmaWVkIGlmIFNVQlNFVHMgb2YgY2VsbHMgbmVlZCB0byBiZSBkaWZmZXJlbnRpYWxseSBwcmVmaXhlZC4KYGBge3J9CmlmIChsZW5ndGgocHJlZml4KSkgewogICMgYWRkLmNlbGwuaWQgcHV0cyB1bmRlcnNjb3JlIGJldHdlZW4gcHJlZml4IGFuZCBvcmlnaW5hbCBjZWxsIG5hbWUKICAjZGF0YSA8LSBSZW5hbWVDZWxscyhkYXRhLCBhZGQuY2VsbC5pZCA9IHByZWZpeCkKICAjIHNldCB1cCB0aGUgZm9sbG93aW5nIHRvIHB1dCBhIGh5cGhlbiwgcmF0aGVyIHRoYW4gdW5kZXJzY29yZSwgYXMgc2VwYXJhdG9yCiAgIyB3aGljaCBzZXBhcmF0b3IgeW91IGNob29zZSBpcyB1cCB0byB5b3UsIGJvdGggYXJlIGFjY2VwdGFibGUKICBkYXRhIDwtIFJlbmFtZUNlbGxzKGRhdGEsIG5ldy5uYW1lcyA9IHBhc3RlMChwcmVmaXgsICItIiwgY29sbmFtZXMoZGF0YSkpKQogIGhlYWQoY29sbmFtZXMoZGF0YSkpCn0KYGBgCgojIyBUaGUgY29kZSBpbiB0aGlzIG5vdGVib29rIGFzc3VtZXM6CiMjIC0gcmF3IGNvdW50cyBpbiB0aGUgImNvdW50cyIgc2xvdCB1bmRlciBAYXNzYXlzIGluIHRoZSBTZXVyYXQgT2JqZWN0CiMjIC0gcHJvY2Vzc2VkIGNvdW50cyBpbiB0aGUgImRhdGEiIHNsb3QgdW5kZXIgQGFzc2F5cyBpbiB0aGUgU2V1cmF0IE9iamVjdAojIyAtIG1ldGFkYXRhIHVuZGVyIEBtZXRhLmRhdGEgaW4gdGhlIFNldXJhdCBPYmplY3QKIyMgLSAidW1hcCIgY2FsY3VsYXRpb24gdW5kZXIgQHJlZHVjdGlvbnMgaW4gdGhlIFNldXJhdCBPYmplY3QKIyMjIGlmIHlvdXIgZGF0YSBpcyBub3Qgc3RvcmVkIGFzIGRlc2NyaWJlZCBhYm92ZSwgcGxlYXNlIG1vZGlmeSB0aGUgY29kZSB0byByZWZsZWN0IHlvdXIgU2V1cmF0IG9iamVjdCdzIGxheW91dAoKIyMjIFNob3cgZGV0YWlscyBvZiB0aGUgU2V1cmF0IG9iamVjdAojIyMjIyBpbmNsdWRpbmcgdGhlIGFuYWx5c2lzIGNvbW1hbmRzIHRoYXQgaGF2ZSBiZWVuIHJ1biBvbiB0aGUgZGF0YQpgYGB7cn0Kc3RyKGRhdGEpCmBgYAojIyMgVXBkYXRlIHRoZSBTZXVyYXQgb2JqZWN0LCBpZiBuZWVkZWQKIyMjIyMgVGhpcyBub3RlYm9vayBzaG91bGQgc3RpbGwgd29yayB3aXRoIFNldXJhdCB2MiBidXQgaGFzIG5vdCBiZWVuIHRlc3RlZApgYGB7cn0Kc192ZXJzaW9uIDwtIHBhY2thZ2VWZXJzaW9uKCdTZXVyYXQnKSRtYWpvcgogIGlmIChzX3ZlcnNpb24gPT0gMikgewogICAgc3RvcCAoJ1BvcnRpb25zIG9mIHRoaXMgbm90ZWJvb2sgbWF5IG5lZWQgdXBkYXRpbmcgZm9yIFNldXJhdCB2MiwgcHJvY2VlZCB3aXRoIGNhdXRpb24uJykKICB9IGVsc2UgaWYgKHNfdmVyc2lvbiA+PSAzKSB7CiAgICBkYXRhIDwtIFVwZGF0ZVNldXJhdE9iamVjdChvYmplY3QgPSBkYXRhKQogIH0gZWxzZSB7CiAgICBzdG9wICgnU2V1cmF0IHYxIG9iamVjdHMgYXJlIG5vdCBzdXBwb3J0ZWQuJykKICB9CmBgYAoKIyMjIEdlbmVyYXRlIGEgY2x1c3RlciBmaWxlCiMjIyMjIE1hbnkgcmVkdWN0aW9uLnVzZSBvcHRpb25zIGFyZSBwb3NzaWJsZSwgKipyZXBsYWNlICJ1bWFwIiB3aXRoIHRoZSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gb3B0aW9uIHVzZWQgaW4gdGhlIGFuYWx5c2lzKiouIFJlZmVyIHRvIHRoZSBvdXRwdXQgb2Ygc3RyKGRhdGEpIGlmIHVuZmFtaWxpYXIgd2l0aCBob3cgdGhlIGRhdGEgd2FzIGFuYWx5emVkIChsb29rIHVuZGVyIEByZWR1Y3Rpb25zKQpgYGB7cn0KY2x1c3Rlcl9uYW1lIDwtIHBhc3RlMChvdXRkaXIsICIvIiwgcHJlZml4LCAiLSIsICJjbHVzdGVyLnRzdiIpCmdlbmVyYXRlQ2x1c3RlckZpbGUoZGF0YSwgY2x1c3Rlcl9uYW1lLCByZWR1Y3Rpb24udXNlID0gInVtYXAiKQpgYGAKCgojIyMgR2VuZXJhdGUgcmF3IGFuZCBwcm9jZXNzZWQgY291bnQgbWF0cmljZXMKIyMjIyMgZmlsZXMgZ2VuZXJhdGVkIGhhdmUgZml4ZWQgbmFtZXMgKG1hdHJpeC5tdHgsIGJhcmNvZGVzLnRzdiwgZ2VuZXMudHN2KQojIyMjIyBTQ1AgZXhwZWN0cyByYXcgYW5kIHByb2Nlc3NlZCBtYXRyaWNlcyB0byBoYXZlIGRpZmZlcmVudCBmaWxlIG5hbWVzLCByZW5hbWUgb25lIHNldCBvZiBtYXRyaWNlcyBwcmlvciB0byB1cGxvYWQKYGBge3J9CnJhd19kaXIgPC0gcGFzdGUwKG91dGRpciwgIi8iLCAicmF3IikKIyBjcmVhdGUgcmF3IGNvdW50IE1UWCBJRiB1c2luZyBjb252ZW50aW9uYWwgU2V1cmF0IHNsb3QgbmFtaW5nCmdlbmVyYXRlRXhwcmVzc2lvbk1hdHJpeChkYXRhLCByYXdfZGlyLCBzbG90LnVzZSA9ICJjb3VudHMiLCBjb21wcmVzcy5maWxlcyA9IFQpCgpwcm9jX2RpciA8LSBwYXN0ZTAob3V0ZGlyLCAiLyIsICJwcm9jZXNzZWQiKQojIGNyZWF0ZSBwcm9jZXNzZWQgY291bnQgTVRYIElGIHVzaW5nIGNvbnZlbnRpb25hbCBTZXVyYXQgc2xvdCBuYW1pbmcKZ2VuZXJhdGVFeHByZXNzaW9uTWF0cml4KGRhdGEsIHByb2NfZGlyLCBzbG90LnVzZSA9ICJkYXRhIiwgY29tcHJlc3MuZmlsZXMgPSBUKQpgYGAKCiMjIyBBZGQgU0NQIHJlcXVpcmVkIG1ldGFkYXRhIHRvIHlvdXIgU2V1cmF0IG9iamVjdAojIyMjIyBVc2UgdGhlIGludGVyYWN0aXZlIG1ldGFkYXRhIG9wdGlvbiB0byBhZGQgbWV0YWRhdGEgdGhhdCBhcmUgY29uc2lzdGVudCBhY3Jvc3MgQUxMIGNlbGxzCiMjIyMjIyBtZXRhZGF0YSB0aGF0IHZhcnkgYnkgZ3JvdXBzIG9mIGNlbGxzIGNhbm5vdCBiZSBhbm5vdGF0ZWQgdXNpbmcgdGhpcyBzY3JpcHQgKGVnLiBpZiB5b3UgaGF2ZSBtdWx0aXBsZSBiaW9zYW1wbGVzLCBkaWVhc2UgdnMgY29udHJvbDsgb3IgbXVsdGlwbGUgZG9ub3JzLCBtb3VzZTEsIG1vdXNlMiAuLi4gbW91c2VOKQojIyMjIyBNYW55IFNDUCByZXF1aXJlZCBtZXRhZGF0YSBhcmUgb250b2xvZ3ktYmFzZWQsIGxvb2sgdXAgb250b2xvZ3kgSUQgdmFsdWVzIHVzaW5nIHRoZSBsaW5rcyBmb3VuZCBhdCBodHRwczovL3NpbmdsZWNlbGwuemVuZGVzay5jb20vaGMvZW4tdXMvYXJ0aWNsZXMvMzYwMDYwNjA5ODUyLVJlcXVpcmVkLU1ldGFkYXRhCiMjIyMjIG9udG9sb2d5IGxhYmVscyBhcmUgdGhlIGh1bWFuLXJlYWRhYmxlIHRleHQgdGhhdCBhY2NvbXBhbnkgb250b2xvZ3kgSURzCiMjIyMjIyBTQ1AgdXNlcyB0aGUgb250b2xvZ3lfbGFiZWwgdG8gdmFsaWRhdGUgdGhhdCB0aGUgcHJvdmlkZWQgb250b2xvZ3kgSUQgaXMgdGhlIGludGVuZGVkIHRlcm0gYW5kIG5vdCBtaXMtZW50ZXJlZCAKIyMjIyMgRm9yIGV4YW1wbGU6IEZvciB0aGUgbWV0YWRhdGEgInNwZWNpZXMiLCBOQ0JJVGF4b25fOTYwNiBpcyBhIHZhbGlkIG9udG9sb2d5IElECiMjIyMjIEhvbW8gc2FwaWVucyBpcyB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZSBmb3IgInNwZWNpZXNfX29udG9sb2d5X2xhYmVsIgoKIyMjIyAqKldoZW4gcHJvbXB0ZWQgdG8gIkVudGVyIGNvbHVtbnMgeW91IHdpc2ggdG8gYWRkIiBwcm92aWRlIHRoZSBmb2xsb3dpbmcgbWV0YWRhdGEgY29sdW1ucyBhcyB0aGV5IGFyZSBhbHNvIFNDUCByZXF1aXJlZCBtZXRhZGF0YSoqCiMjIyMjIHNwZWNpZXNfX29udG9sb2d5X2xhYmVsIGRpc2Vhc2VfX29udG9sb2d5X2xhYmVsIG9yZ2FuX19vbnRvbG9neV9sYWJlbCBsaWJyYXJ5X3ByZXBhcmF0aW9uX3Byb3RvY29sX19vbnRvbG9neV9sYWJlbApgYGB7cn0KI1ZlbGluYSdzIHNjcmlwdCBkb2VzIG5vdCBhZGQgdGhlIHJlcXVpcmVkIG9udG9sb2d5IGxhYmVsIGNvbHVtbnMgCiN1c2UgdGhlICJhZGQgb3B0aW9uYWwgbWV0YWRhdGEiIGZlYXR1cmUgaW4gYWRkQ29uc2lzdGVudE1ldGFkYXRhQ29sdW1ucwoKZGF0YSA9IGFkZENvbnNpc3RlbnRNZXRhZGF0YUNvbHVtbnMoZGF0YSwgcmV0dXJuLm9iamVjdCA9IFQpCmBgYAojIyMjIyMgSWYgeW91IHVzZSBFeGNlbCB0byBhZGQgbWV0YWRhdGEgdGhhdCB2YXJpZXMgYnkgZ3JvdXBzIG9mIGNlbGxzLCB0YWtlIGNhcmUgdGhhdCBFeGNlbCBjb3B5L3Bhc3RlIGRvZXMgbm90IGF1dG9tYWdpY2FsbHkgaW5jcmVtZW50IHRoZSBwYXN0ZWQgdmFsdWUgKGllLiBOQ0JJVGF4b25fOTYwNiwgTkNCSVRheG9uXzk2MDcsIE5DQklUYXhvbl85NjA4IGV0YykKCgoKIyMjIFJldmlldyBleGlzdGluZyBtZXRhZGF0YSBhbmQgaWRlbnRpZnkgbWV0YWRhdGEgdG8gZXhjbHVkZQojIyMjIyBpZS4gYW55IG1ldGFkYXRhIHVuaXF1ZSB0byBhbGwgY2VsbHMgT1IgbWV0YWRhdGEgbm90IHVzZWZ1bCBmb3IgYW5hbHlzaXMKIyMjIyAqKnVzZSB0aGUgZ2VuZXJhdGVkIHN0cmluZyBvZiBjb2x1bW4gbmFtZXMgaW4gdGhlIG5leHQgKEdlbmVyYXRlIG1ldGFkYXRhIGZpbGUpIGJsb2NrKioKYGBge3J9Cm1ldGFkYXRhID0gZGF0YUBtZXRhLmRhdGEKI0VkaXQgdGhpcyBzdHJpbmcgdG8gcmVuYW1lIG1ldGFkYXRhIG9yIGV4Y2x1ZGUgbWV0YWRhdGEKZHB1dChjb2xuYW1lcyhtZXRhZGF0YSkpCmBgYAoKIyMjIEdlbmVyYXRlIG1ldGFkYXRhIGZpbGUKIyMjIyMgY29scy51c2UgY2FuIGJlIHVzZWQgdG8gb21pdCBtZXRhZGF0YSBjb2x1bW5zIG9yIHRvIHJlLW9yZGVyIHRoZSBjb2x1bW5zCiMjIyMjIHVzZSB0aGUgc3RyaW5nIGluIHRoZSBibG9jayBhYm92ZSB0byBtYW5pcHVsYXRlIHRoZSBtZXRhZGF0YSBmaWxlIHlvdSB3aWxsIGdlbmVyYXRlCiMjIyMjIGNvbHVtbiBvcmRlciBpbiBjb2xzLnVzZSBkZXRlcm1pbmVzIHRoZSBvcmRlciB0aGUgbWV0YWRhdGEgYXJlIGxpc3RlZCBpbiB0aGUgYW5ub3RhdGlvbnMgZHJvcGRvd24KIyMjICoqY29sdW1uIG5hbWVzIGNhbiBvbmx5IGhhdmUgb25seSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBhbmQgdW5kZXJzY29yZSBjaGFyYWN0ZXJzKioKIyMjIyMgbmV3LmNvbC5uYW1lcyBjYW4gYmUgdXNlZCB0byByZW5hbWUgY29sdW1ucyBzdWNoIGFzICJwZXJjZW50Lm10IiB3aGljaCBoYXZlIGNoYXJhY3RlcnMgdGhhdCBhcmUgZGlzYWxsb3dlZAojIyMjIyMgZm9yIHRoaXMgZXhhbXBsZSwgbWV0YWRhdGEgbmFtZXMgd2l0aCAiLiIgIHNlcGFyYXRvcnMgd2VyZSByZXBsYWNlZCB3aXRoICJfIgojIyMjIyMgaWYgYSBtZXRhZGF0YSAoZm9yIGV4YW1wbGUsIG9yaWcuaWRlbnQpIHdhcyBub3QgdXNlZnVsLCBpdCBjYW4gYmUgb21pdHRlZCBmcm9tIGJvdGggY29scy51c2UgYW5kIG5ldy5jb2wubmFtZXMgYW5kIHRoYXQgbWV0YWRhdGEgd2lsbCBiZSBvbWl0dGVkIGZyb20gdGhlIG91dHB1dCBmaWxlLgojIyMjIyBzcGFjaW5nIGluIGdlbmVyYXRlTWV0YWRhdGFGaWxlIGNvbW1hbmQgd2FzIGFkZGVkIGZvciByZWFkYWJpbGl0eSwgdGhlIHN0cmluZyBmcm9tIHRoZSBwcmlvciBibG9jayBjYW4gYmUgY3V0IGFuZCBwYXN0ZSBhcy1pcyBhbmQgZG9lcyBub3QgbmVlZCB0byByZXNlbWJsZSB0aGUgYmxvY2sgYmVsb3cuCmBgYHtyfQptZXRhZGF0YV9uYW1lIDwtIHBhc3RlMChvdXRkaXIsICIvIiwgcHJlZml4LCAiLSIsICJtZXRhZGF0YS50c3YiKQojIGdlbmVyYXRlIG1ldGFkYXRhIGZpbGUgb21pdHRpbmcgIm9yaWcuaWRlbnQiCmdlbmVyYXRlTWV0YWRhdGFGaWxlKGRhdGEsIG1ldGFkYXRhX25hbWUsIAogICAgY29scy51c2UgPSBjKCAic2V1cmF0X2NsdXN0ZXJzIiwgImJpb3NhbXBsZV9pZCIsICJkb25vcl9pZCIsIAogICAgICAic3BlY2llcyIsICJkaXNlYXNlIiwgIm9yZ2FuIiwgImxpYnJhcnlfcHJlcGFyYXRpb25fcHJvdG9jb2wiLCAKICAgICAgInNleCIsICJiaW9zYW1wbGVfdHlwZSIsICJzcGVjaWVzX19vbnRvbG9neV9sYWJlbCIsIAogICAgICAiZGlzZWFzZV9fb250b2xvZ3lfbGFiZWwiLCAib3JnYW5fX29udG9sb2d5X2xhYmVsIiwgCiAgICAgICJsaWJyYXJ5X3ByZXBhcmF0aW9uX3Byb3RvY29sX19vbnRvbG9neV9sYWJlbCIsIAogICAgICAib3JpZy5pZGVudCIsICJuQ291bnRfUk5BIiwgIm5GZWF0dXJlX1JOQSIsIAogICAgICAicGVyY2VudC5tdCIsIlJOQV9zbm5fcmVzLjAuNSIpLAogICAgbmV3LmNvbC5uYW1lcyA9IGMoICJzZXVyYXRfY2x1c3RlcnMiLCAiYmlvc2FtcGxlX2lkIiwgImRvbm9yX2lkIiwgCiAgICAgICJzcGVjaWVzIiwgImRpc2Vhc2UiLCAib3JnYW4iLCAibGlicmFyeV9wcmVwYXJhdGlvbl9wcm90b2NvbCIsIAogICAgICAic2V4IiwgImJpb3NhbXBsZV90eXBlIiwgInNwZWNpZXNfX29udG9sb2d5X2xhYmVsIiwgCiAgICAgICJkaXNlYXNlX19vbnRvbG9neV9sYWJlbCIsICJvcmdhbl9fb250b2xvZ3lfbGFiZWwiLCAKICAgICAgImxpYnJhcnlfcHJlcGFyYXRpb25fcHJvdG9jb2xfX29udG9sb2d5X2xhYmVsIiwgCiAgICAgICJvcmlnX2lkZW50IiwgIm5Db3VudF9STkEiLCAibkZlYXR1cmVfUk5BIiwgCiAgICAgICJwZXJjZW50X210IiwgIlJOQV9zbm5fcmVzXzBfNSIpCikKYGBgCgo=
+ + + +
+ + + + + + + + + + + + + + + +