inst/app.R

library(shiny)
library(shinydashboard)
library(shinyjs)
library(DT)
library(V8)
library(igraph)
library(rcytoscapejs)

load('GDinfo.RData')
download_data = function(filename, species){
  githubURL = paste("https://github.com/GScluster/data/raw/master/",species,"/",filename, sep='')
  download.file(url = githubURL,filename)
}

check_data = function(species){
  species = tolower(species)
  nowdir = getwd()

  nowTOv = getOption('timeout')

  options(timeout=1800)

  data_dir = file.path('data',species, fsep = '/')
  dir.create('data')
  if(!dir.exists(data_dir)){dir.create(data_dir)}

  setwd(data_dir)

  filename_footer = '.RData'
  filenames= c('li1','li2','li3','li4','li5','li6','li7','ensg_ent','ent_sym','string')

  # when species == 'ecoli / yeast'
  if(species=='ecoli' | species=='yeast' || species =='arabidopsis'){
    filenames= c('li1','li2','li3','li4','li5','li6','li7','ent_sym','string')
  }
  progress_download = shiny::Progress$new()
  on.exit(progress_download$close())
  progress_download$set(message='Download Datas', value = 0)

  for(i in filenames){
    filename = paste(i,filename_footer,sep='')
	  progress_download$inc(1/length(filenames), detail = i)
    if(!file.exists(filename)){ download_data(filename, species) }
  }

  progress_download$close()

  progress_load = shiny::Progress$new()
  on.exit(progress_load$close())
  progress_load$set(message='Loading Datas', value = 0)

  for(i in dir()){
    load(i, envir = .GlobalEnv)
	  progress_load$inc(1/length(filenames), detail = i)
  }

  options(timeout = nowTOv)
  setwd(nowdir)
}

tablestring = function(x, lx, cv, cls){
  temp = ""
  for(i in 1:floor(lx/cv)){ temp = paste(temp, paste(x[(1:cv+cv*(i-1))], collapse = cls), '\n', sep = '') }
  if(i*cv+1 <= lx){
  temp = paste(temp, paste(x[(i*cv+1):lx], collapse = cls), collapse = '', sep = '')}
  return(temp)
}

ovl = function(a, b){length(intersect(a, b))/min(length(a), length(b))}

get_dist_O = function(gsl){

  d = length(gsl)
  gsl_dist = matrix(0,d,d)

  Distance_O = function(gs1,gs2){ 1-ovl(gs1,gs2) }

  for(i in 1:d){
    for(j in 1:d){
      if(i>j){gsl_dist[i,j] = gsl_dist[j,i]; next}
      if(i==j){gsl_dist[i,j] = 0.001; next}
      gsl_dist[i,j] = Distance_O(gsl[[i]],gsl[[j]])
    }
  }
  return(gsl_dist);
}

build_clust_info = function(clusts, GS, GM, GQ){

  df = data.frame(matrix(ncol = 4, nrow = 0))
  colnames(df) = c("Geneset Name","Geneset Qvalue", "Geneset member", 'Cluster')

  global_gsm = list()
  gs_cnt = 1

  nodes = c()

  for(i in 1:length(clusts)){
    this_clust = clusts[[i]]

    for(j in 1:length(this_clust)){
      gsn = GS[this_clust[j]]
      lgsn = nchar(gsn)

      # if long: add \n
      if(lgsn>30){ gsn = tablestring(x = strsplit(gsn,'')[[1]],lx=lgsn,cv=30, cls = '') }

      gsm = GM[[this_clust[j]]]
      # if long: add \n
      if(length(gsm)>20){ gsm = tablestring(x = gsm, lx = length(gsm), cv = 20, cls=',') }
      else{ gsm = paste(gsm,collapse = ',') }

      global_gsm[[gs_cnt]] = gsm;
      gs_cnt = gs_cnt + 1

      gsq = GQ[this_clust[j]]
      df = rbind(df,cbind(gsn, round(gsq,5), gsm, i))
    }
  }

  assign('global_gsm',global_gsm, envir = .GlobalEnv)

  df[,1] = as.character(df[,1])
  df[,2] = as.numeric(as.character(df[,2]))
  return(df)
}

jsCode = 'shinyjs.pageCol = function(i){color = i[1];i = i[0];cy.nodes("#".concat(i)).style("background-color",color)};
shinyjs.clearCol = function(i){cy.nodes("#".concat(i)).style("background-color","#888888")};
shinyjs.remove_cy = function(){cy.$().remove()};
shinyjs.geneColQ1 = function(i){cy.nodes("#".concat(i)).style("background-color","#FBCDCD")};
shinyjs.geneColQ2 = function(i){cy.nodes("#".concat(i)).style("background-color","#F89A9A")};
shinyjs.geneColQ3 = function(i){cy.nodes("#".concat(i)).style("background-color","#F46767")};
shinyjs.geneColQ4 = function(i){cy.nodes("#".concat(i)).style("background-color","#F03434")};
shinyjs.download = function(){download()};
shinyjs.layout_as_cose = function(){layout_as_cose()};
shinyjs.layout_as_cola = function(){layout_as_cola()};
shinyjs.layout_as_circle = function(){layout_as_circle()};
shinyjs.fold_sidebar = function(){$("body").addClass("sidebar-collapse")};
shinyjs.open_sidebar = function(){$("body").removeClass("sidebar-collapse")};
shinyjs.define_cy = function(){cy = cytoscape()};

shinyjs.fit_node = function(id){
  cy.zoom(0.7);
	curpos = cy.pan();
	curpos_x = curpos.x;
	curpos_y = curpos.y;

	nodpos = cy.nodes("#"+id).renderedPosition();
	nodpos_x = nodpos.x;
	nodpos_y = nodpos.y;

	cy.pan({x: curpos_x+ cy.width()/2 - nodpos_x, y : curpos_y + cy.height()/2 - nodpos_y});

}

shinyjs.draw_edge = function(v){
  v = v[0];
  var source = v[0];
  var target = v[1];
  var w = v[2];
  cy.edges(\'[source="\' + source + \'"][target="\' + target + \'"]\').css("width",w)
}

shinyjs.rename = function(name_before, name_after){
  cy.nodes(paste0("#",name_before)).data("name",name_after)
}
'

node_rename = function(name_before, name_after){
  js$rename(name_before, name_after)
}

UI_header = function(){
  dashboardHeader( title = 'GScluster', titleWidth = 250)
}

UI_sidebar = function(){
  dashboardSidebar(
	width = 250,
    sidebarMenu(
      id='tabs',
      menuItem(text = "Geneset Network", tabName = "Genesets", icon = icon("share-alt")),
      menuItem(text = "Cluster info", tabName = "Clusters", icon = icon("list-ul")),
      menuItem(text = "Downloads", tabName = "Downloads", icon = icon("download")),
      menuItem(text = "MANUAL", tabName = "README", icon = icon("info-circle")),
      hidden(actionButton("AB1","AB1"),actionButton("AB2","AB2"))
    )
  )
}

InputBox = function(){
  div(
    id = 'Input_box',
    fileInput(inputId = "INPUT_GENESET_FILE", label = "Geneset: ", accept = 'text/plain'),
    numericInput(inputId = 'GENESET_CUTOFF', label = "Geneset Cutoff: ", min = 0, max = 1, value = 0.25, step = 0.01),

    fileInput(inputId = "INPUT_GENESCORE_FILE", label = "Gene score file : (Optional) ", accept = 'text/plain'),
    numericInput(inputId = 'GENESCORE_CUTOFF', label = "Gene score Cutoff: ", min = 0, max = 1, value = 0.05, step = 0.01),

    selectInput(inputId = 'INPUT_SPECIES', label='Choose Species', choices = c('Human', 'Arabidopsis', 'Celegans','Ecoli','Fly','Mouse','Rat','Yeast','Zebrafish'), selected = 'Human'),

    checkboxInput(inputId = 'WORKING_GENE', label = 'Sig Gene only', value = FALSE),
    actionButton(inputId = 'RUN', label = 'RUN'),
    actionButton(inputId = 'DEMO',label = 'TRY DEMO')
  )
}

NodeSearch = function(){
  fluidRow( style = {'position:absolute;margin-left:7%;z-index:999;width:15%;'},selectizeInput('FIT',label = 'Gene-set search', choices = NULL) )
}

NodeSearchSubmit = function(){
  fluidRow( style={'position:absolute;margin-left:25%;margin-top:24px;z-index:999'},actionButton('ACTIVATEFIT',"Search"))
}

ClusterLegend = function(){
  uiOutput(
    style={'position:absolute;top:6em;left:6em;z-index:999'},
    outputId='legend'
  )
}


build_Disease_Table = function(genes){
  res = GDinfo[genes]
  Ds = c()
  for(i in 1:length(res)){ Ds = c(Ds,names(res[[i]])) }
  sigDs = names(which(table(Ds)>1))
  getV = function(res,sigD){
    v = c()
    for(i in 1:length(res)){ if(sigD %in% names(res[[i]])) { v = c(v,names(res)[i]) } }
    return(c(paste(v,collapse=', '), length(v)))
  }
  df = data.frame(matrix(ncol = 3, nrow = 0))
  for(i in 1:length(sigDs)){
    v = getV(res, sigDs[i])
    v = cbind(sigDs[i], v[2],v[1] )
    df = rbind(df, v)
  }
  colnames(df) = c("Disease", "Count", "Genes")

  dtres = datatable(
    df,
    filter = 'top',
    options = list(
      lengthChange = TRUE,
      pageLength = 10,
      columnDefs = list(list(targets = c(2), searchable = FALSE)),
      scrollX = '350px',#TRUE,
      scrollY = '300px',#TRUE,
      autoWidth = TRUE,
      order = list(2,'desc')
    ),
    colnames = c("Disease", "Count", "Genes"),
    selection = 'none'
  )

  return(dtres)
}



Download_SVG = function(){
  fluidRow(
    style={'position:absolute; margin-left:53%;z-index:999'},
    actionButton(inputId='download_button',label='Download Graph', onclick='shinyjs.download()')
  )
}

Download_SUBPPI = function(){
  fluidRow(
    style={'position:absolute; margin-left:66%;z-index:999'},
    downloadButton(outputId = 'subPPI',label= 'Download PPI', style='display:none')
  )
}

LayoutButton = function(){
  fluidRow(
    style={'position:absolute; margin-left:40%;z-index:999'},
    verticalLayout(
      actionButton(inputId = 'Layout_button', label = 'Layout Options', onclick='$("#DISPLAY_OPTIONS").toggle("slow","swing")'),
      fluidRow(
        id='DISPLAY_OPTIONS',
        style='display:none;margin-top:10px;margin-left:0px;',
        actionButton(inputId='circle_button',label='Circle', onclick= 'layout_as_circle()'),
        actionButton(inputId='cola_button',label='Cola', onclick='layout_as_cola()')
      )
    )
  )
}

ClusterOption = function(){
  fluidRow(
    style={'position:absolute;top:10px;right:40px;z-index:999;padding:1em;'},
    actionButton(
      inputId='cog_button',
      label='Clustering Options',
      onclick='$("#CLUST_OPTIONS,#hub_button,#swap_button").toggle("slow","swing")'),
    div(
      style='display:none;background:white;padding:1em;width:15em;',id = 'CLUST_OPTIONS',
      selectInput(inputId='CLUSTER_METHOD',label='Distance type',choices = c("MM","pMM2",'Kappa'),selected = 'pMM2'),
      numericInput(inputId='CLUSTER_MIN_SIZE',label='Minimum seed size',value=5,min=3,max=10,step=1),
      numericInput(inputId='CLUSTER_MIN_DISTANCE',label='Maximum Distance',value=0.4,min=0,max=1,step=0.05),
      actionButton(inputId='CLUSTER_CHANGE',label='APPLY'),
      hr(),
      p('Distance Converter', style={'font-weight:bold'}),
      fluidRow(
        column(selectInput(inputId='TEMP1',choices=c('MM','pMM','Kappa'),selected='MM',label='From'),width=6),
        column(selectInput(inputId='TEMP2',choices=c('MM','pMM','Kappa'),selected='MM',label='To'),width=6)
      ),
      fluidRow(
        column(numericInput(inputId='TEMP3',value=NULL,label=NULL),width=6),
        column(numericInput(inputId='TEMP4',value=NULL,label=NULL),width=6)
      ),
      actionButton(inputId='TRANSFORM_ACTIVATE',label="Transform")
    )
  )
}

BuildGeneNetwork = function(){
  fluidRow(
    style={'position:absolute;top:50px;right:40px;z-index:999;padding:1em;'},
    actionButton(
      inputId='swap_button',
      label='Gene Network',
      onclick='$("#GENENETWORK_OPTIONS,#cog_button,#hub_button").toggle("slow","swing");'
    ),
    div(
      style='display:none;background:white;padding:1em;',id='GENENETWORK_OPTIONS',
      verticalLayout(
        selectizeInput(inputId='menuI',label='SELECT CLUST',choices='NOT BUILT YET',selected=NULL),
        sliderInput(inputId='PPI_CUTOFF',label="PPI Cutoff: ",min=0,max=999,value=700,step=10),
        checkboxInput(inputId='GRAY_EDGE',label='Combined Score',value=TRUE),
        uiOutput(outputId="my_cbgi"),
        actionButton(inputId = "DRAW_GENENETWORK", label = "Draw Gene Network"),
        hr(),
        div(
          id='HUB_DIV',style='display:none',
          numericInput(inputId = 'DEGREE_CUTOFF',label = "Find hubgene with DEGREE rank <= ",value = 3),
          actionButton(inputId = "DEGREE",label = "Search"),
          DT::dataTableOutput(outputId ='DEGREE_OUTPUT'),
          hr()
        ),
        actionButton(inputId = 'RESTORE_GENESET_NETWORK',label = 'Reset',icon = icon('undo'))
      ),
      width = 12
    )
  )
}

HubBox = function(){
  fluidRow(
    style={'position:absolute;top:90px;right:40px;z-index:999;padding:1em;'},
    actionButton(
      inputId = 'hub_button',
      label = 'Hub',
      onclick='$("#HUB_OPTIONS,#swap_button, #cog_button").toggle("slow","swing")'
    ),
    div(
      style='display:none;background:white;padding:1em;',id='HUB_OPTIONS',
      verticalLayout(
        numericInput('RANK_CUTOFF',"Find Hubgenes around clusters with rank <=",value = 3),
        actionButton('CHECK','around all clutser'),
        tableOutput(outputId = "HUB_TABLE")
      ),
      width = 12
    )
  )
}

Disease_Table = function(){
  fluidRow(
    style={'position:absolute;top:17em;left:2em;z-index:999;'},
    actionButton(
      inputId = 'Disease_button',
      label = 'Disease',
      onclick = '$("#Disease_Table").toggle("slow","swing")'
      ,style='display:none'
    ),
    div(
      style='background:white;padding:1em;',
      id = 'Disease_Table',
      DT::dataTableOutput(outputId ='dTable_OUTPUT')
      ,width = 12
    )
  )
}


UI_tabItems = function(){
  tabItems(
    tabItem(
      tabName = "Genesets",
      InputBox(),
      hidden(
      fluidRow(
        id='main_panel',
        box(
          NodeSearch(),
          NodeSearchSubmit(),
          ClusterLegend(),
          Download_SVG(),
		      Download_SUBPPI(),
          LayoutButton(),
          ClusterOption(),
          BuildGeneNetwork(),
          HubBox(),
		      Disease_Table(),
          rcytoscapejs::rcytoscapejsOutput(outputId = 'plot1'),
          width = 12
        )
      ))
    ),

    tabItem(
      tabName = 'Clusters',
      p(id = 'cluster_message','GSCluster not activated, information will show after RUN'),
      hidden(
        fluidRow(
          id='cluster_row',
          box(
            DT::dataTableOutput(outputId = 'gsinfo'),
            downloadButton(outputId = 'CLUST_RESULT',label= 'CLUSTERING_RESULT'),
            width = 12
          )
        )
      )
    ),

    tabItem(
      tabName = 'Downloads',
      fluidRow(
        box(
          title = 'Human',
          downloadButton('HGS', 'Example Geneset file'),
          downloadButton('HGS2', 'Example Genescore file'),
          width = 4
          ),
        box(
          title = 'Arabidopsis',
          downloadButton('AGS', 'Example Geneset file'),
          downloadButton('AGS2', 'Example Genescore file'),
          width = 4

        ),
        box(
          title = 'Celegans',
          downloadButton('CGS', 'Example Geneset file'),
          downloadButton('CGS2', 'Example Genescore file'),
          width = 4
        )
      ),

      fluidRow(
        box(
          title = 'Ecoli',
          downloadButton('EGS', 'Example Geneset file'),
          downloadButton('EGS2', 'Example Genescore file'),
          width = 4
          ),
        box(
          title = 'Fly',
          downloadButton('FGS', 'Example Geneset file'),
          downloadButton('FGS2', 'Example Genescore file'),
          width = 4
          ),
        box(
          title = 'Mouse',
          downloadButton('MGS', 'Example Geneset file'),
          downloadButton('MGS2', 'Example Genescore file'),
          width = 4
        )
      ),

      fluidRow(
        box(
          title = 'Rat',
          downloadButton('RGS', 'Example Geneset file'),
          downloadButton('RGS2', 'Example Genescore file'),
          width = 4
          ),
        box(
          title = 'Yeast',
          downloadButton('YGS', 'Example Geneset file'),
          downloadButton('YGS2', 'Example Genescore file'),
          width = 4
          ),
        box(
          title = 'Zebrafish',
          downloadButton('ZGS', 'Example Geneset file'),
          downloadButton('ZGS2', 'Example Genescore file'),
          width = 4
        )
      )
    ),

    tabItem(
      tabName='README',
      uiOutput("pdfview")
    )
  )
}


ui = function(){
dashboardPage(
  header = UI_header(),
  sidebar = UI_sidebar(),

  body = dashboardBody(
    useShinyjs(), # useshinyjs in body
    extendShinyjs(text = jsCode),

  	tags$head(tags$style(HTML('
      .skin-blue .main-header .logo {
        background-color: #3c8dbc;
      }
      .skin-blue .main-header .logo:hover {
        background-color: #3c8dbc;
      }
     '))),

    tags$style(type = "text/css", "#plot1 {height: calc(100vh - 125px) !important;}"),
    tags$style(type = "text/css", "#pdfview {height: calc(100vh - 80px) !important;}"),

    tags$head(tags$script(src="cytoscape-cy-svg-convertor.js")),
    tags$head(tags$script(src="cytoscape-svg-convertor.js")),
    tags$head(tags$script(src="svg.min.js")),
    tags$head(tags$script(src="additional_script.js")),
    tags$link(rel = "stylesheet", type = "text/css", href = "stylesheet.css"),

    div(id='create', display='none'), # EMPTY DIV use to download SVG

    UI_tabItems()
  )
)}

function_buildlegends = function(colors){
  res = c()
  colors = setdiff(unique(colors), '#666666')
  for(i in 1:length(colors)){
    b = HTML(
      paste0(
        '<div style="background:',
        colors[i],
        ';margin-bottom:0.3em;width:20px;height:20px;display:inline-block"></div>',
        '<div style="float:right;text-align:center;height:20px;line-height:20px;width:70px;">Cluster ',
        i,'</div><br>'
      )
    )
    res = paste0(res,b)
  }
  return(HTML(res))
}

my_checkboxGroupInput = function(variable, label, choices, selected, colors){
  choices_names <- choices
  if(length(names(choices))>0) {choices_names = names(choices)}
  my_colors = rep("black", length(choices))
  is_selected = choices %in% selected
  my_colors[is_selected] = colors[is_selected]

  div(
    id=variable,
    class="form-group shiny-input-checkboxgroup shiny-input-container shiny-bound-input",
    HTML(
      paste0('<label class="control-label" for="',variable,'">',label,'</label>')
    ),
    div(
      class="shiny-options-group",
      HTML(
        paste0(
          '<div class="checkbox" style="color:', my_colors, '">',
          '<label>',
          '<input type="checkbox" name="', variable,
          '" value="', choices,
          '"', ifelse(is_selected, 'checked="checked"', ''),
          '/>',
          '<span>', choices_names,'</span>',
          '</label>',
          '</div>', collapse = " "
        )
      )
    )
  )
}

my_names = c('Neighborhood','Gene Fusion',"Cooccurence",'Coexpression','Experiments','Databases','Textmining')
my_selected = my_names[1:5]
my_colors = c('red','orange','yellow', 'green', 'blue','navy','purple')

function_downloadHandler_Clust_info = function(gsinfo){
  tmp = gsinfo
  tmp[,1] = sapply(tmp[,1],FUN = function(i){gsub('\n','',i)})
  colnames(tmp) = c('Name','Qvalue','Member', 'Cluster')
  downloadHandler(
    filename = 'Cluster_info.csv',
    content = function(con){write.csv(tmp,con)}
  )
}

get_matrix = function(genes, ppi_matrix){
  rp = rownames(ppi_matrix)
  genes_idx = unlist(sapply(genes, function(i){
    a = which(rp==i)
    if(length(a)>0){return(a)}
  }))
  return(ppi_matrix[genes_idx, genes_idx])
}

build_multiEdge = function(GENE_NETWORK_OBJ, MULTIEDGE){

  genes = GENE_NETWORK_OBJ$nodeData$id
  edges = GENE_NETWORK_OBJ$edgeData

	myf = function(genes, li, col, edges){
	  source = c()
	  target = c()
	  color = c()
	  for(i in 1:length(genes)){
	    e1 = edges[which(edges$source == genes[i]),]
  		sel = intersect(genes, li[[genes[i]]])
  		sel = sel[which(sel < genes[i])] # to build one way edge

  		if(length(sel)>0){ # add edge
  		  for(j in 1:length(sel)){
  		    if(length(which(e1$target==sel[j]))>0){
  		      source = c(source, genes[i])
  			    target = c(target, sel[j])
  			    color = c(color, col)
  		    }
  		  }
  		}
	  }
	  return(data.frame(cbind(source, target, color)))
	}

	edgeData = myf(genes,li1,col = 'red', edges)
	if("Gene Fusion"%in%MULTIEDGE){
	edgeData = rbind(edgeData, myf(genes,li2,col = 'orange', edges))}
	if("Cooccurence"%in%MULTIEDGE){
	edgeData = rbind(edgeData, myf(genes,li3,col = 'yellow', edges))}
	if("Coexpression"%in%MULTIEDGE){
	edgeData = rbind(edgeData, myf(genes,li4,col = 'green', edges))}
	if("Experiments"%in%MULTIEDGE){
	edgeData = rbind(edgeData, myf(genes,li5,col = 'blue', edges))}
	if("Databases"%in%MULTIEDGE){
	edgeData = rbind(edgeData, myf(genes,li6,col = 'navy', edges))}
	if("Textmining"%in%MULTIEDGE){
	edgeData = rbind(edgeData, myf(genes,li7,col = 'purple', edges))}

	if(!"Neighborhood"%in%MULTIEDGE){edgeData = edgeData[-which(edgeData[,'color']=='red'),]}

	if(length(edgeData)==0){return(NULL)}
	return(edgeData)
}

build_GSINFO = function(DATA, QV_CUTOFF){
  for(i in 1:length(DATA)){
    temp = strsplit(DATA[i],'\t')[[1]]
    GS_NAME = temp[1]
    GS_MEMBER = strsplit(temp[2],' ')[[1]]
    GS_QVALUE = as.numeric(temp[3])
    if(GS_QVALUE > QV_CUTOFF){next}
    GS[i] = GS_NAME
    GM[[i]] = GS_MEMBER
    GQ[i] = GS_QVALUE
  }
  return(list(GS=GS, GM=GM, GQ=GQ))
}

get_nodeColor = function(id){
  if(length(id)==0){return(0)}
	sapply(1:length(id), FUN = function(i){a = gene_colors[id[i]]; if(is.na(a)){return('#FFFFFF')};return(a)})
}

clique60 = function(g){
  res = list()
  nv = function(g,lc){
    gs = neighbors(g,lc)
    for(i in 2:length(lc)){ gs = igraph::union(gs,neighbors(g,lc[i])) } # get all nodes linked with cliques;
    gs = difference(gs,lc) # remove clique itself;
    return(gs)
  }

  while(TRUE){
    lc = largest.cliques(g)[[1]] # get largest clique
    if(length(lc)<4){return(res)} # if largest size < 4 , return;
    res[[length(res)+1]] = attributes(lc)$names
    gs = nv(g,lc)
    if(length(gs)!=0){
      sel = which(sapply(gs, function(i){ ( sum(sapply(lc, function(j){ are_adjacent(g,j,i)}))/length(lc) ) > 0.6 })) # select nodes with linked with clique > 60%

      if(length(sel)>0){
        lc = igraph::union(lc,gs[sel])
        res[[length(res)]] = attributes(lc)$names
      } # add them to clique then, remove them
    }
    g = g-lc
  }
  return(res)
}

apply_cliq60 = function(network){

  nodeData = network$nodeData[,1:2]
  edgeData = network$edgeData
  color = network$color
  if(is.null(color)){color = as.character(network$nodeData[,'color'])} # GENE NETWORK
  width = network$width
  shape = rep('ellipse',nrow(nodeData))
  height = rep('50px',nrow(nodeData))
  width = rep('50px',nrow(nodeData))

  cliqlist = clique60(graph.data.frame(edgeData, directed = F))

  for(i in 1:length(cliqlist)){ # for test result
    this_cliq = cliqlist[[i]]

    # add "Super node" , and it's color
    id = paste0('Module',i)
    supernode = c(id,id) # supernode = white;
    nodeData = rbind(nodeData, supernode)
    #e17055 : BROWN
    #32ff7e : flour green
    #fced20 : YELLOW
    color = c(color,'#fced20')
    shape = c(shape,'ellipse')
    height = c(height,'100px')
    width = c(width,'100px')

    # remove edge between this cliq
    v = intersect(which(sapply(1:nrow(edgeData), function(i){edgeData[i,1] %in% this_cliq})),
    which(sapply(1:nrow(edgeData), function(i){edgeData[i,2] %in% this_cliq})))

    if(length(v)!=0){edgeData = edgeData[-v,]}

    # add edge Supernode and them.

    if(ncol(edgeData) ==3){
      for(j in 1:length(this_cliq)){
        superEdge = c(id,this_cliq[j], '#666666')
        edgeData = rbind(edgeData,superEdge)
        # width = c(width,5.495) # 0.5
      }
    }
    else{
      for(j in 1:length(this_cliq)){
        superEdge = c(id,this_cliq[j])
        edgeData = rbind(edgeData,superEdge)
        # width = c(width,5.495) # 0.5
      }
    }

  }
  nodeData = cbind(nodeData, color, shape, height, width)
  return(list (nodeData = nodeData, edgeData = edgeData, color = nodeData$color))
}

get_dist_OP = function(gsl, ppi_matrix = string, clust_method){

  d = length(gsl)
  gsl_dist = matrix(0,d,d)

  pre_OP = function(gsl, rp){
    res = list()
    for(i in 1:length(gsl)){
      a = unlist(sapply(gsl[[i]], function(i){a=which(rp==i); if(length(a)){return(a)}}))
      names(a) = NULL
      res[[i]] = a
    }

    return(res)
  }

  Distance_OP = function(gs1, gs2, gsi1, gsi2){

    interact = function(idx1,idx2, tab){
      if(length(idx1)==0 | length(idx2)==0){return(0)}
      return(sum(tab[idx1,idx2]) )
    } # / 1000?

    interact2 = function(idx1,idx2, tab,k){
      if(length(idx1)==0 | length(idx2)==0){return(0)}
      return(sum(tab[idx1,idx2]^(1/k)) )
    } # / 1000?

    get_score = function(main, sub, lc, lm, ls){

      common = intersect(main,sub)
      uniq = setdiff(sub, common);
      uniq2 = setdiff(main,sub);

      w = ls/(lm+ls)

      nom = interact(common,uniq, ppi_matrix)*w+interact(uniq2,uniq, ppi_matrix);
      denom = w*lc+lm-lc
      score = 1-((lc+nom/denom)/ls)

      return(score)
    }

    score1 = function(A,B,idx_A,idx_B){
      w = min(length(A), length(B))/ (length(A)+length(B)) # 0.5633803
      m = min(length(A),length(B)) # 93
      i = length(intersect(A,B)) # 93
      uniqA = setdiff(idx_A,idx_B)
      uniqB = setdiff(idx_B,idx_A)
      common = intersect(idx_A,idx_B)
      nom = w*interact(uniqA,common,ppi_matrix)+interact(uniqA,uniqB,ppi_matrix)
      denom = w*i+length(setdiff(B,A))
      1- (i+nom/denom)/m
    }

    score2 = function(A,B,idx_A,idx_B,k=5){
      w = min(length(A), length(B))/ (length(A)+length(B)) # 0.5633803
      a = length(A)
      i = length(intersect(A,B))
      uniqA = setdiff(idx_A,idx_B)
      uniqB = setdiff(idx_B,idx_A)
      common = intersect(idx_A,idx_B)
      nom = w*interact2(uniqA,common,ppi_matrix,k) + interact2(uniqA,uniqB,ppi_matrix,k)
      #nom = w*interact(uniqA,common,ppi_matrix) + interact(uniqA,uniqB,ppi_matrix)
      denom = w*i+length(setdiff(B,A))
      #1-(i*k+nom/denom*(1-k))/a
      1-(i+nom/denom)/a
    }

    score3 = function(A,B,idx_A,idx_B,k=.8){
      w = min(length(A), length(B))/ (length(A)+length(B)) # 0.5633803
      a = length(A)
      i = length(intersect(A,B))
      uniqA = setdiff(idx_A,idx_B)
      uniqB = setdiff(idx_B,idx_A)
      common = intersect(idx_A,idx_B)
      nom = w*interact(uniqA,common, ppi_matrix)+interact(uniqA,uniqB, ppi_matrix)
      denom = w*i+length(setdiff(B,A))
      1-(i+(nom/denom)^(1/k))/a
    }

  	if(clust_method =='pMM1'){
  		score = min(score1(gs1,gs2,gsi1,gsi2), score1(gs2,gs1,gsi2,gsi1))
  	}

    else if(clust_method=='pMM2'){
  		score = min(score2(gs1,gs2,gsi1,gsi2), score2(gs2,gs1,gsi2,gsi1))
  	}

  	else if(clust_method=='pMM3'){
  		score = min(score3(gs1,gs2,gsi1,gsi2), score3(gs2,gs1,gsi2,gsi1))
  	}
  	else{

      gsl1 = length(gs1)
      gsl2 = length(gs2)
      lc = length(intersect(gs1, gs2))
      lm = max(gsl1,gsl2)
      ls = min(gsl1,gsl2)

      if(gsl1>gsl2){score = get_score(gsi1,gsi2, lc, lm, ls)}
      else if(gsl2>gsl1){score = get_score(gsi2,gsi1, lc, lm, ls)}
    	else{ score = min(get_score(gsi1,gsi2, lc, lm, ls), get_score(gsi2,gsi1, lc, lm, ls)) }
  	}
    	if(score == 0){score = 0.001}
    	return(score)

  }

  gslp = pre_OP(gsl, rownames(string))

	for(i in 1:d){
	  if(i%%10==0){print(i)}
		for(j in 1:d){
			if(i>j){ gsl_dist[i,j] = gsl_dist[j,i]; next}
			if(i==j){ gsl_dist[i,j] = 0.001; next}
			gsl_dist[i,j] = Distance_OP(gsl[[i]],gsl[[j]], gslp[[i]], gslp[[j]])
		}
	}
	return(gsl_dist);
}

get_dist_K = function(gsl){

  ALLGENE = length(unique(unlist(gsl)))
  d = length(gsl)
  gsl_dist = matrix(0,d,d)

  Distance_K = function(gs1,gs2){
    l = ALLGENE
    A = length(intersect(gs1, gs2))
    B = length(setdiff(gs1,gs2))
    C = length(setdiff(gs2,gs1))
    D = ALLGENE - (A+B+C)

    O = (A+D)/l;
    E = ((A+C)*(A+B)+(B+D)*(C+D))/(l*l);
    kappa = (O-E)/(1-E);
    return(1-kappa)
  }
  for(i in 1:d){
    for(j in 1:d){
      if(i>j){ gsl_dist[i,j] = gsl_dist[j,i] }
      else if(i==j){ gsl_dist[i,j] = 0 }
      else { gsl_dist[i,j] = Distance_K(gsl[[i]], gsl[[j]]) }
    }
  }
  return(gsl_dist)
}

build_datatable = function(gsinfo){
  dtres = datatable(
    gsinfo,
    filter = 'top',
    options = list(
      lengthChange = TRUE,
      pageLength = 10,
      columnDefs = list(list(targets = c(3), searchable = FALSE)),
	  autoWidth = TRUE,
      scrollX = TRUE,
      scrollY = TRUE
    ),
    colnames = c("Name", 'Qvalue', 'Member', 'Cluster'),
    selection = 'none'
  )
}

update_input = function(session,lugi4){ # length(unique(gsinfo[,4]))
  updateSelectizeInput(
    session,
    inputId = 'menuI',
    label = 'Gene Network in Cluster',
    choices = 1:lugi4
  )
}

update_input2 = function(session,lugi4){ # length(unique(gsinfo[,4]))
  updateSelectizeInput(
    session,
    inputId = 'menuI_INCOLOR',
    label = 'select Cluster',
    choices = 1:lugi4
  )
}

find_degree = function(network_obj){

  # for gene network
  edgeData = network_obj$edgeData
  nodeData = network_obj$nodeData$id

  nodes = unique(nodeData)
  res = sapply(1:length(nodes), FUN = function(i){
    this_node = nodes[i]
    connected = length(intersect(
      union(
        which(edgeData['source'] == this_node),
        which(edgeData['target'] == this_node)),
      which(edgeData['color']== '#666666')
    ))
    return(connected)
  })
  names(res) = nodes

  return(res)
}

summary_dist = function(m){
  v = as.numeric(m)
  v = v[which(v<max(v) & v>min(v))]
  quantile(v,seq(0,1,0.01))
}





server <- function(input, output, session) {

  GM = 'NULL'
  GS = 'NULL'
  GQ = 'NULL'
  GENE_NETWORK_OBJ = 'NULL'
  clusts = 'NULL'

  output$AGS = downloadHandler(
      filename = 'ara_sample_geneset.txt',
      content <- function(file) { file.copy("samples/arabidopsis/sample_geneset.txt", file)}
    )

  output$AGS2 = downloadHandler(
      filename = 'ara_sample_genescore.txt',
      content <- function(file) { file.copy("samples/arabidopsis/sample_genescore.txt", file)}
      )

  output$CGS = downloadHandler(
      filename = 'cel_sample_geneset.txt',
      content <- function(file) { file.copy("samples/celegans/sample_geneset.txt", file)}
    )

  output$CGS2 = downloadHandler(
      filename = 'cel_sample_genescore.txt',
      content <- function(file) { file.copy("samples/celegans/sample_genescore.txt", file)}
      )

  output$EGS = downloadHandler(
      filename = 'eco_sample_geneset.txt',
      content <- function(file) { file.copy("samples/ecoli/sample_geneset.txt", file)}
    )

  output$EGS2 = downloadHandler(
      filename = 'eco_sample_genescore.txt',
      content <- function(file) { file.copy("samples/ecoli/sample_genescore.txt", file)}
      )

  output$FGS = downloadHandler(
      filename = 'fly_sample_geneset.txt',
      content <- function(file) { file.copy("samples/fly/sample_geneset.txt", file)}
    )

  output$FGS2 = downloadHandler(
      filename = 'fly_sample_genescore.txt',
      content <- function(file) { file.copy("samples/fly/sample_genescore.txt", file)}
      )

  output$HGS = downloadHandler(
      filename = 'hum_sample_geneset.txt',
      content <- function(file) { file.copy("samples/human/sample_geneset.txt", file)}
    )
  output$HGS2 = downloadHandler(
      filename = 'hum_sample_genescore.txt',
      content <- function(file) { file.copy("samples/human/sample_genescore.txt", file)}
      )

  output$MGS = downloadHandler(
      filename = 'mou_sample_geneset.txt',
      content <- function(file) { file.copy("samples/mouse/sample_geneset.txt", file)}
    )

  output$MGS2 = downloadHandler(
      filename = 'mou_sample_genescore.txt',
      content <- function(file) { file.copy("samples/mouse/sample_genescore.txt", file)}
    )

  output$RGS = downloadHandler(
      filename = 'rat_sample_geneset.txt',
      content <- function(file) { file.copy("samples/rat/sample_geneset.txt", file)}
    )

  output$RGS2 = downloadHandler(
      filename = 'rat_sample_genescore.txt',
      content <- function(file) { file.copy("samples/rat/sample_genescore.txt", file)}
    )

  output$YGS = downloadHandler(
      filename = 'yea_sample_geneset.txt',
      content <- function(file) { file.copy("samples/yeast/sample_geneset.txt", file)}
    )

  output$YGS2 = downloadHandler(
      filename = 'yea_sample_genescore.txt',
      content <- function(file) { file.copy("samples/yeast/sample_genescore.txt", file)}
    )

  output$ZGS = downloadHandler(
      filename = 'zeb_sample_geneset.txt',
      content <- function(file) { file.copy("samples/zebrafish/sample_geneset.txt", file)}
    )

  output$ZGS2 = downloadHandler(
      filename = 'zeb_sample_genescore.txt',
      content <- function(file) { file.copy("samples/zebrafish/sample_genescore.txt", file)}
    )

  output$my_cbgi = renderUI({})
  outputOptions(output, "my_cbgi", suspendWhenHidden = FALSE)

  output$HUB_TABLE = renderUI({})
  outputOptions(output, "HUB_TABLE", suspendWhenHidden = FALSE)

  output$pdfview <- renderUI({
    tags$iframe(style="height:100%; width:100%", src="GScluster User Manual.pdf")
  })


  observeEvent(input$TRANSFORM_ACTIVATE,{
    T1 = input$TEMP1
    T2 = input$TEMP2
    V1 = input$TEMP3

    tpm = function(T1, T2, V1){
      if(T1=='MM'){v = as.numeric(distO)}
      if(T1=='pMM'){v = as.numeric(distOP)}
      if(T1=='Kappa'){v = as.numeric(distK)}

      if(T2=='MM'){v2 = as.numeric(distO)}
      if(T2=='pMM'){v2 = as.numeric(distOP)}
      if(T2=='Kappa'){v2 = as.numeric(distK)}

      as.numeric(quantile(v2, ecdf(v)(V1)))
    }

    updateNumericInput(session, inputId = 'TEMP4',value = tpm(T1,T2,V1))
  })

  build_genescore_filter = function(Data){
  	res = c()
  	for(i in 1:length(Data)){
  		temp = strsplit(Data[i],'\t')[[1]]
  		if(as.numeric(temp[2])>input$GENESCORE_CUTOFF){next}
  		res= c(res,temp[1])
  	}
  	return(res)
  }

  build_gene_colorlist = function(Data){

    res = sapply(1:length(Data), FUN = function(i){
      temp = strsplit(Data[i],'\t')[[1]]
      GENE = temp[1]
      GENESCORE = as.numeric(temp[2])
      ret = GENESCORE
      names(ret) = GENE
      return(ret)
    })
    res = res[which(res<input$GENESCORE_CUTOFF)]
    stats = summary(res)

    Q1 = stats[2]
    Q2 = stats[3]
    Q3 = stats[5]

    res2 = res
    res2[which(res<=Q1)] = '#FBCDCD'
    res2[which(res>Q1 & res<=Q2)] = '#F89A9A'
    res2[which(res>Q2 & res<=Q3)] = '#F46767'
    res2[which(res>Q3) ] = '#F03434'
    res = res2

    ### COLOR LIST
    # 255,255,255 	# NONE,   FFFFFF
    # 251,205,205 	# ~ Q1    FBCDCD
    # 248,154,154 	# Q1 ~ Q2 F89A9A
    # 244,103,103 	# Q2 ~ Q3 F46767
    # 240,52,52		 # Q3 ~    F03434

    return(res)
  }

  build_genenetwork = function(genes, ppi_cutoff = 0.7, ppi_matrix, multiEdge = TRUE, showError = TRUE){
    if(input$PPI_CUTOFF!=700){ppi_cutoff = input$PPI_CUTOFF/1000}

	  # build edges
	  tab = get_matrix(genes, ppi_matrix)
    source = c()
    target = c()
    w = c()
    calculate_edgeW = function(i){ return(round(i/0.111+(10-1/0.111),3)) }
    rd = rownames(tab)
    for(i in 1:nrow(tab)){
      v = setdiff(which(tab[i,] >= ppi_cutoff),i)
      if(is.null(names(v))){names(v) = rd[v]}
      if(length(v) > 0){v = v[which( names(v) < rd[i] )]}

      if(length(v) > 0){
        sel = names(v)
        source = c(source, rep(rd[i], length(sel)))
        target = c(target, sel)
        w = c(w,sapply(tab[i,names(v)], calculate_edgeW))
      }
    }
	  color = rep('#666666', length(source))
    edgeData <- data.frame(source, target, color, stringsAsFactors=FALSE)

    # build nodes
    id = unique(union(source, target))
    name = id
    nodeData = data.frame(id, name, stringsAsFactors=FALSE)
    if(exists('gene_colors')){
      color = get_nodeColor(id)
      if(length(color) == 1){
        if(color==0){
          if(showError){ showNotification("NO GENES WITH CUTOFF", type = 'error') }
          return()
        }
      }
      nodeData = cbind(nodeData, color)
    }
    else{ showNotification("GENESCORE FILE NOT GIVEN", type = 'error') }

    # remove edge between white nodes
    whiteNodes = nodeData[which(nodeData['color']=='#FFFFFF'),'id']
    v = intersect(which(sapply(1:nrow(edgeData), function(i){edgeData[i,1] %in% whiteNodes})),
    which(sapply(1:nrow(edgeData), function(i){edgeData[i,2] %in% whiteNodes})))
    if(length(v)!=0){edgeData = edgeData[-v,]}

    # remove whitenode with enoughrednode
    redNodes = nodeData[which(nodeData['color']!='#FFFFFF'),'id']

    edgesBetweenredNodes = intersect(which(sapply(1:nrow(edgeData), function(i){edgeData[i,1] %in% redNodes})),
    which(sapply(1:nrow(edgeData), function(i){edgeData[i,2] %in% redNodes})))

    edgesBetweenredNodes = edgeData[edgesBetweenredNodes,]

    enoughredNodes = union(edgesBetweenredNodes[,1],edgesBetweenredNodes[,2])
    notenoughredNodes = setdiff(redNodes, enoughredNodes)

    for(i in 1:length(whiteNodes)){
      this_node = whiteNodes[i]
      v = union(which(edgeData[,1] == this_node),which(edgeData[,2] == this_node))
      if(length(v)==1){
        if(edgeData[v,1] %in% enoughredNodes | edgeData[v,2] %in% enoughredNodes){
          edgeData = edgeData[-v,]
        }
      }
    }

    # remove nodes without edges
    edgeNodes = union(edgeData[,"source"], edgeData[,"target"])
    v = which(sapply(1:nrow(nodeData), function(i){nodeData[i,1] %in% edgeNodes}))
    if(length(v)!=0){nodeData = nodeData[v,]}

    GENE_NETWORK_OBJ = list(nodeData = nodeData, edgeData = edgeData, width = w)

    if(length(input$MULTIEDGE)>0){
      multi_edge = build_multiEdge(GENE_NETWORK_OBJ, input$MULTIEDGE)
      GENE_NETWORK_OBJ$edgeData = rbind(GENE_NETWORK_OBJ$edgeData, multi_edge)
    }

    return(GENE_NETWORK_OBJ)
  }

  build_cytoscape_network = function(clusts_table, Dist){

    build_col = function(i){
  		sapply(1:i, FUN = function(i){
    		k = round(runif(3,min = 0,max = 255))
    		return(rgb(k[1],k[2],k[3],max=255))
    		})
    }

  	cl1 = sapply(clusts_table[,1], function(i){gsub('\n','',i)}, USE.NAMES = FALSE) # remove \n

	  name = id = unique(cl1)

    nodeData = data.frame(id, name, stringsAsFactors=FALSE)

    col = build_col(length(unique(clusts_table[,4])))

    color = sapply(1:length(id), FUN = function(i){
    	a = which(id[i]==cl1)
  	  if(length(a)>1){return('#666666')}
  	  else{return(col[clusts_table[a,4]])}
    })

    nodeData = cbind(nodeData, color)

    rd = rownames(Dist) # replace GS??
    EDGED = input$CLUSTER_MIN_DISTANCE

    source = c()
    target = c()
    w = c()

    rd_idx = sapply(id, function(i){a = which(i==rd); if(length(a)>1){a[1]} else{a}}, USE.NAMES = FALSE)
    Dist = Dist[rd_idx,rd_idx]
    rd = rownames(Dist)

    calculate_edgeW = function(i){ return(round(i/0.111+(10-1/0.111),3)) }

      for(i in 1:length(rd_idx)){
        v = which(Dist[i,-i]<=EDGED)
        if(length(v)>0){v = v[which(names(v)<rd[i])]}

        if(length(v)>0){
          sel = names(v)
          source = c(source, rep(rd[i], length(sel)))
          target = c(target, sel)
          w = c(w,sapply(Dist[i,names(v)], calculate_edgeW))
        }
      }

      edgeData <- data.frame(source, target, stringsAsFactors=FALSE)
      return(list (nodeData = nodeData, edgeData = edgeData, color = color, width = w))
    }

  fuzzy_clust = function(var_D = 0.5, Dist, dist_type, GS, GM, GQ){

  	neighbor = function(vector, var_D){ return(which(vector<=var_D)) }
  	find_ratio = function(v){
  		l = length(v)
  		if(l==1){return(0)}
  		count = ( length(which(Dist[v, v]<var_D)) - l )
  		return( count/(l^2-l) )
  	}
  	remove_duplicated = function(track){ return(track[which(!duplicated(track))]) }
  	remove_included = function(track){
  		remove = c()
  		for(i in 1:(length(track)-1)){
  			for(j in (i+1):length(track)){
  				if(ovl(track[[i]],track[[j]])==1){
  					if(length(track[[i]])>length(track[[j]])){ remove = c(remove,j) }
  					else{ remove = c(remove,i) }
  				}
  			}
  		}
  		if(length(remove)>0){track = track[-remove]}
  		return(track)
  	}

  	track_gene = function(idx){
  		res = c();
  		for(i in 1:length(idx)){ res = c(res, geneset_member[idx[i]]) }
  		return(sort(unique(res)))
  	}

  	track2genelist = function(track){ lapply(1:length(track), FUN = function(i){ unique(unlist(GM[track[[i]]], use.names = FALSE)) })}

  	var_M = var_D
  	var_X = input$CLUSTER_MIN_SIZE
  	var_w = 0.5

  	track = list()

  	for(i in 1:nrow(Dist)){
  		v = neighbor(Dist[i,], var_D)
  		track[[i]] = sort(v)
  	}

  	track = track[which(unlist(lapply(track, length))>=var_X)]
  	track = track[which(unlist(lapply(track, find_ratio))>=var_w)] # ratio cutoff
  	names(track) = NULL
  	min_dis = -9999;

  	while(min_dis <= var_M){

  		track = remove_duplicated(track)
  		track = remove_included(track)
  		track_genelist = track2genelist(track)

  		if(dist_type==1){ Dist = get_dist_O(track_genelist) }
  		if(dist_type==2){ Dist = get_dist_OP(track_genelist, ppi_matrix = string, input$CLUSTER_METHOD)}
  		if(dist_type==3){ Dist = get_dist_K(track_genelist) }

  		# merge and move

  		track2 = lapply(1:length(track), FUN = function(i){sort(unique(unlist(track[which(Dist[i,]<var_M)]))) })
  		track = remove_included(track2)
  		track = remove_duplicated(track)
  		track_genelist = track2genelist(track)

  		min_dis = 9999;

  		if(length(track)==1){break}
  		if(dist_type==1){Dist = get_dist_O(track_genelist)}
  		if(dist_type==2){Dist = get_dist_OP(track_genelist, ppi_matrix = string, input$CLUSTER_METHOD)}
  		if(dist_type==3){Dist = get_dist_K(track_genelist)}
  		min_dis = min(sapply(1:nrow(Dist), FUN = function(i){min(Dist[i, -i])}))

  	}
  	return(track) # return index form
  }

  get_clust_gs = function(i, query = FALSE){
    GS = gsinfo[which(gsinfo[,4] == i),1]
    GS = sapply(GS, function(i){gsub('\n','',i)}, USE.NAMES=FALSE)
    if(query){ GS = paste(GS, collapse=',#') }
    return(GS)
  }

  get_clust_gm = function(clust_no){#, selected_idx){
    genemember = unlist(global_gsm[which(gsinfo[,4] == clust_no)])#[selected_idx]])
    res = c()
    genemember = sapply(genemember, function(i){gsub('\n',',',i)}) # remove \n
    for(i in 1:length(genemember)){ res = c(res,strsplit(genemember[i],',')[[1]]) }
    res = unique(res)
    return(res)
  }

  my = reactiveValues(selected=my_selected, firt_call_ignore=TRUE)
  output$my_cbgi = renderUI( my_checkboxGroupInput( "MULTIEDGE", "Evidence :", choices = my_names, selected = my$selected, colors = my_colors ) )

  observeEvent(input$MULTIEDGE,{
    if(my$firt_call_ignore){my$firt_call_ignore=FALSE}
    else{my$selected <- input$MULTIEDGE}},
    ignoreNULL = FALSE
  )

  observeEvent(input$AB1, {
    print('go to sleep')
    Sys.sleep(2)
    myf = function(edgeData, w){ for(i in 1:nrow(edgeData)){ js$draw_edge( c(edgeData[i,1],edgeData[i,2], w[i]))}}
    edgeData= GENESET_NETWORK_OBJ$edgeData
    w = GENESET_NETWORK_OBJ$width
    names(edgeData[,1]) = NULL
    names(edgeData[,2]) = NULL
    names(w) = NULL
    myf(edgeData, w)
    js$layout_as_cola()
  })

  observeEvent(input$Disease_button,{

    clust_idx = input$menuI
    genes = get_clust_gm(clust_idx)
	  working_gene = TRUE
	  if(working_gene){
	    genes = intersect(get_clust_gm(clust_idx), gene_score_filter)
	  }
  	if(length(genes)<=1){
	    showNotification("NO GENES SATISFIED THE GENE SCORE CUTOFF", type = 'error')
	    shinyjs::hide(id='Disease_button')
	    return()
	  }

    dTable = build_Disease_Table(genes)
    output$dTable_OUTPUT = renderDataTable(dTable)

  })

  observeEvent(input$AB2, {
    print('go to sleep2')
    Sys.sleep(2)
    myf = function(edgeData, w){for(i in 1:nrow(edgeData)){ js$draw_edge( c(edgeData[i,1],edgeData[i,2], w[i])) }}
    edgeData= GENE_NETWORK_OBJ$edgeData[,1:2]
    w = GENE_NETWORK_OBJ$width
    names(edgeData[,1]) = NULL
    names(edgeData[,2]) = NULL
    names(w) = NULL
    myf(edgeData, w )
    js$layout_as_cola()
  })

  observeEvent(input$ACTIVATEFIT,{
    txt = gsub('\n','',input$FIT)
    js$fit_node(txt)
  })

  observeEvent(input$RESTORE_GENESET_NETWORK, {
    js$remove_cy()
    shinyjs::hide(id='HUB_DIV')
    shinyjs::hide(id='Disease_button')
    shinyjs::hide(id='subPPI')
	  nodeData = GENESET_NETWORK_OBJ$nodeData
    edgeData = GENESET_NETWORK_OBJ$edgeData
    color = GENESET_NETWORK_OBJ$color
    output$legend <- renderUI( function_buildlegends(color) )

    GNO2 = apply_cliq60(GENESET_NETWORK_OBJ)
    #GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData, edgeTargetShape = 'none',nodeLabelColor = 'black')

    GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')

    updateSelectizeInput(session, "FIT", choices = unique(gsinfo[,1]), server = TRUE)

	  #GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')


	output$plot1 = rcytoscapejs::renderRcytoscapejs({
		res = rcytoscapejs(
			layout='cose',
			nodeEntries = GENESET_NETWORK_OBJ$nodes,
			edgeEntries = GENESET_NETWORK_OBJ$edges,
			boxSelectionEnabled = FALSE)
		return(res)
    })
	shinyjs::click('AB1')
  })

  bridge = function(network_obj){

  # assume gene_network_obj
    clust_idx = input$menuI
    genes = get_clust_gm(clust_idx)
    genes = intersect(rownames(string), genes)

    exp = network_obj$nodeData$id
    exp = intersect(rownames(string),exp)
    #non_exp = setdiff(unique(unlist(GM)), exp)
    non_exp = setdiff(genes, exp)
    if(length(exp)==0){return(network_obj)}

    matrix = string[exp,non_exp] # among non_expressed genes.

    node_added = c()
    # id , name, color
    for(i in 1:length(exp)){
      linked_genes = names(which(matrix[i,]>0))
      node_added = c(node_added, linked_genes)
    }

    if(length(node_added)>0){
      tn = table(node_added)

      # node

      # #7efff5 SKYBLUE
      # #fbc531 YELLOW
      # #e67e22 ORANGE

      node_added = names(which(tn > (length(exp)*2/(3+1)) ))
      i = 2
      while(length(node_added)>20){
        i = i+1
        node_added = names(which(tn > (length(exp)*i/(i+1)) ))
      }

      v = data.frame(id=node_added, name = node_added, color = '#e67e22', shape='rectangle', height='30px',width = '30px')
      network_obj$nodeData = rbind(network_obj$nodeData, v)

      # bridge - intersect

      targets = list()
      for(i in 1:length(node_added)){
        this_source = node_added[i]
        this_target = names(which(matrix[exp,this_source]>0))
        targets[[i]] = this_target
        names(targets)[i] = this_source
      }

      target_D = matrix(0,length(targets), length(targets))
      for(i in 1:length(targets)){
        for(j in 1:length(targets)){
          if(i==j){target_D[i,j] = 1; next}
          if(i>j){target_D[i,j] = target_D[j,i]; next}
          target_D[i,j] = length(intersect(targets[[i]], targets[[j]])) / min(length(targets[[i]]), length(targets[[j]]))
        }
      }

      # SELECTION P = 2/3

      chunk = list()
      remain = 1:length(targets)
      while(length(remain)>0){
        a = intersect(remain, which(target_D[remain[1],] > 2/3))
        chunk[[length(chunk)+1]] = a
        remain = setdiff(remain, a)
      }

      # chunk node

      v = data.frame(
        id = paste0('Bridge' ,1:length(chunk)),
        name = paste0('Bridge' ,1:length(chunk)),
        color = '#7efff5', shape='ellipse', height='20px',width = '20px')

      network_obj$nodeData = rbind(network_obj$nodeData, v)

      # chunk edge

      # bridge -> exp

      # light gray #aaa69d
      for(i in 1:length(chunk)){
        this_source = paste0('Bridge',i)
        this_target = names(targets)[chunk[[i]]]
        v = data.frame(source = this_source, target = this_target, color = '#aaa69d')
        network_obj$edgeData = rbind(network_obj$edgeData, v)
      }

      # bridge -> exp
      for(i in 1:length(chunk)){
        this_nodes = unique(unlist(targets[chunk[[i]]]))
        v = data.frame(source = paste0('Bridge',i), target = this_nodes, color = '#aaa69d')
        network_obj$edgeData = rbind(network_obj$edgeData, v)
      }

    }
    else{
      print('no bridge')
    }

    return(network_obj)
  }


  observeEvent(input$DRAW_GENENETWORK,{
    shinyjs::show(id = 'HUB_DIV')
	  shinyjs::show(id = 'subPPI')
    shinyjs::show(id = 'Disease_button')
	  clust_idx = input$menuI
    if(length(clust_idx)==0){showNotification("NONE CLUSTER SELECTED", type = 'error');return(NULL)}

	  genes = get_clust_gm(clust_idx)
	  working_gene = TRUE
	  if(working_gene){
	    genes = intersect(get_clust_gm(clust_idx), gene_score_filter)
	  }
  	if(length(genes)<=1){
	    showNotification("NO GENES SATISFIED THE GENE SCORE CUTOFF", type = 'error')
	    shinyjs::hide(id='HUB_DIV')
		  shinyjs::hide(id='subPPI')
		  shinyjs::hide(id='Disease_button')
	    return()
	  }
    res = build_genenetwork(genes = genes, ppi_matrix = string)
    if(is.null(res)){return()}

    GENE_NETWORK_OBJ = res
    assign('GENE_NETWORK_OBJ', GENE_NETWORK_OBJ, envir = .GlobalEnv)
    GENE_NETWORK_OBJ <<- GENE_NETWORK_OBJ

	  function_downloadHandler_subPPI = function(i){
      val = paste('Gene1','Gene2','PPI Score','Common Gene-set','Gene1 only','Gene2 only', sep='\t')
      e = GENE_NETWORK_OBJ$edgeData
      e = e[which(e[,'color']=='#666666'), ]
      width = GENE_NETWORK_OBJ$width
      genesets = gsinfo[which(gsinfo[,4] == i),]
      genesets[,1] = sapply(genesets[,1],FUN = function(i){gsub('\n','',i)})

      for(i in 1: nrow(e)){
        ss = e$source[i]
        tt = e$target[i]
        ww = round((width[i]-(10-1/0.111))*0.111,3)
        res = c()
        ret = c()

        for(j in 1:nrow(genesets)){
          k = strsplit(as.character(genesets[j,3]),',')[[1]]
          if(ss %in% k) res = c(res,genesets[j,1])
          if(tt %in% k) ret = c(ret,genesets[j,1])
        }

        # gene1, gene2, ppi score, common geneset, gene1 only, gene2 only

        within = intersect(res,ret)
        res = setdiff(res,within)
        ret = setdiff(ret,within)

        temp = paste(ss,tt,ww, sep='\t') # gene1, gene2, score
        if(length(within)>0) {
          temp = paste(temp,paste(within,collapse=','), sep='\t' ) # common geneset
        }
        else{
          temp = paste(temp, '...', sep='\t')
        }
        if(length(res)>0) {
          temp = paste(temp,paste(res,collapse=','), sep='\t' ) # gene1 only
        }
        else{
          temp = paste(temp, '...', sep='\t')
        }
        if(length(ret)>0) {
          temp = paste(temp,paste(ret,collapse=','), sep='\t' ) # gene2 only
        }
        else{
          temp = paste(temp, '...', sep='\t')
        }
        val = c(val,temp)
      }
      downloadHandler(filename='subppi.txt',content = function(con){writeLines(val,con)})
    }
  	output$subPPI = function_downloadHandler_subPPI(input$menuI)

    if(!input$GRAY_EDGE){
      res$edgeData = res$edgeData[which(res$edgeData[,'color']!='#666666'),]
      #genenetwork = createCytoscapeJsNetwork(res$nodeData, res$edgeData[which(res$edgeData[,'color']!='#666666'),], edgeTargetShape = 'none', nodeLabelColor = 'black')
    }

#    else{
      #genenetwork = createCytoscapeJsNetwork(res$nodeData, res$edgeData, edgeTargetShape = 'none', nodeLabelColor = 'black')
    #}

  	GNO2 = apply_cliq60(GENE_NETWORK_OBJ)
    #genenetwork = createCytoscapeJsNetwork(res$nodeData, res$edgeData, edgeTargetShape = 'none', nodeLabelColor = 'black')

  	GNO2 = bridge(GNO2)

    genenetwork = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData, edgeTargetShape = 'none', nodeLabelColor = 'black')
	  #res = createCytoscapeJsNetwork(res$nodeData, res$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')

    js$remove_cy()

    output$plot1 = rcytoscapejs::renderRcytoscapejs({
      rcytoscapejs(
        nodeEntries = genenetwork$nodes,
        edgeEntries = genenetwork$edges,
        boxSelectionEnabled = FALSE,
		    layout='cola'
      )
    })

    build_color_labels = function(){
      res = c()
      colors = c('#F03434','#F46767',"#F89A9A",'#FBCDCD')#,'#FFFFFF')
      texts = c("Very Strong (0~25%)","Strong (25~50%)","Moderate (50~75%)","Weak (75~100%)")#,"NO SCORE")
      for(i in 1:length(colors)){
        b = HTML(
          paste0(
            '<div style="background:',
            colors[i],
            ';margin-bottom:1em;width:20px;height:20px;display:inline-block; border :black solid 1px;"></div>',
            '<div style="float:right;text-align:center;height:20px;line-height:20px;width:70px;"> ',
            texts[i],'</div><br>'
          )
        )
        res = paste0(res,b)
      }
      return(HTML(res))
    }

    dTable = build_Disease_Table(genes)
    output$dTable_OUTPUT = renderDataTable(dTable)
    output$legend <- renderUI( build_color_labels() )

    updateSelectizeInput(session, "FIT", choices = unique(GNO2$nodeData$name), server = TRUE)

    shinyjs::click('AB2')
  })

  observeEvent(input$CLUSTER_CHANGE, {

  	progress <- shiny::Progress$new()
    on.exit(progress$close())
  	progress$set(message = "Building", value = 0)

    var_D = input$CLUSTER_MIN_DISTANCE
    v = 101
    #distOP_calc = FALSE
    progress$inc(1/2, detail = "Clustering")
    while(v>100){

      cluster_method = input$CLUSTER_METHOD
      if(cluster_method=='MM'){ clusts = fuzzy_clust(var_D, distO, dist_type = 1, GS, GM, GQ)}
      if(cluster_method=='pMM' || cluster_method=='pMM1' || cluster_method=='pMM2' || cluster_method=='pMM3'){
        #if(!distOP_calc){
      	  #distOP = get_dist_OP(GM, ppi_matrix = string, input$CLUSTER_METHOD)
      	  #distOP_calc = TRUE
      	  #rownames(distOP) = colnames(distOP) = GS
      	  #assign('distOP',distOP, envir = .GlobalEnv)
      	#}
      	clusts = fuzzy_clust(var_D, distOP, dist_type = 2, GS, GM, GQ)
    	}
      if(cluster_method=='Kappa'){ clusts = fuzzy_clust(var_D, distK, dist_type = 3, GS, GM, GQ)}

      assign('clusts',clusts,envir = .GlobalEnv)

  	  v = max(unlist(lapply(clusts,length)))

      print(paste('v: ',v))
  	  if(v > 100){
  	    print('too large cluster; distance will adjusted')
  	    var_D = var_D - 0.5
	    }
	    if(var_D<0){break}
    }

    gsinfo = build_clust_info(clusts, GS, GM, GQ)
    dtres = build_datatable(gsinfo)
    assign('gsinfo', gsinfo, envir = .GlobalEnv)
    output$gsinfo = DT::renderDataTable(dtres)
	  output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)
    update_input(session, length(unique(gsinfo[,4])))

    if(cluster_method=='MM'){ GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distO)}
    if(cluster_method=='pMM' || cluster_method=='pMM1' || cluster_method=='pMM2' || cluster_method=='pMM3'){
      GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distOP) }
	  if(cluster_method=='Kappa'){GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distK)}

  	nodeData = GENESET_NETWORK_OBJ$nodeData
  	edgeData = GENESET_NETWORK_OBJ$edgeData
  	color = GENESET_NETWORK_OBJ$color

	  assign('GENESET_NETWORK_OBJ',GENESET_NETWORK_OBJ,envir = .GlobalEnv)

	  #GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')

  	GNO2 = apply_cliq60(GENESET_NETWORK_OBJ)

	  GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')

	  output$legend <- renderUI( function_buildlegends(color) )

	  progress$inc(1/2, detail = "Rendering")

  	output$plot1 = rcytoscapejs::renderRcytoscapejs({
  		res = rcytoscapejs(
  			nodeEntries = GENESET_NETWORK_OBJ$nodes,
  			edgeEntries = GENESET_NETWORK_OBJ$edges,
  			layout='cose',
  			boxSelectionEnabled = FALSE)
  		return(res)
      })
  	shinyjs::click("AB1")
  })

  observeEvent(input$DEMO,{

    check_data('Human')

    progress <- shiny::Progress$new()
    on.exit(progress$close())
	  progress$set(message = "Building", value = 0)

    shinyjs::hide(id='Input_box')
    shinyjs::show(id='main_panel')
    shinyjs::show(id='cluster_row')
    shinyjs::hide(id='cluster_message')

    progress$inc(1/8, detail = "Reading Geneset File")

    infile = list(datapath = 'sample_geneset.txt')
    x = readLines(con = infile$datapath)
    x = x[-1] # header

    GS = c()
    GM = list()
    GQ = c()

    makeReactiveBinding("GS")
    makeReactiveBinding("GM")
    makeReactiveBinding("GQ")

    for(i in 1:length(x)){
      temp = strsplit(x[i],'\t')[[1]]
	  if(as.numeric(temp[3])>input$GENESET_CUTOFF){next}
      GS[i] = temp[1]
      GM[[i]] = strsplit(temp[2],' ')[[1]]
      GQ[i] = as.numeric(temp[3])
    }

    progress$inc(1/8, detail = "Reading Genescore File")

    infile = list(datapath='sample_genescore.txt')
	  x = readLines(con = infile$datapath)
	  x = x[-1]
	  gene_colors = build_gene_colorlist(x)
	  assign('gene_colors',gene_colors,envir = .GlobalEnv)
	  gene_score_filter = build_genescore_filter(x)
	  assign('gene_score_filter',gene_score_filter,envir = .GlobalEnv)

    GS <<- GS
    GM <<- GM
    GQ <<- GQ

    progress$inc(1/8, detail = "Calculate MM")

    distO = get_dist_O(GM)
    rownames(distO) = colnames(distO) = GS
    assign('distO',distO, envir = .GlobalEnv)

    assign('GM',GM,envir = .GlobalEnv)

    progress$inc(1/8, detail = "Calculate pMM")

    distOP = get_dist_OP(GM, ppi_matrix = string, input$CLUSTER_METHOD)
    rownames(distOP) = colnames(distOP) = GS
    assign('distOP',distOP, envir = .GlobalEnv)

    progress$inc(1/8, detail = "Calculate Kappa")

    distK = get_dist_K(GM)
    rownames(distK) = colnames(distK) = GS
    assign('distK',distK, envir = .GlobalEnv)

    progress$inc(1/8, detail = "Clustering")

  	var_D = input$CLUSTER_MIN_DISTANCE
    clusts = fuzzy_clust(var_D, distOP, dist_type = 2, GS, GM, GQ)
    clusts <<- clusts
    assign('clusts',clusts,envir = .GlobalEnv)

    gsinfo = build_clust_info(clusts, GS, GM, GQ)
    assign('gsinfo', gsinfo, envir = .GlobalEnv)
    dtres = build_datatable(gsinfo)
    output$gsinfo = DT::renderDataTable(dtres)
  	output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)
    update_input(session, length(unique(gsinfo[,4])))
    update_input2(session, length(unique(gsinfo[,4])))

    progress$inc(1/8, detail = "Rendering Network")

    GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distOP)
    nodeData = GENESET_NETWORK_OBJ$nodeData
    edgeData = GENESET_NETWORK_OBJ$edgeData
	  color = GENESET_NETWORK_OBJ$color
	  output$legend = renderUI( function_buildlegends(color) )
	  assign('GENESET_NETWORK_OBJ',GENESET_NETWORK_OBJ,envir = .GlobalEnv)

    #GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')

	  GNO2 = apply_cliq60(GENESET_NETWORK_OBJ)
	  #GNO2 = GENESET_NETWORK_OBJ
	  GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')

    output$plot1 = rcytoscapejs::renderRcytoscapejs({
		  res = rcytoscapejs(
		  nodeEntries = GENESET_NETWORK_OBJ$nodes,
		  edgeEntries = GENESET_NETWORK_OBJ$edges,
		  layout='cose',
		  boxSelectionEnabled = FALSE)
		  return(res)
	  })

    output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)

    progress$inc(1/8, detail = "Wait for rendered Network")


    #NodeSearch = function(){
      #fluidRow( style = {'position:absolute;margin-left:7%;z-index:999'},textInput('FIT','Gene-set search') )
    #}


    updateSelectizeInput(session, "FIT", choices = unique(gsinfo[,1]), server = TRUE)

    shinyjs::click('AB1')

  })


  observeEvent(input$RUN, {

	  check_data(input$INPUT_SPECIES)

	  progress <- shiny::Progress$new()
    on.exit(progress$close())
  	progress$set(message = "Building", value = 0)

    shinyjs::hide(id='Input_box')
    shinyjs::show(id='main_panel')
    shinyjs::show(id='cluster_row')
	  shinyjs::hide(id='cluster_message')

	  progress$inc(1/8, detail = "Reading Geneset File")

    GS = c()
    GM = list()
    GQ = c()

    makeReactiveBinding("GS")
    makeReactiveBinding("GM")
    makeReactiveBinding("GQ")

    infile = input$INPUT_GENESET_FILE

    if(is.null(infile)){
  		showNotification("INPUT FILE NOT GIVEN", type = 'error')
  		shinyjs::show(id='Input_box')
  		shinyjs::hide(id='main_panel')
  		shinyjs::hide(id='cluster_row')
  		shinyjs::show(id='cluster_message')
  		return(NULL)
    }

    x = readLines(con = infile$datapath)
    x = x[-1] # remove header

    for(i in 1:length(x)){
      temp = strsplit(x[i],'\t')[[1]]
  	  if(as.numeric(temp[3])>input$GENESET_CUTOFF){next}
      GS[i] = temp[1]
      GM[[i]] = strsplit(temp[2],' ')[[1]]
      GQ[i] = as.numeric(temp[3])
    }

  	progress$inc(1/8, detail = "Reading Genescore File")

    infile = input$INPUT_GENESCORE_FILE
    if(!is.null(infile)){
  		x = readLines(con = infile$datapath)
  		x = x[-1]
  		gene_colors = build_gene_colorlist(x)
  		assign('gene_colors',gene_colors,envir = .GlobalEnv)
		  gene_score_filter = build_genescore_filter(x)
		  assign('gene_score_filter',gene_score_filter,envir = .GlobalEnv)
  	}
    SIGGENE_ONLY = input$WORKING_GENE
    if(SIGGENE_ONLY){
      for(i in 1:length(GM)){
        GM[[i]] = intersect(GM[[i]], gene_score_filter)
      }
    }
    assign('GM',GM, envir = .GlobalEnv)

    # ENSEMBL GENESET
    if(length(grep('ENS',GM[[1]][1]))!=0){
      for(i in 1:length(GM)){ GM[[i]] = unlist(toupper(ent_sym[unlist(ensg_ent[GM[[i]]],use.names = FALSE)]),use.names = FALSE) }
    }

    # ENSEMBL GENESCORE
    if(length(grep('ENS',gene_score_filter[1]))!=0){
      for(i in length(gene_score_filter):1){
        a = ensg_ent[[gene_score_filter[i]]]
        if(length(a)>1){a = a[1]}
        a = toupper(ent_sym[[a]])
        if(is.null(a)){gene_score_filter = gene_score_filter[-i]; gene_colors = gene_colors[-i]; next}
        gene_score_filter[i] = a
      }
      names(gene_colors) = gene_score_filter
    }

    # ENTREZ GENESET
    if(!is.na(as.numeric(GM[[1]][1]))){
      for(i in 1:length(GM)){GM[[i]] = unlist(toupper(ent_sym[GM[[i]]]), use.names = FALSE)}
    }

	# ENTREZ GENESCORE
    if(!is.na(as.numeric(gene_score_filter[1]))){
      for(i in length(gene_score_filter):1){
        a = toupper(ent_sym[[gene_score_filter[i]]])
        if(is.null(a)){gene_score_filter = gene_score_filter[-i]; gene_colors = gene_colors[-i]; next}
        gene_score_filter[i] = a
      }
      names(gene_colors) = gene_score_filter
    }

  	GS = GS[which(lapply(GM, length)!=0)]
    GQ = GQ[which(lapply(GM, length)!=0)]
    GM = GM[which(lapply(GM, length)!=0)]

    GS <<- GS
    GM <<- GM
    GQ <<- GQ

  	progress$inc(1/8, detail = "Calculate MM")

    distO = get_dist_O(GM)
    rownames(distO) = colnames(distO) = GS
    assign('distO',distO, envir = .GlobalEnv)

	  progress$inc(1/8, detail = "Calculate pMM")

    distOP = get_dist_OP(GM, ppi_matrix = string, input$CLUSTER_METHOD)
    rownames(distOP) = colnames(distOP) = GS
    assign('distOP',distOP, envir = .GlobalEnv)

	  progress$inc(1/8, detail = "Calculate Kappa")

    distK = get_dist_K(GM)
    rownames(distK) = colnames(distK) = GS
    assign('distK',distK, envir = .GlobalEnv)

	  progress$inc(1/8, detail = "Clustering")

    var_D = input$CLUSTER_MIN_DISTANCE
    clusts = fuzzy_clust(var_D, distOP, dist_type = 2, GS, GM, GQ)
    clusts <<- clusts

    gsinfo = build_clust_info(clusts, GS, GM, GQ)
    assign('gsinfo', gsinfo, envir = .GlobalEnv)
    dtres = build_datatable(gsinfo)
    output$gsinfo = DT::renderDataTable(dtres)
  	output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)
    update_input(session, length(unique(gsinfo[,4])))
    update_input2(session, length(unique(gsinfo[,4])))

	  progress$inc(1/8, detail = "Rendering Network")

    GENESET_NETWORK_OBJ = build_cytoscape_network(gsinfo, distOP)
    nodeData = GENESET_NETWORK_OBJ$nodeData
    edgeData = GENESET_NETWORK_OBJ$edgeData

  	color = GENESET_NETWORK_OBJ$color
  	output$legend = renderUI( function_buildlegends(color) )
  	assign('GENESET_NETWORK_OBJ',GENESET_NETWORK_OBJ,envir = .GlobalEnv)


	  GNO2 = apply_cliq60(GENESET_NETWORK_OBJ)
    #GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(nodeData, edgeData, edgeTargetShape = 'none',nodeLabelColor = 'black')

    GENESET_NETWORK_OBJ = createCytoscapeJsNetwork(GNO2$nodeData, GNO2$edgeData,edgeTargetShape = 'none',nodeLabelColor = 'black')
    #rcytoscapejs(gno4$nodes, gno4$edges, layout='cose',boxSelectionEnabled = FALSE, width = 1000, height = 1000)

    output$plot1 = rcytoscapejs::renderRcytoscapejs({
		res = rcytoscapejs(
        nodeEntries = GENESET_NETWORK_OBJ$nodes,
        edgeEntries = GENESET_NETWORK_OBJ$edges,
	    	layout='cose',
        boxSelectionEnabled = FALSE)
		return(res)
    })

    output$CLUST_RESULT = function_downloadHandler_Clust_info(gsinfo)

  	progress$inc(1/8, detail = "Wait for rendered Network")

  	updateSelectizeInput(session, "FIT", choices = unique(gsinfo[,1]), server = TRUE)

  	shinyjs::click("AB1")
  })

  observeEvent(input$DEGREE, {
  	degrees = find_degree(GENE_NETWORK_OBJ)
  	tt = degrees[sort(which(rank(-degrees, ties.method = 'min')<=input$DEGREE_CUTOFF), decreasing = TRUE)]
  	hub_table = data.frame(matrix(ncol=2,nrow=0))
  	colnames(hub_table) = c("GENE","LINKS")
  	for(i in 1:length(tt)){ hub_table[i,] = c(names(tt)[i], tt[i]) }
  	output$DEGREE_OUTPUT = DT::renderDataTable(hub_table, options= list(autoWidth=TRUE,bFilter=FALSE),rownames = FALSE)
  })

  observeEvent(input$CHECK,{
    clust_obj = clusts
    res = c()

    for(i in 1:length(clust_obj)){
		this_clust = clust_obj[[i]]
		this_clust_genes = unique(unlist(GM[this_clust]))

		this_clust_genes = intersect(this_clust_genes, gene_score_filter)
		if(length(this_clust_genes)<=1){next}

		GENE_NETWORK_OBJ = build_genenetwork(
			genes = this_clust_genes,
			ppi_cutoff = input$PPI_CUTOFF/1000,
			ppi_matrix = string,
			multiEdge = FALSE,
			showError = FALSE
		)

		degrees = find_degree(GENE_NETWORK_OBJ)

		tt = degrees[sort(which(rank(-degrees, ties.method = 'min')<=input$RANK_CUTOFF), decreasing = TRUE)]

		if(is.null(names(degrees))){next}

		clust_no = rep(i,length(tt))
		gene = names(tt)
		names(tt) = NULL
		degree = tt

		res = rbind(res,data.frame(cbind(gene, degree, clust_no), stringsAsFactors = FALSE))
    }

  	if(nrow(res)==0){
      showNotification("NO GENES WITH DEGREE CUTOFF", type = 'error')
      return()
    }

    k = sort(unique(res[which(duplicated(res['gene'])),'gene']))

  	if(length(k)==0){
      showNotification("NO HUBS WITH DEGREE CUTOFF", type = 'error')
      return()
    }

    kk = c()

    for(i in 1:length(k)){ kk = c(kk, which(res['gene']==k[i]))  }

    output$HUB_TABLE = renderTable(res[kk,])
  })

}

shinyApp(ui = ui(), server = server)
GScluster/application documentation built on May 18, 2019, 2:37 a.m.