Skip to content

Commit

Permalink
Merge pull request #10 from EMSL-Computing/feature/map-upload
Browse files Browse the repository at this point in the history
Feature/map upload
  • Loading branch information
clabornd authored Apr 23, 2024
2 parents f7bd042 + 4b1f9dd commit 01be8fa
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 70 deletions.
15 changes: 7 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@ vignettes/*.pdf
tests/screenshots/*
!tests/screenshots/info.txt
tests/test_*/
#packrat
/packrat/*
#random
script_dump.R
packrat/lib*/
Data/
untracked_resources
cfg
# config and renv
cfg/*
!cfg/minio_config_example.yml
!cfg/minio_config_corems.yml
!cfg/minio_config_map.yml
renv
!renv/settings.json
#random
script_dump.R
Data/
untracked_resources
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: FREDA
Title: An app for the processing and visualization of Fourier-transform mass spectrometry data.
Version: 1.1.1
Version: 1.2.0
Authors@R: c(person("Lisa", "Bramer", "[email protected]", role = "aut", "cre"),
person("Daniel", "Claborne", "[email protected]", role = c("aut")))
Description: A frontend application which exposes functionality of the ftmsRanalysis R package. See
Expand Down
11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ APP_REGISTRY="docker.artifactory.pnnl.gov/mscviz/freda"
BASE_IMAGE_TAG="${APP_REGISTRY}/base:${BASE_VERSION}"
IMAGE_TAG="${APP_REGISTRY}:${TOP_VERSION}"
MAP_SHINYTEST=2
PROFILE=local
PROFILE=''
DO_BUILD=false

ifeq ($(DO_BUILD), true)
BUILD_TARGET=build_top
endif

.PHONY: build_base
build_base:
Expand All @@ -30,8 +35,8 @@ build_top:
build: build_base build_top

.PHONY: run
run:
docker compose up --build
run: ${BUILD_TARGET}
docker compose --profile ${PROFILE} up

.PHONY: login
login:
Expand Down
159 changes: 115 additions & 44 deletions Observers/startup_observers.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,93 @@ observe({

# establish minio connection if we are pulling cloud resources
if (any(names(query) %in% VALID_MINIO_HEADER_PARAMS)) {
cfg_location = if (Sys.getenv("MINIO_CONFIG_PATH") == "") "./cfg/minio_config.yml" else Sys.getenv("MINIO_CONFIG_PATH")
minio_con <<- mapDataAccess::map_data_connection(cfg_location)
isolate({
# store header params in a reactive variable
for (key in names(query)) {
header_params[[key]] <- query[[key]]
message(sprintf("INFO: stored parameter %s: %s", key, query[[key]]))
}

if ('corems-prefix' %in% names(query)) {
# get the appropriate minio config for retrieving CoreMS files
cfg_location = if (Sys.getenv("COREMS_MINIO_CONFIG_PATH") == "") "./cfg/minio_config_corems.yml" else Sys.getenv("COREMS_MINIO_CONFIG_PATH")
cms_minio_con <<- mapDataAccess::map_data_connection(cfg_location)

html(selector = "#loading-gray-overlay > div", html = "Loading Core-MS data...")

uris <- reticulate::iterate(
cms_minio_con$client$list_objects(
cms_minio_con$bucket,
prefix = header_params[['corems-prefix']],
recursive = TRUE),
function(x) x$object_name
)

if (length(uris) > 0) {
corems_upload_success <- tryCatch({
fpaths <- lapply(uris, function(uri) {
mapDataAccess::get_file(
cms_minio_con, id = uri, filename = file.path(tempfile(), basename(uri)),
use_dir = FALSE
)
})

modalmessage <- store_corems(fpaths)
TRUE

}, error = function(e) {
modalmessage <<- div(sprintf(info_text[["COREMS_UPLOAD_ERROR"]], e))
FALSE
})
} else {
corems_upload_success <- FALSE
modalmessage <- div(info_text[["COREMS_UPLOAD_NOSAMPS"]])
}

if (corems_upload_success) {
# defined in srv_ui_elements/corems_UI.R
showModal(corems_upload_success_modal(modalmessage))
} else {
showNotification(
modalmessage,
duration = NULL,
type = "error"
)
}
} else if ('map-object' %in% names(query)) {
# get the appropriate minio config for retrieving CoreMS files
cfg_location = if (Sys.getenv("MAP_MINIO_CONFIG_PATH") == "") "./cfg/minio_config_map.yml" else Sys.getenv("MAP_MINIO_CONFIG_PATH")
map_minio_con <<- mapDataAccess::map_data_connection(cfg_location)

html(selector = "#loading-gray-overlay > div", html = "Loading data from MAP...")

ftms_obj <- tryCatch({
mapDataAccess::get_data(map_minio_con, header_params[['map-object']])
}, error = function(e) {
NULL
})

valid_obj_types = c("project omic")

if (!inherits(ftms_obj, valid_obj_types)) {
showNotification(
HTML(sprintf("Something went wrong retrieving your data from MAP. Your MAP object was not of the appropriate type. Please confirm that the object is of types: [%s]", valid_obj_types)),
duration = NULL,
type = "error"
)
} else {
# store in some reactive variable that e_data and e_meta....essentially check exists and use if so.
revals$map_project <- ftms_obj
}
}
})

} else if (length(names(query)) > 0) {
showNotification(
sprintf("No valid header parameters found in query string. Found parameters: (%s). Valid header parameters: (%s). Presenting manual upload dialog.", paste(names(query), collapse = ", "), paste(VALID_MINIO_HEADER_PARAMS, collapse = ", ")),
duration = NULL,
type = 'error'
)
}

on.exit({
Expand All @@ -15,49 +100,17 @@ observe({
})

isolate({
# store header params in a reactive variable
for (key in names(query)) {
header_params[[key]] <- query[[key]]
message(sprintf("INFO: stored parameter %s: %s", key, query[[key]]))
}

if ('corems-prefix' %in% names(query)) {
html(selector = "#loading-gray-overlay > div", html = "Loading Core-MS data...")

uris <- reticulate::iterate(
minio_con$client$list_objects(
minio_con$bucket,
prefix = header_params[['corems-prefix']],
recursive = TRUE),
function(x) x$object_name
)

if (length(uris) > 0) {
tryCatch({
fpaths <- lapply(uris, function(uri) {
mapDataAccess::get_file(
minio_con, id = uri, filename = file.path(tempfile(), basename(uri)),
use_dir = FALSE
)
})

modalmessage <- store_corems(fpaths)

}, error = function(e) {
modalmessage <<- div(sprintf(info_text[["COREMS_UPLOAD_ERROR"]], e))
})
} else {
modalmessage <- div(info_text[["COREMS_UPLOAD_NOSAMPS"]])
}

# defined in srv_ui_elements/corems_UI.R
showModal(corems_upload_success_modal(modalmessage))
}

# if we're not coming from minio, ask whether they have multiple CoreMS files to upload.
# if they don't automatically insert the Core
if (length(corems_revals[['combined_tables']]) == 0) {
# if we're not coming from minio (CoreMS files or MAP project object), ask whether they have multiple CoreMS files to upload or a single unified file.
if ((length(corems_revals[['combined_tables']]) == 0) && is.null(revals$map_project)) {
showModal(upload_type_modal())
} else if (!is.null(revals$map_project)) {
insertTab(
"top_page",
target = "Welcome",
tab = upload_tab(),
position = "after"
)
showModal(map_upload_modal())
} else {
insertTab(
"top_page",
Expand All @@ -81,6 +134,24 @@ upload_type_modal <- function() {
)
}

#' Modal which informs the user that a MAP object was uploaded correctly (or incorrectly)
map_upload_modal <- function() {
modalDialog(
title = "Data Uploaded from MAP",
tags$p("Your data has been uploaded from the Multi-Omics Analysis Portal. Your data will be pre-populated on the Upload tab"),
footer = tagList(
actionButton("map_modal_goto_upload", "Go to Upload tab"),
modalButton("Dismiss")
)
)
}

#' observer for above modal actionbutton
observeEvent(input$map_modal_goto_upload, {
updateTabsetPanel(inputId = "top_page", selected="Upload")
removeModal()
})

#' @details Insert the manual CoreMS upload tab
observeEvent(input$upload_type_modal_multiple, {
insertTab(
Expand Down
22 changes: 18 additions & 4 deletions Observers/upload_observers.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# MAP Upload. Disable the two file upload widgets if we've loaded data from MAP.
observeEvent(input$top_page, {
req(input$top_page == "Upload")

if (!is.null(revals$map_project)) {
edata_placeholder_content = revals$map_project$Data$e_data_filename
emeta_placeholder_content = revals$map_project$Data$e_meta_filename

mimic_fileinput_upload(id = "file_edata", progress_content="Uploaded from MAP", placeholder_content = edata_placeholder_content)
mimic_fileinput_upload(id = "file_emeta", progress_content="Uploaded from MAP", placeholder_content = emeta_placeholder_content)
}

})

# Main: Create peakData when upload button or preprocess button clicked
observeEvent(input$upload_click, {
# prevent multiple clicks
Expand Down Expand Up @@ -208,12 +222,12 @@ observeEvent(Edata(), {
})

# Files Selected?
observeEvent(c(input$top_page, input$file_edata, input$file_emeta), {
observeEvent(c(input$top_page, input$file_edata, input$file_emeta, revals$map_project), {
req(input$top_page == "Upload")
toggleCssClass("js_file_edata", "suggest-upload", is.null(input$file_edata))
toggleCssClass("js_file_emeta", "suggest-upload", is.null(input$file_emeta))
toggleCssClass("js_file_edata", "suggest-upload", is.null(input$file_edata) && is.null(revals$map_project))
toggleCssClass("js_file_emeta", "suggest-upload", is.null(input$file_emeta) && is.null(revals$map_project))

if (!is.null(input$file_edata) & !is.null(input$file_emeta)) {
if ((!is.null(input$file_edata) & !is.null(input$file_emeta)) || !is.null(revals$map_project)) {
revals$warningmessage_upload$upload <- NULL
}

Expand Down
14 changes: 10 additions & 4 deletions Reactive_Variables/upload_revals.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
Edata <- reactive({
# Handle scenario where we made edata from another source.
if (!is.null(revals$uploaded_data) & is.null(input$file_edata$datapath)) {
return(revals$uploaded_data$e_data %>%
dplyr::select(-dplyr::one_of(
ftmsRanalysis::getEDataColName(revals$uploaded_data)
)))
return(revals$uploaded_data$e_data)
}

# If we uploaded from a MAP file
if (!is.null(revals$map_project)) {
return(revals$map_project$Data$e_data)
}

# Error handling: Need file_edata path
req(input$file_edata$datapath)

Expand All @@ -28,6 +30,10 @@ edata_cnames <- reactive({

# Object: Get e_meta from file input
Emeta <- reactive({
# If we uploaded from a MAP file
if (!is.null(revals$map_project)) {
return(revals$map_project$Data$e_meta)
}
# Error handling: Need file_emeta to be valid
req(input$file_emeta$datapath)
# Load file
Expand Down
8 changes: 8 additions & 0 deletions cfg/minio_config_corems.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type: minio
endpoint: minio-freda:9000
access_key: minioadmin
secret_key: minioadmin
bucket: corems-freda
secure: False
python_venv: /venv
verbose: true
8 changes: 8 additions & 0 deletions cfg/minio_config_map.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type: minio
endpoint: minio-freda:9000
access_key: minioadmin
secret_key: minioadmin
bucket: map
secure: False
python_venv: /venv
verbose: true
9 changes: 6 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@
version: "3"
services:
freda:
profiles: ['']
image: "docker.artifactory.pnnl.gov/mscviz/freda:${TOP_VERSION:-latest}"
container_name: freda
ports:
- "${PORT:-3838}:3838"
volumes:
- "./cfg/minio_config_corems_docker.yml:/srv/shiny-server/FREDA/cfg/minio_config.yml"
- "${COREMS_MINIO_CONFIG_PATH:-./cfg/minio_config_corems.yml}:/srv/shiny-server/FREDA/cfg/minio_config_corems.yml"
- "${MAP_MINIO_CONFIG_PATH:-./cfg/minio_config_map.yml}:/srv/shiny-server/FREDA/cfg/minio_config_map.yml"
environment:
- RETICULATE_PYTHON=/venv/bin/python
minio:
profiles: ['', 'minio']
image: minio/minio
container_name: minio-freda
ports:
- "9002:9000"
- "9003:9001"
- "9000:9000"
- "9001:9001"
command: server --console-address ":9001" /data

networks:
Expand Down
2 changes: 1 addition & 1 deletion global.R
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ info_text = list(
)

# cloud/minio resources
VALID_MINIO_HEADER_PARAMS = c("corems-prefix")
VALID_MINIO_HEADER_PARAMS = c("corems-prefix", "map-object")

#' @SECTION Variables for selectors/inputs ##

Expand Down
Loading

0 comments on commit 01be8fa

Please sign in to comment.