Note, I am using my previous worksheet from when last I worked with Rezia as a template for this (I copied it from there and am modifying it now).

1 S.pyogenes 5448 rofA RNASeq version: 202301

1.1 Preprocessing

I used my cyoa tool to process these samples by doing the following:

  1. Copying the data from the sequencer into the directory ‘preprocessing/’
  2. Used a slightly involved shell command to create a directory for each sample and copy the reads for it to the ‘unprocessed/’ subdirectory within it.
  3. invoked the following:
cd preprocessing
start=$(pwd)
for i in $(/bin/ls -d ./*)
do
  cd $i
  rm -rf outputs scripts
  cyoa --task pipe --method prnas --species spyogenes_5448 \
       --gff_type gene --gff_tag locus_tag \
       --input $(/bin/ls unprocessed/* | tr '\n' ':' | sed 's/:$//g')
  cd $start
done

The above for loop goes into each sample and does the following:

  1. Trims the data, heavily compresses the outputs.
  2. Runs fastqc
  3. Runs hisat2 using my spyogenes_5448 indices.
  4. Converts the sam alignment to sorted/indexed bam.
  5. Makes a couple of extra copies of it with some filters.
  6. Compresses the aligned/unaligned reads.
  7. Runs htseq-count on the alignments to count reads/gene.

Note the following steps were not actually run because I had a speeling error. But since they are not necessary for the explicitly RNASeq analyses I first want to do, I ignored it. I am curious though to see if there are other mutations in these strains, so I will likely run those portions manually.

  1. Runs freebayes on the alignments to look for variants.
  2. Sorts/compresses the freebayes output.
  3. Does some parsing of the freebayes output and provides some tables about where mutations were observed.

1.2 Collect annotation information

Same two primary annotation sources, the gff file used for mapping/counting, and microbesonline.org. Note that since I moved to just downloading the material from the web interface, I no longer have a handy method to get the taxon ID, so I go there and hunt down the taxId manually.

Now that I am thinking about it, my 5448 genome/annotations are kind of old, I will ask and check to see if there is anything newer.

Also, 5448 does not have an entry at microbesonline.org, a fact which I forgot. I need to go poking in my notes to reconnect 5005 and 5448.

gff_annot <- load_gff_annotations("reference/spyogenes_5448.gff", type = "gene")
## Trying attempt: rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo = TRUE)
## Trying attempt: rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo = FALSE)
## Had a successful gff import with rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo = FALSE)
## Returning a df with 14 columns and 1814 rows.
rownames(gff_annot) <- gff_annot[["locus_tag"]]
head(gff_annot)
##              seqnames start  end width strand                 source type score
## SP5448_00005 CP008776   232 1587  1356      + EMBL/GenBank/SwissProt gene    NA
## SP5448_00010 CP008776  1742 2878  1137      + EMBL/GenBank/SwissProt gene    NA
## SP5448_00015 CP008776  2953 3150   198      + EMBL/GenBank/SwissProt gene    NA
## SP5448_00020 CP008776  3480 4595  1116      + EMBL/GenBank/SwissProt gene    NA
## SP5448_00025 CP008776  4665 5234   570      + EMBL/GenBank/SwissProt gene    NA
## SP5448_00030 CP008776  5237 8740  3504      + EMBL/GenBank/SwissProt gene    NA
##              phase    locus_tag gene gene_synonym note pseudo
## SP5448_00005     1 SP5448_00005 <NA>              <NA>   <NA>
## SP5448_00010     1 SP5448_00010 <NA>              <NA>   <NA>
## SP5448_00015     1 SP5448_00015 <NA>              <NA>   <NA>
## SP5448_00020     1 SP5448_00020 <NA>              <NA>   <NA>
## SP5448_00025     1 SP5448_00025 <NA>              <NA>   <NA>
## SP5448_00030     1 SP5448_00030 <NA>              <NA>   <NA>
mgas_data <- load_genbank_annotations(accession="CP008776")
## Loading required namespace: rentrez
## Done Parsing raw GenBank file text. [ 14.042 seconds ]
## 2023-02-01 14:06:06 Starting creation of gene GRanges
## 2023-02-01 14:06:07 Starting creation of CDS GRanges
## 2023-02-01 14:06:09 Starting creation of exon GRanges
## No exons read from genbank file. Assuming sections of CDS are full exons
## 2023-02-01 14:06:09 Starting creation of variant VRanges
## 2023-02-01 14:06:09 Starting creation of transcript GRanges
## No transcript features (mRNA) found, using spans of CDSs
## 2023-02-01 14:06:09 Starting creation of misc feature GRanges
## Warning in fill_stack_df(feats[!typs %in% c("gene", "exon", "CDS",
## "variation", : Got unexpected multi-value field(s) [ inference ]. The resulting
## column(s) will be of class CharacterList, rather than vector(s). Please contact
## the maintainer if multi-valuedness is expected/meaningful for the listed
## field(s).
## 2023-02-01 14:06:09 - Done creating GenBankRecord object [ 3.937 seconds ]
genome_size <- GenomicRanges::width(mgas_data$seq)  ## This fails on travis?
mgas_cds <- as.data.frame(mgas_data$cds)
## Get rid of amino acid sequence
rownames(mgas_cds) <- mgas_cds[["locus_tag"]]
wanted <- ! colnames(mgas_cds) %in% c("translation", "type", "strand", "seqnames", "start", "end", "locus_tag", "note", "gene", "gene_synonym", "width")
mgas_cds <- mgas_cds[, wanted]
## And EC_number because wtf is that?
mgas_annot <- merge(mgas_cds, gff_annot, by="row.names")
rownames(mgas_annot) <- mgas_annot[["Row.names"]]
mgas_annot[["Row.names"]] <- NULL

2 5005 Annotations

I remapped the data using 5005 because the annotations are much better.

ref_gff_annot <- load_gff_annotations("reference/spyogenes_5005.gff", type="CDS")
## Trying attempt: rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo = TRUE)
## Trying attempt: rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo = FALSE)
## Had a successful gff import with rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo = FALSE)
## Returning a df with 19 columns and 1841 rows.
rownames(ref_gff_annot) <- ref_gff_annot[["locus_tag"]]

microbes_annot <- load_microbesonline_annotations(species="5005")
## Found 1 entry.
## Streptococcus pyogenes MGAS5005Firmicutesyes2005-08-25yes101950293653
## The species being downloaded is: Streptococcus pyogenes MGAS5005
## Downloading: http://www.microbesonline.org/cgi-bin/genomeInfo.cgi?tId=293653;export=tab
microbes_df <- as.data.frame(microbes_annot)
rownames(microbes_df) <- make.names(gsub(x=microbes_df[["sysName"]], pattern="Spy_", replacement="Spy"), unique=TRUE)

s5005_annot <- merge(ref_gff_annot, microbes_df, by="row.names")
rownames(s5005_annot) <- s5005_annot[["Row.names"]]
s5005_annot[["Row.names"]] <- NULL

microbes_go <- load_microbesonline_go(species="5005", id_column="sysName")
## Found 1 entry.
## Streptococcus pyogenes MGAS5005Firmicutesyes2005-08-25yes101950293653
## The species being downloaded is: Streptococcus pyogenes MGAS5005 and is being downloaded as 293653.tab.
microbes_go[["sysName"]] <- gsub(x=microbes_go[["sysName"]], pattern="Spy_", replacement="Spy")
colnames(microbes_go) <- c("ID", "GO")
single_hits <- readr::read_tsv("single_multi/outputs/fasta_spyogenes_5448_cds_spyogenes_5005_cds/spyogenes_5448_cds_singles.txt")
## Rows: 1340 Columns: 2
## ── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (2): AKK69518.1, AAZ50620.1:1.000:0
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
colnames(single_hits) <- c("from", "to")
single_hits[["to"]] <- gsub(pattern="(^.*?):.*$", replacement="\\1",
                            x=single_hits[["to"]], perl=TRUE)
## The gff annotation has the protein_id column matching this cds entry.
single_both <- merge(mgas_annot, single_hits, by.x="protein_id", by.y="from", all.x=TRUE)
single_both <- merge(single_both, ref_gff_annot, by.x="to", by.y="protein_id", all.x=TRUE)

## Now pick up the missing old_locus_tags and put in the 5448 IDs
missing_ids <- is.na(single_both[["old_locus_tag"]])
new_ids <- single_both[missing_ids, "locus_tag.x"]
single_both[missing_ids, "old_locus_tag"] <- new_ids

single_both <- merge(single_both, microbes_annot, by.x="old_locus_tag", by.y="sysName", all.x=TRUE)
rownames(single_both) <- make.names(single_both[["gene_id"]], unique=TRUE)

2.1 Create expressionSet

Note that I did the following to the sample sheet provided by Dr. McIver:

  1. Changed the dP_R20_4 sample to dP_R20_2 (The original sample name is still there are the original column).
  2. Added columns at the end containing the count table locations.
  3. Added columns ‘short_media’, ‘growth_phase’, ‘genotype’ which hopefully contain the relevant metadata extracted from the sample descriptions.
  4. Added a column ‘Experiment’ which is either ‘rofA’ or ‘pdxR’.
rofa_expt <- create_expt(metadata="sample_sheets/all_samples.xlsx",
                        gene_info=s5005_annot, file_column="spyogenes5005genecounts") %>%
  subset_expt(subset="experiment=='rofA'") %>%
  set_expt_conditions(fact="genotype") %>%
  set_expt_batches(fact="growthphase")
## Reading the sample metadata.
## Did not find the condition column in the sample sheet.
## Filling it in as undefined.
## Did not find the batch column in the sample sheet.
## Filling it in as undefined.
## The sample definitions comprises: 72 rows(samples) and 27 columns(metadata fields).
## Matched 1841 annotations and counts.
## Bringing together the count matrix and gene information.
## Some annotations were lost in merging, setting them to 'undefined'.
## Saving the expressionset to 'expt.rda'.
## The final expressionset has 1926 features and 72 samples.
## subset_expt(): There were 72, now there are 36 samples.
## 
##  delta revert     WT 
##     12     12     12 
## 
## exponential  stationary  transition 
##          12          12          12

I have 36 samples to play with, let us see what they look like.

2.2 Poke expressionSet

rofa_libsize <- plot_libsize(rofa_expt)
rofa_libsize$plot

rofa_filter_plot <- plot_libsize_prepost(rofa_expt)
rofa_filter_plot$count_plot

rofa_filter_plot$lowgene_plot
## Warning: Using alpha for a discrete variable is not advised.

rofa_nonzero <- plot_nonzero(rofa_expt)
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
rofa_nonzero$plot
## Warning: ggrepel: 5 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## awesome, there is a range of ~ 25 genes.

written <- write_expt(rofa_expt, excel = glue::glue("excel/rofA_expt-v{ver}.xlsx"))
## Deleting the file excel/rofA_expt-v202301.xlsx before writing the tables.
## Writing the first sheet, containing a legend and some summary data.
## `geom_smooth()` using formula = 'y ~ x'Loading required package: Matrix
## 
## Attaching package: 'Matrix'
## 
## The following object is masked from 'package:S4Vectors':
## 
##     expand
## 
## 
## Total:14 s
## `geom_smooth()` using formula = 'y ~ x'
## Total:13 s

2.3 Quick visualizations

2.3.1 Without considering time

Let us start with some views of the data without thinking about batch effects.

rofa_norm <- normalize_expt(rofa_expt, filter=TRUE, norm="quant", convert="cpm", transform="log2")
## Removing 103 low-count genes (1823 remaining).
rofa_pca <- plot_pca(rofa_norm)
rofa_pca$plot
## Warning: The following aesthetics were dropped during statistical transformation: text
## ℹ This can happen when ggplot fails to infer the correct grouping structure in the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical variable into a factor?
## The following aesthetics were dropped during statistical transformation: text
## ℹ This can happen when ggplot fails to infer the correct grouping structure in the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical variable into a factor?

rofa_heatmap <- plot_disheat(rofa_norm)
rofa_heatmap$plot

2.3.2 Considering time

Repeat the previous plots, but this time using limma’s batch removal method (which is just a residuals).

rofa_time <- set_expt_conditions(rofa_expt, fact="growthphase") %>%
  set_expt_batches(fact="genotype")
## 
## exponential  stationary  transition 
##          12          12          12 
## 
##  delta revert     WT 
##     12     12     12
rofa_time_norm <- normalize_expt(rofa_time, filter=TRUE, norm="quant", convert="cpm",
                                 transform="log2")
## Removing 103 low-count genes (1823 remaining).
rofa_time_pca <- plot_pca(rofa_time_norm)
rofa_time_pca$plot
## Warning: The following aesthetics were dropped during statistical transformation: text
## ℹ This can happen when ggplot fails to infer the correct grouping structure in the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical variable into a factor?
## The following aesthetics were dropped during statistical transformation: text
## ℹ This can happen when ggplot fails to infer the correct grouping structure in the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical variable into a factor?

rofa_time_nb <- normalize_expt(rofa_time, filter=TRUE, norm="quant", convert="cpm",
                             transform="log2", batch="limma")
## Removing 103 low-count genes (1823 remaining).
## If you receive a warning: 'NANs produced', one potential reason is that the data was quantile normalized.
## Setting 46 low elements to zero.
## transform_counts: Found 46 values equal to 0, adding 1 to the matrix.
rofa_time_nb_pca <- plot_pca(rofa_time_nb)
rofa_time_nb_pca$plot
## Warning: The following aesthetics were dropped during statistical transformation: text
## ℹ This can happen when ggplot fails to infer the correct grouping structure in the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical variable into a factor?
## The following aesthetics were dropped during statistical transformation: text
## ℹ This can happen when ggplot fails to infer the correct grouping structure in the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical variable into a factor?

Well, it is pretty clear that time is the dominant factor.

2.4 Differential Expression analyses

I am going to do the DE in 4 separate pieces:

  1. Only compare strains
  2. Only compare times
  3. Compare the concatenation of strains and times.

2.4.1 Strain only comparisons

strain_de <- all_pairwise(rofa_expt, model_batch=TRUE, filter=TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
##  delta revert     WT 
##     12     12     12
## This analysis will include a batch factor in the model comprised of:
## 
## exponential  stationary  transition 
##          12          12          12
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## Using limma's removeBatchEffect to visualize with(out) batch inclusion.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

strain_keepers <- list(
    "delta_wt" = c("delta", "WT"),
    "revert_wt" = c("revert", "WT"),
    "delta_revert" = c("delta", "revert"))
strain_tables <- combine_de_tables(
    strain_de, keepers = strain_keepers,
    excel = glue::glue("excel/rofa_strain_tables-v{ver}.xlsx"))
## Deleting the file excel/rofa_strain_tables-v202301.xlsx before writing the tables.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of WT_vs_delta according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_delta according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_delta according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of WT_vs_revert according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_revert according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_revert according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of revert_vs_delta according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revert_vs_delta according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of revert_vs_delta according to the columns: logFC and adj.P.Val using the expressionset colors.
strain_sig <- extract_significant_genes(
    strain_tables,
    excel = glue::glue("excel/rofa_strain_sig-v{ver}.xlsx"))
## Deleting the file excel/rofa_strain_sig-v202301.xlsx before writing the tables.
## Plotting volcano plot of the DE results of WT_vs_delta according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_revert according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revert_vs_delta according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_delta according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_revert according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of revert_vs_delta according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_delta according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WT_vs_revert according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revert_vs_delta according to the columns: logFC and adj.P.Val using the expressionset colors.

2.4.1.1 Ontology search of delta vs wt

ups <- strain_sig[["deseq"]][["ups"]][["delta_wt"]]
downs <- strain_sig[["deseq"]][["downs"]][["delta_wt"]]
both <- rbind(ups, downs)
length_db <- fData(rofa_expt)[, c("start.y", "stop")]
length_db[["ID"]] <- rownames(length_db)
undef_idx <- length_db[["stop"]] == "undefined"
length_db <- length_db[!undef_idx, ]
length_db[["length"]] <- abs(as.numeric(length_db[["stop"]]) - as.numeric(length_db[["start.y"]]))
test <- simple_goseq(both, go_db = microbes_go, length_db = length_db)
## Found 25 go_db genes and 42 length_db genes out of 46.
## Testing that go categories are defined.
## Removing undefined categories.
## Gathering synonyms.
## Gathering category definitions.
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
library(enrichplot)
dotplot(test$bp_enrich)

2.4.2 Time only comparisons

time_de <- all_pairwise(rofa_time, model_batch=TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
## exponential  stationary  transition 
##          12          12          12
## This analysis will include a batch factor in the model comprised of:
## 
##  delta revert     WT 
##     12     12     12
## Using limma's removeBatchEffect to visualize with(out) batch inclusion.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

time_keepers <- list(
    "transition_exponential" = c("transition", "exponential"),
    "stationary_exponential" = c("stationary", "exponential"),
    "stationary_transition" = c("stationary", "transition"))
time_tables <- combine_de_tables(
    time_de, keepers = time_keepers,
    excel = glue::glue("excel/rofa_time_tables-v{ver}.xlsx"))
## Deleting the file excel/rofa_time_tables-v202301.xlsx before writing the tables.
## Starting combine_extracted_plots() with do_inverse as: FALSE.
## Plotting volcano plot of the DE results of transition_vs_exponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_exponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_exponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: FALSE.
## Plotting volcano plot of the DE results of stationary_vs_exponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of stationary_vs_exponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of stationary_vs_exponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of transition_vs_stationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_stationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_stationary according to the columns: logFC and adj.P.Val using the expressionset colors.
time_sig <- extract_significant_genes(
    time_tables,
    excel = glue::glue("excel/rofa_time_sig-v{ver}.xlsx"))
## Deleting the file excel/rofa_time_sig-v202301.xlsx before writing the tables.
## Plotting volcano plot of the DE results of transition_vs_exponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of stationary_vs_exponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_stationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_exponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of stationary_vs_exponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_stationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_exponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of stationary_vs_exponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of transition_vs_stationary according to the columns: logFC and adj.P.Val using the expressionset colors.

2.4.2.1 Ontology search of stationary vs exponential

ups <- time_sig[["deseq"]][["ups"]][["stationary_exponential"]]
downs <- time_sig[["deseq"]][["downs"]][["stationary_exponential"]]
both <- rbind(ups, downs)
up_time_goseq <- simple_goseq(ups, go_db = microbes_go, length_db = length_db)
## Found 255 go_db genes and 376 length_db genes out of 379.
## Testing that go categories are defined.
## Removing undefined categories.
## Gathering synonyms.
## Gathering category definitions.
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
fc_values <- time_tables[["data"]][["stationary_exponential"]][["deseq_logfc"]]
names(fc_values) <- rownames(time_tables[["data"]][["stationary_exponential"]])
head(fc_values)
## M5005_Spy0001 M5005_Spy0002 M5005_Spy0003 M5005_Spy0004 M5005_Spy0005 
##       -0.1191       -0.1996       -1.2100       -0.2377       -0.8275 
## M5005_Spy0006 
##       -0.9872
dotplot(up_time_goseq$mf_enrich)

cnetplot(up_time_goseq$mf_enrich, categorysize="pvalue", foldChange=fc_values)
## Warning in cnetplot.enrichResult(x, ...): Use 'color.params = list(foldChange = your_value)' instead of 'foldChange'.
##  The foldChange parameter will be removed in the next version.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.

heatplot(up_time_goseq$mf_enrich, foldChange=fc_values)

term_sim <- pairwise_termsim(up_time_goseq$mf_enrich)
treeplot(term_sim)

emapplot(term_sim)

both_time_goseq <- simple_goseq(both, go_db = microbes_go, length_db = length_db)
## Found 378 go_db genes and 533 length_db genes out of 541.
## Testing that go categories are defined.
## Removing undefined categories.
## Gathering synonyms.
## Gathering category definitions.
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
## The score column is null, defaulting to score.
## Possible columns are:
## [1] "category"                 "over_represented_pvalue" 
## [3] "under_represented_pvalue" "numDEInCat"              
## [5] "numInCat"                 "term"                    
## [7] "ontology"                 "qvalue"
## The over_represented_pvalue column is null, defaulting to score.
## Possible columns are:
## [1] "term"    "pvalue"  "score"   "num_de"  "num_cat"
dotplot(both_time_goseq$mf_enrich)

2.4.2.2 Compare times vs strains

I always worry that comparing a data set across multiple conditions results in not what I think it will. Let us therefore plot the logFCs of likely contrasts against each other.

x_axis <- time_tables[["data"]][["transition_exponential"]][, c("deseq_logfc", "deseq_adjp")]
y_axis <- strain_tables[["data"]][["delta_wt"]][, c("deseq_logfc", "deseq_adjp")]
both <- merge(x_axis, y_axis, by="row.names")
rownames(both) <- both[["Row.names"]]
both[["Row.names"]] <- NULL
cor.test(both[["deseq_logfc.x"]], both[["deseq_logfc.y"]], method="spearman")
## Warning in cor.test.default(both[["deseq_logfc.x"]], both[["deseq_logfc.y"]], :
## Cannot compute exact p-value with ties
## 
##  Spearman's rank correlation rho
## 
## data:  both[["deseq_logfc.x"]] and both[["deseq_logfc.y"]]
## S = 6.2e+08, p-value <2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##    rho 
## 0.3811
plotted <- plot_linear_scatter(both[, c("deseq_logfc.x", "deseq_logfc.y")])
## Warning in plot_multihistogram(df): NAs introduced by coercion
plotted$scatter

2.4.3 Interaction model

I want to make sure that my methods of performing interaction models work as I think it does, and this data set looks to me to be a perfect place to test that.

combined_factors <- paste0(pData(rofa_expt)[["genotype"]], "_",
                           pData(rofa_expt)[["growthphase"]])
combined_factors
##  [1] "WT_transition"      "WT_transition"      "WT_transition"     
##  [4] "WT_transition"      "delta_transition"   "delta_transition"  
##  [7] "delta_transition"   "delta_transition"   "revert_transition" 
## [10] "revert_transition"  "revert_transition"  "revert_transition" 
## [13] "WT_exponential"     "WT_exponential"     "WT_exponential"    
## [16] "WT_exponential"     "delta_exponential"  "delta_exponential" 
## [19] "delta_exponential"  "delta_exponential"  "revert_exponential"
## [22] "revert_exponential" "revert_exponential" "WT_stationary"     
## [25] "WT_stationary"      "WT_stationary"      "delta_stationary"  
## [28] "delta_stationary"   "delta_stationary"   "delta_stationary"  
## [31] "revert_stationary"  "revert_stationary"  "revert_stationary" 
## [34] "revert_stationary"  "revert_exponential" "WT_stationary"
combined_expt <- set_expt_conditions(rofa_expt, fact = combined_factors)
## 
##  delta_exponential   delta_stationary   delta_transition revert_exponential 
##                  4                  4                  4                  4 
##  revert_stationary  revert_transition     WT_exponential      WT_stationary 
##                  4                  4                  4                  4 
##      WT_transition 
##                  4
combined_de <- all_pairwise(combined_expt, model_batch = "svaseq", surrogates = 2,
                            filter = TRUE, parallel = FALSE)
## This DE analysis will perform all pairwise comparisons among:
## 
##  delta_exponential   delta_stationary   delta_transition revert_exponential 
##                  4                  4                  4                  4 
##  revert_stationary  revert_transition     WT_exponential      WT_stationary 
##                  4                  4                  4                  4 
##      WT_transition 
##                  4
## This analysis will include surrogate estimates from: svaseq.
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## Removing 0 low-count genes (1823 remaining).
## Setting 3755 low elements to zero.
## transform_counts: Found 3755 values equal to 0, adding 1 to the matrix.
## Starting basic_pairwise().
## Starting basic pairwise comparison.
## Basic step 0/3: Normalizing data.
## Basic step 0/3: Converting data.
## Basic step 0/3: Transforming data.
## Basic step 1/3: Creating mean and variance tables.
## Basic step 2/3: Performing 45 comparisons.
## Basic step 3/3: Creating faux DE Tables.
## Basic: Returning tables.
## Starting deseq_pairwise().
## Starting DESeq2 pairwise comparisons.
## The data should be suitable for EdgeR/DESeq/EBSeq. If they freak out, check the state of the count table and ensure that it is in integer counts.
## Including batch estimates from sva/ruv/pca in the model.
## Choosing the non-intercept containing model.
## DESeq2 step 1/5: Including a matrix of batch estimates in the deseq model.
## converting counts to integer mode
## DESeq2 step 2/5: Estimate size factors.
## DESeq2 step 3/5: Estimate dispersions.
## gene-wise dispersion estimates
## mean-dispersion relationship
## final dispersion estimates
## Using a parametric fitting seems to have worked.
## DESeq2 step 4/5: nbinomWaldTest.
## Starting edger_pairwise().
## Starting edgeR pairwise comparisons.
## The data should be suitable for EdgeR/DESeq/EBSeq. If they freak out, check the state of the count table and ensure that it is in integer counts.
## Including batch estimates from sva/ruv/pca in the model.
## Choosing the non-intercept containing model.
## EdgeR step 1/9: Importing and normalizing data.
## EdgeR step 2/9: Estimating the common dispersion.
## EdgeR step 3/9: Estimating dispersion across genes.
## EdgeR step 4/9: Estimating GLM Common dispersion.
## EdgeR step 5/9: Estimating GLM Trended dispersion.
## EdgeR step 6/9: Estimating GLM Tagged dispersion.
## EdgeR step 7/9: Running glmFit, switch to glmQLFit by changing the argument 'edger_test'.
## EdgeR step 8/9: Making pairwise contrasts.

## Starting limma_pairwise().
##                        Length Class         Mode     
## title                   1     -none-        character
## notes                   1     -none-        character
## initial_metadata       28     data.frame    list     
## expressionset           1     ExpressionSet S4       
## design                 28     data.frame    list     
## conditions             36     -none-        character
## batches                36     -none-        character
## samplenames            36     -none-        character
## colors                 36     -none-        character
## state                   5     -none-        list     
## libsize                36     -none-        numeric  
## original_expressionset  1     ExpressionSet S4       
## normalized              6     -none-        list     
## best_libsize           36     -none-        numeric  
## norm_result             6     -none-        list
## Starting limma pairwise comparison.
## libsize was not specified, this parameter has profound effects on limma's result.
## Using the libsize from expt$best_libsize.
## Limma step 1/6: choosing model.
## Including batch estimates from sva/ruv/pca in the model.
## Choosing the non-intercept containing model.
## Limma step 2/6: running limma::voom(), switch with the argument 'which_voom'.
## Using normalize.method = quantile for voom.

## Limma step 3/6: running lmFit with method: ls.
## Limma step 4/6: making and fitting contrasts with no intercept. (~ 0 + factors)
## Limma step 5/6: Running eBayes with robust = FALSE and trend = FALSE.
## Limma step 6/6: Writing limma outputs.
## Limma step 6/6: 1/36: Creating table: deltastationary_vs_deltaexponential.  Adjust = BH
## Limma step 6/6: 2/36: Creating table: deltatransition_vs_deltaexponential.  Adjust = BH
## Limma step 6/6: 3/36: Creating table: revertexponential_vs_deltaexponential.  Adjust = BH
## Limma step 6/6: 4/36: Creating table: revertstationary_vs_deltaexponential.  Adjust = BH
## Limma step 6/6: 5/36: Creating table: reverttransition_vs_deltaexponential.  Adjust = BH
## Limma step 6/6: 6/36: Creating table: WTexponential_vs_deltaexponential.  Adjust = BH
## Limma step 6/6: 7/36: Creating table: WTstationary_vs_deltaexponential.  Adjust = BH
## Limma step 6/6: 8/36: Creating table: WTtransition_vs_deltaexponential.  Adjust = BH
## Limma step 6/6: 9/36: Creating table: deltatransition_vs_deltastationary.  Adjust = BH
## Limma step 6/6: 10/36: Creating table: revertexponential_vs_deltastationary.  Adjust = BH
## Limma step 6/6: 11/36: Creating table: revertstationary_vs_deltastationary.  Adjust = BH
## Limma step 6/6: 12/36: Creating table: reverttransition_vs_deltastationary.  Adjust = BH
## Limma step 6/6: 13/36: Creating table: WTexponential_vs_deltastationary.  Adjust = BH
## Limma step 6/6: 14/36: Creating table: WTstationary_vs_deltastationary.  Adjust = BH
## Limma step 6/6: 15/36: Creating table: WTtransition_vs_deltastationary.  Adjust = BH
## Limma step 6/6: 16/36: Creating table: revertexponential_vs_deltatransition.  Adjust = BH
## Limma step 6/6: 17/36: Creating table: revertstationary_vs_deltatransition.  Adjust = BH
## Limma step 6/6: 18/36: Creating table: reverttransition_vs_deltatransition.  Adjust = BH
## Limma step 6/6: 19/36: Creating table: WTexponential_vs_deltatransition.  Adjust = BH
## Limma step 6/6: 20/36: Creating table: WTstationary_vs_deltatransition.  Adjust = BH
## Limma step 6/6: 21/36: Creating table: WTtransition_vs_deltatransition.  Adjust = BH
## Limma step 6/6: 22/36: Creating table: revertstationary_vs_revertexponential.  Adjust = BH
## Limma step 6/6: 23/36: Creating table: reverttransition_vs_revertexponential.  Adjust = BH
## Limma step 6/6: 24/36: Creating table: WTexponential_vs_revertexponential.  Adjust = BH
## Limma step 6/6: 25/36: Creating table: WTstationary_vs_revertexponential.  Adjust = BH
## Limma step 6/6: 26/36: Creating table: WTtransition_vs_revertexponential.  Adjust = BH
## Limma step 6/6: 27/36: Creating table: reverttransition_vs_revertstationary.  Adjust = BH
## Limma step 6/6: 28/36: Creating table: WTexponential_vs_revertstationary.  Adjust = BH
## Limma step 6/6: 29/36: Creating table: WTstationary_vs_revertstationary.  Adjust = BH
## Limma step 6/6: 30/36: Creating table: WTtransition_vs_revertstationary.  Adjust = BH
## Limma step 6/6: 31/36: Creating table: WTexponential_vs_reverttransition.  Adjust = BH
## Limma step 6/6: 32/36: Creating table: WTstationary_vs_reverttransition.  Adjust = BH
## Limma step 6/6: 33/36: Creating table: WTtransition_vs_reverttransition.  Adjust = BH
## Limma step 6/6: 34/36: Creating table: WTstationary_vs_WTexponential.  Adjust = BH
## Limma step 6/6: 35/36: Creating table: WTtransition_vs_WTexponential.  Adjust = BH
## Limma step 6/6: 36/36: Creating table: WTtransition_vs_WTstationary.  Adjust = BH
## Limma step 6/6: 1/9: Creating table: deltaexponential.  Adjust = BH
## Limma step 6/6: 2/9: Creating table: deltastationary.  Adjust = BH
## Limma step 6/6: 3/9: Creating table: deltatransition.  Adjust = BH
## Limma step 6/6: 4/9: Creating table: revertexponential.  Adjust = BH
## Limma step 6/6: 5/9: Creating table: revertstationary.  Adjust = BH
## Limma step 6/6: 6/9: Creating table: reverttransition.  Adjust = BH
## Limma step 6/6: 7/9: Creating table: WTexponential.  Adjust = BH
## Limma step 6/6: 8/9: Creating table: WTstationary.  Adjust = BH
## Limma step 6/6: 9/9: Creating table: WTtransition.  Adjust = BH
##                        Length Class         Mode     
## title                   1     -none-        character
## notes                   1     -none-        character
## initial_metadata       28     data.frame    list     
## expressionset           1     ExpressionSet S4       
## design                 28     data.frame    list     
## conditions             36     -none-        character
## batches                36     -none-        character
## samplenames            36     -none-        character
## colors                 36     -none-        character
## state                   5     -none-        list     
## libsize                36     -none-        numeric  
## original_expressionset  1     ExpressionSet S4       
## normalized              6     -none-        list     
## best_libsize           36     -none-        numeric  
## norm_result             6     -none-        list
## Comparing analyses.

combined_keepers <- list(
    "exponential_delta_vs_wt" = c("deltaexponential", "WTexponential"),
    "exponential_delta_vs_revert" = c("deltaexponential", "revertexponential"),
    "stationary_delta_vs_wt" = c("deltastationary", "WTstationary"),
    "stationary_delta_vs_revert" = c("deltastationary", "revertstationary"),
    "transition_delta_vs_wt" = c("deltatransition", "WTtransition"),
    "transition_delta_vs_revert" = c("deltatransition", "reverttransition"),
    "WT_exponential_vs_transition" = c("WTexponential", "WTtransition"),
    "delta_exponential_vs_transition" = c("deltaexponential", "deltatransition"),
    "revert_exponential_vs_transition" = c("revertexponential", "reverttransition"),
    "WT_stationary_vs_transition" = c("WTstationary", "WTtransition"),
    "delta_stationary_vs_transition" = c("deltastationary", "deltatransition"),
    "revert_stationary_vs_transition" = c("revertstationary", "reverttransition"),
    "WT_stationary_vs_exponential" = c("WTstationary", "WTexponential"),
    "delta_stationary_vs_exponential" = c("deltastationary", "deltaexponential"),
    "revert_stationary_vs_exponential" = c("revertstationary", "revertexponential"))


combined_tables <- combine_de_tables(
    combined_de, keepers = combined_keepers,
    excel = glue::glue("excel/rofa_combined_tables-v{ver}.xlsx"))
## Deleting the file excel/rofa_combined_tables-v202301.xlsx before writing the tables.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of WTexponential_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTexponential_vs_deltaexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTexponential_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of revertexponential_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertexponential_vs_deltaexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of revertexponential_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of WTstationary_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_deltastationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of revertstationary_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_deltastationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of WTtransition_vs_deltatransition according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_deltatransition according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_deltatransition according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of reverttransition_vs_deltatransition according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_deltatransition according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_deltatransition according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of WTtransition_vs_WTexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of deltatransition_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltaexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of reverttransition_vs_revertexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of WTtransition_vs_WTstationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTstationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTstationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of deltatransition_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltastationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: TRUE.
## Plotting volcano plot of the DE results of reverttransition_vs_revertstationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertstationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertstationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: FALSE.
## Plotting volcano plot of the DE results of WTstationary_vs_WTexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_WTexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_WTexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: FALSE.
## Plotting volcano plot of the DE results of deltastationary_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltastationary_vs_deltaexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of deltastationary_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Starting combine_extracted_plots() with do_inverse as: FALSE.
## Plotting volcano plot of the DE results of revertstationary_vs_revertexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_revertexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_revertexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
combined_sig <- extract_significant_genes(
    combined_tables,
    excel = glue::glue("excel/rofa_combined_sig-v{ver}.xlsx"))
## Deleting the file excel/rofa_combined_sig-v202301.xlsx before writing the tables.
## Plotting volcano plot of the DE results of WTexponential_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertexponential_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_deltatransition according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_deltatransition according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTstationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertstationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_WTexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltastationary_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_revertexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTexponential_vs_deltaexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of revertexponential_vs_deltaexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_deltastationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_deltastationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_deltatransition according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_deltatransition according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltaexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTstationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltastationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertstationary according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_WTexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of deltastationary_vs_deltaexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_revertexponential according to the columns: logFC and FDR using the expressionset colors.
## Plotting volcano plot of the DE results of WTexponential_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertexponential_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_deltatransition according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_deltatransition according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTtransition_vs_WTstationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltatransition_vs_deltastationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of reverttransition_vs_revertstationary according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of WTstationary_vs_WTexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of deltastationary_vs_deltaexponential according to the columns: logFC and adj.P.Val using the expressionset colors.
## Plotting volcano plot of the DE results of revertstationary_vs_revertexponential according to the columns: logFC and adj.P.Val using the expressionset colors.

3 Make a circos picture

Work on making a pretty picture, there are kind of a lot of potential contrasts, so lets just start with one.

circos_cfg <- circos_prefix(fData(rofa_expt), name="rofa", chr_column = "seqnames",
                            start_column = "start.x", stop_column = "end",
                            strand_column = "strand.x", cog_column = "COGFun")
## This assumes you have a colors.conf in circos/colors/ and fonts.conf in circos/fonts/
## It also assumes you have conf/ideogram.conf, conf/ticks.conf, and conf/housekeeping.conf
## It will write circos/conf/rofa.conf with a reasonable first approximation config file.
## Setting 86 undefined entries to the plus strand.
## Warning in circos_prefix(fData(rofa_expt), name = "rofa", chr_column =
## "seqnames", : NAs introduced by coercion

## Warning in circos_prefix(fData(rofa_expt), name = "rofa", chr_column =
## "seqnames", : NAs introduced by coercion
## Wrote karyotype to circos/conf/ideograms/rofa.conf
## This should match the ideogram= line in rofa.conf
## Wrote ticks to circos/conf/ticks_rofa.conf
kary <- circos_karyotype(circos_cfg, fasta = "reference/spyogenes_5005.fasta")
## Wrote karyotype to circos/conf/karyotypes/rofa.conf
## This should match the karyotype= line in rofa.conf
plus_minus <- circos_plus_minus(circos_cfg, width = 0.06, thickness = 40,
                                url_string = "http://www.microbesonline.org/cgi-bin/fetchLocus.cgi?locus=[id]")
## Writing data file: circos/data/rofa_plus_go.txt with the + strand GO data.
## Writing data file: circos/data/rofa_minus_go.txt with the - strand GO data.
## Wrote the +/- config files.  Appending their inclusion to the master file.
## Returning the inner width: 0.88.  Use it as the outer for the next ring.
exp_delta_vs_wt_hist <- circos_hist(circos_cfg, combined_tables[["data"]][["exponential_delta_vs_wt"]],
                                    colname="deseq_logfc", basename="exp_deltawt",
                                    outer=plus_minus)
## Assuming the input is a dataframe.
## Writing data file: circos/data/rofa_exp_deltawtdeseq_logfc_hist.txt with the exp_deltawtdeseq_logfc column.
## Returning the inner width: 0.8.  Use it as the outer for the next ring.
cjb_suffix <- circos_suffix(circos_cfg)
made <- circos_make(circos_cfg, target="rofa")

circos/rofa.png

if (!isTRUE(get0("skip_load"))) {
  pander::pander(sessionInfo())
  message(paste0("This is hpgltools commit: ", get_git_commit()))
  this_save <- paste0(gsub(pattern = "\\.Rmd", replace = "", x = rmd_file), "-v", ver, ".rda.xz")
  message(paste0("Saving to ", this_save))
  tmp <- sm(saveme(filename = this_save))
}
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 140f18734ff1a7e49669ad91dd4f469f0560ca1a
## This is hpgltools commit: Sun Jan 29 15:36:20 2023 -0500: 140f18734ff1a7e49669ad91dd4f469f0560ca1a
## Saving to index_rofA-v202301.rda.xz
LS0tCnRpdGxlOiAiUy5weW9nZW5lcyA1NDQ4IDIwMjMwMTogUk5BU2VxIGNvbXBhcmluZyByb2ZBIHN0cmFpbnMgYWNyb3NzIHRpbWUuIgphdXRob3I6ICJhdGIgYWJlbGV3QGdtYWlsLmNvbSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiBodG1sX2RvY3VtZW50OgogIGNvZGVfZG93bmxvYWQ6IHRydWUKICBjb2RlX2ZvbGRpbmc6IHNob3cKICBmaWdfY2FwdGlvbjogdHJ1ZQogIGZpZ19oZWlnaHQ6IDcKICBmaWdfd2lkdGg6IDcKICBoaWdobGlnaHQ6IGRlZmF1bHQKICBrZWVwX21kOiBmYWxzZQogIG1vZGU6IHNlbGZjb250YWluZWQKICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHRoZW1lOiByZWFkYWJsZQogIHRvYzogdHJ1ZQogIHRvY19mbG9hdDoKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlPgogIGJvZHkgLm1haW4tY29udGFpbmVyIHsKICAgIG1heC13aWR0aDogMTYwMHB4OwogIH0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGUgPSBGQUxTRX0KbGlicmFyeShocGdsdG9vbHMpCnR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDkwLAogICAgICAgICAgICAgICAgICAgICBlY2hvID0gVFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDgsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0ID0gOCwKICAgICAgICAgICAgICAgICAgICAgIGRwaSA9IDk2KQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cyA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemUgPSAxMCkpCnNldC5zZWVkKDEpCnZlciA8LSAiMjAyMzAxIgpybWRfZmlsZSA8LSAiaW5kZXhfcm9mQS5SbWQiCmBgYAoKTm90ZSwgSSBhbSB1c2luZyBteSBwcmV2aW91cyB3b3Jrc2hlZXQgZnJvbSB3aGVuIGxhc3QgSSB3b3JrZWQgd2l0aApSZXppYSBhcyBhIHRlbXBsYXRlIGZvciB0aGlzIChJIGNvcGllZCBpdCBmcm9tIHRoZXJlIGFuZCBhbSBtb2RpZnlpbmcKaXQgbm93KS4KCiMgUy5weW9nZW5lcyA1NDQ4IHJvZkEgUk5BU2VxIHZlcnNpb246IGByIHZlcmAKCiMjIFByZXByb2Nlc3NpbmcKCkkgdXNlZCBteSBjeW9hIHRvb2wgdG8gcHJvY2VzcyB0aGVzZSBzYW1wbGVzIGJ5IGRvaW5nIHRoZSBmb2xsb3dpbmc6CgoxLiAgQ29weWluZyB0aGUgZGF0YSBmcm9tIHRoZSBzZXF1ZW5jZXIgaW50byB0aGUgZGlyZWN0b3J5ICdwcmVwcm9jZXNzaW5nLycKMi4gIFVzZWQgYSBzbGlnaHRseSBpbnZvbHZlZCBzaGVsbCBjb21tYW5kIHRvIGNyZWF0ZSBhIGRpcmVjdG9yeSBmb3IKICAgIGVhY2ggc2FtcGxlIGFuZCBjb3B5IHRoZSByZWFkcyBmb3IgaXQgdG8gdGhlICd1bnByb2Nlc3NlZC8nCiAgICBzdWJkaXJlY3Rvcnkgd2l0aGluIGl0LgozLiAgaW52b2tlZCB0aGUgZm9sbG93aW5nOgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9CmNkIHByZXByb2Nlc3NpbmcKc3RhcnQ9JChwd2QpCmZvciBpIGluICQoL2Jpbi9scyAtZCAuLyopCmRvCiAgY2QgJGkKICBybSAtcmYgb3V0cHV0cyBzY3JpcHRzCiAgY3lvYSAtLXRhc2sgcGlwZSAtLW1ldGhvZCBwcm5hcyAtLXNwZWNpZXMgc3B5b2dlbmVzXzU0NDggXAogICAgICAgLS1nZmZfdHlwZSBnZW5lIC0tZ2ZmX3RhZyBsb2N1c190YWcgXAogICAgICAgLS1pbnB1dCAkKC9iaW4vbHMgdW5wcm9jZXNzZWQvKiB8IHRyICdcbicgJzonIHwgc2VkICdzLzokLy9nJykKICBjZCAkc3RhcnQKZG9uZQpgYGAKClRoZSBhYm92ZSBmb3IgbG9vcCBnb2VzIGludG8gZWFjaCBzYW1wbGUgYW5kIGRvZXMgdGhlIGZvbGxvd2luZzoKCjEuICBUcmltcyB0aGUgZGF0YSwgaGVhdmlseSBjb21wcmVzc2VzIHRoZSBvdXRwdXRzLgoyLiAgUnVucyBmYXN0cWMKMy4gIFJ1bnMgaGlzYXQyIHVzaW5nIG15IHNweW9nZW5lc181NDQ4IGluZGljZXMuCjQuICBDb252ZXJ0cyB0aGUgc2FtIGFsaWdubWVudCB0byBzb3J0ZWQvaW5kZXhlZCBiYW0uCjUuICBNYWtlcyBhIGNvdXBsZSBvZiBleHRyYSBjb3BpZXMgb2YgaXQgd2l0aCBzb21lIGZpbHRlcnMuCjYuICBDb21wcmVzc2VzIHRoZSBhbGlnbmVkL3VuYWxpZ25lZCByZWFkcy4KNy4gIFJ1bnMgaHRzZXEtY291bnQgb24gdGhlIGFsaWdubWVudHMgdG8gY291bnQgcmVhZHMvZ2VuZS4KCiAgTm90ZSB0aGUgZm9sbG93aW5nIHN0ZXBzIHdlcmUgbm90IGFjdHVhbGx5IHJ1biBiZWNhdXNlIEkgaGFkIGEKICBzcGVlbGluZyBlcnJvci4gIEJ1dCBzaW5jZSB0aGV5IGFyZSBub3QgbmVjZXNzYXJ5IGZvciB0aGUgZXhwbGljaXRseQogIFJOQVNlcSBhbmFseXNlcyBJIGZpcnN0IHdhbnQgdG8gZG8sIEkgaWdub3JlZCBpdC4gIEkgYW0gY3VyaW91cwogIHRob3VnaCB0byBzZWUgaWYgdGhlcmUgYXJlIG90aGVyIG11dGF0aW9ucyBpbiB0aGVzZSBzdHJhaW5zLCBzbyBJCiAgd2lsbCBsaWtlbHkgcnVuIHRob3NlIHBvcnRpb25zIG1hbnVhbGx5LgoKOC4gIFJ1bnMgZnJlZWJheWVzIG9uIHRoZSBhbGlnbm1lbnRzIHRvIGxvb2sgZm9yIHZhcmlhbnRzLgo5LiAgU29ydHMvY29tcHJlc3NlcyB0aGUgZnJlZWJheWVzIG91dHB1dC4KMTAuIERvZXMgc29tZSBwYXJzaW5nIG9mIHRoZSBmcmVlYmF5ZXMgb3V0cHV0IGFuZCBwcm92aWRlcyBzb21lIHRhYmxlcwogICAgYWJvdXQgd2hlcmUgbXV0YXRpb25zIHdlcmUgb2JzZXJ2ZWQuCgojIyBDb2xsZWN0IGFubm90YXRpb24gaW5mb3JtYXRpb24KClNhbWUgdHdvIHByaW1hcnkgYW5ub3RhdGlvbiBzb3VyY2VzLCB0aGUgZ2ZmIGZpbGUgdXNlZCBmb3IgbWFwcGluZy9jb3VudGluZywKYW5kIG1pY3JvYmVzb25saW5lLm9yZy4gIE5vdGUgdGhhdCBzaW5jZSBJIG1vdmVkIHRvIGp1c3QgZG93bmxvYWRpbmcgdGhlCm1hdGVyaWFsIGZyb20gdGhlIHdlYiBpbnRlcmZhY2UsIEkgbm8gbG9uZ2VyIGhhdmUgYSBoYW5keSBtZXRob2QgdG8gZ2V0IHRoZQp0YXhvbiBJRCwgc28gSSBnbyB0aGVyZSBhbmQgaHVudCBkb3duIHRoZSB0YXhJZCBtYW51YWxseS4KCk5vdyB0aGF0IEkgYW0gdGhpbmtpbmcgYWJvdXQgaXQsIG15IDU0NDggZ2Vub21lL2Fubm90YXRpb25zIGFyZSBraW5kCm9mIG9sZCwgSSB3aWxsIGFzayBhbmQgY2hlY2sgdG8gc2VlIGlmIHRoZXJlIGlzIGFueXRoaW5nIG5ld2VyLgoKQWxzbywgNTQ0OCBkb2VzIG5vdCBoYXZlIGFuIGVudHJ5IGF0IG1pY3JvYmVzb25saW5lLm9yZywgYSBmYWN0IHdoaWNoCkkgZm9yZ290LiAgSSBuZWVkIHRvIGdvIHBva2luZyBpbiBteSBub3RlcyB0byByZWNvbm5lY3QgNTAwNSBhbmQgNTQ0OC4KCmBgYHtyIGFubm90YXRpb259CmdmZl9hbm5vdCA8LSBsb2FkX2dmZl9hbm5vdGF0aW9ucygicmVmZXJlbmNlL3NweW9nZW5lc181NDQ4LmdmZiIsIHR5cGUgPSAiZ2VuZSIpCnJvd25hbWVzKGdmZl9hbm5vdCkgPC0gZ2ZmX2Fubm90W1sibG9jdXNfdGFnIl1dCmhlYWQoZ2ZmX2Fubm90KQoKbWdhc19kYXRhIDwtIGxvYWRfZ2VuYmFua19hbm5vdGF0aW9ucyhhY2Nlc3Npb249IkNQMDA4Nzc2IikKZ2Vub21lX3NpemUgPC0gR2Vub21pY1Jhbmdlczo6d2lkdGgobWdhc19kYXRhJHNlcSkgICMjIFRoaXMgZmFpbHMgb24gdHJhdmlzPwptZ2FzX2NkcyA8LSBhcy5kYXRhLmZyYW1lKG1nYXNfZGF0YSRjZHMpCiMjIEdldCByaWQgb2YgYW1pbm8gYWNpZCBzZXF1ZW5jZQpyb3duYW1lcyhtZ2FzX2NkcykgPC0gbWdhc19jZHNbWyJsb2N1c190YWciXV0Kd2FudGVkIDwtICEgY29sbmFtZXMobWdhc19jZHMpICVpbiUgYygidHJhbnNsYXRpb24iLCAidHlwZSIsICJzdHJhbmQiLCAic2VxbmFtZXMiLCAic3RhcnQiLCAiZW5kIiwgImxvY3VzX3RhZyIsICJub3RlIiwgImdlbmUiLCAiZ2VuZV9zeW5vbnltIiwgIndpZHRoIikKbWdhc19jZHMgPC0gbWdhc19jZHNbLCB3YW50ZWRdCiMjIEFuZCBFQ19udW1iZXIgYmVjYXVzZSB3dGYgaXMgdGhhdD8KbWdhc19hbm5vdCA8LSBtZXJnZShtZ2FzX2NkcywgZ2ZmX2Fubm90LCBieT0icm93Lm5hbWVzIikKcm93bmFtZXMobWdhc19hbm5vdCkgPC0gbWdhc19hbm5vdFtbIlJvdy5uYW1lcyJdXQptZ2FzX2Fubm90W1siUm93Lm5hbWVzIl1dIDwtIE5VTEwKYGBgCgojIDUwMDUgQW5ub3RhdGlvbnMKCkkgcmVtYXBwZWQgdGhlIGRhdGEgdXNpbmcgNTAwNSBiZWNhdXNlIHRoZSBhbm5vdGF0aW9ucyBhcmUgbXVjaCBiZXR0ZXIuCgpgYGB7ciBzcHlvZ2VuZXNfNTAwNV9hbm5vdH0KcmVmX2dmZl9hbm5vdCA8LSBsb2FkX2dmZl9hbm5vdGF0aW9ucygicmVmZXJlbmNlL3NweW9nZW5lc181MDA1LmdmZiIsIHR5cGU9IkNEUyIpCnJvd25hbWVzKHJlZl9nZmZfYW5ub3QpIDwtIHJlZl9nZmZfYW5ub3RbWyJsb2N1c190YWciXV0KCm1pY3JvYmVzX2Fubm90IDwtIGxvYWRfbWljcm9iZXNvbmxpbmVfYW5ub3RhdGlvbnMoc3BlY2llcz0iNTAwNSIpCm1pY3JvYmVzX2RmIDwtIGFzLmRhdGEuZnJhbWUobWljcm9iZXNfYW5ub3QpCnJvd25hbWVzKG1pY3JvYmVzX2RmKSA8LSBtYWtlLm5hbWVzKGdzdWIoeD1taWNyb2Jlc19kZltbInN5c05hbWUiXV0sIHBhdHRlcm49IlNweV8iLCByZXBsYWNlbWVudD0iU3B5IiksIHVuaXF1ZT1UUlVFKQoKczUwMDVfYW5ub3QgPC0gbWVyZ2UocmVmX2dmZl9hbm5vdCwgbWljcm9iZXNfZGYsIGJ5PSJyb3cubmFtZXMiKQpyb3duYW1lcyhzNTAwNV9hbm5vdCkgPC0gczUwMDVfYW5ub3RbWyJSb3cubmFtZXMiXV0KczUwMDVfYW5ub3RbWyJSb3cubmFtZXMiXV0gPC0gTlVMTAoKbWljcm9iZXNfZ28gPC0gbG9hZF9taWNyb2Jlc29ubGluZV9nbyhzcGVjaWVzPSI1MDA1IiwgaWRfY29sdW1uPSJzeXNOYW1lIikKbWljcm9iZXNfZ29bWyJzeXNOYW1lIl1dIDwtIGdzdWIoeD1taWNyb2Jlc19nb1tbInN5c05hbWUiXV0sIHBhdHRlcm49IlNweV8iLCByZXBsYWNlbWVudD0iU3B5IikKY29sbmFtZXMobWljcm9iZXNfZ28pIDwtIGMoIklEIiwgIkdPIikKYGBgCgpgYGB7ciBjb21iaW5lX3N0cmFpbl9hbm5vdGF0aW9uc30Kc2luZ2xlX2hpdHMgPC0gcmVhZHI6OnJlYWRfdHN2KCJzaW5nbGVfbXVsdGkvb3V0cHV0cy9mYXN0YV9zcHlvZ2VuZXNfNTQ0OF9jZHNfc3B5b2dlbmVzXzUwMDVfY2RzL3NweW9nZW5lc181NDQ4X2Nkc19zaW5nbGVzLnR4dCIpCmNvbG5hbWVzKHNpbmdsZV9oaXRzKSA8LSBjKCJmcm9tIiwgInRvIikKc2luZ2xlX2hpdHNbWyJ0byJdXSA8LSBnc3ViKHBhdHRlcm49IiheLio/KTouKiQiLCByZXBsYWNlbWVudD0iXFwxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg9c2luZ2xlX2hpdHNbWyJ0byJdXSwgcGVybD1UUlVFKQojIyBUaGUgZ2ZmIGFubm90YXRpb24gaGFzIHRoZSBwcm90ZWluX2lkIGNvbHVtbiBtYXRjaGluZyB0aGlzIGNkcyBlbnRyeS4Kc2luZ2xlX2JvdGggPC0gbWVyZ2UobWdhc19hbm5vdCwgc2luZ2xlX2hpdHMsIGJ5Lng9InByb3RlaW5faWQiLCBieS55PSJmcm9tIiwgYWxsLng9VFJVRSkKc2luZ2xlX2JvdGggPC0gbWVyZ2Uoc2luZ2xlX2JvdGgsIHJlZl9nZmZfYW5ub3QsIGJ5Lng9InRvIiwgYnkueT0icHJvdGVpbl9pZCIsIGFsbC54PVRSVUUpCgojIyBOb3cgcGljayB1cCB0aGUgbWlzc2luZyBvbGRfbG9jdXNfdGFncyBhbmQgcHV0IGluIHRoZSA1NDQ4IElEcwptaXNzaW5nX2lkcyA8LSBpcy5uYShzaW5nbGVfYm90aFtbIm9sZF9sb2N1c190YWciXV0pCm5ld19pZHMgPC0gc2luZ2xlX2JvdGhbbWlzc2luZ19pZHMsICJsb2N1c190YWcueCJdCnNpbmdsZV9ib3RoW21pc3NpbmdfaWRzLCAib2xkX2xvY3VzX3RhZyJdIDwtIG5ld19pZHMKCnNpbmdsZV9ib3RoIDwtIG1lcmdlKHNpbmdsZV9ib3RoLCBtaWNyb2Jlc19hbm5vdCwgYnkueD0ib2xkX2xvY3VzX3RhZyIsIGJ5Lnk9InN5c05hbWUiLCBhbGwueD1UUlVFKQpyb3duYW1lcyhzaW5nbGVfYm90aCkgPC0gbWFrZS5uYW1lcyhzaW5nbGVfYm90aFtbImdlbmVfaWQiXV0sIHVuaXF1ZT1UUlVFKQpgYGAKCiMjIENyZWF0ZSBleHByZXNzaW9uU2V0CgpOb3RlIHRoYXQgSSBkaWQgdGhlIGZvbGxvd2luZyB0byB0aGUgc2FtcGxlIHNoZWV0IHByb3ZpZGVkIGJ5CkRyLiBNY0l2ZXI6CgoxLiAgQ2hhbmdlZCB0aGUgZFBfUjIwXzQgc2FtcGxlIHRvIGRQX1IyMF8yIChUaGUgb3JpZ2luYWwgc2FtcGxlIG5hbWUKICAgIGlzIHN0aWxsIHRoZXJlIGFyZSB0aGUgb3JpZ2luYWwgY29sdW1uKS4KMi4gIEFkZGVkIGNvbHVtbnMgYXQgdGhlIGVuZCBjb250YWluaW5nIHRoZSBjb3VudCB0YWJsZSBsb2NhdGlvbnMuCjMuICBBZGRlZCBjb2x1bW5zICdzaG9ydF9tZWRpYScsICdncm93dGhfcGhhc2UnLCAnZ2Vub3R5cGUnIHdoaWNoCiAgICBob3BlZnVsbHkgY29udGFpbiB0aGUgcmVsZXZhbnQgbWV0YWRhdGEgZXh0cmFjdGVkIGZyb20gdGhlIHNhbXBsZQogICAgZGVzY3JpcHRpb25zLgo0LiAgQWRkZWQgYSBjb2x1bW4gJ0V4cGVyaW1lbnQnIHdoaWNoIGlzIGVpdGhlciAncm9mQScgb3IgJ3BkeFInLgoKYGBge3IgZXhwdH0Kcm9mYV9leHB0IDwtIGNyZWF0ZV9leHB0KG1ldGFkYXRhPSJzYW1wbGVfc2hlZXRzL2FsbF9zYW1wbGVzLnhsc3giLAogICAgICAgICAgICAgICAgICAgICAgICBnZW5lX2luZm89czUwMDVfYW5ub3QsIGZpbGVfY29sdW1uPSJzcHlvZ2VuZXM1MDA1Z2VuZWNvdW50cyIpICU+JQogIHN1YnNldF9leHB0KHN1YnNldD0iZXhwZXJpbWVudD09J3JvZkEnIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0PSJnZW5vdHlwZSIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdD0iZ3Jvd3RocGhhc2UiKQpgYGAKCkkgaGF2ZSAzNiBzYW1wbGVzIHRvIHBsYXkgd2l0aCwgbGV0IHVzIHNlZSB3aGF0IHRoZXkgbG9vayBsaWtlLgoKIyMgUG9rZSBleHByZXNzaW9uU2V0CgpgYGB7ciBwb2tlfQpyb2ZhX2xpYnNpemUgPC0gcGxvdF9saWJzaXplKHJvZmFfZXhwdCkKcm9mYV9saWJzaXplJHBsb3QKCnJvZmFfZmlsdGVyX3Bsb3QgPC0gcGxvdF9saWJzaXplX3ByZXBvc3Qocm9mYV9leHB0KQpyb2ZhX2ZpbHRlcl9wbG90JGNvdW50X3Bsb3QKcm9mYV9maWx0ZXJfcGxvdCRsb3dnZW5lX3Bsb3QKCnJvZmFfbm9uemVybyA8LSBwbG90X25vbnplcm8ocm9mYV9leHB0KQpyb2ZhX25vbnplcm8kcGxvdAojIyBhd2Vzb21lLCB0aGVyZSBpcyBhIHJhbmdlIG9mIH4gMjUgZ2VuZXMuCgp3cml0dGVuIDwtIHdyaXRlX2V4cHQocm9mYV9leHB0LCBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3JvZkFfZXhwdC12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIFF1aWNrIHZpc3VhbGl6YXRpb25zCgojIyMgV2l0aG91dCBjb25zaWRlcmluZyB0aW1lCgpMZXQgdXMgc3RhcnQgd2l0aCBzb21lIHZpZXdzIG9mIHRoZSBkYXRhIHdpdGhvdXQgdGhpbmtpbmcgYWJvdXQgYmF0Y2ggZWZmZWN0cy4KCmBgYHtyIHZpZXdfbm9iYXRjaH0Kcm9mYV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHJvZmFfZXhwdCwgZmlsdGVyPVRSVUUsIG5vcm09InF1YW50IiwgY29udmVydD0iY3BtIiwgdHJhbnNmb3JtPSJsb2cyIikKcm9mYV9wY2EgPC0gcGxvdF9wY2Eocm9mYV9ub3JtKQpyb2ZhX3BjYSRwbG90Cgpyb2ZhX2hlYXRtYXAgPC0gcGxvdF9kaXNoZWF0KHJvZmFfbm9ybSkKcm9mYV9oZWF0bWFwJHBsb3QKYGBgCgojIyMgQ29uc2lkZXJpbmcgdGltZQoKUmVwZWF0IHRoZSBwcmV2aW91cyBwbG90cywgYnV0IHRoaXMgdGltZSB1c2luZyBsaW1tYSdzIGJhdGNoIHJlbW92YWwKbWV0aG9kICh3aGljaCBpcyBqdXN0IGEgcmVzaWR1YWxzKS4KCmBgYHtyIG5iX3ZpZXd9CnJvZmFfdGltZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHJvZmFfZXhwdCwgZmFjdD0iZ3Jvd3RocGhhc2UiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3Q9Imdlbm90eXBlIikKCnJvZmFfdGltZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHJvZmFfdGltZSwgZmlsdGVyPVRSVUUsIG5vcm09InF1YW50IiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtPSJsb2cyIikKcm9mYV90aW1lX3BjYSA8LSBwbG90X3BjYShyb2ZhX3RpbWVfbm9ybSkKcm9mYV90aW1lX3BjYSRwbG90Cgpyb2ZhX3RpbWVfbmIgPC0gbm9ybWFsaXplX2V4cHQocm9mYV90aW1lLCBmaWx0ZXI9VFJVRSwgbm9ybT0icXVhbnQiLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT0ibG9nMiIsIGJhdGNoPSJsaW1tYSIpCnJvZmFfdGltZV9uYl9wY2EgPC0gcGxvdF9wY2Eocm9mYV90aW1lX25iKQpyb2ZhX3RpbWVfbmJfcGNhJHBsb3QKYGBgCgpXZWxsLCBpdCBpcyBwcmV0dHkgY2xlYXIgdGhhdCB0aW1lIGlzIHRoZSBkb21pbmFudCBmYWN0b3IuCgojIyBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbiBhbmFseXNlcwoKSSBhbSBnb2luZyB0byBkbyB0aGUgREUgaW4gNCBzZXBhcmF0ZSBwaWVjZXM6CgoxLiAgT25seSBjb21wYXJlIHN0cmFpbnMKMi4gIE9ubHkgY29tcGFyZSB0aW1lcwozLiAgQ29tcGFyZSB0aGUgY29uY2F0ZW5hdGlvbiBvZiBzdHJhaW5zIGFuZCB0aW1lcy4KCiMjIyBTdHJhaW4gb25seSBjb21wYXJpc29ucwoKYGBge3IgcGFpcndpc2Vfc3RyYWlufQpzdHJhaW5fZGUgPC0gYWxsX3BhaXJ3aXNlKHJvZmFfZXhwdCwgbW9kZWxfYmF0Y2g9VFJVRSwgZmlsdGVyPVRSVUUpCnN0cmFpbl9rZWVwZXJzIDwtIGxpc3QoCiAgICAiZGVsdGFfd3QiID0gYygiZGVsdGEiLCAiV1QiKSwKICAgICJyZXZlcnRfd3QiID0gYygicmV2ZXJ0IiwgIldUIiksCiAgICAiZGVsdGFfcmV2ZXJ0IiA9IGMoImRlbHRhIiwgInJldmVydCIpKQpzdHJhaW5fdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgc3RyYWluX2RlLCBrZWVwZXJzID0gc3RyYWluX2tlZXBlcnMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3JvZmFfc3RyYWluX3RhYmxlcy12e3Zlcn0ueGxzeCIpKQpzdHJhaW5fc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBzdHJhaW5fdGFibGVzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9yb2ZhX3N0cmFpbl9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIE9udG9sb2d5IHNlYXJjaCBvZiBkZWx0YSB2cyB3dAoKYGBge3IgZ29zZXFfZGVsdGFfd3QwMX0KdXBzIDwtIHN0cmFpbl9zaWdbWyJkZXNlcSJdXVtbInVwcyJdXVtbImRlbHRhX3d0Il1dCmRvd25zIDwtIHN0cmFpbl9zaWdbWyJkZXNlcSJdXVtbImRvd25zIl1dW1siZGVsdGFfd3QiXV0KYm90aCA8LSByYmluZCh1cHMsIGRvd25zKQpsZW5ndGhfZGIgPC0gZkRhdGEocm9mYV9leHB0KVssIGMoInN0YXJ0LnkiLCAic3RvcCIpXQpsZW5ndGhfZGJbWyJJRCJdXSA8LSByb3duYW1lcyhsZW5ndGhfZGIpCnVuZGVmX2lkeCA8LSBsZW5ndGhfZGJbWyJzdG9wIl1dID09ICJ1bmRlZmluZWQiCmxlbmd0aF9kYiA8LSBsZW5ndGhfZGJbIXVuZGVmX2lkeCwgXQpsZW5ndGhfZGJbWyJsZW5ndGgiXV0gPC0gYWJzKGFzLm51bWVyaWMobGVuZ3RoX2RiW1sic3RvcCJdXSkgLSBhcy5udW1lcmljKGxlbmd0aF9kYltbInN0YXJ0LnkiXV0pKQp0ZXN0IDwtIHNpbXBsZV9nb3NlcShib3RoLCBnb19kYiA9IG1pY3JvYmVzX2dvLCBsZW5ndGhfZGIgPSBsZW5ndGhfZGIpCmxpYnJhcnkoZW5yaWNocGxvdCkKZG90cGxvdCh0ZXN0JGJwX2VucmljaCkKYGBgCgojIyMgVGltZSBvbmx5IGNvbXBhcmlzb25zCgpgYGB7ciBwYWlyd2lzZV90aW1lfQp0aW1lX2RlIDwtIGFsbF9wYWlyd2lzZShyb2ZhX3RpbWUsIG1vZGVsX2JhdGNoPVRSVUUpCnRpbWVfa2VlcGVycyA8LSBsaXN0KAogICAgInRyYW5zaXRpb25fZXhwb25lbnRpYWwiID0gYygidHJhbnNpdGlvbiIsICJleHBvbmVudGlhbCIpLAogICAgInN0YXRpb25hcnlfZXhwb25lbnRpYWwiID0gYygic3RhdGlvbmFyeSIsICJleHBvbmVudGlhbCIpLAogICAgInN0YXRpb25hcnlfdHJhbnNpdGlvbiIgPSBjKCJzdGF0aW9uYXJ5IiwgInRyYW5zaXRpb24iKSkKdGltZV90YWJsZXMgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB0aW1lX2RlLCBrZWVwZXJzID0gdGltZV9rZWVwZXJzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9yb2ZhX3RpbWVfdGFibGVzLXZ7dmVyfS54bHN4IikpCnRpbWVfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICB0aW1lX3RhYmxlcywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvcm9mYV90aW1lX3NpZy12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyMgT250b2xvZ3kgc2VhcmNoIG9mIHN0YXRpb25hcnkgdnMgZXhwb25lbnRpYWwKCmBgYHtyIGdvc2VxX2RlbHRhX3d0MDJ9CnVwcyA8LSB0aW1lX3NpZ1tbImRlc2VxIl1dW1sidXBzIl1dW1sic3RhdGlvbmFyeV9leHBvbmVudGlhbCJdXQpkb3ducyA8LSB0aW1lX3NpZ1tbImRlc2VxIl1dW1siZG93bnMiXV1bWyJzdGF0aW9uYXJ5X2V4cG9uZW50aWFsIl1dCmJvdGggPC0gcmJpbmQodXBzLCBkb3ducykKdXBfdGltZV9nb3NlcSA8LSBzaW1wbGVfZ29zZXEodXBzLCBnb19kYiA9IG1pY3JvYmVzX2dvLCBsZW5ndGhfZGIgPSBsZW5ndGhfZGIpCgpmY192YWx1ZXMgPC0gdGltZV90YWJsZXNbWyJkYXRhIl1dW1sic3RhdGlvbmFyeV9leHBvbmVudGlhbCJdXVtbImRlc2VxX2xvZ2ZjIl1dCm5hbWVzKGZjX3ZhbHVlcykgPC0gcm93bmFtZXModGltZV90YWJsZXNbWyJkYXRhIl1dW1sic3RhdGlvbmFyeV9leHBvbmVudGlhbCJdXSkKaGVhZChmY192YWx1ZXMpCgpkb3RwbG90KHVwX3RpbWVfZ29zZXEkbWZfZW5yaWNoKQpjbmV0cGxvdCh1cF90aW1lX2dvc2VxJG1mX2VucmljaCwgY2F0ZWdvcnlzaXplPSJwdmFsdWUiLCBmb2xkQ2hhbmdlPWZjX3ZhbHVlcykKaGVhdHBsb3QodXBfdGltZV9nb3NlcSRtZl9lbnJpY2gsIGZvbGRDaGFuZ2U9ZmNfdmFsdWVzKQp0ZXJtX3NpbSA8LSBwYWlyd2lzZV90ZXJtc2ltKHVwX3RpbWVfZ29zZXEkbWZfZW5yaWNoKQp0cmVlcGxvdCh0ZXJtX3NpbSkKZW1hcHBsb3QodGVybV9zaW0pCgpib3RoX3RpbWVfZ29zZXEgPC0gc2ltcGxlX2dvc2VxKGJvdGgsIGdvX2RiID0gbWljcm9iZXNfZ28sIGxlbmd0aF9kYiA9IGxlbmd0aF9kYikKZG90cGxvdChib3RoX3RpbWVfZ29zZXEkbWZfZW5yaWNoKQpgYGAKCiMjIyMgQ29tcGFyZSB0aW1lcyB2cyBzdHJhaW5zCgpJIGFsd2F5cyB3b3JyeSB0aGF0IGNvbXBhcmluZyBhIGRhdGEgc2V0IGFjcm9zcyBtdWx0aXBsZSBjb25kaXRpb25zCnJlc3VsdHMgaW4gbm90IHdoYXQgSSB0aGluayBpdCB3aWxsLiAgTGV0IHVzIHRoZXJlZm9yZSBwbG90IHRoZSBsb2dGQ3MKb2YgbGlrZWx5IGNvbnRyYXN0cyBhZ2FpbnN0IGVhY2ggb3RoZXIuCgpgYGB7ciBjb21wYXJlX3RpbWVzX3ZzX3N0cmFpbnN9CnhfYXhpcyA8LSB0aW1lX3RhYmxlc1tbImRhdGEiXV1bWyJ0cmFuc2l0aW9uX2V4cG9uZW50aWFsIl1dWywgYygiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpXQp5X2F4aXMgPC0gc3RyYWluX3RhYmxlc1tbImRhdGEiXV1bWyJkZWx0YV93dCJdXVssIGMoImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0KYm90aCA8LSBtZXJnZSh4X2F4aXMsIHlfYXhpcywgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGJvdGgpIDwtIGJvdGhbWyJSb3cubmFtZXMiXV0KYm90aFtbIlJvdy5uYW1lcyJdXSA8LSBOVUxMCmNvci50ZXN0KGJvdGhbWyJkZXNlcV9sb2dmYy54Il1dLCBib3RoW1siZGVzZXFfbG9nZmMueSJdXSwgbWV0aG9kPSJzcGVhcm1hbiIpCnBsb3R0ZWQgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihib3RoWywgYygiZGVzZXFfbG9nZmMueCIsICJkZXNlcV9sb2dmYy55IildKQpwbG90dGVkJHNjYXR0ZXIKYGBgCgojIyMgSW50ZXJhY3Rpb24gbW9kZWwKCkkgd2FudCB0byBtYWtlIHN1cmUgdGhhdCBteSBtZXRob2RzIG9mIHBlcmZvcm1pbmcgaW50ZXJhY3Rpb24gbW9kZWxzCndvcmsgYXMgSSB0aGluayBpdCBkb2VzLCBhbmQgdGhpcyBkYXRhIHNldCBsb29rcyB0byBtZSB0byBiZSBhIHBlcmZlY3QKcGxhY2UgdG8gdGVzdCB0aGF0LgoKYGBge3IgY29tYmluZWRfZGV9CmNvbWJpbmVkX2ZhY3RvcnMgPC0gcGFzdGUwKHBEYXRhKHJvZmFfZXhwdClbWyJnZW5vdHlwZSJdXSwgIl8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBwRGF0YShyb2ZhX2V4cHQpW1siZ3Jvd3RocGhhc2UiXV0pCmNvbWJpbmVkX2ZhY3RvcnMKCmNvbWJpbmVkX2V4cHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyhyb2ZhX2V4cHQsIGZhY3QgPSBjb21iaW5lZF9mYWN0b3JzKQpjb21iaW5lZF9kZSA8LSBhbGxfcGFpcndpc2UoY29tYmluZWRfZXhwdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgc3Vycm9nYXRlcyA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBwYXJhbGxlbCA9IEZBTFNFKQoKY29tYmluZWRfa2VlcGVycyA8LSBsaXN0KAogICAgImV4cG9uZW50aWFsX2RlbHRhX3ZzX3d0IiA9IGMoImRlbHRhZXhwb25lbnRpYWwiLCAiV1RleHBvbmVudGlhbCIpLAogICAgImV4cG9uZW50aWFsX2RlbHRhX3ZzX3JldmVydCIgPSBjKCJkZWx0YWV4cG9uZW50aWFsIiwgInJldmVydGV4cG9uZW50aWFsIiksCiAgICAic3RhdGlvbmFyeV9kZWx0YV92c193dCIgPSBjKCJkZWx0YXN0YXRpb25hcnkiLCAiV1RzdGF0aW9uYXJ5IiksCiAgICAic3RhdGlvbmFyeV9kZWx0YV92c19yZXZlcnQiID0gYygiZGVsdGFzdGF0aW9uYXJ5IiwgInJldmVydHN0YXRpb25hcnkiKSwKICAgICJ0cmFuc2l0aW9uX2RlbHRhX3ZzX3d0IiA9IGMoImRlbHRhdHJhbnNpdGlvbiIsICJXVHRyYW5zaXRpb24iKSwKICAgICJ0cmFuc2l0aW9uX2RlbHRhX3ZzX3JldmVydCIgPSBjKCJkZWx0YXRyYW5zaXRpb24iLCAicmV2ZXJ0dHJhbnNpdGlvbiIpLAogICAgIldUX2V4cG9uZW50aWFsX3ZzX3RyYW5zaXRpb24iID0gYygiV1RleHBvbmVudGlhbCIsICJXVHRyYW5zaXRpb24iKSwKICAgICJkZWx0YV9leHBvbmVudGlhbF92c190cmFuc2l0aW9uIiA9IGMoImRlbHRhZXhwb25lbnRpYWwiLCAiZGVsdGF0cmFuc2l0aW9uIiksCiAgICAicmV2ZXJ0X2V4cG9uZW50aWFsX3ZzX3RyYW5zaXRpb24iID0gYygicmV2ZXJ0ZXhwb25lbnRpYWwiLCAicmV2ZXJ0dHJhbnNpdGlvbiIpLAogICAgIldUX3N0YXRpb25hcnlfdnNfdHJhbnNpdGlvbiIgPSBjKCJXVHN0YXRpb25hcnkiLCAiV1R0cmFuc2l0aW9uIiksCiAgICAiZGVsdGFfc3RhdGlvbmFyeV92c190cmFuc2l0aW9uIiA9IGMoImRlbHRhc3RhdGlvbmFyeSIsICJkZWx0YXRyYW5zaXRpb24iKSwKICAgICJyZXZlcnRfc3RhdGlvbmFyeV92c190cmFuc2l0aW9uIiA9IGMoInJldmVydHN0YXRpb25hcnkiLCAicmV2ZXJ0dHJhbnNpdGlvbiIpLAogICAgIldUX3N0YXRpb25hcnlfdnNfZXhwb25lbnRpYWwiID0gYygiV1RzdGF0aW9uYXJ5IiwgIldUZXhwb25lbnRpYWwiKSwKICAgICJkZWx0YV9zdGF0aW9uYXJ5X3ZzX2V4cG9uZW50aWFsIiA9IGMoImRlbHRhc3RhdGlvbmFyeSIsICJkZWx0YWV4cG9uZW50aWFsIiksCiAgICAicmV2ZXJ0X3N0YXRpb25hcnlfdnNfZXhwb25lbnRpYWwiID0gYygicmV2ZXJ0c3RhdGlvbmFyeSIsICJyZXZlcnRleHBvbmVudGlhbCIpKQoKCmNvbWJpbmVkX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIGNvbWJpbmVkX2RlLCBrZWVwZXJzID0gY29tYmluZWRfa2VlcGVycywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvcm9mYV9jb21iaW5lZF90YWJsZXMtdnt2ZXJ9Lnhsc3giKSkKY29tYmluZWRfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBjb21iaW5lZF90YWJsZXMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3JvZmFfY29tYmluZWRfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyBNYWtlIGEgY2lyY29zIHBpY3R1cmUKCldvcmsgb24gbWFraW5nIGEgcHJldHR5IHBpY3R1cmUsIHRoZXJlIGFyZSBraW5kIG9mIGEgbG90IG9mIHBvdGVudGlhbCBjb250cmFzdHMsIHNvIGxldHMganVzdApzdGFydCB3aXRoIG9uZS4KCmBgYHtyIGNpcmNvc19yZXN1bHR9CmNpcmNvc19jZmcgPC0gY2lyY29zX3ByZWZpeChmRGF0YShyb2ZhX2V4cHQpLCBuYW1lPSJyb2ZhIiwgY2hyX2NvbHVtbiA9ICJzZXFuYW1lcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydF9jb2x1bW4gPSAic3RhcnQueCIsIHN0b3BfY29sdW1uID0gImVuZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhbmRfY29sdW1uID0gInN0cmFuZC54IiwgY29nX2NvbHVtbiA9ICJDT0dGdW4iKQprYXJ5IDwtIGNpcmNvc19rYXJ5b3R5cGUoY2lyY29zX2NmZywgZmFzdGEgPSAicmVmZXJlbmNlL3NweW9nZW5lc181MDA1LmZhc3RhIikKcGx1c19taW51cyA8LSBjaXJjb3NfcGx1c19taW51cyhjaXJjb3NfY2ZnLCB3aWR0aCA9IDAuMDYsIHRoaWNrbmVzcyA9IDQwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybF9zdHJpbmcgPSAiaHR0cDovL3d3dy5taWNyb2Jlc29ubGluZS5vcmcvY2dpLWJpbi9mZXRjaExvY3VzLmNnaT9sb2N1cz1baWRdIikKZXhwX2RlbHRhX3ZzX3d0X2hpc3QgPC0gY2lyY29zX2hpc3QoY2lyY29zX2NmZywgY29tYmluZWRfdGFibGVzW1siZGF0YSJdXVtbImV4cG9uZW50aWFsX2RlbHRhX3ZzX3d0Il1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xuYW1lPSJkZXNlcV9sb2dmYyIsIGJhc2VuYW1lPSJleHBfZGVsdGF3dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGVyPXBsdXNfbWludXMpCmNqYl9zdWZmaXggPC0gY2lyY29zX3N1ZmZpeChjaXJjb3NfY2ZnKQptYWRlIDwtIGNpcmNvc19tYWtlKGNpcmNvc19jZmcsIHRhcmdldD0icm9mYSIpCmBgYAoKW2NpcmNvcy9yb2ZhLnBuZ10oY2lyY29zL3JvZmEucG5nKQoKCmBgYHtyIHNhdmVtZX0KaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiAgcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKICBtZXNzYWdlKHBhc3RlMCgiVGhpcyBpcyBocGdsdG9vbHMgY29tbWl0OiAiLCBnZXRfZ2l0X2NvbW1pdCgpKSkKICB0aGlzX3NhdmUgPC0gcGFzdGUwKGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLCByZXBsYWNlID0gIiIsIHggPSBybWRfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKQogIG1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgdGhpc19zYXZlKSkKICB0bXAgPC0gc20oc2F2ZW1lKGZpbGVuYW1lID0gdGhpc19zYXZlKSkKfQpgYGAK