1 Sample Estimation, Macrophages: 20170820

This document is concerned with analyzing RNAseq data of human and parasite during the infection of human macrophages. A few different strains of L. panamensis were used; the experiment is therefore segregated into groups named ‘self-healing’, ‘chronic’, and ‘uninfected’. Two separate sets of libraries were generated, one earlier set with greater coverage, and a later set including only 1 uninfected sample, and 2-3 chronic samples.

1.1 Extract the macrophage experiment

The following subset operation extract the samples used for the macrophage experiment. The next three lines then change the colors from the defaults.

hs_expt <- sm(create_expt(metadata="sample_sheets/all_samples-combined.xlsx",
                          gene_info=hs_annotations,
                          file_column="humanfile"))

hs_macr <- subset_expt(hs_expt, subset="experimentname=='macrophage'")
## There were 50, now there are 11 samples.
new_colors <- c("#009900", "#990000", "#000099")
names(new_colors) <- c("uninf", "chr", "sh")

hs_macr <- set_expt_colors(hs_macr, colors=new_colors)
## The new colors are a character, changing according to condition.
labels <- as.character(pData(hs_macr)[["label"]])
hs_macr <- set_expt_samplenames(hs_macr, labels)

hs_cds_expt <- exclude_genes_expt(hs_expt, column='Type', patterns="protein_coding")
## Before removal, there were 51041 entries.
## Now there are 32233 entries.
## Percent kept: 6.800, 4.913, 4.463, 3.420, 4.095, 3.758, 4.250, 3.901, 2.844, 2.354, 3.398, 2.979, 3.360, 2.824, 3.827, 3.483, 5.058, 5.009, 4.342, 4.748, 5.045, 5.140, 5.233, 3.496, 3.612, 4.589, 2.427, 2.134, 2.082, 1.978, 12.185, 10.054, 9.846, 9.990, 16.555, 7.559, 5.374, 3.647, 3.770, 4.198, 3.756, 3.777, 3.723, 6.072, 5.246, 5.389, 5.451, 5.071, 5.186, 4.931
## Percent removed: 93.200, 95.087, 95.537, 96.580, 95.905, 96.242, 95.750, 96.099, 97.156, 97.646, 96.602, 97.021, 96.640, 97.176, 96.173, 96.517, 94.942, 94.991, 95.658, 95.252, 94.955, 94.860, 94.767, 96.504, 96.388, 95.411, 97.573, 97.866, 97.918, 98.022, 87.815, 89.946, 90.154, 90.010, 83.445, 92.441, 94.626, 96.353, 96.230, 95.802, 96.244, 96.223, 96.277, 93.928, 94.754, 94.611, 94.549, 94.929, 94.814, 95.069
hs_cds_macr <- subset_expt(hs_cds_expt, subset="experimentname=='macrophage'")
## There were 50, now there are 11 samples.
hs_cds_macr <- set_expt_colors(hs_cds_macr, colors=new_colors)
## The new colors are a character, changing according to condition.
hs_cds_macr <- set_expt_samplenames(hs_cds_macr, labels)

2 Figure S1

Figure S1 should include nice versions of the sample metrics. The normalization chosen is batch-in-model.

First, however, we will make some plots of the raw data.

Sample names are going to be ‘infectionstate_strainnumber’ : chr_7721

  • Panel A: Library sizes.
  • Panel B: Heatmap distance raw.
  • Panel C: PCA
  • Panel D: TSNE
fig_s1 <- sm(write_expt(hs_macr, norm="quant", violin=FALSE, convert="cpm",
                        transform="log2", batch="pca", filter=TRUE,
                        excel=paste0("excel/figure_s1_sample_estimation-v", ver, ".xlsx")))
fig_s1_cds <- sm(write_expt(hs_cds_macr, norm="quant", violin=FALSE, convert="cpm",
                            transform="log2", batch="pca", filter=TRUE,
                            excel=paste0("excel/figure_s1_sample_estimation_cds_only-v", ver, ".xlsx")))

First look for clustering patterns in the raw data, in all data followed by only the CDS regions.

plot_tsne(hs_macr)$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

plot_tsne(hs_cds_macr)$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

2.1 Write S1 images

Once the experiment has been written with the various normalizations in place, we can use that to print and view some representative plots.

pp(file="images/figure_s1a.pdf", image=fig_s1$raw_libsize)
## Writing the image to: images/figure_s1a.pdf and calling dev.off().

## Show the library sizes of all features.

pp(file="images/figure_s1b.pdf", image=fig_s1$raw_disheat)
## Writing the image to: images/figure_s1b.pdf and calling dev.off().

## Show the clustering by euclidean distance of the raw data all features.

pp(file="images/figure_s1c.pdf", image=fig_s1$raw_scaled_pca)
## Writing the image to: images/figure_s1c.pdf and calling dev.off().
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## Do a PCA plot of the log2(normalized(data)) without any batch-in-model

pp(file="images/figure_s1d.pdf", image=fig_s1$norm_tsne)
## Writing the image to: images/figure_s1d.pdf and calling dev.off().
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## Do a TSNE of the normalized data after condition is in the model.

3 Figure 1

  • Figure 1a distance heatmap of the normalized data.
  • Figure 1b is a PCA of the normalized data.

In a similar fashion to what is above, I am printing the figure 1 images.

pp(file="images/figure_1a.pdf", fig_s1$norm_disheat)
## Writing the image to: images/figure_1a.pdf and calling dev.off().

## Show the changes in clustering after adding batch to the model and normalizing.

pp(file="images/figure_1a_cds.pdf", image=fig_s1_cds$norm_disheat)
## Writing the image to: images/figure_1a_cds.pdf and calling dev.off().

## Observe that the clustering is nearly identical when only looking at the CDS features.

pp(file="images/figure_1b.pdf", image=fig_s1$norm_pca)
## Writing the image to: images/figure_1b.pdf and calling dev.off().
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## Visualize the clustering after normalization via PCA.
knitr::kable(fig_s1$norm_pca_table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.3001 0.5411
HPGL0242 sh a 1 #000099 sh_2271 -0.1826 -0.1392
HPGL0243 sh a 1 #000099 sh_2272 -0.1623 -0.0610
HPGL0244 chr a 1 #990000 chr_5433 0.5607 0.1367
HPGL0245 chr a 1 #990000 chr_1320 0.1739 -0.2052
HPGL0246 chr a 1 #990000 chr_2504 0.3305 -0.1978
HPGL0247 chr a 1 #990000 chr_5430 -0.0119 -0.1666
HPGL0248 chr a 1 #990000 chr_5397 0.2537 -0.2304
HPGL0637 uninf b 2 #009900 uninf 0.0142 0.5954
HPGL0638 sh b 2 #000099 sh_2189 -0.1111 0.0995
HPGL0639 sh b 2 #000099 sh_1022 -0.5651 -0.3727
write.csv(fig_s1$norm_pca_table, file="images/fig_1a.csv")

pp(file="images/figure_1b_cds.pdf", image=fig_s1_cds$norm_pca)
## Writing the image to: images/figure_1b_cds.pdf and calling dev.off().
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## Once again, see that it is mostly unchanged when using only CDS features.
knitr::kable(fig_s1_cds$norm_pca_table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.7944 0.1829
HPGL0242 sh a 1 #000099 sh_2271 0.1567 -0.2831
HPGL0243 sh a 1 #000099 sh_2272 0.1705 -0.4056
HPGL0244 chr a 1 #990000 chr_5433 0.1587 0.7099
HPGL0245 chr a 1 #990000 chr_1320 0.1713 0.2040
HPGL0246 chr a 1 #990000 chr_2504 0.1925 0.1750
HPGL0247 chr a 1 #990000 chr_5430 0.1967 0.1279
HPGL0248 chr a 1 #990000 chr_5397 0.1991 -0.1948
HPGL0637 uninf b 2 #009900 uninf -0.3759 -0.2131
HPGL0638 sh b 2 #000099 sh_2189 -0.0127 -0.1561
HPGL0639 sh b 2 #000099 sh_1022 -0.0624 -0.1470
write.csv(fig_s1_cds$norm_pca_table, file="images/fig_1a_cds.csv")

4 Sample metrics

The following is mostly used to compare different methodologies and is therefore not likely to be useful for most.

The various metrics used to describe and examine the data come once before, and once after normalization.

4.1 Initial sample metrics

graph_metrics creates a set of plots we can use to look at the data before messing with it.

written <- sm(write_expt(hs_macr,
                         excel=paste0("excel/macrophage_human_data-v", ver, ".xlsx"),
                         violin=TRUE))
hs_macr_metrics <- sm(graph_metrics(hs_macr))

The two most likely plots one will want to see immediately are the library sizes and data densities.

hs_macr_metrics$libsize

## The libraries > 600 in HPGL id have lower coverage as they were sequenced many more to a lane.
hs_macr_metrics$density

## This same phenomenon is visible in the density plot
hs_macr_metrics$nonzero

## and the non-zero gene / cpm plot.

4.2 Normalization effects on the macrophage data

The plotted library sizes suggest that differences observed in the raw data are due at least partially to less saturation in the new samples. Therefore, low-count filtering is almost certainly to prove an important parameter. Similarly, a batch correction should help alleviate these differences.

hs_macr_nonil <- subset_expt(hs_macr, subset="condition=='sh'|condition=='chr'")
## There were 11, now there are 9 samples.
hs_macr_cpmlow <- sm(normalize_expt(hs_macr, filter="cbcb", convert="cpm"))
hs_macr_l2cpmlow <- sm(normalize_expt(hs_macr, filter="cbcb", convert="cpm", transform="log2"))
hs_macr_l2cpmpofa <- sm(normalize_expt(hs_macr, filter="pofa", convert="cpm", transform="log2"))
hs_macr_cpmrlelow <- sm(normalize_expt(hs_macr, filter="cbcb", convert="cpm", norm="rle"))
hs_macr_l2cpmrlelow <- sm(normalize_expt(hs_macr, filter="cbcb", convert="cpm",
                                         norm="rle", transform="log2"))

The normalizations in the block above do not attempt any batch correction. Now take a moment to view how they affect pca plots.

hs_macr_pca <- plot_pca(hs_macr)
## Start with the unmodified data
## It is clearly a mess.
hs_macr_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

knitr::kable(hs_macr_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.5683 -0.3528
HPGL0242 sh a 1 #000099 sh_2271 -0.1753 -0.2831
HPGL0243 sh a 1 #000099 sh_2272 -0.2902 -0.1149
HPGL0244 chr a 1 #990000 chr_5433 -0.0763 0.6999
HPGL0245 chr a 1 #990000 chr_1320 0.0355 0.0086
HPGL0246 chr a 1 #990000 chr_2504 -0.2197 0.3669
HPGL0247 chr a 1 #990000 chr_5430 -0.0294 -0.0494
HPGL0248 chr a 1 #990000 chr_5397 0.1368 0.0229
HPGL0637 uninf b 2 #009900 uninf 0.3007 0.1848
HPGL0638 sh b 2 #000099 sh_2189 0.4894 -0.1976
HPGL0639 sh b 2 #000099 sh_1022 0.3966 -0.2854
hs_macr_cpmlow_pca <- plot_pca(hs_macr_cpmlow)
hs_macr_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## low-filtering and cpm is insufficient to clarify the data, but it is a start
knitr::kable(hs_macr_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.5683 -0.3528
HPGL0242 sh a 1 #000099 sh_2271 -0.1753 -0.2831
HPGL0243 sh a 1 #000099 sh_2272 -0.2902 -0.1149
HPGL0244 chr a 1 #990000 chr_5433 -0.0763 0.6999
HPGL0245 chr a 1 #990000 chr_1320 0.0355 0.0086
HPGL0246 chr a 1 #990000 chr_2504 -0.2197 0.3669
HPGL0247 chr a 1 #990000 chr_5430 -0.0294 -0.0494
HPGL0248 chr a 1 #990000 chr_5397 0.1368 0.0229
HPGL0637 uninf b 2 #009900 uninf 0.3007 0.1848
HPGL0638 sh b 2 #000099 sh_2189 0.4894 -0.1976
HPGL0639 sh b 2 #000099 sh_1022 0.3966 -0.2854
hs_macr_l2cpmlow_pca <- plot_pca(hs_macr_l2cpmlow)
hs_macr_l2cpmlow_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## Moving to the log scale makes much clearer the batch effect
## and shows that the data is actually pretty well separated by condition already.
knitr::kable(hs_macr_l2cpmlow_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.2740 -0.6084
HPGL0242 sh a 1 #000099 sh_2271 -0.2364 -0.3174
HPGL0243 sh a 1 #000099 sh_2272 -0.1964 -0.1616
HPGL0244 chr a 1 #990000 chr_5433 -0.1603 0.4705
HPGL0245 chr a 1 #990000 chr_1320 -0.1480 0.2027
HPGL0246 chr a 1 #990000 chr_2504 -0.1549 0.2445
HPGL0247 chr a 1 #990000 chr_5430 -0.1323 0.1467
HPGL0248 chr a 1 #990000 chr_5397 -0.1605 0.2113
HPGL0637 uninf b 2 #009900 uninf 0.5074 0.1015
HPGL0638 sh b 2 #000099 sh_2189 0.5063 0.0315
HPGL0639 sh b 2 #000099 sh_1022 0.4492 -0.3213
hs_macr_l2cpmpofa_pca <- plot_pca(hs_macr_l2cpmpofa)
hs_macr_l2cpmpofa_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## I have access to a few low-count filters, but they appear to make little or no difference.
knitr::kable(hs_macr_l2cpmpofa_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.2784 -0.6197
HPGL0242 sh a 1 #000099 sh_2271 -0.2380 -0.3080
HPGL0243 sh a 1 #000099 sh_2272 -0.1973 -0.1527
HPGL0244 chr a 1 #990000 chr_5433 -0.1575 0.4586
HPGL0245 chr a 1 #990000 chr_1320 -0.1471 0.2057
HPGL0246 chr a 1 #990000 chr_2504 -0.1526 0.2483
HPGL0247 chr a 1 #990000 chr_5430 -0.1320 0.1522
HPGL0248 chr a 1 #990000 chr_5397 -0.1590 0.2123
HPGL0637 uninf b 2 #009900 uninf 0.5043 0.0919
HPGL0638 sh b 2 #000099 sh_2189 0.5071 0.0361
HPGL0639 sh b 2 #000099 sh_1022 0.4506 -0.3249
hs_macr_cpmrlelow_pca <- plot_pca(hs_macr_cpmrlelow)
hs_macr_cpmrlelow_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## RLE normalization has an interesting effect on the data
knitr::kable(hs_macr_cpmrlelow_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.3996 0.1372
HPGL0242 sh a 1 #000099 sh_2271 -0.3481 0.0650
HPGL0243 sh a 1 #000099 sh_2272 -0.3362 -0.0977
HPGL0244 chr a 1 #990000 chr_5433 0.3113 -0.5311
HPGL0245 chr a 1 #990000 chr_1320 -0.1105 -0.1660
HPGL0246 chr a 1 #990000 chr_2504 0.0868 -0.2796
HPGL0247 chr a 1 #990000 chr_5430 -0.1558 -0.1185
HPGL0248 chr a 1 #990000 chr_5397 0.0940 -0.1828
HPGL0637 uninf b 2 #009900 uninf 0.5731 0.1938
HPGL0638 sh b 2 #000099 sh_2189 0.3514 0.4037
HPGL0639 sh b 2 #000099 sh_1022 -0.0665 0.5759
hs_macr_l2cpmrlelow_pca <- plot_pca(hs_macr_l2cpmrlelow, size_column="pctcategory")
hs_macr_l2cpmrlelow_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## Still the batch effect is pretty ridiculous
## This plot resizes the glyphs to indicate the % mapping.
knitr::kable(hs_macr_l2cpmrlelow_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2 pctcategory size
HPGL0241 uninf a 1 #009900 uninf_1 -0.2742 -0.5998 0 1
HPGL0242 sh a 1 #000099 sh_2271 -0.2458 -0.3404 3 4
HPGL0243 sh a 1 #000099 sh_2272 -0.1979 -0.1365 3 4
HPGL0244 chr a 1 #990000 chr_5433 -0.1559 0.4444 1 2
HPGL0245 chr a 1 #990000 chr_1320 -0.1431 0.2312 4 5
HPGL0246 chr a 1 #990000 chr_2504 -0.1560 0.2440 2 3
HPGL0247 chr a 1 #990000 chr_5430 -0.1326 0.1528 2 3
HPGL0248 chr a 1 #990000 chr_5397 -0.1557 0.2075 4 5
HPGL0637 uninf b 2 #009900 uninf 0.5065 0.1159 0 1
HPGL0638 sh b 2 #000099 sh_2189 0.5091 0.0200 5 6
HPGL0639 sh b 2 #000099 sh_1022 0.4456 -0.3390 3 4

4.2.1 Look at the principal components

hs_macr_pca_info <- sm(pca_information(hs_macr,
                                       expt_factors=c("condition","batch","pctmappedparasite",
                                                      "state","pathogenstrain","rnangul")))

##write.csv(macro_pca_info$rsquared_table, file="images/rsquared.csv")
##write.csv(macro_pca_info$anova_p, file="images/anova_p.csv")
hs_macr_pca_info$anova_fstat_heatmap

I could continue the above normalizations and plots, but it quickly becomes boring and redundant. The batch effect is too significant to continue without addressing it. One thing that was brought up in previous discussions: does the mapping percentage act as a surrogate variable? This suggests that if it does, it is pretty weak, and the last PCA plot shows that is cosegregates with the existing conditions: uninfected has the lowest mapping percent to the parasite [0%]; while chronic has the lower percentage of the infections, but not so much lower than self-healing in general.

4.2.2 Normalization with batch effect minimization

We have good information that suggests a strong batch effect in this data. Let us put that information to use in the following block.

How do these modifications affect the separation of the data?

hs_macr_cpmlowcbcb <- sm(normalize_expt(hs_macr, filter="hpgl", convert="cpm", batch=TRUE))
hs_macr_l2cpmlowcom <- sm(normalize_expt(hs_macr, filter="hpgl", convert="cpm",
                                         batch="combat_scale", transform="log2"))
hs_macr_l2cpmrlelowcom <- sm(normalize_expt(hs_macr, filter="hpgl", convert="cpm",
                                            batch="combat_scale", transform="log2", norm="rle"))
hs_macr_l2cpmquantlowcmod <- sm(normalize_expt(hs_macr, filter="hpgl", convert="cpm",
                                               batch="combatmod", transform="log2", norm="quant"))
hs_macr_l2cpmquantlowcom <- sm(normalize_expt(hs_macr, filter="hpgl", convert="cpm",
                                              batch="combat_scale", transform="log2", norm="quant"))
hs_macr_l2cpmquantlowsva <- sm(normalize_expt(hs_macr, filter="hpgl", convert="cpm",
                                              batch="svaseq", norm="quant"))
hs_macr_l2cpmquantlowfsva <- sm(normalize_expt(hs_macr, filter="hpgl", convert="cpm",
                                               batch="fsva", norm="quant"))
hs_macr_l2cpmquantlowruv <- sm(normalize_expt(hs_macr, filter="hpgl", convert="cpm",
                                              batch="combat_scale", transform="log2", norm="quant"))
tt <- sm(graph_metrics(hs_macr_l2cpmquantlowruv))
hs_macr_cpmlowcbcb_pca <- plot_pca(hs_macr_cpmlowcbcb)
hs_macr_cpmlowcbcb_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## cbcb's batch correction is insufficient, at least without log2
hs_macr_cpmlowcbcb_pca$table
##    sampleid condition batch batch_int  colors   labels      PC1      PC2
## 1  HPGL0241     uninf     a         1 #009900  uninf_1 -0.09337  0.66888
## 2  HPGL0242        sh     a         1 #000099  sh_2271 -0.23685 -0.15485
## 3  HPGL0243        sh     a         1 #000099  sh_2272 -0.06401 -0.01482
## 4  HPGL0244       chr     a         1 #990000 chr_5433  0.60514 -0.04000
## 5  HPGL0245       chr     a         1 #990000 chr_1320  0.09059 -0.20559
## 6  HPGL0246       chr     a         1 #990000 chr_2504  0.21245 -0.28906
## 7  HPGL0247       chr     a         1 #990000 chr_5430 -0.05050 -0.20619
## 8  HPGL0248       chr     a         1 #990000 chr_5397  0.19782 -0.22250
## 9  HPGL0637     uninf     b         2 #009900    uninf  0.13221  0.51916
## 10 HPGL0638        sh     b         2 #000099  sh_2189 -0.13449  0.11016
## 11 HPGL0639        sh     b         2 #000099  sh_1022 -0.65901 -0.16518
hs_macr_l2cpmlowcom_pca <- plot_pca(hs_macr_l2cpmlowcom)
hs_macr_l2cpmlowcom_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## oooo pretty
knitr::kable(hs_macr_l2cpmlowcom_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.5445 0.0803
HPGL0242 sh a 1 #000099 sh_2271 -0.2561 0.2708
HPGL0243 sh a 1 #000099 sh_2272 -0.0981 -0.2656
HPGL0244 chr a 1 #990000 chr_5433 0.4802 0.1559
HPGL0245 chr a 1 #990000 chr_1320 0.2490 -0.3045
HPGL0246 chr a 1 #990000 chr_2504 0.2955 0.4898
HPGL0247 chr a 1 #990000 chr_5430 0.2064 -0.5245
HPGL0248 chr a 1 #990000 chr_5397 0.2660 0.2246
HPGL0637 uninf b 2 #009900 uninf -0.2121 -0.2582
HPGL0638 sh b 2 #000099 sh_2189 -0.1054 -0.1486
HPGL0639 sh b 2 #000099 sh_1022 -0.2810 0.2800
hs_macr_l2cpmrlelowcom_pca <- plot_pca(hs_macr_l2cpmrlelowcom)
hs_macr_l2cpmrlelowcom_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## also looking good
knitr::kable(hs_macr_l2cpmrlelowcom_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.5606 0.0681
HPGL0242 sh a 1 #000099 sh_2271 -0.2444 -0.2858
HPGL0243 sh a 1 #000099 sh_2272 -0.0863 0.0807
HPGL0244 chr a 1 #990000 chr_5433 0.4560 0.1062
HPGL0245 chr a 1 #990000 chr_1320 0.2571 0.0781
HPGL0246 chr a 1 #990000 chr_2504 0.2825 -0.3644
HPGL0247 chr a 1 #990000 chr_5430 0.2205 0.4784
HPGL0248 chr a 1 #990000 chr_5397 0.2767 -0.3788
HPGL0637 uninf b 2 #009900 uninf -0.2143 0.4161
HPGL0638 sh b 2 #000099 sh_2189 -0.0971 0.2104
HPGL0639 sh b 2 #000099 sh_1022 -0.2902 -0.4090
hs_macr_l2cpmquantlowcmod_pca <- plot_pca(hs_macr_l2cpmquantlowcmod)
hs_macr_l2cpmquantlowcmod_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## not as good
knitr::kable(hs_macr_l2cpmquantlowcmod_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.6808 0.1257
HPGL0242 sh a 1 #000099 sh_2271 -0.3746 -0.1335
HPGL0243 sh a 1 #000099 sh_2272 -0.2021 0.2806
HPGL0244 chr a 1 #990000 chr_5433 0.3934 -0.1607
HPGL0245 chr a 1 #990000 chr_1320 0.1805 0.2191
HPGL0246 chr a 1 #990000 chr_2504 0.1726 -0.4126
HPGL0247 chr a 1 #990000 chr_5430 0.1340 0.3985
HPGL0248 chr a 1 #990000 chr_5397 0.1736 -0.2283
HPGL0637 uninf b 2 #009900 uninf 0.2009 0.3443
HPGL0638 sh b 2 #000099 sh_2189 0.1591 0.1152
HPGL0639 sh b 2 #000099 sh_1022 -0.1566 -0.5484
hs_macr_l2cpmquantlowfsva_pca <- plot_pca(hs_macr_l2cpmquantlowfsva)
hs_macr_l2cpmquantlowfsva_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

pretty_pca <- plot_pca(hs_macr_l2cpmquantlowcom)
pretty_pca$plot
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## perhaps the best?
knitr::kable(pretty_pca$table)
sampleid condition batch batch_int colors labels PC1 PC2
HPGL0241 uninf a 1 #009900 uninf_1 -0.5479 0.0811
HPGL0242 sh a 1 #000099 sh_2271 -0.2444 0.2656
HPGL0243 sh a 1 #000099 sh_2272 -0.0984 -0.2749
HPGL0244 chr a 1 #990000 chr_5433 0.4800 0.1569
HPGL0245 chr a 1 #990000 chr_1320 0.2584 -0.3114
HPGL0246 chr a 1 #990000 chr_2504 0.2798 0.5005
HPGL0247 chr a 1 #990000 chr_5430 0.2043 -0.5226
HPGL0248 chr a 1 #990000 chr_5397 0.2774 0.2092
HPGL0637 uninf b 2 #009900 uninf -0.2271 -0.2421
HPGL0638 sh b 2 #000099 sh_2189 -0.1144 -0.1436
HPGL0639 sh b 2 #000099 sh_1022 -0.2676 0.2813
##write.csv(pretty_pca$table, file="excel/pretty_pca.csv")

4.2.3 Surrogate estimations

## Now try and combine this with
## https://github.com/jtleek/svaseq/blob/master/recount.Rmd
## To see if things become clearer
hs_macr_filt <- sm(normalize_expt(expt=hs_macr, filter=TRUE))
hs_macr_se <- sm(compare_surrogate_estimates(hs_macr_filt))

## I think my implementation of ruv_empirical may be borken.
hs_macr_se$pca_plots$ruvsup
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

hs_macr_se$ruv_supervised_adjust$svs_sample

hs_macr_se$pca_plots$svasup
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

hs_macr_se$sva_supervised_adjust$svs_sample

## The new uninfected sample still seems oddly placed
hs_macr_se$pca_plots$pca
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

hs_macr_se$pca_adjust$svs_sample

## Ditto here
hs_macr_se$pca_plots$svaunsup
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## This seems pretty reasonable to me
hs_macr_se$pca_plots$ruvresid
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## This looks a lot like pca and ruvsup, but the corrplot suggested to me that it would look weirder.

4.2.4 Effect on other metrics by batch correction

Lets see how these modification affect the visualizations

hs_macr_batchnorm_metrics <- sm(graph_metrics(hs_macr_l2cpmquantlowcom))
print(hs_macr_batchnorm_metrics$corheat)

## The combat adjusted counts seem to split  relatively clearly between types.
print(hs_macr_batchnorm_metrics$smc)

## This one sample is still problematic, though.
print(hs_macr_batchnorm_metrics$pcaplot)
## Too few points to calculate an ellipse
## Too few points to calculate an ellipse

## But quantile normalization really does smash them into the same distribution.

Some other analyses performed suggest a possible switch between two samples. We can artifically see what the data would look like if that is true by switching those two samples in a separate experimental design.

5 TODO 201611 #4

PBMC: variance partition human, “Are there any genes with variance we can ascribe to condition?” That set of genes is the most interesting. – use the variance parition table and pull the top 200. Report back the % variance by condition for all of these genes.

6 Variance Partition

In the following, I will attempt to find the variance associated with different experimental factors in the macrophage data with mappings against the human transcriptome.

6.1 Setting up

As in macrophage_estimation_human.html, I need to pull out the relevant samples:

7 Perform variancePartition analyses

7.1 Condition + batch

Start out with just condition and batch

## The default arguments are to query ~ condition + (1|batch)
## Which, because condition is categorical, will end badly.
hs_macr_vp_cb <- sm(varpart(hs_macr_filt,
                    predictor=NULL,
                    factors=c("condition","batch")))
hs_macr_vp_cb$percent_plot

hs_macr_vp_cb$partition_plot

## Batch is dominant, but there is still quite a lot left in residuals.

7.2 Condition + batch + snpclades

hs_macr_vp_cbs3 <- sm(varpart(hs_macr_l2cpmquantlowsva,
                      predictor=NULL,
                      factors=c("condition","batch","snpcladev3")))
hs_macr_vp_cbs3$percent_plot

hs_macr_vp_cbs3$partition_plot

8 Repeat analyses, Leishmania samples

9 Sample metrics

I just realized that what I need to do is to take the surrogate estimates from the human experiment. Using those I think I will be able to get a more realistic estimate of what is going on.

9.1 But first, attempt a normal estimation

parasite_expt <- create_expt(metadata="sample_sheets/all_samples-combined.xlsx",
                                gene_info=lp_annotations,
                                file_column="parasitefile")
## Reading the sample metadata.
## The sample definitions comprises: 50, 37 rows, columns.
## Reading count tables.
## Reading count tables with read.table().
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0242/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0243/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0244/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0245/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0246/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0247/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0248/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0316/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0318/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0320/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0322/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0631/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0632/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0633/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0634/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0635/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0636/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0638/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0639/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0641/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0643/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0651/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0652/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0653/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0654/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0655/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0656/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0658/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0659/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0660/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0661/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0662/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## /cbcb/nelsayed-scratch/atb/rnaseq/lpanamensis_2016/preprocessing/hpgl0663/outputs/tophat_lpanamensis/accepted_paired.count.xz contains 8846 rows and merges to 8846 rows.
## Finished reading count tables.
## Matched 8778 annotations and counts.
## Bringing together the count matrix and gene information.
## Some annotations were lost in merging, setting them to 'undefined'.
lp_macr <- subset_expt(parasite_expt, subset="experimentname=='macrophage'")
## There were 33, now there are 9 samples.
chosen_colors <- c("#990000", "#000099")
names(chosen_colors) <- c("chr", "sh")
lp_macr <- set_expt_colors(lp_macr, colors=chosen_colors)
## The new colors are a character, changing according to condition.
lp_testing <- sm(write_expt(lp_macr,
                            excel=paste0("excel/macrophage_parasite_data-v", ver, ".xlsx"),
                            violin=TRUE))
lp_testing$norm_pca

Now lets try removing some of the surrogates, the two primary candidates are the strains which I proxy with 3 columns: snpclade, snpcladev2, and snpcladev3; and the batch. In this data set batch is either a or b.

In theory, sva should pick up both of those in one invocation.

## Perform a 'normal' sva
lp_macr_sva <- sm(normalize_expt(lp_macr, batch="svaseq", filter=TRUE))
## Play with the normalization of it
lp_macr_sva_norm <- sm(normalize_expt(lp_macr_sva, filter=TRUE, convert="cpm",
                                      norm="quant", transform="log2"))
lp_macr_sva_norm_metr <- sm(graph_metrics(lp_macr_sva_norm))
## Try limma's method
lp_macr_limma_fcqlr <- sm(normalize_expt(lp_macr, batch="limma", filter=TRUE,
                                        batch2="snpcladev3", convert="cpm", norm="quant"))

9.2 Start with a pca from sva

lp_macr_sva_norm_metr$pcaplot

9.3 Try limma’s removebatcheffect

Another method might be to try using limmaresid to explicitly pull both columns.

plot_pca(lp_macr_limma_fcqlr)$plot

Another method might be to try pca on two separate invocations.

## frrpr rprrf
## raw(pca(raw(raw(filter(data)))))
## thus fcqsl would be log2(sva(quant(cpm(filter(data)))))
lp_macr_rprrf <- sm(normalize_expt(lp_macr, batch="pca", filter=TRUE))
lp_macr_rprrf <- set_expt_batches(expt=lp_macr_rprrf, fact="snpcladev3")
lp_macr_rprrf <- sm(normalize_expt(lp_macr_rprrf, batch="pca"))
lp_macr_lpqcf <- sm(normalize_expt(lp_macr_rprrf, convert="cpm",
                                   norm="quant", transform="log2",
                                   filter=TRUE))
lp_macr_lpqcf_metr <- sm(graph_metrics(lp_macr_lpqcf))

lp_macr_lpqcf_metr$pcaplot

9.4 Attempting count extraction from human surrogates

If indeed the human surrogates are a primary determinant in the parasite data, then we should be able to see that in some sample estimations of the parasite data. Let us try!

summary(hs_macr_se)
##                         Length Class        Mode   
## pca_adjust               7     -none-       list   
## sva_supervised_adjust    7     -none-       list   
## sva_unsupervised_adjust  7     -none-       list   
## ruv_supervised_adjust    7     -none-       list   
## ruv_residual_adjust      7     -none-       list   
## ruv_empirical_adjust     7     -none-       list   
## adjustments              8     -none-       list   
## correlations            64     -none-       numeric
## plot                     3     recordedplot list   
## pca_plots                7     -none-       list   
## catplots                 0     -none-       NULL
adjusts <- hs_macr_se$sva_supervised_adjust$model_adjust
## Remove surrogate estimates #1 and #9
new_adjusts <- as.matrix(adjusts[c(-1, -9), ])
## The question of course,  how do I use these estimations to adjust the data?

test_adjusted <- counts_from_surrogates(lp_macr, new_adjusts)
sv_adjusted <- lp_macr
Biobase::exprs(sv_adjusted$expressionset) <- test_adjusted

hs_adjusted <- subset_expt(sv_adjusted, subset="sampleid!='HPGL0248'")
## There were 9, now there are 8 samples.
hs_adjusted_fcqsl <- sm(normalize_expt(hs_adjusted, convert="cpm", filter=TRUE,
                                       batch="sva", norm="quant", transform="log2"))
hs_adjusted_fcqsl_metr <- sm(graph_metrics(hs_adjusted_fcqsl))
hs_sv_adjusted <- subset_expt(sv_adjusted, subset="sampleid!='HPGL0248'")
## There were 9, now there are 8 samples.
hs_sv_adjusted_fcqsl <- sm(normalize_expt(hs_sv_adjusted, convert="cpm", filter=TRUE,
                                          batch="sva", norm="quant", transform="log2"))
hs_sv_adjusted_fcqsl_metr <- sm(graph_metrics(hs_sv_adjusted_fcqsl))
lp_macr_rrrrr_metr <- sm(graph_metrics(lp_macr))
lp_macr_fcqrr <- sm(normalize_expt(lp_macr, convert="cpm", filter=TRUE, norm="quant"))
lp_macr_fcqrr_metr <- sm(graph_metrics(lp_macr_fcqrr))
lp_macr_fcqfl <- sm(normalize_expt(lp_macr, convert="cpm", filter=TRUE, norm="quant",
                                   batch="fsva", transform="log2"))
lp_macr_fcqfl_metr <- sm(graph_metrics(lp_macr_fcqfl))
lp_macr_fcqcl <- sm(normalize_expt(lp_macr, convert="cpm", filter=TRUE,
                                   norm="quant", batch="combat_scale", transform="log2"))
lp_macr_fcqcl_metr <- sm(graph_metrics(lp_macr_fcqcl))
lp_macr_fcrfl <- sm(normalize_expt(lp_macr, filter=TRUE, norm="quant",
                                   transform="log2", batch="fsva"))
lp_macr_fcrfl_metr <- sm(graph_metrics(lp_macr_fcrfl))

10 Compare results

Now lets compare the results of using the human data to inform the parasite estimations.

10.1 Before including the new estimates

Lets first print a few using different metrics before using the human SV estimates. It looks like sva etc are not too bad.

lp_macr_fcqrr_metr$pcaplot

## Just normalizing shows the central concern.

hs_sv_adjusted_fcqsl_metr$pcaplot

## The human surrogates work pretty well

lp_macr_fcqcl_metr$pcaplot

## Combat cannot deal with this data very well.

lp_macr_fcrfl_metr$pcaplot

## fsva gets a little confused, but not bad.

11 Parasite variance partition

11.1 Condition + batch

Start out with just condition and batch

## The default arguments are to query ~ condition + (1|batch)
## Which, because condition is categorical, will end badly.
lp_macr_vp_cb <- sm(varpart(lp_macr, predictor=NULL, factors=c("condition","batch")))
lp_macr_vp_cb$percent_plot

lp_macr_vp_cb$partition_plot

lp_macr_vp_lpqcf <- sm(varpart(lp_macr_lpqcf, predictor=NULL, factors=c("condition","batch")))
lp_macr_vp_lpqcf$percent_plot

lp_macr_vp_lpqcf$partition_plot

lp_macr_vp_hsfcqsl <- sm(varpart(hs_adjusted_fcqsl, predictor=NULL, factors=c("condition","batch")))
lp_macr_vp_hsfcqsl$percent_plot

lp_macr_vp_hsfcqsl$partition_plot

pander::pander(sessionInfo())

R version 3.4.4 (2018-03-15)

Platform: x86_64-pc-linux-gnu (64-bit)

locale: LC_CTYPE=en_US.utf8, LC_NUMERIC=C, LC_TIME=en_US.utf8, LC_COLLATE=en_US.utf8, LC_MONETARY=en_US.utf8, LC_MESSAGES=en_US.utf8, LC_PAPER=en_US.utf8, LC_NAME=C, LC_ADDRESS=C, LC_TELEPHONE=C, LC_MEASUREMENT=en_US.utf8 and LC_IDENTIFICATION=C

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: ruv(v.0.9.7) and hpgltools(v.2018.03)

loaded via a namespace (and not attached): backports(v.1.1.2), corrplot(v.0.84), aroma.light(v.3.8.0), plyr(v.1.8.4), lazyeval(v.0.2.1), survJamda.data(v.1.0.2), splines(v.3.4.4), BiocParallel(v.1.12.0), GenomeInfoDb(v.1.14.0), ggplot2(v.2.2.1), sva(v.3.26.0), digest(v.0.6.15), SuppDists(v.1.1-9.4), foreach(v.1.4.4), BiocInstaller(v.1.28.0), htmltools(v.0.3.6), gdata(v.2.18.0), magrittr(v.1.5), memoise(v.1.1.0), survJamda(v.1.1.4), doParallel(v.1.0.11), openxlsx(v.4.0.17), limma(v.3.34.9), Biostrings(v.2.46.0), annotate(v.1.56.2), matrixStats(v.0.53.1), R.utils(v.2.6.0), prettyunits(v.1.0.2), colorspace(v.1.3-2), blob(v.1.1.1), ggrepel(v.0.7.0), RCurl(v.1.95-4.10), graph(v.1.56.0), roxygen2(v.6.0.1), genefilter(v.1.60.0), lme4(v.1.1-17), survival(v.2.42-3), iterators(v.1.0.9), gtable(v.0.2.0), zlibbioc(v.1.24.0), XVector(v.0.18.0), DelayedArray(v.0.4.1), BiocGenerics(v.0.24.0), scales(v.0.5.0.9000), DESeq(v.1.30.0), DBI(v.0.8), edgeR(v.3.20.9), Rcpp(v.0.12.16), xtable(v.1.8-2), progress(v.1.1.2), bit(v.1.1-12), OrganismDbi(v.1.20.0), preprocessCore(v.1.40.0), stats4(v.3.4.4), lava(v.1.6.1), prodlim(v.2018.04.18), ecodist(v.2.0.1), httr(v.1.3.1), gplots(v.3.0.1), RColorBrewer(v.1.1-2), XML(v.3.98-1.11), R.methodsS3(v.1.7.1), locfit(v.1.5-9.1), labeling(v.0.3), rlang(v.0.2.0.9001), reshape2(v.1.4.3), AnnotationDbi(v.1.40.0), munsell(v.0.4.3), tools(v.3.4.4), RSQLite(v.2.1.0), devtools(v.1.13.5), evaluate(v.0.10.1), stringr(v.1.3.0), yaml(v.2.1.19), bootstrap(v.2017.2), knitr(v.1.20), bit64(v.0.9-7), pander(v.0.6.1), caTools(v.1.17.1), EDASeq(v.2.12.0), RBGL(v.1.54.0), nlme(v.3.1-137), R.oo(v.1.22.0), xml2(v.1.2.0), biomaRt(v.2.34.2), compiler(v.3.4.4), pbkrtest(v.0.4-7), testthat(v.2.0.0), variancePartition(v.1.8.1), tibble(v.1.4.2), statmod(v.1.4.30), geneplotter(v.1.56.0), stringi(v.1.1.7), highr(v.0.6), GenomicFeatures(v.1.30.3), lattice(v.0.20-35), Matrix(v.1.2-14), commonmark(v.1.5), survcomp(v.1.28.5), nloptr(v.1.0.4), survivalROC(v.1.0.3), pillar(v.1.2.2), data.table(v.1.10.4-3), bitops(v.1.0-6), corpcor(v.1.6.9), rtracklayer(v.1.38.3), GenomicRanges(v.1.30.3), colorRamps(v.2.3), R6(v.2.2.2), latticeExtra(v.0.6-28), directlabels(v.2017.03.31), hwriter(v.1.3.2), RMySQL(v.0.10.14), ShortRead(v.1.36.1), KernSmooth(v.2.23-15), gridExtra(v.2.3), IRanges(v.2.12.0), codetools(v.0.2-15), MASS(v.7.3-50), gtools(v.3.5.0), assertthat(v.0.2.0), SummarizedExperiment(v.1.8.1), rprojroot(v.1.3-2), withr(v.2.1.2), RUVSeq(v.1.12.0), GenomicAlignments(v.1.14.2), Rsamtools(v.1.30.0), S4Vectors(v.0.16.0), GenomeInfoDbData(v.1.0.0), mgcv(v.1.8-23), parallel(v.3.4.4), quadprog(v.1.5-5), grid(v.3.4.4), minqa(v.1.2.4), rmarkdown(v.1.9), Rtsne(v.0.13), Biobase(v.2.38.0), base64enc(v.0.1-3) and rmeta(v.3.0)

message(paste0("This is hpgltools commit: ", get_git_commit()))
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 19d49d10f887097fff276c8f5a1db2dbc9168e8d
## R> packrat::restore()
## This is hpgltools commit: Wed May 2 10:24:05 2018 -0400: 19d49d10f887097fff276c8f5a1db2dbc9168e8d
this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
message(paste0("Saving to ", this_save))
## Saving to 02_estimation_macrophage-v20170820.rda.xz
tmp <- sm(saveme(filename=this_save))
LS0tCnRpdGxlOiAiTC5wYW5hbWVuc2lzIDIwMTY6IFNhbXBsZSBlc3RpbWF0aW9uIG9mIEh1bWFuIG1hY3JvcGhhZ2VzLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSgiaHBnbHRvb2xzIikKdHQgPC0gZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgd2lkdGg9OTAsCiAgICAgICAgICAgICAgICAgICAgIGVjaG89VFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGg9OCwKICAgICAgICAgICAgICAgICAgICAgIGZpZy5oZWlnaHQ9OCwKICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKb2xkX29wdGlvbnMgPC0gb3B0aW9ucygKICBkaWdpdHM9NCwKICBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFLAogIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbD0iYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplPTEwKSkKc2V0LnNlZWQoMSkKcHJldmlvdXNfZmlsZSA8LSAiMDFfYW5ub3RhdGlvbi5SbWQiCnZlciA8LSAiMjAxNzA4MjAiCgp0bXAgPC0gc20obG9hZG1lKGZpbGVuYW1lPXBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cHJldmlvdXNfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKSkpCnJtZF9maWxlIDwtICIwMl9lc3RpbWF0aW9uX21hY3JvcGhhZ2UuUm1kIgpgYGAKCiMgU2FtcGxlIEVzdGltYXRpb24sIE1hY3JvcGhhZ2VzOiBgciB2ZXJgCgpUaGlzIGRvY3VtZW50IGlzIGNvbmNlcm5lZCB3aXRoIGFuYWx5emluZyBSTkFzZXEgZGF0YSBvZiBodW1hbiBhbmQgcGFyYXNpdGUgZHVyaW5nIHRoZSBpbmZlY3Rpb24gb2YKaHVtYW4gbWFjcm9waGFnZXMuICBBIGZldyBkaWZmZXJlbnQgc3RyYWlucyBvZiBMLiBwYW5hbWVuc2lzIHdlcmUgdXNlZDsgdGhlIGV4cGVyaW1lbnQgaXMgdGhlcmVmb3JlCnNlZ3JlZ2F0ZWQgaW50byBncm91cHMgbmFtZWQgJ3NlbGYtaGVhbGluZycsICdjaHJvbmljJywgYW5kICd1bmluZmVjdGVkJy4gIFR3byBzZXBhcmF0ZSBzZXRzIG9mCmxpYnJhcmllcyB3ZXJlIGdlbmVyYXRlZCwgb25lIGVhcmxpZXIgc2V0IHdpdGggZ3JlYXRlciBjb3ZlcmFnZSwgYW5kIGEgbGF0ZXIgc2V0IGluY2x1ZGluZyBvbmx5IDEKdW5pbmZlY3RlZCBzYW1wbGUsIGFuZCAyLTMgY2hyb25pYyBzYW1wbGVzLgoKIyMgRXh0cmFjdCB0aGUgbWFjcm9waGFnZSBleHBlcmltZW50CgpUaGUgZm9sbG93aW5nIHN1YnNldCBvcGVyYXRpb24gZXh0cmFjdCB0aGUgc2FtcGxlcyB1c2VkIGZvciB0aGUgbWFjcm9waGFnZSBleHBlcmltZW50LiBUaGUgbmV4dAp0aHJlZSBsaW5lcyB0aGVuIGNoYW5nZSB0aGUgY29sb3JzIGZyb20gdGhlIGRlZmF1bHRzLgoKYGBge3IgbWFjcm9waGFnZXN9CmhzX2V4cHQgPC0gc20oY3JlYXRlX2V4cHQobWV0YWRhdGE9InNhbXBsZV9zaGVldHMvYWxsX3NhbXBsZXMtY29tYmluZWQueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZV9pbmZvPWhzX2Fubm90YXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uPSJodW1hbmZpbGUiKSkKCmhzX21hY3IgPC0gc3Vic2V0X2V4cHQoaHNfZXhwdCwgc3Vic2V0PSJleHBlcmltZW50bmFtZT09J21hY3JvcGhhZ2UnIikKbmV3X2NvbG9ycyA8LSBjKCIjMDA5OTAwIiwgIiM5OTAwMDAiLCAiIzAwMDA5OSIpCm5hbWVzKG5ld19jb2xvcnMpIDwtIGMoInVuaW5mIiwgImNociIsICJzaCIpCgpoc19tYWNyIDwtIHNldF9leHB0X2NvbG9ycyhoc19tYWNyLCBjb2xvcnM9bmV3X2NvbG9ycykKbGFiZWxzIDwtIGFzLmNoYXJhY3RlcihwRGF0YShoc19tYWNyKVtbImxhYmVsIl1dKQpoc19tYWNyIDwtIHNldF9leHB0X3NhbXBsZW5hbWVzKGhzX21hY3IsIGxhYmVscykKCmhzX2Nkc19leHB0IDwtIGV4Y2x1ZGVfZ2VuZXNfZXhwdChoc19leHB0LCBjb2x1bW49J1R5cGUnLCBwYXR0ZXJucz0icHJvdGVpbl9jb2RpbmciKQpoc19jZHNfbWFjciA8LSBzdWJzZXRfZXhwdChoc19jZHNfZXhwdCwgc3Vic2V0PSJleHBlcmltZW50bmFtZT09J21hY3JvcGhhZ2UnIikKaHNfY2RzX21hY3IgPC0gc2V0X2V4cHRfY29sb3JzKGhzX2Nkc19tYWNyLCBjb2xvcnM9bmV3X2NvbG9ycykKaHNfY2RzX21hY3IgPC0gc2V0X2V4cHRfc2FtcGxlbmFtZXMoaHNfY2RzX21hY3IsIGxhYmVscykKYGBgCgojIEZpZ3VyZSBTMQoKRmlndXJlIFMxIHNob3VsZCBpbmNsdWRlIG5pY2UgdmVyc2lvbnMgb2YgdGhlIHNhbXBsZSBtZXRyaWNzLgpUaGUgbm9ybWFsaXphdGlvbiBjaG9zZW4gaXMgYmF0Y2gtaW4tbW9kZWwuCgpGaXJzdCwgaG93ZXZlciwgd2Ugd2lsbCBtYWtlIHNvbWUgcGxvdHMgb2YgdGhlIHJhdyBkYXRhLgoKU2FtcGxlIG5hbWVzIGFyZSBnb2luZyB0byBiZSAnaW5mZWN0aW9uc3RhdGVfc3RyYWlubnVtYmVyJyA6IGNocl83NzIxCgoqIFBhbmVsIEE6IExpYnJhcnkgc2l6ZXMuCiogUGFuZWwgQjogSGVhdG1hcCBkaXN0YW5jZSByYXcuCiogUGFuZWwgQzogUENBCiogUGFuZWwgRDogVFNORQoKYGBge3IgZmlnX3MxX3dyaXRlLCBmaWcuc2hvdz0iaGlkZSJ9CmZpZ19zMSA8LSBzbSh3cml0ZV9leHB0KGhzX21hY3IsIG5vcm09InF1YW50IiwgdmlvbGluPUZBTFNFLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm09ImxvZzIiLCBiYXRjaD0icGNhIiwgZmlsdGVyPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvZmlndXJlX3MxX3NhbXBsZV9lc3RpbWF0aW9uLXYiLCB2ZXIsICIueGxzeCIpKSkKZmlnX3MxX2NkcyA8LSBzbSh3cml0ZV9leHB0KGhzX2Nkc19tYWNyLCBub3JtPSJxdWFudCIsIHZpb2xpbj1GQUxTRSwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT0ibG9nMiIsIGJhdGNoPSJwY2EiLCBmaWx0ZXI9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvZmlndXJlX3MxX3NhbXBsZV9lc3RpbWF0aW9uX2Nkc19vbmx5LXYiLCB2ZXIsICIueGxzeCIpKSkKYGBgCgpGaXJzdCBsb29rIGZvciBjbHVzdGVyaW5nIHBhdHRlcm5zIGluIHRoZSByYXcgZGF0YSwgaW4gYWxsIGRhdGEgZm9sbG93ZWQgYnkgb25seSB0aGUgQ0RTIHJlZ2lvbnMuCgpgYGB7ciBmaWd1cmVfczF9CnBsb3RfdHNuZShoc19tYWNyKSRwbG90CnBsb3RfdHNuZShoc19jZHNfbWFjcikkcGxvdApgYGAKCiMjIFdyaXRlIFMxIGltYWdlcwoKT25jZSB0aGUgZXhwZXJpbWVudCBoYXMgYmVlbiB3cml0dGVuIHdpdGggdGhlIHZhcmlvdXMgbm9ybWFsaXphdGlvbnMgaW4gcGxhY2UsCndlIGNhbiB1c2UgdGhhdCB0byBwcmludCBhbmQgdmlldyBzb21lIHJlcHJlc2VudGF0aXZlIHBsb3RzLgoKYGBge3Igdmlld19maWdfczF9CnBwKGZpbGU9ImltYWdlcy9maWd1cmVfczFhLnBkZiIsIGltYWdlPWZpZ19zMSRyYXdfbGlic2l6ZSkKIyMgU2hvdyB0aGUgbGlicmFyeSBzaXplcyBvZiBhbGwgZmVhdHVyZXMuCgpwcChmaWxlPSJpbWFnZXMvZmlndXJlX3MxYi5wZGYiLCBpbWFnZT1maWdfczEkcmF3X2Rpc2hlYXQpCiMjIFNob3cgdGhlIGNsdXN0ZXJpbmcgYnkgZXVjbGlkZWFuIGRpc3RhbmNlIG9mIHRoZSByYXcgZGF0YSBhbGwgZmVhdHVyZXMuCgpwcChmaWxlPSJpbWFnZXMvZmlndXJlX3MxYy5wZGYiLCBpbWFnZT1maWdfczEkcmF3X3NjYWxlZF9wY2EpCiMjIERvIGEgUENBIHBsb3Qgb2YgdGhlIGxvZzIobm9ybWFsaXplZChkYXRhKSkgd2l0aG91dCBhbnkgYmF0Y2gtaW4tbW9kZWwKCnBwKGZpbGU9ImltYWdlcy9maWd1cmVfczFkLnBkZiIsIGltYWdlPWZpZ19zMSRub3JtX3RzbmUpCiMjIERvIGEgVFNORSBvZiB0aGUgbm9ybWFsaXplZCBkYXRhIGFmdGVyIGNvbmRpdGlvbiBpcyBpbiB0aGUgbW9kZWwuCmBgYAoKIyBGaWd1cmUgMQoKICogRmlndXJlIDFhIGRpc3RhbmNlIGhlYXRtYXAgb2YgdGhlIG5vcm1hbGl6ZWQgZGF0YS4KICogRmlndXJlIDFiIGlzIGEgUENBIG9mIHRoZSBub3JtYWxpemVkIGRhdGEuCgpJbiBhIHNpbWlsYXIgZmFzaGlvbiB0byB3aGF0IGlzIGFib3ZlLCBJIGFtIHByaW50aW5nIHRoZSBmaWd1cmUgMSBpbWFnZXMuCgpgYGB7ciBmaWd1cmVfMX0KcHAoZmlsZT0iaW1hZ2VzL2ZpZ3VyZV8xYS5wZGYiLCBmaWdfczEkbm9ybV9kaXNoZWF0KQojIyBTaG93IHRoZSBjaGFuZ2VzIGluIGNsdXN0ZXJpbmcgYWZ0ZXIgYWRkaW5nIGJhdGNoIHRvIHRoZSBtb2RlbCBhbmQgbm9ybWFsaXppbmcuCgpwcChmaWxlPSJpbWFnZXMvZmlndXJlXzFhX2Nkcy5wZGYiLCBpbWFnZT1maWdfczFfY2RzJG5vcm1fZGlzaGVhdCkKIyMgT2JzZXJ2ZSB0aGF0IHRoZSBjbHVzdGVyaW5nIGlzIG5lYXJseSBpZGVudGljYWwgd2hlbiBvbmx5IGxvb2tpbmcgYXQgdGhlIENEUyBmZWF0dXJlcy4KCnBwKGZpbGU9ImltYWdlcy9maWd1cmVfMWIucGRmIiwgaW1hZ2U9ZmlnX3MxJG5vcm1fcGNhKQojIyBWaXN1YWxpemUgdGhlIGNsdXN0ZXJpbmcgYWZ0ZXIgbm9ybWFsaXphdGlvbiB2aWEgUENBLgprbml0cjo6a2FibGUoZmlnX3MxJG5vcm1fcGNhX3RhYmxlKQp3cml0ZS5jc3YoZmlnX3MxJG5vcm1fcGNhX3RhYmxlLCBmaWxlPSJpbWFnZXMvZmlnXzFhLmNzdiIpCgpwcChmaWxlPSJpbWFnZXMvZmlndXJlXzFiX2Nkcy5wZGYiLCBpbWFnZT1maWdfczFfY2RzJG5vcm1fcGNhKQojIyBPbmNlIGFnYWluLCBzZWUgdGhhdCBpdCBpcyBtb3N0bHkgdW5jaGFuZ2VkIHdoZW4gdXNpbmcgb25seSBDRFMgZmVhdHVyZXMuCmtuaXRyOjprYWJsZShmaWdfczFfY2RzJG5vcm1fcGNhX3RhYmxlKQp3cml0ZS5jc3YoZmlnX3MxX2NkcyRub3JtX3BjYV90YWJsZSwgZmlsZT0iaW1hZ2VzL2ZpZ18xYV9jZHMuY3N2IikKYGBgCgojIFNhbXBsZSBtZXRyaWNzCgpUaGUgZm9sbG93aW5nIGlzIG1vc3RseSB1c2VkIHRvIGNvbXBhcmUgZGlmZmVyZW50IG1ldGhvZG9sb2dpZXMgYW5kIGlzIHRoZXJlZm9yZQpub3QgbGlrZWx5IHRvIGJlIHVzZWZ1bCBmb3IgbW9zdC4KClRoZSB2YXJpb3VzIG1ldHJpY3MgdXNlZCB0byBkZXNjcmliZSBhbmQgZXhhbWluZSB0aGUgZGF0YSBjb21lIG9uY2UgYmVmb3JlLCBhbmQgb25jZSBhZnRlciBub3JtYWxpemF0aW9uLgoKIyMgSW5pdGlhbCBzYW1wbGUgbWV0cmljcwoKZ3JhcGhfbWV0cmljcyBjcmVhdGVzIGEgc2V0IG9mIHBsb3RzIHdlIGNhbiB1c2UgdG8gbG9vayBhdCB0aGUgZGF0YSBiZWZvcmUgbWVzc2luZyB3aXRoIGl0LgoKYGBge3IgaW5pdGlhbF9tZXRyaWNzLCBmaWcuc2hvdz0iaGlkZSJ9CndyaXR0ZW4gPC0gc20od3JpdGVfZXhwdChoc19tYWNyLAogICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9tYWNyb3BoYWdlX2h1bWFuX2RhdGEtdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICB2aW9saW49VFJVRSkpCmhzX21hY3JfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKGhzX21hY3IpKQpgYGAKClRoZSB0d28gbW9zdCBsaWtlbHkgcGxvdHMgb25lIHdpbGwgd2FudCB0byBzZWUgaW1tZWRpYXRlbHkgYXJlIHRoZSBsaWJyYXJ5IHNpemVzIGFuZCBkYXRhIGRlbnNpdGllcy4KCmBgYHtyIHZpc19pbml0aWFsX21ldHJpY3N9CmhzX21hY3JfbWV0cmljcyRsaWJzaXplCiMjIFRoZSBsaWJyYXJpZXMgPiA2MDAgaW4gSFBHTCBpZCBoYXZlIGxvd2VyIGNvdmVyYWdlIGFzIHRoZXkgd2VyZSBzZXF1ZW5jZWQgbWFueSBtb3JlIHRvIGEgbGFuZS4KaHNfbWFjcl9tZXRyaWNzJGRlbnNpdHkKIyMgVGhpcyBzYW1lIHBoZW5vbWVub24gaXMgdmlzaWJsZSBpbiB0aGUgZGVuc2l0eSBwbG90CmhzX21hY3JfbWV0cmljcyRub256ZXJvCiMjIGFuZCB0aGUgbm9uLXplcm8gZ2VuZSAvIGNwbSBwbG90LgpgYGAKCiMjIE5vcm1hbGl6YXRpb24gZWZmZWN0cyBvbiB0aGUgbWFjcm9waGFnZSBkYXRhCgpUaGUgcGxvdHRlZCBsaWJyYXJ5IHNpemVzIHN1Z2dlc3QgdGhhdCBkaWZmZXJlbmNlcyBvYnNlcnZlZCBpbiB0aGUgcmF3IGRhdGEgYXJlIGR1ZSBhdCBsZWFzdApwYXJ0aWFsbHkgdG8gbGVzcyBzYXR1cmF0aW9uIGluIHRoZSBuZXcgc2FtcGxlcy4gIFRoZXJlZm9yZSwgbG93LWNvdW50IGZpbHRlcmluZyBpcyBhbG1vc3QgY2VydGFpbmx5CnRvIHByb3ZlIGFuIGltcG9ydGFudCBwYXJhbWV0ZXIuICBTaW1pbGFybHksIGEgYmF0Y2ggY29ycmVjdGlvbiBzaG91bGQgaGVscCBhbGxldmlhdGUgdGhlc2UKZGlmZmVyZW5jZXMuCgpgYGB7ciBtYWNyb3BoYWdlX25vcm1hbGl6YXRpb259CmhzX21hY3Jfbm9uaWwgPC0gc3Vic2V0X2V4cHQoaHNfbWFjciwgc3Vic2V0PSJjb25kaXRpb249PSdzaCd8Y29uZGl0aW9uPT0nY2hyJyIpCmhzX21hY3JfY3BtbG93IDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX21hY3IsIGZpbHRlcj0iY2JjYiIsIGNvbnZlcnQ9ImNwbSIpKQpoc19tYWNyX2wyY3BtbG93IDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX21hY3IsIGZpbHRlcj0iY2JjYiIsIGNvbnZlcnQ9ImNwbSIsIHRyYW5zZm9ybT0ibG9nMiIpKQpoc19tYWNyX2wyY3BtcG9mYSA8LSBzbShub3JtYWxpemVfZXhwdChoc19tYWNyLCBmaWx0ZXI9InBvZmEiLCBjb252ZXJ0PSJjcG0iLCB0cmFuc2Zvcm09ImxvZzIiKSkKaHNfbWFjcl9jcG1ybGVsb3cgPC0gc20obm9ybWFsaXplX2V4cHQoaHNfbWFjciwgZmlsdGVyPSJjYmNiIiwgY29udmVydD0iY3BtIiwgbm9ybT0icmxlIikpCmhzX21hY3JfbDJjcG1ybGVsb3cgPC0gc20obm9ybWFsaXplX2V4cHQoaHNfbWFjciwgZmlsdGVyPSJjYmNiIiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtPSJybGUiLCB0cmFuc2Zvcm09ImxvZzIiKSkKYGBgCgpUaGUgbm9ybWFsaXphdGlvbnMgaW4gdGhlIGJsb2NrIGFib3ZlIGRvIG5vdCBhdHRlbXB0IGFueSBiYXRjaCBjb3JyZWN0aW9uLiAgTm93IHRha2UgYSBtb21lbnQgdG8KdmlldyBob3cgdGhleSBhZmZlY3QgcGNhIHBsb3RzLgoKYGBge3IgcGNhX25vcm1hbGl6ZWR9CmhzX21hY3JfcGNhIDwtIHBsb3RfcGNhKGhzX21hY3IpCiMjIFN0YXJ0IHdpdGggdGhlIHVubW9kaWZpZWQgZGF0YQojIyBJdCBpcyBjbGVhcmx5IGEgbWVzcy4KaHNfbWFjcl9wY2EkcGxvdAprbml0cjo6a2FibGUoaHNfbWFjcl9wY2EkdGFibGUpCgpoc19tYWNyX2NwbWxvd19wY2EgPC0gcGxvdF9wY2EoaHNfbWFjcl9jcG1sb3cpCmhzX21hY3JfcGNhJHBsb3QKIyMgbG93LWZpbHRlcmluZyBhbmQgY3BtIGlzIGluc3VmZmljaWVudCB0byBjbGFyaWZ5IHRoZSBkYXRhLCBidXQgaXQgaXMgYSBzdGFydAprbml0cjo6a2FibGUoaHNfbWFjcl9wY2EkdGFibGUpCgpoc19tYWNyX2wyY3BtbG93X3BjYSA8LSBwbG90X3BjYShoc19tYWNyX2wyY3BtbG93KQpoc19tYWNyX2wyY3BtbG93X3BjYSRwbG90CiMjIE1vdmluZyB0byB0aGUgbG9nIHNjYWxlIG1ha2VzIG11Y2ggY2xlYXJlciB0aGUgYmF0Y2ggZWZmZWN0CiMjIGFuZCBzaG93cyB0aGF0IHRoZSBkYXRhIGlzIGFjdHVhbGx5IHByZXR0eSB3ZWxsIHNlcGFyYXRlZCBieSBjb25kaXRpb24gYWxyZWFkeS4Ka25pdHI6OmthYmxlKGhzX21hY3JfbDJjcG1sb3dfcGNhJHRhYmxlKQoKaHNfbWFjcl9sMmNwbXBvZmFfcGNhIDwtIHBsb3RfcGNhKGhzX21hY3JfbDJjcG1wb2ZhKQpoc19tYWNyX2wyY3BtcG9mYV9wY2EkcGxvdAojIyBJIGhhdmUgYWNjZXNzIHRvIGEgZmV3IGxvdy1jb3VudCBmaWx0ZXJzLCBidXQgdGhleSBhcHBlYXIgdG8gbWFrZSBsaXR0bGUgb3Igbm8gZGlmZmVyZW5jZS4Ka25pdHI6OmthYmxlKGhzX21hY3JfbDJjcG1wb2ZhX3BjYSR0YWJsZSkKCmhzX21hY3JfY3BtcmxlbG93X3BjYSA8LSBwbG90X3BjYShoc19tYWNyX2NwbXJsZWxvdykKaHNfbWFjcl9jcG1ybGVsb3dfcGNhJHBsb3QKIyMgUkxFIG5vcm1hbGl6YXRpb24gaGFzIGFuIGludGVyZXN0aW5nIGVmZmVjdCBvbiB0aGUgZGF0YQprbml0cjo6a2FibGUoaHNfbWFjcl9jcG1ybGVsb3dfcGNhJHRhYmxlKQoKaHNfbWFjcl9sMmNwbXJsZWxvd19wY2EgPC0gcGxvdF9wY2EoaHNfbWFjcl9sMmNwbXJsZWxvdywgc2l6ZV9jb2x1bW49InBjdGNhdGVnb3J5IikKaHNfbWFjcl9sMmNwbXJsZWxvd19wY2EkcGxvdAojIyBTdGlsbCB0aGUgYmF0Y2ggZWZmZWN0IGlzIHByZXR0eSByaWRpY3Vsb3VzCiMjIFRoaXMgcGxvdCByZXNpemVzIHRoZSBnbHlwaHMgdG8gaW5kaWNhdGUgdGhlICUgbWFwcGluZy4Ka25pdHI6OmthYmxlKGhzX21hY3JfbDJjcG1ybGVsb3dfcGNhJHRhYmxlKQpgYGAKCiMjIyBMb29rIGF0IHRoZSBwcmluY2lwYWwgY29tcG9uZW50cwoKYGBge3IgcGNhX2luZm8sIHNob3cuZmlnPSJoaWRlIn0KaHNfbWFjcl9wY2FfaW5mbyA8LSBzbShwY2FfaW5mb3JtYXRpb24oaHNfbWFjciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwdF9mYWN0b3JzPWMoImNvbmRpdGlvbiIsImJhdGNoIiwicGN0bWFwcGVkcGFyYXNpdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RhdGUiLCJwYXRob2dlbnN0cmFpbiIsInJuYW5ndWwiKSkpCiMjd3JpdGUuY3N2KG1hY3JvX3BjYV9pbmZvJHJzcXVhcmVkX3RhYmxlLCBmaWxlPSJpbWFnZXMvcnNxdWFyZWQuY3N2IikKIyN3cml0ZS5jc3YobWFjcm9fcGNhX2luZm8kYW5vdmFfcCwgZmlsZT0iaW1hZ2VzL2Fub3ZhX3AuY3N2IikKYGBgCgpgYGB7ciBwY2FfaW5mb19oZWF0bWFwfQpoc19tYWNyX3BjYV9pbmZvJGFub3ZhX2ZzdGF0X2hlYXRtYXAKYGBgCgpJIGNvdWxkIGNvbnRpbnVlIHRoZSBhYm92ZSBub3JtYWxpemF0aW9ucyBhbmQgcGxvdHMsIGJ1dCBpdCBxdWlja2x5IGJlY29tZXMgYm9yaW5nIGFuZCByZWR1bmRhbnQuClRoZSBiYXRjaCBlZmZlY3QgaXMgdG9vIHNpZ25pZmljYW50IHRvIGNvbnRpbnVlIHdpdGhvdXQgYWRkcmVzc2luZyBpdC4gIE9uZSB0aGluZyB0aGF0IHdhcyBicm91Z2h0CnVwIGluIHByZXZpb3VzIGRpc2N1c3Npb25zOiBkb2VzIHRoZSBtYXBwaW5nIHBlcmNlbnRhZ2UgYWN0IGFzIGEgc3Vycm9nYXRlIHZhcmlhYmxlPyAgVGhpcyBzdWdnZXN0cwp0aGF0IGlmIGl0IGRvZXMsIGl0IGlzIHByZXR0eSB3ZWFrLCBhbmQgdGhlIGxhc3QgUENBIHBsb3Qgc2hvd3MgdGhhdCBpcyBjb3NlZ3JlZ2F0ZXMgd2l0aCB0aGUKZXhpc3RpbmcgY29uZGl0aW9uczogdW5pbmZlY3RlZCBoYXMgdGhlIGxvd2VzdCBtYXBwaW5nIHBlcmNlbnQgdG8gdGhlIHBhcmFzaXRlIFswJV07IHdoaWxlIGNocm9uaWMKaGFzIHRoZSBsb3dlciBwZXJjZW50YWdlIG9mIHRoZSBpbmZlY3Rpb25zLCBidXQgbm90IHNvIG11Y2ggbG93ZXIgdGhhbiBzZWxmLWhlYWxpbmcgaW4gZ2VuZXJhbC4KCiMjIyBOb3JtYWxpemF0aW9uIHdpdGggYmF0Y2ggZWZmZWN0IG1pbmltaXphdGlvbgoKV2UgaGF2ZSBnb29kIGluZm9ybWF0aW9uIHRoYXQgc3VnZ2VzdHMgYSBzdHJvbmcgYmF0Y2ggZWZmZWN0IGluIHRoaXMgZGF0YS4gIExldCB1cyBwdXQgdGhhdAppbmZvcm1hdGlvbiB0byB1c2UgaW4gdGhlIGZvbGxvd2luZyBibG9jay4KCkhvdyBkbyB0aGVzZSBtb2RpZmljYXRpb25zIGFmZmVjdCB0aGUgc2VwYXJhdGlvbiBvZiB0aGUgZGF0YT8KCmBgYHtyIG1hY3JvYmF0Y2hfbm9ybWFsaXphdGlvbiwgZmlnLnNob3c9ImhpZGUifQpoc19tYWNyX2NwbWxvd2NiY2IgPC0gc20obm9ybWFsaXplX2V4cHQoaHNfbWFjciwgZmlsdGVyPSJocGdsIiwgY29udmVydD0iY3BtIiwgYmF0Y2g9VFJVRSkpCmhzX21hY3JfbDJjcG1sb3djb20gPC0gc20obm9ybWFsaXplX2V4cHQoaHNfbWFjciwgZmlsdGVyPSJocGdsIiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0iY29tYmF0X3NjYWxlIiwgdHJhbnNmb3JtPSJsb2cyIikpCmhzX21hY3JfbDJjcG1ybGVsb3djb20gPC0gc20obm9ybWFsaXplX2V4cHQoaHNfbWFjciwgZmlsdGVyPSJocGdsIiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0iY29tYmF0X3NjYWxlIiwgdHJhbnNmb3JtPSJsb2cyIiwgbm9ybT0icmxlIikpCmhzX21hY3JfbDJjcG1xdWFudGxvd2Ntb2QgPC0gc20obm9ybWFsaXplX2V4cHQoaHNfbWFjciwgZmlsdGVyPSJocGdsIiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0iY29tYmF0bW9kIiwgdHJhbnNmb3JtPSJsb2cyIiwgbm9ybT0icXVhbnQiKSkKaHNfbWFjcl9sMmNwbXF1YW50bG93Y29tIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX21hY3IsIGZpbHRlcj0iaHBnbCIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0iY29tYmF0X3NjYWxlIiwgdHJhbnNmb3JtPSJsb2cyIiwgbm9ybT0icXVhbnQiKSkKaHNfbWFjcl9sMmNwbXF1YW50bG93c3ZhIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX21hY3IsIGZpbHRlcj0iaHBnbCIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0ic3Zhc2VxIiwgbm9ybT0icXVhbnQiKSkKaHNfbWFjcl9sMmNwbXF1YW50bG93ZnN2YSA8LSBzbShub3JtYWxpemVfZXhwdChoc19tYWNyLCBmaWx0ZXI9ImhwZ2wiLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoPSJmc3ZhIiwgbm9ybT0icXVhbnQiKSkKaHNfbWFjcl9sMmNwbXF1YW50bG93cnV2IDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX21hY3IsIGZpbHRlcj0iaHBnbCIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0iY29tYmF0X3NjYWxlIiwgdHJhbnNmb3JtPSJsb2cyIiwgbm9ybT0icXVhbnQiKSkKdHQgPC0gc20oZ3JhcGhfbWV0cmljcyhoc19tYWNyX2wyY3BtcXVhbnRsb3dydXYpKQpgYGAKCmBgYHtyIG1hY3JvYmF0Y2hfbm9ybV9wbG90fQpoc19tYWNyX2NwbWxvd2NiY2JfcGNhIDwtIHBsb3RfcGNhKGhzX21hY3JfY3BtbG93Y2JjYikKaHNfbWFjcl9jcG1sb3djYmNiX3BjYSRwbG90CiMjIGNiY2IncyBiYXRjaCBjb3JyZWN0aW9uIGlzIGluc3VmZmljaWVudCwgYXQgbGVhc3Qgd2l0aG91dCBsb2cyCmhzX21hY3JfY3BtbG93Y2JjYl9wY2EkdGFibGUKCmhzX21hY3JfbDJjcG1sb3djb21fcGNhIDwtIHBsb3RfcGNhKGhzX21hY3JfbDJjcG1sb3djb20pCmhzX21hY3JfbDJjcG1sb3djb21fcGNhJHBsb3QKIyMgb29vbyBwcmV0dHkKa25pdHI6OmthYmxlKGhzX21hY3JfbDJjcG1sb3djb21fcGNhJHRhYmxlKQoKaHNfbWFjcl9sMmNwbXJsZWxvd2NvbV9wY2EgPC0gcGxvdF9wY2EoaHNfbWFjcl9sMmNwbXJsZWxvd2NvbSkKaHNfbWFjcl9sMmNwbXJsZWxvd2NvbV9wY2EkcGxvdAojIyBhbHNvIGxvb2tpbmcgZ29vZAprbml0cjo6a2FibGUoaHNfbWFjcl9sMmNwbXJsZWxvd2NvbV9wY2EkdGFibGUpCgpoc19tYWNyX2wyY3BtcXVhbnRsb3djbW9kX3BjYSA8LSBwbG90X3BjYShoc19tYWNyX2wyY3BtcXVhbnRsb3djbW9kKQpoc19tYWNyX2wyY3BtcXVhbnRsb3djbW9kX3BjYSRwbG90CiMjIG5vdCBhcyBnb29kCmtuaXRyOjprYWJsZShoc19tYWNyX2wyY3BtcXVhbnRsb3djbW9kX3BjYSR0YWJsZSkKCmhzX21hY3JfbDJjcG1xdWFudGxvd2ZzdmFfcGNhIDwtIHBsb3RfcGNhKGhzX21hY3JfbDJjcG1xdWFudGxvd2ZzdmEpCmhzX21hY3JfbDJjcG1xdWFudGxvd2ZzdmFfcGNhJHBsb3QKCnByZXR0eV9wY2EgPC0gcGxvdF9wY2EoaHNfbWFjcl9sMmNwbXF1YW50bG93Y29tKQpwcmV0dHlfcGNhJHBsb3QKIyMgcGVyaGFwcyB0aGUgYmVzdD8Ka25pdHI6OmthYmxlKHByZXR0eV9wY2EkdGFibGUpCiMjd3JpdGUuY3N2KHByZXR0eV9wY2EkdGFibGUsIGZpbGU9ImV4Y2VsL3ByZXR0eV9wY2EuY3N2IikKYGBgCgojIyMgU3Vycm9nYXRlIGVzdGltYXRpb25zCgpgYGB7ciBzdXJyb2dhdGVzX2VzdGltYXRlc30KIyMgTm93IHRyeSBhbmQgY29tYmluZSB0aGlzIHdpdGgKIyMgaHR0cHM6Ly9naXRodWIuY29tL2p0bGVlay9zdmFzZXEvYmxvYi9tYXN0ZXIvcmVjb3VudC5SbWQKIyMgVG8gc2VlIGlmIHRoaW5ncyBiZWNvbWUgY2xlYXJlcgpoc19tYWNyX2ZpbHQgPC0gc20obm9ybWFsaXplX2V4cHQoZXhwdD1oc19tYWNyLCBmaWx0ZXI9VFJVRSkpCmhzX21hY3Jfc2UgPC0gc20oY29tcGFyZV9zdXJyb2dhdGVfZXN0aW1hdGVzKGhzX21hY3JfZmlsdCkpCiMjIEkgdGhpbmsgbXkgaW1wbGVtZW50YXRpb24gb2YgcnV2X2VtcGlyaWNhbCBtYXkgYmUgYm9ya2VuLgpoc19tYWNyX3NlJHBjYV9wbG90cyRydXZzdXAKaHNfbWFjcl9zZSRydXZfc3VwZXJ2aXNlZF9hZGp1c3Qkc3ZzX3NhbXBsZQpoc19tYWNyX3NlJHBjYV9wbG90cyRzdmFzdXAKaHNfbWFjcl9zZSRzdmFfc3VwZXJ2aXNlZF9hZGp1c3Qkc3ZzX3NhbXBsZQojIyBUaGUgbmV3IHVuaW5mZWN0ZWQgc2FtcGxlIHN0aWxsIHNlZW1zIG9kZGx5IHBsYWNlZApoc19tYWNyX3NlJHBjYV9wbG90cyRwY2EKaHNfbWFjcl9zZSRwY2FfYWRqdXN0JHN2c19zYW1wbGUKIyMgRGl0dG8gaGVyZQpoc19tYWNyX3NlJHBjYV9wbG90cyRzdmF1bnN1cAojIyBUaGlzIHNlZW1zIHByZXR0eSByZWFzb25hYmxlIHRvIG1lCmhzX21hY3Jfc2UkcGNhX3Bsb3RzJHJ1dnJlc2lkCiMjIFRoaXMgbG9va3MgYSBsb3QgbGlrZSBwY2EgYW5kIHJ1dnN1cCwgYnV0IHRoZSBjb3JycGxvdCBzdWdnZXN0ZWQgdG8gbWUgdGhhdCBpdCB3b3VsZCBsb29rIHdlaXJkZXIuCmBgYAoKIyMjIEVmZmVjdCBvbiBvdGhlciBtZXRyaWNzIGJ5IGJhdGNoIGNvcnJlY3Rpb24KCkxldHMgc2VlIGhvdyB0aGVzZSBtb2RpZmljYXRpb24gYWZmZWN0IHRoZSB2aXN1YWxpemF0aW9ucwoKYGBge3IgdmlzdWFsaXplX25vcm1hLCBmaWcuc2hvdz0iaGlkZSJ9CmhzX21hY3JfYmF0Y2hub3JtX21ldHJpY3MgPC0gc20oZ3JhcGhfbWV0cmljcyhoc19tYWNyX2wyY3BtcXVhbnRsb3djb20pKQpgYGAKCmBgYHtyIHNlZV9ub3JtfQpwcmludChoc19tYWNyX2JhdGNobm9ybV9tZXRyaWNzJGNvcmhlYXQpCiMjIFRoZSBjb21iYXQgYWRqdXN0ZWQgY291bnRzIHNlZW0gdG8gc3BsaXQgIHJlbGF0aXZlbHkgY2xlYXJseSBiZXR3ZWVuIHR5cGVzLgpwcmludChoc19tYWNyX2JhdGNobm9ybV9tZXRyaWNzJHNtYykKIyMgVGhpcyBvbmUgc2FtcGxlIGlzIHN0aWxsIHByb2JsZW1hdGljLCB0aG91Z2guCnByaW50KGhzX21hY3JfYmF0Y2hub3JtX21ldHJpY3MkcGNhcGxvdCkKIyMgQnV0IHF1YW50aWxlIG5vcm1hbGl6YXRpb24gcmVhbGx5IGRvZXMgc21hc2ggdGhlbSBpbnRvIHRoZSBzYW1lIGRpc3RyaWJ1dGlvbi4KYGBgCgpTb21lIG90aGVyIGFuYWx5c2VzIHBlcmZvcm1lZCBzdWdnZXN0IGEgcG9zc2libGUgc3dpdGNoIGJldHdlZW4gdHdvIHNhbXBsZXMuICBXZSBjYW4gYXJ0aWZpY2FsbHkgc2VlCndoYXQgdGhlIGRhdGEgd291bGQgbG9vayBsaWtlIGlmIHRoYXQgaXMgdHJ1ZSBieSBzd2l0Y2hpbmcgdGhvc2UgdHdvIHNhbXBsZXMgaW4gYSBzZXBhcmF0ZQpleHBlcmltZW50YWwgZGVzaWduLgoKIyBUT0RPIDIwMTYxMSAjNAoKUEJNQzogdmFyaWFuY2UgcGFydGl0aW9uIGh1bWFuLCAiQXJlIHRoZXJlIGFueSBnZW5lcyB3aXRoIHZhcmlhbmNlIHdlIGNhbiBhc2NyaWJlIHRvIGNvbmRpdGlvbj8iClRoYXQgc2V0IG9mIGdlbmVzIGlzIHRoZSBtb3N0IGludGVyZXN0aW5nLiAtLSB1c2UgdGhlIHZhcmlhbmNlIHBhcml0aW9uIHRhYmxlIGFuZCBwdWxsIHRoZSB0b3AgMjAwLgpSZXBvcnQgYmFjayB0aGUgJSB2YXJpYW5jZSBieSBjb25kaXRpb24gZm9yIGFsbCBvZiB0aGVzZSBnZW5lcy4KCiMgVmFyaWFuY2UgUGFydGl0aW9uCgpJbiB0aGUgZm9sbG93aW5nLCBJIHdpbGwgYXR0ZW1wdCB0byBmaW5kIHRoZSB2YXJpYW5jZSBhc3NvY2lhdGVkIHdpdGggZGlmZmVyZW50IGV4cGVyaW1lbnRhbCBmYWN0b3JzCmluIHRoZSBtYWNyb3BoYWdlIGRhdGEgd2l0aCBtYXBwaW5ncyBhZ2FpbnN0IHRoZSBodW1hbiB0cmFuc2NyaXB0b21lLgoKIyMgU2V0dGluZyB1cAoKQXMgaW4gW21hY3JvcGhhZ2VfZXN0aW1hdGlvbl9odW1hbi5odG1sXShtYWNyb3BoYWdlX2VzdGltYXRpb25faHVtYW4uaHRtbCksIEkgbmVlZCB0byBwdWxsIG91dCB0aGUKcmVsZXZhbnQgc2FtcGxlczoKCiMgUGVyZm9ybSB2YXJpYW5jZVBhcnRpdGlvbiBhbmFseXNlcwoKIyMgQ29uZGl0aW9uICsgYmF0Y2gKClN0YXJ0IG91dCB3aXRoIGp1c3QgY29uZGl0aW9uIGFuZCBiYXRjaAoKYGBge3IgdmFycGFydF9jb25kYmF0Y2gxfQojIyBUaGUgZGVmYXVsdCBhcmd1bWVudHMgYXJlIHRvIHF1ZXJ5IH4gY29uZGl0aW9uICsgKDF8YmF0Y2gpCiMjIFdoaWNoLCBiZWNhdXNlIGNvbmRpdGlvbiBpcyBjYXRlZ29yaWNhbCwgd2lsbCBlbmQgYmFkbHkuCmhzX21hY3JfdnBfY2IgPC0gc20odmFycGFydChoc19tYWNyX2ZpbHQsCiAgICAgICAgICAgICAgICAgICAgcHJlZGljdG9yPU5VTEwsCiAgICAgICAgICAgICAgICAgICAgZmFjdG9ycz1jKCJjb25kaXRpb24iLCJiYXRjaCIpKSkKaHNfbWFjcl92cF9jYiRwZXJjZW50X3Bsb3QKaHNfbWFjcl92cF9jYiRwYXJ0aXRpb25fcGxvdAojIyBCYXRjaCBpcyBkb21pbmFudCwgYnV0IHRoZXJlIGlzIHN0aWxsIHF1aXRlIGEgbG90IGxlZnQgaW4gcmVzaWR1YWxzLgpgYGAKCiMjIENvbmRpdGlvbiArIGJhdGNoICsgc25wY2xhZGVzCgpgYGB7ciB2YXJwYXJ0X2NvbmRiYXRjaHNucH0KaHNfbWFjcl92cF9jYnMzIDwtIHNtKHZhcnBhcnQoaHNfbWFjcl9sMmNwbXF1YW50bG93c3ZhLAogICAgICAgICAgICAgICAgICAgICAgcHJlZGljdG9yPU5VTEwsCiAgICAgICAgICAgICAgICAgICAgICBmYWN0b3JzPWMoImNvbmRpdGlvbiIsImJhdGNoIiwic25wY2xhZGV2MyIpKSkKaHNfbWFjcl92cF9jYnMzJHBlcmNlbnRfcGxvdApoc19tYWNyX3ZwX2NiczMkcGFydGl0aW9uX3Bsb3QKYGBgCgojIFJlcGVhdCBhbmFseXNlcywgTGVpc2htYW5pYSBzYW1wbGVzCgojIFNhbXBsZSBtZXRyaWNzCgpJIGp1c3QgcmVhbGl6ZWQgdGhhdCB3aGF0IEkgbmVlZCB0byBkbyBpcyB0byB0YWtlIHRoZSBzdXJyb2dhdGUgZXN0aW1hdGVzIGZyb20gdGhlIGh1bWFuIGV4cGVyaW1lbnQuClVzaW5nIHRob3NlIEkgdGhpbmsgSSB3aWxsIGJlIGFibGUgdG8gZ2V0IGEgbW9yZSByZWFsaXN0aWMgZXN0aW1hdGUgb2Ygd2hhdCBpcyBnb2luZyBvbi4KCiMjIEJ1dCBmaXJzdCwgYXR0ZW1wdCBhIG5vcm1hbCBlc3RpbWF0aW9uCgpgYGB7ciBwYXJhc2l0ZV9lc3RpbWF0ZXNfbm9ybWFsLCBmaWcuc2hvdz0iaGlkZSJ9CnBhcmFzaXRlX2V4cHQgPC0gY3JlYXRlX2V4cHQobWV0YWRhdGE9InNhbXBsZV9zaGVldHMvYWxsX3NhbXBsZXMtY29tYmluZWQueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZV9pbmZvPWxwX2Fubm90YXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uPSJwYXJhc2l0ZWZpbGUiKQoKbHBfbWFjciA8LSBzdWJzZXRfZXhwdChwYXJhc2l0ZV9leHB0LCBzdWJzZXQ9ImV4cGVyaW1lbnRuYW1lPT0nbWFjcm9waGFnZSciKQpjaG9zZW5fY29sb3JzIDwtIGMoIiM5OTAwMDAiLCAiIzAwMDA5OSIpCm5hbWVzKGNob3Nlbl9jb2xvcnMpIDwtIGMoImNociIsICJzaCIpCmxwX21hY3IgPC0gc2V0X2V4cHRfY29sb3JzKGxwX21hY3IsIGNvbG9ycz1jaG9zZW5fY29sb3JzKQpscF90ZXN0aW5nIDwtIHNtKHdyaXRlX2V4cHQobHBfbWFjciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvbWFjcm9waGFnZV9wYXJhc2l0ZV9kYXRhLXYiLCB2ZXIsICIueGxzeCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlvbGluPVRSVUUpKQpscF90ZXN0aW5nJG5vcm1fcGNhCmBgYAoKTm93IGxldHMgdHJ5IHJlbW92aW5nIHNvbWUgb2YgdGhlIHN1cnJvZ2F0ZXMsIHRoZSB0d28gcHJpbWFyeSBjYW5kaWRhdGVzIGFyZSB0aGUgc3RyYWlucwp3aGljaCBJIHByb3h5IHdpdGggMyBjb2x1bW5zOiBzbnBjbGFkZSwgc25wY2xhZGV2MiwgYW5kIHNucGNsYWRldjM7IGFuZCB0aGUgYmF0Y2guICBJbiB0aGlzCmRhdGEgc2V0IGJhdGNoIGlzIGVpdGhlciBhIG9yIGIuCgpJbiB0aGVvcnksIHN2YSBzaG91bGQgcGljayB1cCBib3RoIG9mIHRob3NlIGluIG9uZSBpbnZvY2F0aW9uLgoKYGBge3IgZ2VuZXJhdGVfZ3JhcGhzLCBmaWcuc2hvdz0iaGlkZSJ9CiMjIFBlcmZvcm0gYSAnbm9ybWFsJyBzdmEKbHBfbWFjcl9zdmEgPC0gc20obm9ybWFsaXplX2V4cHQobHBfbWFjciwgYmF0Y2g9InN2YXNlcSIsIGZpbHRlcj1UUlVFKSkKIyMgUGxheSB3aXRoIHRoZSBub3JtYWxpemF0aW9uIG9mIGl0CmxwX21hY3Jfc3ZhX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQobHBfbWFjcl9zdmEsIGZpbHRlcj1UUlVFLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IiwgdHJhbnNmb3JtPSJsb2cyIikpCmxwX21hY3Jfc3ZhX25vcm1fbWV0ciA8LSBzbShncmFwaF9tZXRyaWNzKGxwX21hY3Jfc3ZhX25vcm0pKQojIyBUcnkgbGltbWEncyBtZXRob2QKbHBfbWFjcl9saW1tYV9mY3FsciA8LSBzbShub3JtYWxpemVfZXhwdChscF9tYWNyLCBiYXRjaD0ibGltbWEiLCBmaWx0ZXI9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoMj0ic25wY2xhZGV2MyIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpCmBgYAoKIyMgU3RhcnQgd2l0aCBhIHBjYSBmcm9tIHN2YQoKYGBge3Igc3ZhX2F0dGVtcHR9CmxwX21hY3Jfc3ZhX25vcm1fbWV0ciRwY2FwbG90CmBgYAoKIyMgVHJ5IGxpbW1hJ3MgcmVtb3ZlYmF0Y2hlZmZlY3QKCkFub3RoZXIgbWV0aG9kIG1pZ2h0IGJlIHRvIHRyeSB1c2luZyBsaW1tYXJlc2lkIHRvIGV4cGxpY2l0bHkgcHVsbCBib3RoIGNvbHVtbnMuCgpgYGB7ciByZXNpZF9hdHRlbXB0fQpwbG90X3BjYShscF9tYWNyX2xpbW1hX2ZjcWxyKSRwbG90CmBgYAoKQW5vdGhlciBtZXRob2QgbWlnaHQgYmUgdG8gdHJ5IHBjYSBvbiB0d28gc2VwYXJhdGUgaW52b2NhdGlvbnMuCgpgYGB7ciBwZXJmb3JtX3Jlc2lkdWFscywgZmlnLnNob3c9RkFMU0V9CiMjIGZycnByIHJwcnJmCiMjIHJhdyhwY2EocmF3KHJhdyhmaWx0ZXIoZGF0YSkpKSkpCiMjIHRodXMgZmNxc2wgd291bGQgYmUgbG9nMihzdmEocXVhbnQoY3BtKGZpbHRlcihkYXRhKSkpKSkKbHBfbWFjcl9ycHJyZiA8LSBzbShub3JtYWxpemVfZXhwdChscF9tYWNyLCBiYXRjaD0icGNhIiwgZmlsdGVyPVRSVUUpKQpscF9tYWNyX3JwcnJmIDwtIHNldF9leHB0X2JhdGNoZXMoZXhwdD1scF9tYWNyX3JwcnJmLCBmYWN0PSJzbnBjbGFkZXYzIikKbHBfbWFjcl9ycHJyZiA8LSBzbShub3JtYWxpemVfZXhwdChscF9tYWNyX3JwcnJmLCBiYXRjaD0icGNhIikpCmxwX21hY3JfbHBxY2YgPC0gc20obm9ybWFsaXplX2V4cHQobHBfbWFjcl9ycHJyZiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtPSJxdWFudCIsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUpKQpscF9tYWNyX2xwcWNmX21ldHIgPC0gc20oZ3JhcGhfbWV0cmljcyhscF9tYWNyX2xwcWNmKSkKYGBgCgpgYGB7ciBwY2FfYXR0ZW1wdH0KbHBfbWFjcl9scHFjZl9tZXRyJHBjYXBsb3QKYGBgCgojIyBBdHRlbXB0aW5nIGNvdW50IGV4dHJhY3Rpb24gZnJvbSBodW1hbiBzdXJyb2dhdGVzCgpJZiBpbmRlZWQgdGhlIGh1bWFuIHN1cnJvZ2F0ZXMgYXJlIGEgcHJpbWFyeSBkZXRlcm1pbmFudCBpbiB0aGUgcGFyYXNpdGUgZGF0YSwgdGhlbiB3ZSBzaG91bGQKYmUgYWJsZSB0byBzZWUgdGhhdCBpbiBzb21lIHNhbXBsZSBlc3RpbWF0aW9ucyBvZiB0aGUgcGFyYXNpdGUgZGF0YS4gIExldCB1cyB0cnkhCgpgYGB7ciBwYXJhc2l0ZV9lc3RpbWF0aW9uX2h1bWFuX3N1cnJvZ2F0ZXMsIGZpZy5zaG93PSJoaWRlIn0Kc3VtbWFyeShoc19tYWNyX3NlKQphZGp1c3RzIDwtIGhzX21hY3Jfc2Ukc3ZhX3N1cGVydmlzZWRfYWRqdXN0JG1vZGVsX2FkanVzdAojIyBSZW1vdmUgc3Vycm9nYXRlIGVzdGltYXRlcyAjMSBhbmQgIzkKbmV3X2FkanVzdHMgPC0gYXMubWF0cml4KGFkanVzdHNbYygtMSwgLTkpLCBdKQojIyBUaGUgcXVlc3Rpb24gb2YgY291cnNlLCAgaG93IGRvIEkgdXNlIHRoZXNlIGVzdGltYXRpb25zIHRvIGFkanVzdCB0aGUgZGF0YT8KCnRlc3RfYWRqdXN0ZWQgPC0gY291bnRzX2Zyb21fc3Vycm9nYXRlcyhscF9tYWNyLCBuZXdfYWRqdXN0cykKc3ZfYWRqdXN0ZWQgPC0gbHBfbWFjcgpCaW9iYXNlOjpleHBycyhzdl9hZGp1c3RlZCRleHByZXNzaW9uc2V0KSA8LSB0ZXN0X2FkanVzdGVkCgpoc19hZGp1c3RlZCA8LSBzdWJzZXRfZXhwdChzdl9hZGp1c3RlZCwgc3Vic2V0PSJzYW1wbGVpZCE9J0hQR0wwMjQ4JyIpCmhzX2FkanVzdGVkX2ZjcXNsIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX2FkanVzdGVkLCBjb252ZXJ0PSJjcG0iLCBmaWx0ZXI9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9InN2YSIsIG5vcm09InF1YW50IiwgdHJhbnNmb3JtPSJsb2cyIikpCmhzX2FkanVzdGVkX2ZjcXNsX21ldHIgPC0gc20oZ3JhcGhfbWV0cmljcyhoc19hZGp1c3RlZF9mY3FzbCkpCgpoc19zdl9hZGp1c3RlZCA8LSBzdWJzZXRfZXhwdChzdl9hZGp1c3RlZCwgc3Vic2V0PSJzYW1wbGVpZCE9J0hQR0wwMjQ4JyIpCmhzX3N2X2FkanVzdGVkX2ZjcXNsIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX3N2X2FkanVzdGVkLCBjb252ZXJ0PSJjcG0iLCBmaWx0ZXI9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9InN2YSIsIG5vcm09InF1YW50IiwgdHJhbnNmb3JtPSJsb2cyIikpCmhzX3N2X2FkanVzdGVkX2ZjcXNsX21ldHIgPC0gc20oZ3JhcGhfbWV0cmljcyhoc19zdl9hZGp1c3RlZF9mY3FzbCkpCgpscF9tYWNyX3JycnJyX21ldHIgPC0gc20oZ3JhcGhfbWV0cmljcyhscF9tYWNyKSkKbHBfbWFjcl9mY3FyciA8LSBzbShub3JtYWxpemVfZXhwdChscF9tYWNyLCBjb252ZXJ0PSJjcG0iLCBmaWx0ZXI9VFJVRSwgbm9ybT0icXVhbnQiKSkKbHBfbWFjcl9mY3Fycl9tZXRyIDwtIHNtKGdyYXBoX21ldHJpY3MobHBfbWFjcl9mY3FycikpCgpscF9tYWNyX2ZjcWZsIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGxwX21hY3IsIGNvbnZlcnQ9ImNwbSIsIGZpbHRlcj1UUlVFLCBub3JtPSJxdWFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9ImZzdmEiLCB0cmFuc2Zvcm09ImxvZzIiKSkKbHBfbWFjcl9mY3FmbF9tZXRyIDwtIHNtKGdyYXBoX21ldHJpY3MobHBfbWFjcl9mY3FmbCkpCgpscF9tYWNyX2ZjcWNsIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGxwX21hY3IsIGNvbnZlcnQ9ImNwbSIsIGZpbHRlcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IiwgYmF0Y2g9ImNvbWJhdF9zY2FsZSIsIHRyYW5zZm9ybT0ibG9nMiIpKQpscF9tYWNyX2ZjcWNsX21ldHIgPC0gc20oZ3JhcGhfbWV0cmljcyhscF9tYWNyX2ZjcWNsKSkKCmxwX21hY3JfZmNyZmwgPC0gc20obm9ybWFsaXplX2V4cHQobHBfbWFjciwgZmlsdGVyPVRSVUUsIG5vcm09InF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm09ImxvZzIiLCBiYXRjaD0iZnN2YSIpKQpscF9tYWNyX2ZjcmZsX21ldHIgPC0gc20oZ3JhcGhfbWV0cmljcyhscF9tYWNyX2ZjcmZsKSkKYGBgCgojIENvbXBhcmUgcmVzdWx0cwoKTm93IGxldHMgY29tcGFyZSB0aGUgcmVzdWx0cyBvZiB1c2luZyB0aGUgaHVtYW4gZGF0YSB0byBpbmZvcm0gdGhlIHBhcmFzaXRlIGVzdGltYXRpb25zLgoKIyMgQmVmb3JlIGluY2x1ZGluZyB0aGUgbmV3IGVzdGltYXRlcwoKTGV0cyBmaXJzdCBwcmludCBhIGZldyB1c2luZyBkaWZmZXJlbnQgbWV0cmljcyBiZWZvcmUgdXNpbmcgdGhlIGh1bWFuIFNWIGVzdGltYXRlcy4KSXQgbG9va3MgbGlrZSBzdmEgZXRjIGFyZSBub3QgdG9vIGJhZC4KCmBgYHtyIGNvbXBhcmVfcGNhX2Ftb25nX2VzdGltYXRlc30KbHBfbWFjcl9mY3Fycl9tZXRyJHBjYXBsb3QKIyMgSnVzdCBub3JtYWxpemluZyBzaG93cyB0aGUgY2VudHJhbCBjb25jZXJuLgoKaHNfc3ZfYWRqdXN0ZWRfZmNxc2xfbWV0ciRwY2FwbG90CiMjIFRoZSBodW1hbiBzdXJyb2dhdGVzIHdvcmsgcHJldHR5IHdlbGwKCmxwX21hY3JfZmNxY2xfbWV0ciRwY2FwbG90CiMjIENvbWJhdCBjYW5ub3QgZGVhbCB3aXRoIHRoaXMgZGF0YSB2ZXJ5IHdlbGwuCgpscF9tYWNyX2ZjcmZsX21ldHIkcGNhcGxvdAojIyBmc3ZhIGdldHMgYSBsaXR0bGUgY29uZnVzZWQsIGJ1dCBub3QgYmFkLgpgYGAKCiMgUGFyYXNpdGUgdmFyaWFuY2UgcGFydGl0aW9uCgojIyBDb25kaXRpb24gKyBiYXRjaAoKU3RhcnQgb3V0IHdpdGgganVzdCBjb25kaXRpb24gYW5kIGJhdGNoCgpgYGB7ciB2YXJwYXJ0X2NvbmRiYXRjaH0KIyMgVGhlIGRlZmF1bHQgYXJndW1lbnRzIGFyZSB0byBxdWVyeSB+IGNvbmRpdGlvbiArICgxfGJhdGNoKQojIyBXaGljaCwgYmVjYXVzZSBjb25kaXRpb24gaXMgY2F0ZWdvcmljYWwsIHdpbGwgZW5kIGJhZGx5LgpscF9tYWNyX3ZwX2NiIDwtIHNtKHZhcnBhcnQobHBfbWFjciwgcHJlZGljdG9yPU5VTEwsIGZhY3RvcnM9YygiY29uZGl0aW9uIiwiYmF0Y2giKSkpCmxwX21hY3JfdnBfY2IkcGVyY2VudF9wbG90CmxwX21hY3JfdnBfY2IkcGFydGl0aW9uX3Bsb3QKCmxwX21hY3JfdnBfbHBxY2YgPC0gc20odmFycGFydChscF9tYWNyX2xwcWNmLCBwcmVkaWN0b3I9TlVMTCwgZmFjdG9ycz1jKCJjb25kaXRpb24iLCJiYXRjaCIpKSkKbHBfbWFjcl92cF9scHFjZiRwZXJjZW50X3Bsb3QKbHBfbWFjcl92cF9scHFjZiRwYXJ0aXRpb25fcGxvdAoKbHBfbWFjcl92cF9oc2ZjcXNsIDwtIHNtKHZhcnBhcnQoaHNfYWRqdXN0ZWRfZmNxc2wsIHByZWRpY3Rvcj1OVUxMLCBmYWN0b3JzPWMoImNvbmRpdGlvbiIsImJhdGNoIikpKQpscF9tYWNyX3ZwX2hzZmNxc2wkcGVyY2VudF9wbG90CmxwX21hY3JfdnBfaHNmY3FzbCRwYXJ0aXRpb25fcGxvdApgYGAKCmBgYHtyIHNhdmVtZX0KcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCnRoaXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXJtZF9maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpCm1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgdGhpc19zYXZlKSkKdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQpgYGAK