hra-api
Version:
The Human Reference Atlas (HRA) API deployed to https://apps.humanatlas.io/api/
1,087 lines (1,048 loc) • 154 kB
JavaScript
// 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