Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update user docs #364

Merged
merged 2 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions NF.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -2061,7 +2061,7 @@
"@id" : "bts:centimeter"
} ],
"rdfs:label" : "workingDistanceUnit",
"rdfs:comment" : "TBD",
"rdfs:comment" : "Unit for working distance.",
"@type" : "rdfs:Class",
"sms:displayName" : "workingDistanceUnit"
}, {
Expand Down Expand Up @@ -2187,6 +2187,17 @@
"rdfs:comment" : "Technology used to perturb gene",
"@type" : "rdfs:Class",
"sms:displayName" : "genePerturbationTechnology"
}, {
"@id" : "bts:relatedResource",
"@type" : "rdfs:Class",
"rdfs:comment" : "A related resource.",
"rdfs:label" : "relatedResource",
"rdfs:subClassOf" : [ ],
"schema:isPartOf" : {
"@id" : "http://schema.biothings.io/"
},
"sms:displayName" : "relatedResource",
"sms:required" : "sms:false"
}, {
"@id" : "bts:specimenID",
"@type" : "rdfs:Class",
Expand Down Expand Up @@ -5029,7 +5040,7 @@
}, {
"@id" : "bts:relatedStudies",
"@type" : "rdfs:Class",
"rdfs:comment" : "Studies similar to the current study.",
"rdfs:comment" : "Studies similar to the current study. Subproperty of `relatedResource`.",
"rdfs:label" : "relatedStudies",
"rdfs:subClassOf" : [ ],
"schema:isPartOf" : {
Expand Down
83 changes: 55 additions & 28 deletions docs/docTemplate.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
read_properties <- function(file = "../modules/props.yaml") {
props <- yaml::read_yaml(file)$slots
# props <- rbindlist(props, fill = TRUE, idcol = "Property")
props
}

# The range of prop `assay` is anything of class `Assay` --
# However, the json-ld does not make this so conceptually concise for props, instead listing all possible values
# In the docs, we don't want to enumerate all values and instead want to create a _link_ to a class that defines the range
# To do this, we can infer class by look up the class of the first listed enum for that prop
# The range could also be inferred to be a boolean or string/integer rather than a class
summarize_range <- function(prop_id, schema, return_labels = FALSE) {

enums <- nfportalutils::get_by_prop_from_json_schema(id = prop_id,
prop = "schema:rangeIncludes",
schema = schema,
return_labels = FALSE)

# handle how enums are presented
if(is.null(enums)) return("")
if(length(enums) < 5) return(paste(gsub("bts:", "", enums), collapse = ","))
if("bts:Yes" %in% enums) return("Y/N")

enum1 <- enums[1]

# additional lookup class
class <- nfportalutils::get_by_prop_from_json_schema(enum1,
prop = "rdfs:subClassOf",
schema = schema,
return_labels = FALSE)[[1]]
if(length(class) > 1) warning(enum1, " has multiple parent classes")
class <- sub("bts:", "", class[1]) # use first but warn
class <- paste0("#", class)
class
}

#' @param prop_id Namespaced id, e.g. "bts:tumorType"
summarize_range_linkml <- function(prop_id, props) {
prop_id <- sub("^bts:", "", prop_id)

# union ranges
if(!is.null(props[[prop_id]]$any_of)) {
paste0("#", unlist(props[[prop_id]]$any_of, use.names = F), collapse = "|")

} else {
class <- props[[prop_id]]$range
if(is.null(range)) class <- ""
paste0("#", class)
}
}


#' Generate template documentation
#'
#' Basically tries to present a template in a conventional format similar to:
Expand Down Expand Up @@ -38,40 +90,15 @@ docTemplate <- function(templates,
schema = schema,
return_labels = FALSE)

# The range of prop `assay` is anything of class `Assay` --
# However, the json-ld does not make this so conceptually concise for props, instead listing all possible values
# In the docs, we don't want to enumerate all values and instead want to create a _link_ to a class that defines the range
# To do this, we can infer class by look up the class of the first listed enum for that prop
# The range could also be inferred to be a boolean or string/integer rather than a class
summarize_range <- function(prop_id, schema, return_labels = FALSE) {

enums <- nfportalutils::get_by_prop_from_json_schema(id = prop_id,
prop = "schema:rangeIncludes",
schema = schema,
return_labels = FALSE)
if(is.null(enums)) return("")
if(length(enums) < 5) return(paste(gsub("bts:", "", enums), collapse = ","))
if("bts:Yes" %in% enums) return("Y/N")
enum1 <- enums[1]
# additional lookup class
class <- nfportalutils::get_by_prop_from_json_schema(enum1,
prop = "rdfs:subClassOf",
schema = schema,
return_labels = FALSE)[[1]]
if(length(class) > 1) warning(enum1, " has multiple parent classes")
class <- sub("bts:", "", class[1]) # use first but warn
class <- paste0("#", class)
class
}

prop_ref <- read_properties()

# because of the way schematic imports biothings without us having much control over it some ids can be duplicated (!)
schema <- schema[!duplicated(sapply(schema, function(x) x$`@id`))]
sms <- Filter(function(x) x$`@id` %in% prop_ids, schema)
sms <- lapply(sms, function(x) {
list(Field = x$`sms:displayName`,
Description = if(!is.null(x$`rdfs:comment`)) x$`rdfs:comment` else " ",
Required = if(!is.null(x$`sms:required`)) sub("sms:", "", x$`sms:required`) else "?",
ValidRange = summarize_range(x$`@id`, schema))
ValidRange = summarize_range_linkml(prop_id = x$`@id`, props = prop_ref))
})
tt <- rbindlist(sms)

Expand Down
Loading