UNPKG

hra-api

Version:

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

1,087 lines (1,048 loc) 154 kB
// src/library/v1/queries/aggregate-results.rq var aggregate_results_default = 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX rdfs: <http://www.w3.o\ rg/2000/01/rdf-schema#>\nPREFIX ccf: <http://purl.org/ccf/>\nPREFIX DSGraphs: <https://purl.humanatlas.io/collection/ds-gr\ aphs>\nPREFIX DSGraphsExtra: <https://purl.humanatlas.io/graph/ds-graphs-enrichments>\nPREFIX HRA: <https://purl.humanatla\ s.io/collection/hra-api>\n\nCONSTRUCT {\n [] a ccf:AggregateResult ;\n rdfs:label "Consortia" ;\n ccf:count ?consort\ ium_count .\n [] a ccf:AggregateResult ;\n rdfs:label "Tissue Data Providers" ;\n ccf:count ?provider_count .\n []\ a ccf:AggregateResult ;\n rdfs:label "Donors" ;\n ccf:count ?donor_count .\n [] a ccf:AggregateResult ;\n rdfs\ :label "Organs" ;\n ccf:count ?organ_count .\n [] a ccf:AggregateResult ;\n rdfs:label "Extraction Sites" ;\n c\ cf:count ?rui_location_count .\n [] a ccf:AggregateResult ;\n rdfs:label "Tissue Blocks" ;\n ccf:count ?block_coun\ t .\n [] a ccf:AggregateResult ;\n rdfs:label "Tissue Sections" ;\n ccf:count ?section_count .\n [] a ccf:Aggregat\ eResult ;\n rdfs:label "Tissue Datasets" ;\n ccf:count ?dataset_count .\n}\nFROM DSGraphs:\nFROM NAMED DSGraphsExtra:\ \nWHERE {\n {\n SELECT \n (COUNT(DISTINCT ?donor) AS ?donor_count)\n (COUNT(DISTINCT ?organ) AS ?organ_count)\n \ (COUNT(DISTINCT ?consortium) AS ?consortium_count)\n (COUNT(DISTINCT ?provider) AS ?provider_count)\n (COUN\ T(DISTINCT ?block) AS ?block_count)\n (COUNT(DISTINCT ?rui_location) AS ?rui_location_count)\n (COUNT(DISTINCT ?\ section) AS ?section_count)\n (COUNT(DISTINCT ?dataset) AS ?dataset_count)\n WHERE {\n ?block ccf:comes_from ?\ donor ;\n ccf:has_registration_location ?rui_location .\n OPTIONAL {\n ?block ccf:subdivided_into_sectio\ ns ?section .\n }\n OPTIONAL {\n {\n ?block ccf:subdivided_into_sections ?section .\n ?sec\ tion ccf:generates_dataset ?dataset .\n }\n UNION {\n ?block ccf:generates_dataset ?dataset .\n \ }\n }\n OPTIONAL {\n GRAPH DSGraphsExtra: {\n ?rui_location ccf:collides_with ?organ .\n }\ \n GRAPH HRA: {\n ?refOrgan ccf:has_reference_organ ?refOrgan ;\n ccf:representation_of ?organ .\ \n }\n }\n OPTIONAL {\n ?donor ccf:consortium_name ?consortium .\n }\n OPTIONAL {\n ?d\ onor ccf:tissue_provider_name ?provider .\n }\n #{{FILTER}}\n }\n }\n}\n'; // src/library/v1/frames/basic.jsonld var basic_default = { "@context": "https://hubmapconsortium.github.io/ccf-ontology/ccf-context.jsonld" }; // 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 select(query, endpoint) { const resp = await fetchSparql(query, endpoint, "text/csv"); const text = await resp.text(); const { data } = Papa.parse(text, { header: true, skipEmptyLines: true, dynamicTyping: true }); return data || []; } 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; } } async function update(updateQuery, endpoint) { return fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/sparql-update" }, body: updateQuery }); } // src/library/shared/spatial/spatial-graph.js import { Euler, Matrix4, toDegrees, toRadians } from "@math.gl/core"; import { OrientedBoundingBox } from "@math.gl/culling"; import graphology from "graphology"; import reverse from "graphology-operators/reverse.js"; import shortestPath from "graphology-shortest-path/unweighted.js"; import { LRUCache } from "lru-cache"; import { v4 as uuidV4 } from "uuid"; // src/library/v1/queries/spatial-entity-dimensions.rq var spatial_entity_dimensions_default = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX ccf: <http://p\ url.org/ccf/>\n\nSELECT *\n#{{FROM}}\nWHERE {\n [] ccf:has_registration_location ?rui_location .\n ?rui_location\n rdf:typ\ e ccf:SpatialEntity ;\n ccf:x_dimension ?x ;\n ccf:y_dimension ?y ;\n ccf:z_dimension ?z ;\n ccf:dimension_unit \ ?units .\n}\n"; // src/library/v1/queries/spatial-placements-hra.rq var spatial_placements_hra_default = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX ccf: <http://purl\ .org/ccf/>\nPREFIX xsd:<http://www.w3.org/2001/XMLSchema#>\nPREFIX ccf1: <http://purl.org/ccf/latest/ccf.owl#>\nPREFIX HRAb\ ody: <https://purl.humanatlas.io/graph/hra-ccf-body#>\nPREFIX HRA: <https://purl.humanatlas.io/collection/hra-api>\n\nSELEC\ T DISTINCT ?source ?target \n ?x_scaling ?y_scaling ?z_scaling\n ?x_rotation ?y_rotation ?z_rotation\n ?x_translation ?y\ _translation ?z_translation ?translation_units\nFROM HRA:\nWHERE {\n []\n rdf:type ccf:SpatialPlacement ;\n ccf:placem\ ent_for ?source ;\n ccf:placement_relative_to ?target ;\n ccf:x_scaling ?_x_scaling ;\n ccf:y_scaling ?_y_scaling \ ;\n ccf:z_scaling ?_z_scaling ;\n ccf:x_rotation ?_x_rotation ;\n ccf:y_rotation ?_y_rotation ;\n ccf:z_rotation\ ?_z_rotation ;\n ccf:x_translation ?_x_translation ;\n ccf:y_translation ?_y_translation ;\n ccf:z_translation ?_\ z_translation ;\n ccf:translation_unit ?translation_units .\n\n FILTER(?target = ccf1:VHBothSexes || ?target = HRAbod\ y:VHBothSexes || \n !(?source IN (ccf1:VHFemale, ccf1:VHMale, HRAbody:VHFemale, HRAbody:VHMale)))\n\n BIND(xsd:deci\ mal(?_x_scaling) as ?x_scaling)\n BIND(xsd:decimal(?_y_scaling) as ?y_scaling)\n BIND(xsd:decimal(?_z_scaling) as ?z\ _scaling)\n\n BIND(xsd:decimal(?_x_rotation) as ?x_rotation)\n BIND(xsd:decimal(?_y_rotation) as ?y_rotation)\n BIN\ D(xsd:decimal(?_z_rotation) as ?z_rotation)\n\n BIND(xsd:decimal(?_x_translation) as ?x_translation)\n BIND(xsd:decim\ al(?_y_translation) as ?y_translation)\n BIND(xsd:decimal(?_z_translation) as ?z_translation)\n}\nORDER BY ?source"; // src/library/v1/queries/spatial-placements.rq var spatial_placements_default = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX ccf: <http://purl.org\ /ccf/>\nPREFIX xsd:<http://www.w3.org/2001/XMLSchema#>\nPREFIX ccf1: <http://purl.org/ccf/latest/ccf.owl#>\nPREFIX HRAbody:\ <https://purl.humanatlas.io/graph/hra-ccf-body#>\n\nSELECT ?source ?target \n ?x_scaling ?y_scaling ?z_scaling\n ?x_rotat\ ion ?y_rotation ?z_rotation\n ?x_translation ?y_translation ?z_translation ?translation_units\n#{{FROM}}\nWHERE {\n [] ccf\ :has_registration_location ?source .\n []\n rdf:type ccf:SpatialPlacement ;\n ccf:placement_for ?source ;\n ccf:pl\ acement_relative_to ?target ;\n ccf:x_scaling ?_x_scaling ;\n ccf:y_scaling ?_y_scaling ;\n ccf:z_scaling ?_z_scal\ ing ;\n ccf:x_rotation ?_x_rotation ;\n ccf:y_rotation ?_y_rotation ;\n ccf:z_rotation ?_z_rotation ;\n ccf:x_tr\ anslation ?_x_translation ;\n ccf:y_translation ?_y_translation ;\n ccf:z_translation ?_z_translation ;\n ccf:tran\ slation_unit ?translation_units .\n\n FILTER(?target = ccf1:VHBothSexes || ?target = HRAbody:VHBothSexes || \n !(?s\ ource IN (ccf1:VHFemale, ccf1:VHMale, HRAbody:VHFemale, HRAbody:VHMale)))\n\n BIND(xsd:decimal(?_x_scaling) as ?x_scali\ ng)\n BIND(xsd:decimal(?_y_scaling) as ?y_scaling)\n BIND(xsd:decimal(?_z_scaling) as ?z_scaling)\n\n BIND(xsd:deci\ mal(?_x_rotation) as ?x_rotation)\n BIND(xsd:decimal(?_y_rotation) as ?y_rotation)\n BIND(xsd:decimal(?_z_rotation) \ as ?z_rotation)\n\n BIND(xsd:decimal(?_x_translation) as ?x_translation)\n BIND(xsd:decimal(?_y_translation) as ?y_tr\ anslation)\n BIND(xsd:decimal(?_z_translation) as ?z_translation)\n}\n"; // 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(jsonld3, arrayFields = /* @__PURE__ */ new Set(), stringFields = new Set(DEFAULT_STRING_FIELDS)) { return JSON.parse(JSON.stringify(jsonld3), (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 ensureGraphArray(results) { if (results?.["@graph"]) { return results["@graph"]; } else if (results?.["@id"]) { delete results["@context"]; return [results]; } else { return []; } } // src/library/shared/spatial/spatial-graph.js var CACHED_GRAPH = new LRUCache({ max: 20, ttl: 1e3 * 60 * 60 * 8, // 8 hours ttlAutopurge: true }); async function getSpatialGraph(endpoint, useCache = false, token = void 0) { if (!useCache) { return new SpatialGraph(endpoint, token).initialize(); } else { if (!CACHED_GRAPH.has(token)) { const graph = getSpatialGraph(endpoint, false, token); CACHED_GRAPH.set(token, graph); return graph; } else { return CACHED_GRAPH.get(token); } } } function getScaleFactor(units) { switch (units) { case "centimeter": return 0.01; default: case "millimeter": return 1e-3; case "meter": return 1; } } var SpatialGraph = class { constructor(endpoint, token = void 0) { this.endpoint = endpoint; this.token = token; } async initialize() { const graph = this.graph = new graphology.DirectedGraph(); const from = this.token ? `FROM <urn:hra-api:${this.token}:ds-graph>` : ""; const [placements, hraPlacements, dimensions] = await Promise.all([ select(spatial_placements_default.replace("#{{FROM}}", from), this.endpoint), select(spatial_placements_hra_default, this.endpoint), select(spatial_entity_dimensions_default.replace("#{{FROM}}", from), this.endpoint) ]); for (const placement of placements.concat(hraPlacements)) { graph.mergeDirectedEdge(placement.source, placement.target, { placement }); } const halfSizeLookup = this.halfSizeLookup = {}; for (const { rui_location, x, y, z, units } of dimensions) { const factor = getScaleFactor(units) * 0.5; halfSizeLookup[rui_location] = [x, y, z].map((n) => Number(n) * factor); } return this; } getTransformationMatrix(sourceIRI, targetIRI) { if (sourceIRI === targetIRI) { return new Matrix4(Matrix4.IDENTITY); } if (!this.graph.hasNode(sourceIRI) || !this.graph.hasNode(targetIRI)) { return void 0; } const tx = new Matrix4(Matrix4.IDENTITY); const path = shortestPath.bidirectional(this.graph, sourceIRI, targetIRI); if (path && path.length > 0) { path.reverse(); let target = ""; for (const source of path) { if (target) { const placement = this.graph.getEdgeAttribute(source, target, "placement"); this.applySpatialPlacement(tx, placement); } target = source; } return tx; } else { return void 0; } } applySpatialPlacement(tx, placement) { const p = placement; const factor = getScaleFactor(p.translation_units); const T = [p.x_translation * factor, p.y_translation * factor, p.z_translation * factor]; const R = [p.x_rotation, p.y_rotation, p.z_rotation].map(toRadians); const S = [p.x_scaling, p.y_scaling, p.z_scaling]; return tx.translate(T).rotateXYZ(R).scale(S); } getSpatialPlacement(source, targetIri) { const sourceIri = this.graph.hasNode(source["@id"]) ? source["@id"] : void 0; const placement = ensureArray(source.placement)[0]; let matrix; if (placement && this.graph.hasNode(placement.target)) { matrix = this.getTransformationMatrix(placement.target, targetIri); if (matrix) { matrix = this.applySpatialPlacement(matrix, placement); } } else if (sourceIri) { matrix = this.getTransformationMatrix(sourceIri, targetIri); } if (matrix) { return this.matrixToSpatialPlacement(matrix, source["@id"], targetIri); } else { return void 0; } } matrixToSpatialPlacement(matrix, sourceIri, targetIri) { const euler = new Euler().fromRotationMatrix(matrix, Euler.XYZ); const T = matrix.getTranslation().map((n) => n * 1e3); const R = euler.toVector3().map(toDegrees); const S = matrix.getScale().map((n) => n < 1 && n > 0.999999 ? 1 : n); return { "@context": "https://hubmapconsortium.github.io/hubmap-ontology/ccf-context.jsonld", "@id": `http://purl.org/ccf/1.5/${uuidV4()}_placement`, "@type": "SpatialPlacement", source: sourceIri, target: targetIri, placement_date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0], x_scaling: S[0], y_scaling: S[1], z_scaling: S[2], scaling_units: "ratio", x_rotation: R[0], y_rotation: R[1], z_rotation: R[2], rotation_order: "XYZ", rotation_units: "degree", x_translation: T[0], y_translation: T[1], z_translation: T[2], translation_units: "millimeter" }; } getSpatialPlacementsToTarget(targetIri) { const graph = reverse(this.graph); const sources = shortestPath.singleSource(graph, targetIri); const results = []; for (const [sourceIri, path] of Object.entries(sources)) { if (sourceIri !== targetIri) { const tx = new Matrix4(Matrix4.IDENTITY); let target = ""; for (const source of path) { if (target) { const placement = graph.getEdgeAttribute(target, source, "placement"); this.applySpatialPlacement(tx, placement); } target = source; } results.push(this.matrixToSpatialPlacement(tx, sourceIri, targetIri)); } } return results; } get3DObjectTransform(_sourceIri, targetIri, objectRefIri) { let transform = this.getTransformationMatrix(objectRefIri, targetIri); if (transform) { transform = new Matrix4(Matrix4.IDENTITY).rotateX(toRadians(90)).multiplyLeft(transform); } return transform; } getExtractionSiteTransform(sourceIri, targetIri, bounds) { const transform = this.getTransformationMatrix(sourceIri, targetIri); if (transform) { if (bounds) { const factor = getScaleFactor(bounds.dimension_units) * 0.5; const scale = [bounds.x_dimension * factor, bounds.y_dimension * factor, bounds.z_dimension * factor]; transform.scale(scale); } } return transform; } getOrientedBoundingBox(sourceIri, targetIri) { const matrix = this.getTransformationMatrix(sourceIri, targetIri); const halfSize = this.halfSizeLookup[sourceIri]; if (matrix && halfSize) { const center = matrix.getTranslation(); if (center.findIndex(isNaN) === -1) { const quaternion = new Euler().fromRotationMatrix(matrix, Euler.XYZ).toQuaternion().normalize().calculateW(); return new OrientedBoundingBox().fromCenterHalfSizeQuaternion(center, halfSize, quaternion); } } return void 0; } probeExtractionSites(search, results = /* @__PURE__ */ new Set()) { const { x, y, z, radius, target } = search; const radiusSquared = radius / 1e3 * (radius / 1e3); const center = [x, y, z].map((n) => n / 1e3); for (const sourceIri of Object.keys(this.halfSizeLookup)) { const boundingBox = this.getOrientedBoundingBox(sourceIri, target); if (boundingBox) { const distanceSquared = boundingBox.distanceSquaredTo(center); if (distanceSquared <= radiusSquared) { results.add(sourceIri); } } } return results; } }; // src/library/v1/queries/base-subquery.rq var base_subquery_default = "PREFIX ccf: <http://purl.org/ccf/>\nPREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\nPRE\ FIX DSGraphs: <https://purl.humanatlas.io/collection/ds-graphs>\nPREFIX DSGraphsExtra: <https://purl.humanatlas.io/graph/\ ds-graphs-enrichments>\n\n#START-SUBQUERY\nSELECT DISTINCT ?donor ?block ?rui_location ?dataset ?section ?sectionDataset\nWH\ ERE {\n GRAPH DSGraphs: {\n ?block ccf:comes_from ?donor ;\n ccf:has_registration_location ?rui_location .\n OPT\ IONAL { #DATASETS\n ?block ccf:generates_dataset ?dataset .\n #{{DATASET_FILTER}}\n }\n OPTIONAL {\n ?bl\ ock ccf:subdivided_into_sections ?section .\n OPTIONAL { #SECTIONS\n ?section ccf:generates_dataset ?sectionDa\ taset .\n #{{SECTION_FILTER}}\n }\n }\n\n #{{FILTER}}\n }\n\n #hint:SubQuery hint:runOnce true;\n}\n"; // src/library/v1/utils/filter-sparql-query.js async function getFilterQuery(filter, endpoint) { const { ontologyTerms, cellTypeTerms, biomarkerTerms, ageRange, bmiRange, sex, technologies, tmc, consortiums, spatialSearches } = filter; const filters = { donor: [], rui_location: [], dataset: [], sectionDataset: [] }; if (sex && sex !== "Both") { filters.donor.push(` ?donor ccf:sex ?sex . FILTER(?sex = "${sex}")`); } if (ageRange) { filters.donor.push(` ?donor ccf:age ?age . FILTER (?age > ${ageRange[0]} && ?age < ${ageRange[1]})`); } if (bmiRange) { filters.donor.push(` ?donor ccf:bmi ?bmi . FILTER (?bmi > ${bmiRange[0]} && ?bmi < ${bmiRange[1]})`); } if (ontologyTerms?.length > 0) { const terms = ontologyTerms.map((s) => `<${s}>`).join(", "); filters.rui_location.push(` GRAPH DSGraphsExtra: { ?rui_location ccf:collides_with ?anatomical_structure . FILTER(?anatomical_structure IN (${terms})) }`); } if (cellTypeTerms?.length > 0) { const terms = cellTypeTerms.map((s) => `<${s}>`).join(", "); filters.rui_location.push(` GRAPH DSGraphsExtra: { ?rui_location ccf:collides_with_ct ?cell_type . FILTER(?cell_type IN (${terms})) }`); } if (biomarkerTerms?.length > 0) { const terms = biomarkerTerms.map((s) => `<${s}>`).join(", "); filters.rui_location.push(` GRAPH DSGraphsExtra: { ?rui_location ccf:collides_with_bm ?biomarker . FILTER(?biomarker IN (${terms})) }`); } if (tmc?.length > 0) { const providers = tmc.map((s) => `"${s}"`).join(", "); filters.donor.push(` ?donor ccf:tissue_provider_name ?provider . FILTER(?provider IN (${providers}))`); } if (technologies?.length > 0) { const technologiesString = technologies.map((s) => `"${s}"`).join(", "); filters.dataset.push(` ?dataset ccf:technology ?technology . FILTER(?technology IN (${technologiesString}) )`); filters.sectionDataset.push(` ?sectionDataset ccf:technology ?sectionTechnology . FILTER(?sectionTechnology IN (${technologiesString}))`); } if (consortiums?.length > 0) { const terms = consortiums.map((s) => `"${s}"`).join(", "); filters.donor.push(` ?donor ccf:consortium_name ?consortium . FILTER(?consortium IN (${terms}))`); } if (spatialSearches?.length > 0) { const spatialGraph = await getSpatialGraph(endpoint, true, filter.sessionToken); let results = /* @__PURE__ */ new Set(); for (const search of spatialSearches) { results = spatialGraph.probeExtractionSites(search, results); } if (results.size === 0) { filters.rui_location.push(` ?block ccf:has_registration_location ?rui_location . FILTER(?rui_location = <https://no-extraction-sites-found.com/>)`); } else { const sites = [...results].map((s) => `<${s}>`).join(", "); filters.rui_location.push(` ?block ccf:has_registration_location ?rui_location . FILTER(?rui_location IN (${sites}))`); } } if (Object.values(filters).filter((s) => s.length > 0).length > 0) { const entityQuery = base_subquery_default.slice(base_subquery_default.indexOf("#START-SUBQUERY")).replace("#{{FILTER\ }}", filters.donor.concat(filters.rui_location).join("\n")).replace("#{{DATASET_FILTER}}", filters.dataset.join("\n")).replace( "#{{SECTION_FILTER}}", filters.sectionDataset.join("\n")).replace("OPTIONAL { #DATASETS", filters.dataset.length === 0 ? "OPTIONAL {" : "{").replace("OPTIONAL { #SECTIONS", filters.sectionDataset.length === 0 ? "OPTIONAL {" : "{").replace( "#hint:SubQuery", "hint:SubQuery"); return `{ ${entityQuery} }`; } else { return ""; } } function setDatasetGraph(filter, query) { if (filter.sessionToken) { const token = filter.sessionToken; const dsGraph = `urn:hra-api:${token}:ds-graph`; const dsGraphEnrichments = `urn:hra-api:${token}:ds-graph-enrichments`; query = query.replace("PREFIX DSGraphs: <https://purl.humanatlas.io/collection/ds-graphs>", `PREFIX DSGraphs: <${dsGraph}\ >`).replace( "PREFIX DSGraphsExtra: <https://purl.humanatlas.io/graph/ds-graphs-enrichments>", `PREFIX DSGraphsExtra: <${dsGraphEnrichments}>` ); } return query; } async function filterSparqlQuery(sparqlQuery, filter = {}, endpoint = "https://lod.humanatlas.io/sparql") { const sparqlFilter = await getFilterQuery(filter, endpoint); const filteredQuery = setDatasetGraph(filter, sparqlQuery.replace("#{{FILTER}}", sparqlFilter)); return filteredQuery; } // src/library/v1/utils/execute-sparql.js async function executeFilteredQuery(query, filter, endpoint = "https://lod.humanatlas.io/sparql") { let filteredSparqlQuery; try { filteredSparqlQuery = await filterSparqlQuery(query, filter, endpoint); const results = await select(filteredSparqlQuery, endpoint); return results; } catch (error) { console.error("Error executing SELECT query:", error.message, error); if (filteredSparqlQuery) { console.log("\nBad SPARQL Query: \n", filteredSparqlQuery + "\n\n"); } } } async function executeFilteredConstructQuery(query, filter, frame = void 0, endpoint = "https://lod.humanatlas.io/sparql") { let filteredSparqlQuery; try { filteredSparqlQuery = await filterSparqlQuery(query, filter, endpoint); const results = await construct(filteredSparqlQuery, endpoint, frame); return results; } catch (error) { console.error("Error executing CONSTRUCT query:", error.message, error); if (filteredSparqlQuery) { console.log("\nBad SPARQL Query: \n", filteredSparqlQuery + "\n\n"); } } } // src/library/v1/operations/aggregate-results.js function reformatResponse(jsonld3) { return normalizeJsonLd(ensureGraphArray(jsonld3)).map(({ label, count }) => ({ label, count })); } async function getAggregateResults(filter, endpoint = "https://lod.humanatlas.io/sparql") { return reformatResponse(await executeFilteredConstructQuery(aggregate_results_default, filter, basic_default, endpoint)); } // src/library/v1/queries/anatomical-systems-tree-model.rq var anatomical_systems_tree_model_default = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX rdfs: <htt\ p://www.w3.org/2000/01/rdf-schema#>\nPREFIX ccf: <http://purl.org/ccf/>\nPREFIX body: <http://purl.obolibrary.org/obo/UBER\ ON_0013702>\nPREFIX hasExactSynonym: <http://www.geneontology.org/formats/oboInOwl#hasExactSynonym>\nPREFIX HRA: <https://\ purl.humanatlas.io/collection/hra-api>\n\nSELECT DISTINCT ?root ?child ?parent ?label ?synonymLabel\nFROM HRA:\nWHERE {\n BI\ ND(body: as ?root)\n\n {\n BIND(body: as ?child)\n }\n UNION\n {\n # Prioritize ASCT+B relationships from the anatomi\ cal-systems table\n SELECT (1 as ?rank) ?parent ?child\n WHERE {\n GRAPH <https://purl.humanatlas.io/asct-b/anat\ omical-systems> {\n ?child ccf:ccf_part_of ?parent .\n }\n }\n }\n UNION {\n VALUES (?parent ?child) {\n \ # Lymph Node\n (<http://purl.obolibrary.org/obo/UBERON_0000029> <http://purl.obolibrary.org/obo/UBERON_0002509>)\n\ # Eye\n (<http://purl.obolibrary.org/obo/UBERON_0000970> <http://purl.obolibrary.org/obo/UBERON_0004548>)\n \ (<http://purl.obolibrary.org/obo/UBERON_0000970> <http://purl.obolibrary.org/obo/UBERON_0004549>)\n # Fallopian Tu\ be\n (<http://purl.obolibrary.org/obo/UBERON_0003889> <http://purl.obolibrary.org/obo/UBERON_0001303>)\n (<http:\ //purl.obolibrary.org/obo/UBERON_0003889> <http://purl.obolibrary.org/obo/UBERON_0001302>)\n # Kidney\n (<http:/\ /purl.obolibrary.org/obo/UBERON_0002113> <http://purl.obolibrary.org/obo/UBERON_0004538>)\n (<http://purl.obolibrary\ .org/obo/UBERON_0002113> <http://purl.obolibrary.org/obo/UBERON_0004539>)\n # Knee\n (<http://purl.obolibrary.or\ g/obo/UBERON_0001465> <http://purl.org/sig/ont/fma/fma24978>)\n (<http://purl.obolibrary.org/obo/UBERON_0001465> <ht\ tp://purl.org/sig/ont/fma/fma24977>)\n # Mammary Gland\n (<http://purl.obolibrary.org/obo/UBERON_0001911> <http:\ //purl.org/sig/ont/fma/fma57991>)\n (<http://purl.obolibrary.org/obo/UBERON_0001911> <http://purl.org/sig/ont/fma/fm\ a57987>)\n # Ovary\n (<http://purl.obolibrary.org/obo/UBERON_0000992> <http://purl.obolibrary.org/obo/UBERON_000\ 2119>)\n (<http://purl.obolibrary.org/obo/UBERON_0000992> <http://purl.obolibrary.org/obo/UBERON_0002118>)\n # P\ alatine Tonsil\n (<http://purl.obolibrary.org/obo/UBERON_0002373> <http://purl.org/sig/ont/fma/fma54974>)\n (<ht\ tp://purl.obolibrary.org/obo/UBERON_0002373> <http://purl.org/sig/ont/fma/fma54973>)\n # Renal Pelvis\n (<http:/\ /purl.obolibrary.org/obo/UBERON_0001224> <http://purl.obolibrary.org/obo/UBERON_0018116>)\n (<http://purl.obolibrary\ .org/obo/UBERON_0001224> <http://purl.obolibrary.org/obo/UBERON_0018115>)\n # Ureter\n (<http://purl.obolibrary.\ org/obo/UBERON_0000056> <http://purl.obolibrary.org/obo/UBERON_0001223>)\n (<http://purl.obolibrary.org/obo/UBERON_0\ 000056> <http://purl.obolibrary.org/obo/UBERON_0001222>)\n }\n }\n UNION\n {\n ?child ccf:ccf_part_of ?parent .\n \ FILTER(?parent != body:)\n }\n \n ?child ccf:ccf_pref_label ?label1 .\n OPTIONAL {\n {\n ?child hasExactSynonym: ?\ synonymLabel1 .\n }\n UNION\n {\n ?child rdfs:label ?synonymLabel1 .\n }\n }\n\n BIND(IF(?child = ?root, 'bod\ y', STR(LCASE(?label1))) as ?label)\n BIND(STR(?synonymLabel1) as ?synonymLabel)\n BIND(IF(BOUND(?rank), ?rank, 1000) as\ ?rank_order)\n}\nORDER BY ?rank_order ?label ?child\n"; // src/library/v1/utils/format-tree-model.js function formatTreeModel(data) { const root = data[0]?.root; const nodes = {}; for (const { child, parent, label, synonymLabel } of data) { const node = nodes[child] = nodes[child] || { "@id": child, "@type": "OntologyTreeNode", id: child, parent, children: [], synonymLabels: /* @__PURE__ */ new Set(), label: /* @__PURE__ */ new Set() }; if (child === parent) { node.parent = ""; } if (label) { node.label.add(label.trim()); } if (synonymLabel) { node.synonymLabels.add(synonymLabel.trim()); } } for (const node of Object.values(nodes)) { const parent = nodes[node.parent]; if (parent) { parent.children.push(node["@id"]); } const labels = Array.from(node.label).sort(); node.label = labels[0]; if (labels.length > 1) { labels.slice(1).forEach((l) => node.synonymLabels.add(l)); } node.synonymLabels = Array.from(node.synonymLabels).filter((l) => l != node.label); } const tree = { root, nodes }; treeify(tree); return tree; } function treeify(model, nodeIri = void 0, seen = /* @__PURE__ */ new Set()) { const node = model.nodes[nodeIri ?? model.root]; if (node) { node.children = node.children.filter((n) => !seen.has(n)); node.children.forEach((n) => seen.add(n)); for (const childId of node.children) { treeify(model, childId, seen); if (model.nodes[childId]) { model.nodes[childId].parent = node["@id"]; } } } } // src/library/v1/operations/anatomical-systems-tree-model.js async function getAnatomicalSystemsTreeModel(filter, endpoint = "https://lod.humanatlas.io/sparql") { return formatTreeModel(await executeFilteredQuery(anatomical_systems_tree_model_default, filter, endpoint)); } // src/library/v1/operations/asctb-omap-sheet-config.js import Papa2 from "papaparse"; // src/library/v1/queries/asctb-omap-sheet-config-data.rq var asctb_omap_sheet_config_data_default = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\nPREFIX dcat: <http://ww\ w.w3.org/ns/dcat#>\nPREFIX prov: <http://www.w3.org/ns/prov#>\nPREFIX schema: <http://schema.org/>\nPREFIX ccf: <http://pur\ l.org/ccf/>\nPREFIX uberon: <http://purl.obolibrary.org/obo/UBERON_>\nPREFIX LOD: <https://lod.humanatlas.io>\nPREFIX HRA: \ <https://purl.humanatlas.io/collection/hra>\n\nSELECT ?purl ?name ?version ?hraVersion ?representation_of ?organName ?csvU\ rl ?xslxUrl ?tissuePreservationMethod ?imagingMethod\nWHERE {\n GRAPH LOD: {\n ?lodPurl a dcat:Dataset ;\n schema:n\ ame ?name ;\n schema:additionalType ?type ;\n schema:version ?version ;\n prov:wasDerivedFrom [\n dcat\ :distribution [\n dcat:mediaType ?mediaType ;\n dcat:downloadURL ?csvUrl ;\n ] ;\n ] ;\n r\ dfs:seeAlso ?purl ;\n .\n FILTER(?type = 'omap' && !CONTAINS(?name, '-crosswalk') && ?mediaType = 'text/csv')\n BI\ ND(IRI(STRBEFORE(STR(?purl), CONCAT('/', ?version))) as ?purlNoVersion)\n }\n\n GRAPH LOD: {\n [] a dcat:Dataset ;\n \ schema:name ?hraName ;\n schema:additionalType ?hraType ;\n schema:version ?hraVersion ;\n prov:hadMember \ ?purlStr .\n\n FILTER(?hraName = 'hra' && ?hraType = 'collection' && CONTAINS(STR(?purlStr), '/omap/'))\n BIND(IR\ I(STR(?purlStr)) as ?purl)\n }\n\n GRAPH HRA: {\n # <https://purl.humanatlas.io/omap/20-kidney-ims-cycif/v1.0#OMAP-20>\n\ ?row1 a ccf:MultiplexedAntibodyBasedImagingExperiment ;\n ccf:sample_organ ?term ;\n ccf:tissue_preservation\ ?tissuePreservationMethod ;\n ccf:study_method ?imagingMethod ;\n .\n ?term rdfs:label ?organName .\n BIND(RE\ PLACE(STR(?term), STR(uberon:), 'UBERON:') as ?representation_of)\n BIND(IRI(CONCAT('https://purl.humanatlas.io/omap/'\ , STRBEFORE(STRAFTER(STR(?row1), 'https://purl.humanatlas.io/omap/'), '/'))) as ?purlNoVersion)\n }\n}\nORDER BY ?name DES\ C(?version) ?hraVersion\n"; // src/library/v1/operations/asctb-omap-sheet-config.js var OMAP_COUNT_LOOKUP = "https://humanatlas.io/assets/table-data/omaps_release8.csv"; function reformatResponse2(publishedData, countLookupData) { const results = {}; const countLookup = Object.fromEntries(countLookupData.map((row) => [row.omapId, row])); for (const { purl, name, organName, version, hraVersion, representation_of, csvUrl, tissuePreservationMethod, imagingMethod } of publishedData) { let tableInfo = results[name]; if (!tableInfo) { tableInfo = results[name] = { omapId: `OMAP-${name.split("-")[0]}`, name: toTitleCase(organName), display: toTitleCase(organName), tissuePreservationMethod, imagingMethod, config: { bimodal_distance_x: 250, bimodal_distance_y: 60, width: 700, height: 2250 }, uberon_id: representation_of, version: [] }; } let versionInfo = tableInfo.version.find((ver) => ver.viewValue === version); if (!versionInfo) { const counts = countLookup[tableInfo.omapId] || { as: 0, ct: 0, bp: 0 }; versionInfo = { viewValue: version, hraVersion: "", value: `${name}-${version}`, csvUrl, xlsx: csvUrl.replace(/\.csv$/, ".xlsx"), as: counts.as, ct: counts.ct, bp: counts.bp, sheetId: "", gid: "", url: purl }; tableInfo.version.unshift(versionInfo); } if (!versionInfo.hraVersion) { versionInfo.hraVersion = hraVersion; } else { versionInfo.hraVersion += `,${hraVersion}`; } } return Object.values(results); } function toTitleCase(str) { return str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()); } async function fetchSheet(csvUrl) { const resp = await fetch(csvUrl); const text = await resp.text(); const { data } = Papa2.parse(text, { header: true, skipEmptyLines: true, dynamicTyping: true }); return data || []; } async function getASCTBOmapSheetConfig(filter, endpoint = "https://lod.humanatlas.io/sparql") { const [publishedData, countLookupData] = await Promise.all([ executeFilteredQuery(asctb_omap_sheet_config_data_default, filter, endpoint), fetchSheet(OMAP_COUNT_LOOKUP) ]); return reformatResponse2(publishedData, countLookupData); } // src/library/v1/operations/asctb-sheet-config.js import Papa3 from "papaparse"; // src/library/v1/queries/asctb-sheet-config-data.rq var asctb_sheet_config_data_default = "PREFIX dcat: <http://www.w3.org/ns/dcat#>\nPREFIX prov: <http://www.w3.org/ns/prov\ #>\nPREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\nPREFIX schema: <http://schema.org/>\nPREFIX ccf: <http://purl.org\ /ccf/>\nPREFIX uberon: <http://purl.obolibrary.org/obo/UBERON_>\nPREFIX LOD: <https://lod.humanatlas.io>\nPREFIX HRA: <http\ s://purl.humanatlas.io/collection/hra>\n\nSELECT ?purl ?name ?version ?hraVersion ?representation_of ?csvUrl\nWHERE {\n GRA\ PH LOD: {\n ?lodPurl a dcat:Dataset ;\n schema:name ?name ;\n schema:additionalType ?type ;\n schema:versi\ on ?version ;\n prov:wasDerivedFrom [\n dcat:distribution [\n dcat:mediaType ?mediaType ;\n dc\ at:downloadURL ?csvUrl ;\n ]\n ] ;\n rdfs:seeAlso ?purl ;\n .\n FILTER(?type = 'asct-b' && !CONTAINS(?\ name, '-crosswalk') && ?mediaType = 'text/csv')\n BIND(IRI(STRBEFORE(STR(?purl), CONCAT('/', ?version))) as ?purlNoVer\ sion)\n }\n\n GRAPH LOD: {\n [] a dcat:Dataset ;\n schema:name ?hraName ;\n schema:additionalType ?hraType ;\n \ schema:version ?hraVersion ;\n prov:hadMember ?purlStr .\n\n FILTER(?hraName = 'hra' && ?hraType = 'collectio\ n' && CONTAINS(STR(?purlStr), '/asct-b/'))\n BIND(IRI(STR(?purlStr)) as ?purl)\n }\n\n GRAPH HRA: {\n ?row1 a ccf:A\ sctbRecord ;\n ccf:anatomical_structure [\n ccf:source_concept ?term ;\n ccf:order_number 1 ;\n cc\ f:record_number 1 ;\n ] .\n BIND(REPLACE(STR(?term), STR(uberon:), 'UBERON:') as ?representation_of)\n BIND(IRI(\ CONCAT('https://purl.humanatlas.io/asct-b/', STRBEFORE(STRAFTER(STR(?row1), 'https://purl.humanatlas.io/asct-b/'), '/'))\ ) as ?purlNoVersion)\n }\n}\nORDER BY ?name DESC(?version) ?hraVersion\n"; // src/library/v1/operations/asctb-sheet-config.js var DRAFTS_SHEET_ID = "1ER90abGCF84MVdIFl51KEawfuuM5YhUbLCgt2i50nHg"; function reformatResponse3(publishedData, draftData) { const hraVersions = Array.from(new Set(publishedData.map((s) => s.hraVersion))).sort(); const results = { all: { name: "all", display: "All by CCF-HRA release", title: "Organs", body: "Body", sheetId: "1tK916JyG5ZSXW_cXfsyZnzXfjyoN-8B2GXLbYD6_vF0", gid: "", config: { bimodal_distance_x: 350, bimodal_distance_y: 60, width: 700, height: 5e3 }, representation_of: [], version: hraVersions.map((hraVersion) => ({ value: `All_Organs-${hraVersion}`, viewValue: hraVersion, hraVersion })) }, example: { name: "example", display: "Example", sheetId: "0", gid: "0", config: { bimodal_distance_x: 200, bimodal_distance_y: 50, width: 500, height: 500 }, title: "Anatomical Structures", data: "" }, some: { name: "some", display: "Selected Organs", body: "Body", sheetId: "1tK916JyG5ZSXW_cXfsyZnzXfjyoN-8B2GXLbYD6_vF0", gid: "", config: { bimodal_distance_x: 350, bimodal_distance_y: 60, width: 700, height: 5e3 }, representation_of: [], title: "Organs" } }; for (const { folder: name, filename: value, file_id: sheetId } of draftData) { const [doName, doVersion, _draft] = value?.split("_"); results[doName] = { name, display: name.replace(/\_/g, " "), config: { bimodal_distance_x: 250, bimodal_distance_y: 60, width: 700, height: 2250 }, representation_of: [], title: "Anatomical Structures", data: "", version: [ { sheetId, gid: "0", value, viewValue: doVersion + " DRAFT", link: `https://docs.google.com/spreadsheets/d/${sheetId}` } ] }; } for (const { purl, name, version, hraVersion, representation_of, csvUrl } of publishedData) { const tableInfo = results[name]; if (tableInfo) { if (!tableInfo.representation_of.includes(representation_of)) { tableInfo.representation_of.push(representation_of); } let versionInfo = tableInfo.version.find((ver) => ver.viewValue === version); if (!versionInfo) { versionInfo = { csvUrl, value: `${name}-${version}`, viewValue: version, hraVersion: "", link: purl }; tableInfo.version.unshift(versionInfo); } if (!versionInfo.hraVersion) { versionInfo.hraVersion = hraVersion; } else { versionInfo.hraVersion += `,${hraVersion}`; } } } return Object.values(results); } function googleSheetCsvUrl(sheetId, gid = void 0) { let url = `https://docs.google.com/spreadsheets/d/${sheetId}/export?format=csv`; if (gid !== void 0) { url += `?gid=${gid}`; } return url; } async function fetchSheet2(csvUrl) { const resp = await fetch(csvUrl); const text = await resp.text(); const { data } = Papa3.parse(text, { header: true, skipEmptyLines: true, dynamicTyping: true }); return data || []; } async function getASCTBSheetConfig(filter, endpoint = "https://lod.humanatlas.io/sparql") { const [publishedData, draftData] = await Promise.all([ executeFilteredQuery(asctb_sheet_config_data_default, filter, endpoint), fetchSheet2(googleSheetCsvUrl(DRAFTS_SHEET_ID)) ]); return reformatResponse3(publishedData, draftData); } // src/library/v1/queries/biomarker-term-occurences.rq var biomarker_term_occurences_default = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX rdfs: <http://\ www.w3.org/2000/01/rdf-schema#>\nPREFIX ccf: <http://purl.org/ccf/>\nPREFIX DSGraphs: <https://purl.humanatlas.io/collecti\ on/ds-graphs>\nPREFIX DSGraphsExtra: <https://purl.humanatlas.io/graph/ds-graphs-enrichments>\n\nCONSTRUCT {\n ?biomarker c\ cf:count ?count .\n}\nFROM DSGraphs:\nFROM NAMED DSGraphsExtra:\nWHERE {\n SELECT DISTINCT ?biomarker (COUNT(DISTINCT(?block\ )) AS ?count)\n WHERE {\n {\n GRAPH DSGraphsExtra: {\n ?rui_location ccf:collides_with_bm ?biomarker .\n \ }\n }\n UNION\n {\n BIND(ccf:Biomarker as ?biomarker)\n }\n\n ?block ccf:comes_from ?donor ;\n ccf:has\ _registration_location ?rui_location .\n OPTIONAL {\n ?block ccf:generates_dataset ?dataset .\n }\n OPTIONAL {\ \n ?block ccf:subdivided_into_sections ?section .\n OPTIONAL {\n ?section ccf:generates_dataset ?sectionDa\ taset .\n }\n }\n\n #{{FILTER}}\n }\n GROUP BY ?biomarker\n}\n"; // src/library/v1/utils/format-term-occurences.js function formatTermOccurences(dataJsonLd) { return normalizeJsonLd(ensureGraphArray(dataJsonLd)).reduce( (acc, row) => (acc[expandIri(row["@id"])] = row["count"], acc), {} ); } // src/library/v1/operations/biomarker-term-occurences.js function reformatResponse4(jsonld3) { const results = formatTermOccurences(jsonld3); results["biomarkers"] = results["http://purl.org/ccf/Biomarker"]; delete results["http://purl.org/ccf/Biomarker"]; return results; } async function getBiomarkerTermOccurences(filter, endpoint = "https://lod.humanatlas.io/sparql") { return reformatResponse4(await executeFilteredConstructQuery(biomarker_term_occurences_default, filter, basic_default, endpoint)); } // src/library/v1/queries/biomarker-tree-model.rq var biomarker_tree_model_default = `PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX ccf: <http://purl.org/ccf/> PREFIX hasExactSynonym: <http://www.geneontology.org/formats/oboInOwl#hasExactSynonym> PREFIX HRA: <https://purl.humanatlas.io/collection/hra-api> SELECT DISTINCT ?root ?child ?parent ?label ?synonymLabel FROM HRA: WHERE { BIND("biomarkers" as ?root) { BIND("biomarkers" as ?child) BIND("biomarkers" as ?parent) } UNION { ?child ccf:ccf_pref_label ?label1 . OPTIONAL { { ?child hasExactSynonym: ?synonymLabel1 . } UNION { ?child rdfs:label ?synonymLabel1 . } } ?child ccf:ccf_biomarker_type ?parent . BIND (?parent_label AS ?parent) } UNION { [] ccf:ccf_biomarker_type ?label1 . BIND (?label1 AS ?child) BIND ("biomarkers" AS ?parent) } BIND(IF(?child = ?root, 'Biomarkers', STR(?label1)) as ?label) BIND(STR(?synonymLabel1) as ?synonymLabel) FILTER(!CONTAINS(STR(?child), 'https://purl.humanatlas.io/asct-b/')) } ORDER BY ?label ?child `; // src/library/v1/operations/biomarker-tree-model.js async function getBiomarkerTreeModel(filter, endpoint = "https://lod.humanatlas.io/sparql") { return formatTreeModel(await executeFilteredQuery(biomarker_tree_model_default, filter, endpoint)); } // src/library/v1/queries/cell-type-term-occurences.rq var cell_type_term_occurences_default = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX rdfs: <http://\ www.w3.org/2000/01/rdf-schema#>\nPREFIX ccf: <http://purl.org/ccf/>\nPREFIX DSGraphs: <https://purl.humanatlas.io/collecti\ on/ds-graphs>\nPREFIX DSGraphsExtra: <https://purl.humanatlas.io/graph/ds-graphs-enrichments>\nPREFIX cell: <http://purl.o\ bolibrary.org/obo/CL_0000000>\n\nCONSTRUCT {\n ?cell_type ccf:count ?count .\n}\nFROM DSGraphs:\nFROM NAMED DSGraphsExtra:\nWH\ ERE {\n SELECT DISTINCT ?cell_type (COUNT(DISTINCT(?block)) AS ?count)\n WHERE {\n {\n GRAPH DSGraphsExtra: {\n \ ?rui_location ccf:collides_with_ct ?cell_type .\n }\n }\n UNION\n {\n BIND(cell: as ?cell_type)\n }\n\ \n ?block ccf:comes_from ?donor ;\n ccf:has_registration_location ?rui_location .\n OPTIONAL {\n ?block ccf:\ generates_dataset ?dataset .\n }\n OPTIONAL {\n ?block ccf:subdivided_into_sections ?section .\n OPTIONAL {\n\ ?section ccf:generates_dataset ?sectionDataset .\n }\n }\n \n #{{FILTER}}\n }\n GROUP BY ?cell_type\n}\n"; // src/library/v1/operations/cell-type-term-occurences.js async function getCellTypeTermOccurences(filter, endpoint = "https://lod.humanatlas.io/sparql") { return formatTermOccurences(await executeFilteredConstructQuery(cell_type_term_occurences_default, filter, basic_default, endpoint)); } // src/library/v1/queries/cell-type-tree-model.rq var cell_type_tree_model_default = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\nPREFIX rdfs: <http://www.w\ 3.org/2000/01/rdf-schema#>\nPREFIX ccf: <http://purl.org/ccf/>\nPREFIX cell: <http://purl.obolibrary.org/obo/CL_0000000>\nP\ REFIX hasExactSynonym: <http://www.geneontology.org/formats/oboInOwl#hasExactSynonym>\nPREFIX HRA: <https://purl.humanatl\ as.io/collection/hra-api>\n\nSELECT DISTINCT ?root ?child ?parent ?label ?synonymLabel\nFROM HRA:\nWHERE {\n BIND(cell: as ?\ root)\n\n {\n BIND(cell: as ?child)\n BIND(cell: as ?parent)\n }\n UNION\n {\n ?child ccf:ccf_ct_isa ?parent .\n }\n\ \n ?child ccf:ccf_pref_label ?label1 .\n OPTIONAL {\n {\n ?child hasExactSynonym: ?synonymLabel1 .\n }\n UNION\ \n {\n ?child rdfs:label ?synonymLabel1 .\n }\n }\n FILTER (!isBlank(?child) && !isBlank(?parent))\n\n BIND(IF(?c\ hild = ?root, 'cell', STR(LCASE(?label1))) as ?label)\n BIND(STR(?synonymLabel1) as ?synonymLabel)\n}\nORDER BY ?label ?ch\ ild\n"; // src/library/v1/operations/cell-type-tree-model.js async function getCellTypeTreeModel(filter, endpoint = "https://lod.humanatlas.io/sparql") { return formatTreeModel(await executeFilteredQuery(cell_type_tree_model_default, filter, endpoint)); } // src/library/v1/operations/collisions.js var DEFAULT_ENDPOINT = "https://apps.humanatlas.io/api/v1/collisions"; async function getCollisions(ruiLocation, endpoint = DEFAULT_ENDPOINT) { const resp = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(ruiLocation) }); if (resp.ok) { return await resp.json(); } else { return []; } } // src/library/v1/queries/consortium-names.rq var consortium_names_default = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\nPREFIX ccf: <http://purl.org/ccf/>\n\ PREFIX DSGraphs: <https://purl.humanatlas.io/collection/ds-graphs>\nPREFIX DSGraphsExtra: <https://purl.humanatlas.io/gra\ ph/ds-graphs-enrichments>\n\nSELECT DISTINCT ?consortium\nFROM DSGraphs:\nFROM NAMED DSGraphsExtra:\nWHERE {\n # V1 Routes do\ n't respect filters, so disabling them for now\n\n # ?block ccf:comes_from ?donor ;\n # ccf:has_registration_location ?\ rui_location .\n # OPTIONAL {\n # ?block ccf:generates_dataset ?dataset .\n # }\n # OPTIONAL {\n # ?block ccf:subdiv\ ided_into_sections ?section .\n # OPTIONAL {\n # ?section ccf:generates_dataset ?sectionDataset .\n # }\n # }\n\n \ ?donor ccf:consortium_name ?consortium .\n #{{FILTER}}\n}\nORDER BY ?consortium\n"; // src/library/v1/operations/consortium-names.js async function getConsortiumNames(filter, endpoint = "https://lod.humanatlas.io/sparql") { return (await executeFilteredQuery(consortium_names_default, filter, endpoint)).map((row) => row.consortium); } // src/library/v1/operations/corridor.js var DEFAULT_ENDPOINT2 = "https://apps.humanatlas.io/api/v1/corridor"; async function getCorridor(ruiLocation, endpoint = DEFAULT_ENDPOINT2) { const resp = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json", Accept: "model/gltf-binary" }, body: JSON.stringify(ruiLocation) }); if (resp.ok) { return await resp.arrayBuffer(); } else { return void 0; } } // src/library/shared/utils/add-to-endpoint.js import toNT from "@rdfjs/to-ntriples"; import stream from "stream-browserify"; function toTripleString(quad) { const subject = toNT(quad.subject).replace("_:_:", "_:"); const predicate = toNT(quad.predicate).replace("_:_:", "_:"); const object = toNT(quad.object).replace("_:_:", "_:"); return `${subject} ${predicate} ${object} . `; } function* sparqlUpdateIterator(graph, quads) { yield ` INSERT DATA { GRAPH <${graph}> { `; for (const quad of quads) { yield toTripleString(quad); } yield "}}\n"; } async function addToEndpoint(graph, quads, endpoint) { return fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/sparql-update" }, body: stream.Readable.from(sparqlUpdateIterator(graph, quads)) }); } // src/library/shared/utils/fetch-linked-data.js import formats from "@rdfjs/formats-common"; import { isReadableStream } from "is-stream"; import jsonld2 from "jsonld"; import patchResponse from "nodeify-fetch/lib/patchResponse.browser.js"; var EXTENSION_MAPPING = { "json-ld": "a