UNPKG

hra-api

Version:

The Human Reference Atlas (HRA) API deployed to https://apps.humanatlas.io/api/

333 lines (309 loc) 9.26 kB
// src/library/hra-kg/operations/digital-objects.js import { coerce, rsort } from "semver"; // src/library/shared/utils/sparql.js import jsonld from "jsonld"; import Papa from "papaparse"; jsonld.documentLoader = async (documentUrl) => { const document = await fetch(documentUrl).then((r) => r.json()); return { contextUrl: null, document, documentUrl }; }; function fetchSparql(query, endpoint, mimetype) { const body = new URLSearchParams({ query }); return fetch(endpoint, { method: "POST", headers: { Accept: mimetype, "Content-Type": "application/x-www-form-urlencoded", "Content-Length": body.toString().length.toString() }, body }); } async function construct(query, endpoint, frame = void 0) { const resp = await fetchSparql(query, endpoint, "application/ld+json"); const json = await resp.json(); if (frame) { return await jsonld.frame(json, frame); } else { return json; } } // src/library/v1/utils/jsonld-compat.js function expandIri(iri) { return iri && typeof iri === "string" ? iri.replace("ccf:", "http://purl.org/ccf/").replace("ccf1:", "http://purl.org/\ ccf/latest/ccf.owl#").replace("../sig/ont/fma/fma", "http://purl.org/sig/ont/fma/fma").replace("fma:", "http://purl.org/\ sig/ont/fma/fma").replace("http://purl.obolibrary.org/obo/FMA_", "http://purl.org/sig/ont/fma/fma") : iri; } var DEFAULT_STRING_FIELDS = ["creator", "creator_first_name", "creator_last_name"]; function normalizeJsonLd(jsonld2, arrayFields = /* @__PURE__ */ new Set(), stringFields = new Set(DEFAULT_STRING_FIELDS)) { return JSON.parse(JSON.stringify(jsonld2), (key, value) => { if (arrayFields.has(key)) { value = ensureArray(value); } if (stringFields.has(key)) { value = ensureString(value); } if (typeof value === "object" && value?.["@type"] && value["@value"] && (value["@type"].startsWith("xsd:") || value["\ @type"].startsWith("http://www.w3.org/2001/XMLSchema#"))) { switch (value["@type"]) { case "http://www.w3.org/2001/XMLSchema#integer": case "http://www.w3.org/2001/XMLSchema#double": case "http://www.w3.org/2001/XMLSchema#decimal": case "xsd:integer": case "xsd:double": case "xsd:decimal": return Number(value["@value"]); case "http://www.w3.org/2001/XMLSchema#date": case "xsd:date": return value["@value"]; default: return value; } } else if (Array.isArray(value)) { return value.map(expandIri); } else { return expandIri(value); } }); } function ensureString(value, arrayElementSeparator = "; ") { if (Array.isArray(value)) { return value.map(ensureString).join(arrayElementSeparator); } else if (value?.["@value"]) { return value["@value"]; } else { return value; } } function ensureArray(thing) { if (Array.isArray(thing)) { return thing; } else if (thing) { return [thing]; } else { return []; } } function ensureNumber(value) { if (value?.["@type"]) { return Number(value["@value"]); } else if (typeof value === "string") { return Number(value); } else { return value; } } function ensureGraphArray(results) { if (results?.["@graph"]) { return results["@graph"]; } else if (results?.["@id"]) { delete results["@context"]; return [results]; } else { return []; } } // src/library/hra-kg/frames/digital-objects.jsonld var digital_objects_default = { "@context": { dcat: "http://www.w3.org/ns/dcat#", dct: "http://purl.org/dc/terms/", schema: "http://schema.org/", ccf: "http://purl.org/ccf/", rdfs: "http://www.w3.org/2000/01/rdf-schema#", purl: { "@id": "rdfs:seeAlso", "@type": "@id" }, lod: { "@id": "dcat:last", "@type": "@id" }, title: "dct:title", doType: "schema:additionalType", doName: "schema:name", doVersion: "ccf:latestVersion", lastUpdated: "schema:dateCreated", versions: { "@id": "schema:version" }, datasets: { "@id": "dcat:dataset", "@type": "@id" }, cell_count: { "@id": "ccf:cell_count", "@type": "http://www.w3.org/2001/XMLSchema#integer" }, biomarker_count: { "@id": "ccf:biomarker_count", "@type": "http://www.w3.org/2001/XMLSchema#integer" }, organs: "ccf:organ", organIds: { "@id": "ccf:organ_id", "@type": "@id" } }, "@type": "dcat:Catalog" }; // src/library/hra-kg/queries/digital-objects.rq var digital_objects_default2 = `PREFIX ccf: <http://purl.org/ccf/> PREFIX dcat: <http://www.w3.org/ns/dcat#> PREFIX dct: <http://purl.org/dc/terms/> PREFIX hint: <http://www.bigdata.com/queryHints#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX prov: <http://www.w3.org/ns/prov#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX skos: <http://www.w3.org/2004/02/skos/core#> PREFIX schema: <http://schema.org/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX LOD: <https://lod.humanatlas.io> PREFIX HRA: <https://purl.humanatlas.io/collection/hra-api> PREFIX body: <http://purl.obolibrary.org/obo/UBERON_0013702> CONSTRUCT { ?lod a dcat:Catalog ; dcat:last ?latestLodPurl ; rdfs:seeAlso ?graphPurl ; dct:title ?title ; schema:additionalType ?doType ; schema:name ?doName ; ccf:latestVersion ?doVersion ; schema:version ?version ; schema:dateCreated ?lastUpdated ; dcat:dataset ?lodPurl ; ccf:organ ?organ ; ccf:organ_id ?organ_id ; ccf:cell_count ?unique_cells ; ccf:biomarker_count ?unique_biomarkers . } WHERE { hint:Query hint:optimizer "Runtime" . GRAPH LOD: { ?lod a dcat:Catalog ; dcat:dataset ?lodPurl . ?lodPurl a dcat:Dataset ; schema:version ?version ; rdfs:seeAlso ?graphPurlVersioned . BIND(IRI(STRBEFORE(STR(?graphPurlVersioned), CONCAT('/', ?version))) as ?graphPurl) } { SELECT DISTINCT * WHERE { GRAPH ?graphPurl { ?graphPurl rdfs:seeAlso ?latestLodPurl . } GRAPH LOD: { # organ, unique_cells, unique_biomarkers ?lod a dcat:Catalog ; dcat:dataset ?latestLodPurl . ?latestLodPurl schema:additionalType ?doType ; schema:name ?doName ; schema:version ?doVersion ; prov:wasDerivedFrom [ dct:title ?title ; schema:dateCreated ?lastUpdated ; ] . } } } OPTIONAL { SELECT DISTINCT ?graphPurl ?organ ?organ_id { { SELECT (SAMPLE(?organ) as ?organ) ?organ_id WHERE { GRAPH HRA: { ?refOrgan a ccf:SpatialEntity ; ccf:has_reference_organ ?refOrgan ; ccf:representation_of ?refOrganTerm . ?organ_id ccf:ccf_part_of body: . ?organ_id ccf:ccf_pref_label ?organ_label . ?refOrganTerm ccf:ccf_part_of* ?organ_id . FILTER(!CONTAINS(STR(?organ_label), ' system')) BIND(LCASE(?organ_label) as ?organ) } } GROUP BY ?organ_id ORDER BY ?organ } GRAPH ?graphPurl { ?graphPurl rdfs:seeAlso ?lodPurl . { ?organ_id ?pred1 [] . } UNION { [] ?pred2 ?organ_id . FILTER(isIRI(?organ_id)) } } } } OPTIONAL { SELECT ?graphPurl (COUNT(DISTINCT ?cell_id) as ?unique_cells) { GRAPH HRA: { ?cell_id ccf:ccf_asctb_type ?type . FILTER(?type = 'CT') } GRAPH ?graphPurl { ?graphPurl rdfs:seeAlso ?lodPurl . { ?cell_id ?pred1 [] . } UNION { [] ?pred2 ?cell_id . FILTER(isIRI(?cell_id)) } } } GROUP BY ?graphPurl } OPTIONAL { SELECT ?graphPurl (COUNT(DISTINCT ?biomarker) as ?unique_biomarkers) { GRAPH HRA: { ?biomarker ccf:ccf_asctb_type ?type . FILTER(?type = 'BM') } GRAPH ?graphPurl { ?graphPurl rdfs:seeAlso ?lodPurl . { ?biomarker ?pred1 [] . } UNION { [] ?pred2 ?biomarker . FILTER(isIRI(?biomarker)) } } } GROUP BY ?graphPurl } }`; // src/library/hra-kg/operations/digital-objects.js function reformatResponse(jsonld2) { const results = normalizeJsonLd(ensureGraphArray(jsonld2), /* @__PURE__ */ new Set(["versions", "organs", "organIds"])); for (const result of results) { result.versions = sortVersions(result.versions); results.cell_count = ensureNumber(results.cell_count) || 0; results.biomarker_count = ensureNumber(results.biomarker_count) || 0; } return { "@context": jsonld2["@context"], "@graph": results }; } async function getDigitalObjects(endpoint = "https://lod.humanatlas.io/sparql") { return reformatResponse(await construct(digital_objects_default2, endpoint, digital_objects_default)); } function sortVersions(versions) { return rsort( versions.map((version) => { const semver = coerce(version, true); semver.original = version; return semver; }) ).map((semver) => semver.original); } export { getDigitalObjects };