In Synapse, a Submission is your entry to a challenge or evaluation queue. When you participate in a computational challenge or collaborative project, you submit your work (such as predictions, models, or analysis results) as a Submission to be evaluated and scored.
Before working with Submissions, it’s helpful to understand how they fit into Synapse:
When you submit an Entity to an Evaluation:
This tutorial covers two perspectives:
In this tutorial:
As a participant of a Synapse challenge, you will
As an organizer of a Synapse challenge, you will
library(synapser)
synLogin()
# REQUIRED: Set these to your actual Synapse IDs
# Do NOT leave these as NULL - the script will not work properly
EVALUATION_ID <- NULL # Replace with the evaluation queue ID you submitted to
ENTITY_ID <- NULL # Replace with the entity ID you want to submit
stopifnot(
"EVALUATION_ID must be set to the evaluation queue ID" = !is.null(EVALUATION_ID),
"ENTITY_ID must be set to the entity ID you want to submit" = !is.null(ENTITY_ID)
)
print(sprintf("Working with Evaluation: %s", EVALUATION_ID))
print(sprintf("Submitting Entity: %s", ENTITY_ID))# Create a new Submission object
submission <- Submission(
entity_id = ENTITY_ID, evaluation_id = EVALUATION_ID, name = "My Tutorial Submission"
)
# Submit the entity to the evaluation queue
submission <- submission |> synStore()
print("Submission created successfully!")
print(sprintf("Submission ID: %s", submission$id))
print(sprintf("Submitted Entity: %s", submission$entity_id))
print(sprintf("Evaluation: %s", submission$evaluation_id))
print(sprintf("Submission Name: %s", submission$name))
print(sprintf("Created On: %s", submission$created_on))
# Store the submission ID for later use
submission_id <- submission$id# Retrieve the submission we just created
retrieved_submission <- Submission(id = submission_id) |> synGet()
print("Retrieved submission:")
print(sprintf(" ID: %s", retrieved_submission$id))
print(sprintf(" Name: %s", retrieved_submission$name))
print(sprintf(" Entity ID: %s", retrieved_submission$entity_id))
print(sprintf(" Submitter: %s", retrieved_submission$submitter_alias))
print(sprintf(" Created On: %s", retrieved_submission$created_on))# Get all of your submissions for this evaluation
user_submissions <- as.list(Submission() |> synGetUserSubmissions(evaluation_id = EVALUATION_ID))
print(sprintf("Found %d submissions from the current user:", length(user_submissions)))
for (i in seq_along(user_submissions)) {
sub <- user_submissions[[i]]
print(sprintf(" %d. ID: %s, Name: %s, Created: %s", i, sub$id, sub$name, sub$created_on))
}# Fetch the status of our submission
status <- SubmissionStatus(id = submission_id) |> synGet()
print("Submission status details:")
print(sprintf(" Status: %s", status$status))
print(sprintf(" Modified On: %s", status$modified_on))
print(sprintf(" Can Cancel: %s", status$can_cancel))
print(sprintf(" Cancel Requested: %s", status$cancel_requested))
# Check if there are any submission annotations (scores, feedback, etc.)
annotations <- status$submission_annotations
if (length(annotations) > 0) {
print(" Submission Annotations:")
for (key in names(annotations)) {
print(sprintf(" %s: %s", key, paste(unlist(annotations[[key]]), collapse = ", ")))
}
} else {
print(" No submission annotations available")
}Only cancel a submission if it allows it. The cancellation code is commented out by default; uncomment it if you want to test this functionality.
# cancelled_submission = submission |> synCancel()
# print(sprintf("Submission %s has been requested for cancellation", cancelled_submission$id))
#
# # Check the updated status
# updated_status = SubmissionStatus(id = submission_id) |> synGet()
# print(sprintf("Cancel requested: %s", updated_status$cancel_requested))
print(sprintf("Your submission ID %s is ready for evaluation.", submission_id))
print("Check back later to see if the organizers have scored your submission.")library(synapser)
synLogin()
# REQUIRED: Set these to your actual Synapse IDs
# Do NOT leave these as NULL - the script will not work properly
EVALUATION_ID <- NULL # Replace with the evaluation queue ID you submitted to
SUBMISSION_ID <- NULL # Replace with the ID of a submission you made
stopifnot(
"EVALUATION_ID must be set to the evaluation queue ID" = !is.null(EVALUATION_ID),
"SUBMISSION_ID must be set to the ID of a submission you made" = !is.null(SUBMISSION_ID)
)
print(sprintf("Working with Evaluation: %s", EVALUATION_ID))
print(sprintf("Working with Submission: %s", SUBMISSION_ID))# First, get the submission status
status <- SubmissionStatus(id = SUBMISSION_ID) |> synGet()
print(sprintf("Retrieved submission status for submission %s", SUBMISSION_ID))
print(sprintf("Current status: %s", status$status))
# Update the submission status with scoring information
status$status <- "SCORED"
status$submission_annotations <- list(
accuracy = list(0.85),
precision = list(0.82),
feedback = list("Good performance!"),
validation_errors = "None detected",
score_errors = "None detected"
)
# Store the updated status
updated_status <- status |> synStore()
print("Successfully scored submission!")
print(sprintf("Status: %s", updated_status$status))
print("Annotations added:")
for (key in names(updated_status$submission_annotations)) {
print(sprintf(" %s: %s", key, paste(unlist(updated_status$submission_annotations[[key]]), collapse = ", ")))
}# First, get all submission statuses that need updating
statuses_to_update <- synGetAllSubmissionStatuses(
evaluation_id = EVALUATION_ID,
status = "RECEIVED" # Get submissions that haven't been scored yet
)
print(sprintf("Found %d submissions to batch update", length(statuses_to_update)))
if (length(statuses_to_update) > 0) {
# Update each status with validation information
for (i in seq_along(statuses_to_update)) {
status <- statuses_to_update[[i]]
status$status <- "VALIDATED"
status$submission_annotations <- list(
validation_status = list("PASSED"),
validation_timestamp = list("2024-11-24T10:30:00Z"),
batch_number = list(i),
validator = list("automated_system")
)
}
# Perform batch update
batch_response <- synBatchUpdateSubmissionStatuses(
evaluation_id = EVALUATION_ID,
statuses = statuses_to_update,
is_first_batch = TRUE,
is_last_batch = TRUE
)
print("Batch update completed successfully!")
print(batch_response)
} else {
print("No submissions found with 'RECEIVED' status to update")
}# Get all scored submission bundles for the evaluation
print("Fetching all submission bundles for the evaluation...")
bundles <- as.list(SubmissionBundle() |> synGetEvaluationSubmissionBundles(
evaluation_id = EVALUATION_ID,
status = "SCORED" # Only get scored submissions
))
print(sprintf("Found %d scored submission bundles", length(bundles)))
first_bundles <- head(bundles, 5) # Show first 5
for (i in seq_along(first_bundles)) {
submission <- first_bundles[[i]]$submission
status <- first_bundles[[i]]$submission_status
print(sprintf("Bundle %d:", i))
if (!is.null(submission)) {
print(sprintf(" Submission ID: %s", submission$id))
print(sprintf(" Submitter: %s", submission$submitter_alias))
print(sprintf(" Entity ID: %s", submission$entity_id))
print(sprintf(" Created: %s", submission$created_on))
}
if (!is.null(status)) {
print(sprintf(" Status: %s", status$status))
print(sprintf(" Modified: %s", status$modified_on))
annotations <- status$submission_annotations
if (length(annotations) > 0) {
print(" Scores:")
for (key in names(annotations)) {
if (key %in% c("accuracy", "f1_score", "precision", "recall")) {
print(sprintf(" %s: %s", key, paste(unlist(annotations[[key]]), collapse = ", ")))
}
}
}
}
}# First, check if any submissions have requested cancellation
all_statuses <- synGetAllSubmissionStatuses(evaluation_id = EVALUATION_ID)
cancellation_requests <- Filter(function(status) isTRUE(status$cancel_requested), all_statuses)
print(sprintf("Found %d submissions with cancellation requests", length(cancellation_requests)))
# Process cancellation requests
for (status in cancellation_requests) {
print(sprintf("Processing cancellation request for submission %s", status$id))
# Update to allow cancellation (organizer decision)
status$can_cancel <- TRUE
status$status <- "CLOSED"
# submission_annotations comes back as an R copy, so update the copy
# (adding or overwriting these keys) and assign it back
annotations <- as.list(status$submission_annotations)
annotations[c("cancellation_reason", "cancelled_by", "cancellation_date")] <- list(
list("User requested cancellation"),
list("organizer"),
list("2024-11-24")
)
status$submission_annotations <- annotations
# Store the update
updated_status <- status |> synStore()
print(sprintf(" Approved cancellation for submission %s", updated_status$id))
}
# Example: Proactively allow cancellation for a specific submission
print("Enabling cancellation for a specific submission...")
target_status <- SubmissionStatus(id = SUBMISSION_ID) |> synGet()
target_status$can_cancel <- TRUE
target_status <- target_status |> synStore()
print(sprintf("Cancellation enabled for submission %s", SUBMISSION_ID))Find the submissions whose submitters have requested cancellation, and delete them. The deletion code is commented out by default; uncomment it if you want to test this functionality.
# Get all submission statuses to check for cancellation requests
all_statuses <- synGetAllSubmissionStatuses(evaluation_id = EVALUATION_ID)
# Find submissions that have been requested for cancellation
submissions_to_delete <- list()
for (status in all_statuses) {
if (isTRUE(status$cancel_requested)) {
submissions_to_delete <- append(submissions_to_delete, status$id)
}
}
print(sprintf("Found %d submissions with cancellation requests", length(submissions_to_delete)))
# Delete each submission that was requested for cancellation
for (submission_id in submissions_to_delete) {
submission <- Submission(id = submission_id) |> synGet()
submission |> synDelete()
print(sprintf("Successfully deleted submission %s", submission_id))
}
if (length(submissions_to_delete) > 0) {
print(sprintf("Completed deletion of %d requested submissions", length(submissions_to_delete)))
}