R/atlasExplorer.R

Defines functions st.expression.viewer

st.expression.viewer <- function(path.data.dir, win.dim = c(14,14), os.windows = FALSE, X11.type = NULL){

  library(gWidgets)
  library(gWidgetstcltk)
  library(dplyr)
  library(plyr)
  library(plotly)
  library(data.table)
  library(RColorBrewer)
  library(jpeg)

  update.AP <- function(new.val, update.section = TRUE){
    AP <<- new.val
    svalue(txt_coord) <- AP
    if(update.section){
      ord.AP <- sort(unique(spots.table$AP), decreasing = TRUE)
      pos <- which(ord.AP == AP)
      svalue(txt_section) <- pos
    }
  }

  select.cluster.display <- function(type = 1){

    win.select.clusters <- gwindow('Selecting clusters to display', width = 500, height = 500)
    size(win.select.clusters) <- c(500,700)
    horiz.container.select.cl <- ggroup(container = win.select.clusters, horizontal = TRUE)

    df.clust <- data.frame(cluster_ID = as.numeric(as.character(clusters.list$cluster)), cluster_name = as.character(clusters.list$clusters.named))
    df.clust <- unique(df.clust)
    df.clust <- df.clust[order(df.clust$cluster_name),]

    table.select <- gtable(df.clust, container = horiz.container.select.cl)

    names(table.select) <- c('Cluster ID', 'Cluster name')
    size(table.select) <- c(325,600)

    btn_validate_clusters <- gbutton(
      text      = "Validate",
      container = horiz.container.select.cl,
      handler   = function(h, ...){
        dispose(win.select.clusters)
        if(!is.na(svalue(table.select))){
          if(type == 1){
            spots.to.color <<- rownames(clusters.list[clusters.list$cluster == svalue(table.select),])
            svalue(btn_select_clusters) <<- 'Change cluster'
            svalue(txt_cur_clust) <<- paste('Current cluster 1: ',svalue(table.select),'\n(',df.clust[df.clust$cluster_ID==svalue(table.select), 'cluster_name'], ')', sep='')
          }else{
            spots.to.color.2 <<- rownames(clusters.list[clusters.list$cluster == svalue(table.select),])
            svalue(btn_select_clusters.2) <<- 'Change cluster'
            svalue(txt_cur_clust.2) <<- paste('Current cluster 2: ',svalue(table.select),'\n(',df.clust[df.clust$cluster_ID==svalue(table.select), 'cluster_name'], ')', sep='')
          }
        }
        update.atlas.plot()
      }
    )
  }

  select.gene.dea <- function(){

    cl.1 <- clusters.list[spots.to.color[1],'cluster']
    cl.2 <- clusters.list[spots.to.color.2[1],'cluster']
    file.path <- paste(svalue(browse.dea),'/results_',cl.1,'_vs_',cl.2,'.tsv',sep='')

    if (!file.exists(file.path)){
      print('DE file not found.')
      return()
    }
    t <- read.csv(file.path, sep='\t', header = TRUE, row.names = 1)
    t <- t[1:200,]
    t <- signif(t,3)
    t <- cbind(rownames(t),t)
    colnames(t)[1] <- 'Gene'


    win.select.dea <- gwindow('Selecting gene from DEA analysis', width = 500, height = 500)
    size(win.select.dea) <- c(800,700)
    horiz.container.select.dea <- ggroup(container = win.select.dea, horizontal = TRUE)

    table.select.dea <- gtable(t, container = horiz.container.select.dea)
    size(table.select.dea) <- c(500,675)

    btn_validate_dea <- gbutton(
      text      = "Validate",
      container = horiz.container.select.dea,
      handler   = function(h, ...){
        dispose(win.select.dea)
        if(!is.na(svalue(table.select.dea))){
          if(is.element(svalue(table.select.dea),colnames(st.data))){
            gene <<- as.character(svalue(table.select.dea))
            svalue(txt_gene) <- (gene)
            update.atlas.plot()
          }
        }
      }
    )

    btn_cancel_dea <- gbutton(
      text      = "Cancel",
      container = horiz.container.select.dea,
      handler = function(h, ...){
        dispose(win.select.dea)
      }
    )


  }

  update.atlas.plot <- function(val.new.window = bool.new.window, val.slice.index = NULL){

    if(!is.null(spots.to.color) & svalue(btn_show_clusters) == 'Hide')
      val.name.cluster.1 <- unique(clusters.list[spots.to.color,'clusters.named'])
    else
      val.name.cluster.1 <- NULL

    if(!is.null(spots.to.color.2) & svalue(btn_show_clusters.2) == 'Hide')
      val.name.cluster.2 <- unique(clusters.list[spots.to.color.2,'clusters.named'])
    else
      val.name.cluster.2 <- NULL


    if (is.null(val.slice.index))
      plot.2d.atlas.expr(gene, spots.table, st.data, AP = AP, new.window = val.new.window, normalized.scale = bool.norm.scale,
                         log.scale = bool.log.scale, min.expr = min.expr, win.dim = win.dim, os.windows = os.windows, spots.to.color = spots.to.color,
                         spots.to.color.2 = spots.to.color.2, cluster.name.1 = val.name.cluster.1, cluster.name.2 = val.name.cluster.2, X11.type = X11.type)
    else
      plot.2d.atlas.expr(gene ,spots.table, st.data, slice_index = val.slice.index, new.window = val.new.window, normalized.scale = bool.norm.scale,
                         log.scale = bool.log.scale, min.expr = min.expr, win.dim = win.dim, os.windows = os.windows, spots.to.color = spots.to.color,
                         spots.to.color.2 = spots.to.color.2, cluster.name.1 = val.name.cluster.1, cluster.name.2 = val.name.cluster.2, X11.type = X11.type)

  }

  AP <- select.closest.AP(-1,spots.table)
  bool.new.window <- FALSE
  bool.norm.scale <- FALSE
  bool.log.scale <- FALSE
  min.expr <- 0
  gene <- 'Pvalb'
  spots.to.color <- NULL
  spots.to.color.hidden <- NULL
  spots.to.color.2 <- NULL
  spots.to.color.hidden.2 <- NULL
  clusters.list <- NULL

  spots.table.reference <- stExpressionViewer::spots.table
  spots.table <- spots.table.reference
  load(paste(path.data.dir,'exprmat.RData',sep='/'))
  st.data.2 <- NULL

  if (!exists('st.data'))
    stop('Load the expression matrix first.')

  win <- gwindow('Exploring the atlas', width = 500, height = 300)
  size(win) <- c(600,400)

  horiz.container <- ggroup(container = win, horizontal = TRUE)

  buttons.container <- ggroup(container = horiz.container, horizontal = FALSE)
  right.container <- ggroup(container = horiz.container, horizontal = FALSE)

  navigation.frame <- gframe(text = 'Navigation', container = buttons.container, horizontal = FALSE, spacing = 10)
  navigation.container <- ggroup(container = navigation.frame, horizontal = TRUE, spacing = 5)
  coordinates.container <- ggroup(container = navigation.frame, horizontal = TRUE, spacing = 5)
  section.container <- ggroup(container = navigation.frame, horizontal = TRUE, spacing = 5)
  specific.navigation <- ggroup(container = navigation.frame, horizontal = TRUE, spacing = 5)

  data.selection.frame <- gframe(text = 'Data selection', container = buttons.container, horizontal = FALSE, spacing = 10)
  gene.container <- ggroup(container = data.selection.frame, horizontal = TRUE, spacing = 5)
  percentile.container <- ggroup(container = data.selection.frame, horizontal = TRUE, spacing = 5)
  switch.matrix.container <- ggroup(container = data.selection.frame, horizontal = TRUE, spacing = 5)
  checkboxes.container <- ggroup(container = data.selection.frame, horizontal = TRUE, spacing = 5)


  graphics.frame <- gframe(text = 'Graphics', container = right.container, horizontal = FALSE, spacing = 10)
  new.wind.container <- ggroup(container = graphics.frame, horizontal = TRUE, spacing = 5)
  save.plot.container <- ggroup(container = graphics.frame, horizontal = TRUE, spacing = 5)

  clusters.button.frame <- gframe(text = 'Clusters', container = right.container, horizontal = FALSE, spacing = 10)
  browse.cluster.container <- ggroup(container = clusters.button.frame, horizontal = TRUE, spacing = 5)
  navigate.cluster.container <- ggroup(container = clusters.button.frame, horizontal = TRUE, spacing = 5)
  navigate.cluster.container.2 <- ggroup(container = clusters.button.frame, horizontal = TRUE, spacing = 5)
  spots.from.cluster.file.container <- ggroup(container = clusters.button.frame, horizontal = TRUE, spacing = 5)

  dea.frame <- gframe(text = 'DE analysis', container = right.container, horizontal = FALSE, spacing = 10)
  browse.dea.container <- ggroup(container = dea.frame, horizontal = TRUE, spacing = 5)
  open.dea.container <- ggroup(container = dea.frame, horizontal = TRUE, spacing = 5)

  btn_update <- gbutton(
    text      = "Anterior",
    container = navigation.container,
    handler   = function(h, ...){
      update.AP(select.closest.AP(AP,spots.table))
      ord.AP <- sort(unique(spots.table$AP), decreasing = TRUE)
      pos <- which(ord.AP == AP)
      if (pos > 1){
        update.AP(ord.AP[(pos-1)])
        update.atlas.plot()
      }
    }
  )

  btn_refresh <- gbutton(
    text      = "Refresh",
    container = navigation.container,
    handler   = function(h, ...){
      update.atlas.plot()
    }
  )

  btn_posterior <- gbutton(
    text      = "Posterior",
    container = navigation.container,
    handler   = function(h, ...){
      update.AP(select.closest.AP(AP,spots.table))
      ord.AP <- sort(unique(spots.table$AP), decreasing = TRUE)
      pos <- which(ord.AP == AP)
      if (pos < length(ord.AP)){
        update.AP(ord.AP[(pos+1)])
        update.atlas.plot()
      }
    }
  )

  btn_new.wind <- gbutton(
    text      = "New window",
    container = new.wind.container,
    handler   = function(h, ...){
      update.atlas.plot(val.new.window = TRUE)
    }
  )

  btn_3d.plot <- gbutton(
    text      = "3d plot",
    container = new.wind.container,
    handler   = function(h, ...){
      p <- plot.3d.expr(gene,spots.table,st.data)
      open.3d.plot(p)
    }
  )

  check.boxes <- gcheckboxgroup(
    items = c('Log scale', 'Normalized scale', 'New window for every plot', 'Hide 0 reads'),
    container = checkboxes.container,
    handler = function(h, ...){
      if(is.element('Log scale', svalue(h$obj)))
        bool.log.scale <<- TRUE
      else
        bool.log.scale <<- FALSE

      if(is.element('Normalized scale', svalue(h$obj)))
        bool.norm.scale <<- TRUE
      else
        bool.norm.scale <<- FALSE

      if(is.element('New window for every plot',svalue(h$obj)))
        bool.new.window <<- TRUE
      else
        bool.new.window <<- FALSE

      if(is.element('Hide 0 reads',svalue(h$obj)) & is.element(min.expr,c(0,1)))
        min.expr <<- 1
      else if(is.element(min.expr,c(0,1)))
        min.expr <<- 0
    }
  )

  txt_coord <- gedit(AP, width = 10, container = coordinates.container)
  btn_coord <- gbutton(
    text      = "Go to coordinates",
    container = coordinates.container,
    handler = function(h, ...){
      val <- as.numeric(svalue(txt_coord))
      if (!is.na(val)){
        update.AP(select.closest.AP(val, spots.table))
        update.atlas.plot()
      }
    }
  )


  handler.change.gene <- function(h, ...){
    g <- svalue(txt_gene)
    g <- tolower(g)
    substring(g,1,1) <- toupper(substring(g,1,1))
    if (is.element(g,colnames(st.data))){
      gene <<- g
      update.atlas.plot()
    }
  }

  txt_gene <- gedit(gene, width = 10, container = gene.container)

  btn_change.gene <- gbutton(
    text      = "Change gene",
    container = gene.container,
    handler   = handler.change.gene
  )

  txt_percentile <- gedit('0', width = 10, container = percentile.container)
  btn_set.percentile <- gbutton(
    text      = "Only show greater than percentile",
    container = percentile.container,
    handler   = function(h, ...){
      p <- svalue(txt_percentile)
      p <- as.numeric(p)
      if (!is.na(p) & p > 0 & p < 100){
        min.expr <<- p/100
        update.atlas.plot()
      }else if (!is.na(p) & p == 0){
        if(is.element('Hide 0 reads',svalue(check.boxes)))
          min.expr <<- 1
        else
          min.expr <<- 0
        update.atlas.plot()
      }
    }
  )

  txt_section <- gedit('Section', width = 10, container = section.container)
  btn_plot.section.atlas <- gbutton(
    text      = "Show on atlas",
    container = section.container,
    handler   = function(h, ...){
      if(is.element(svalue(txt_section),unique(spots.table$slice_index))){
        update.atlas.plot(val.slice.index = svalue(txt_section))
        update.AP(unique(spots.table[spots.table$slice_index == svalue(txt_section),'AP']), update.section = FALSE)
      }else if(is.element(as.numeric(svalue(txt_section)),1:40)){
        ord.AP <- sort(unique(spots.table$AP), decreasing = TRUE)
        update.AP(ord.AP[as.numeric(svalue(txt_section))])
        update.atlas.plot()
      }
    }
  )

  btn_plot.section.picture <- gbutton(
    text      = "Show on picture",
    container = section.container,
    handler = function(h,...){
      if(is.element(svalue(txt_section),unique(spots.table$slice_index))){
        plot.2d.slice.expr(gene,spots.table, st.data, slice_index = svalue(txt_section), new.window = bool.new.window, normalized.scale = bool.norm.scale, log.scale = bool.log.scale, min.expr = min.expr, win.dim = win.dim, res.ds = 10, path.data.dir = path.data.dir, os.windows = os.windows, X11.type = X11.type)
        update.AP(unique(spots.table[spots.table$slice_index == svalue(txt_section),'AP']))
      }
    }
  )

  btn_go.to.peak <- gbutton(
    text = 'Go to peak expr',
    container = specific.navigation,
    handler = function(h,...){
      slice <- spots.table[rownames(st.data[which.max(st.data[,gene])[1],]),'AP']
      update.AP(slice)
      update.atlas.plot()
    }
  )

  btn_go.to.top.mean <- gbutton(
    text = 'Go to top mean expr',
    container = specific.navigation,
    handler = function(h,...){
      slice <- sort(unique(spots.table$AP))[which.max(sapply(sort(unique(spots.table$AP)),function(x){return(mean(st.data[rownames(spots.table[spots.table$AP == x,]),gene]))}))]
      update.AP(slice)
      update.atlas.plot()
    }
  )

  txt.to.display.for.export <- '(Specify filename if desired)'
  txt_export_picture <- gedit(txt.to.display.for.export, width = 25, container = save.plot.container)
  btn_export_picture <- gbutton(
    text      = "Export as a pdf",
    container = save.plot.container,
    handler   = function(h, ...){
      if(svalue(txt_export_picture) != txt.to.display.for.export)
        path = svalue(txt_export_picture)
      else
        path = paste(svalue(txt_gene),'_',svalue(txt_coord),sep='')

      path.test <- paste(path,'pdf',sep='.')
      cnt <- 0
      while(file.exists(path.test)){
        cnt <- cnt + 1
        path.test <- paste(strsplit(path,'[.]')[[1]][1],'(',cnt,').pdf',sep='')
      }
      path <- path.test
      svalue(txt_export_picture) <- txt.to.display.for.export
      dev.copy2pdf(file = path)
    }
  )


  txt.switch.scran <- "Switch to Scran"
  txt.switch.raw <- "Switch to counts"

  btn_switch_matrix <- gbutton(
    text      = txt.switch.scran,
    container = switch.matrix.container,
    handler = function(h, ...){

      if (is.null(st.data.2)){
        st.data.2 <<- st.data
        load(paste(path.data.dir,'exprmat-normalized.RData',sep='/'))
        st.data <<- log.count
        rm(log.count)
      }else{
        tmp <- st.data
        st.data <<- st.data.2
        st.data.2 <<- tmp
      }

      if(svalue(btn_switch_matrix) == txt.switch.scran){
        svalue(btn_switch_matrix) <- txt.switch.raw
        spots.table <<- spots.table.reference
        spots.table <<- spots.table[intersect(rownames(st.data),rownames(spots.table)),]

        #Case the gene is not in the normalized matrix
        if (!is.element(gene,colnames(st.data))){
          svalue(txt_gene) <- colnames(st.data)[1]
          handler.change.gene()
        }else{
          update.atlas.plot()
        }

      }else{
        svalue(btn_switch_matrix) <- txt.switch.scran
        spots.table <<- spots.table.reference
        update.atlas.plot()
      }
    }
  )

  browse_clust_file <- gfilebrowse(
    text = 'Select clustering file',
    container = browse.cluster.container,
    handler = function(h, ...){
      clusters.list <<- append.cluster.to.spots.table(stExpressionViewer::spots.table, svalue(browse_clust_file))
      clusters.list <<- name.clusters(clusters.list)
    }
  )

  txt_cur_clust <- glabel(
    text      = 'No first cluster selected',
    container = navigate.cluster.container
  )

  btn_select_clusters <- gbutton(
    text      = 'Select a cluster',
    container = navigate.cluster.container,
    handler = function(h, ...){
      select.cluster.display(type = 1)
    }
  )

  btn_show_clusters <- gbutton(
    text      = 'Hide',
    container = navigate.cluster.container,
    handler = function(h, ...){
      if (svalue(btn_show_clusters) == 'Hide'){
        svalue(btn_show_clusters) <- 'Show'
        spots.to.color.hidden <<- spots.to.color
        spots.to.color <<- NULL
        update.atlas.plot()
      }else{
        svalue(btn_show_clusters) <<- 'Hide'
        spots.to.color <<- spots.to.color.hidden
        update.atlas.plot()
      }
    }
  )

  txt_cur_clust.2 <- glabel(
    text      = 'No second cluster selected',
    container = navigate.cluster.container.2
  )

  btn_select_clusters.2 <- gbutton(
    text      = 'Select a cluster',
    container = navigate.cluster.container.2,
    handler = function(h, ...){
      select.cluster.display(type = 2)
    }
  )

  btn_show_clusters.2 <- gbutton(
    text      = 'Hide',
    container = navigate.cluster.container.2,
    handler = function(h, ...){
      if (svalue(btn_show_clusters.2) == 'Hide'){
        svalue(btn_show_clusters.2) <- 'Show'
        spots.to.color.hidden.2 <<- spots.to.color.2
        spots.to.color.2 <<- NULL
        update.atlas.plot()
      }else{
        svalue(btn_show_clusters.2) <<- 'Hide'
        spots.to.color.2 <<- spots.to.color.hidden.2
        update.atlas.plot()
      }
    }
  )

  spots.from.clust.file <- gcheckbox(
    text = 'Only show spots from cluster file',
    container = spots.from.cluster.file.container,
    handler = function(h,...){
      if (svalue(spots.from.clust.file) & !is.null(clusters.list)){
        spots.table.reference <<- clusters.list
      }else{
        spots.table.reference <<- stExpressionViewer::spots.table
      }
      spots.table <<- spots.table.reference
      spots.table <<- spots.table[intersect(rownames(st.data),rownames(spots.table)),]
      update.atlas.plot()
    }
  )

  select.dea <- NULL
  browse.dea <- gfilebrowse(
    text = 'Path to DEA directory',
    type = "selectdir",
    container = browse.dea.container,
    handler = function(h, ...){
      if (is.null(select.dea)){
        select.dea <<- gbutton(
          text = 'Select genes from DEA',
          container = open.dea.container,
          handler = function(h, ...){
            select.gene.dea()
          }
        )
      }
    }
  )

  update.AP(AP)
  update.atlas.plot(val.new.window = TRUE)

}
cantin-ortiz/stExpressionViewer documentation built on May 29, 2019, 11:02 p.m.