From 4f422f205c8695cecfb2caba5098311bcf7da7dc Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Wed, 6 Mar 2024 16:21:49 +0100 Subject: [PATCH] dispatching different queries for different techniques --- apps/nar-v3/src/datastore.js | 1 + apps/nar-v3/src/routes/dataset.jsx | 235 ++------------------- apps/nar-v3/src/routes/datasets.jsx | 25 +-- apps/nar-v3/src/routes/queryLibrary.js | 273 +++++++++++++++++++++++++ 4 files changed, 290 insertions(+), 244 deletions(-) create mode 100644 apps/nar-v3/src/routes/queryLibrary.js diff --git a/apps/nar-v3/src/datastore.js b/apps/nar-v3/src/datastore.js index 96f7e7a..1a85f3b 100644 --- a/apps/nar-v3/src/datastore.js +++ b/apps/nar-v3/src/datastore.js @@ -26,6 +26,7 @@ class DataStore { this.cache = { "datasets summary": {}, "datasets detail": {}, + "datasets techniques": {}, "patch clamp recordings summary": {}, "patch clamp recordings detail": {}, }; diff --git a/apps/nar-v3/src/routes/dataset.jsx b/apps/nar-v3/src/routes/dataset.jsx index 5307559..9e3852c 100644 --- a/apps/nar-v3/src/routes/dataset.jsx +++ b/apps/nar-v3/src/routes/dataset.jsx @@ -1,235 +1,28 @@ import React from "react"; import { Await, defer, useLoaderData } from "react-router-dom"; -import { - buildKGQuery, - simpleProperty as S, - linkProperty as L, - reverseLinkProperty as R, -} from "../queries"; import { datastore } from "../datastore"; import { uuidFromUri } from "../utility.js"; import Navigation from "../components/Navigation"; import DatasetCard from "../components/DatasetCard"; import ProgressIndicator from "../components/ProgressIndicator"; -const MULTIPLE = { expectSingle: false }; - -const actorQuery = [ - S("@id"), - S("@type"), - S("givenName"), - S("familyName"), - S("fullName"), - S("shortName"), -]; - -const quantValQuery = [ - S("value"), - S("minValue"), - S("maxValue"), - L("unit/name"), - L("minValueUnit/name"), - L("maxValueUnit/name"), -]; - -const solutionQuery = [ - S("name"), - S("@id"), - L( - "hasPart", - [L("amount", quantValQuery), L("chemicalProduct", [S("name"), S("@id"), S("@type")])], - MULTIPLE - ), -]; - -const deviceQuery = L("device", [ - S("lookupLabel"), - S("name"), - S("@type"), - S("internalIdentifier"), - S("description"), - L("deviceType/name"), - L("manufacturer", [S("shortName", S("longName"))]), -]); - -const query = buildKGQuery("core/DatasetVersion", [ - S("@id"), - S("fullName"), - S("description"), - S("shortName"), - S("versionIdentifier"), - L("ethicsAssessment/name"), - L("license/shortName"), - S("releaseDate"), - L("technique/name", [], MULTIPLE), - L("custodian", actorQuery, MULTIPLE), - L("author", actorQuery, MULTIPLE), - R("isVersionOf", "hasVersion", [ - S("fullName"), - S("description"), - S("shortName"), - L("custodian", actorQuery, MULTIPLE), - L("author", actorQuery, MULTIPLE), - ]), - L( - "studiedSpecimen", - [ - S("lookupLabel"), - L("species", [S("name"), L("species/name")]), - L("biologicalSex/name"), - L( - "studiedState", - [ - S("lookupLabel"), - L("age", quantValQuery), - L("ageCategory/name"), - L("pathology", [S("name")], MULTIPLE), - R( - "slicePreparation", - "input", - [ - // slice preparation - S("lookupLabel"), - S("@type"), - L( - "device", - [ - // device usage - S("lookupLabel"), - deviceQuery, - L("sliceThickness", quantValQuery), - L("slicingPlane/name"), - ], - MULTIPLE - ), - L("studyTarget/name", [], MULTIPLE), - L("temperature", [S("value"), L("unit/name")]), - L("tissueBathSolution", solutionQuery), - L( - "output", - [ - // slices - S("lookupLabel"), - S("internalIdentifier"), - R("slice", "studiedState", [ - S("lookupLabel"), - S("@type"), - S("internalIdentifier"), - L("anatomicalLocation", [S("name"), S("@type")], MULTIPLE), - L("type/name"), - ]), - R( - "cellPatching", - "input", - [ - S("lookupLabel"), - S("@type"), - L( - "device", - [ - // device usage - S("lookupLabel"), - deviceQuery, - L("pipetteSolution", solutionQuery), - L("sealResistance", [L("value", quantValQuery, MULTIPLE)]), - L("seriesResistance", [L("value", quantValQuery, MULTIPLE)]), - L("holdingPotential", [L("value", quantValQuery, MULTIPLE)]), - ], - MULTIPLE - ), - L("tissueBathSolution", solutionQuery), - L("bathTemperature", quantValQuery), - S("description"), - L("variation/name"), - L( - "output", - [ - // patched cells - S("lookupLabel"), - S("@type"), - R("cell", "studiedState", [ - S("internalIdentifier"), - L("anatomicalLocation", [S("name"), S("@type")], MULTIPLE), - L("type/name"), - ]), - R( - "recordingActivity", - "input", - [ - S("lookupLabel"), - S("@type"), - S("description"), - S("internalIdentifier"), - L("device", [ - R("metadata", "recordedWith", [ - S("name"), - S("additionalRemarks"), - L("samplingFrequency", quantValQuery), - L("channel", [S("internalIdentifier"), L("unit/name")], MULTIPLE), - ]), - ]), - L( - "output", - [ - S("@id"), - S("name"), - S("IRI"), - S("dataType/name"), - S("format/name"), - L("hash", [S("algorithm"), S("digest")], MULTIPLE), - L("storageSize", [S("value"), L("unit/name")]), - ], - MULTIPLE - ), - ], - { type: "ephys/RecordingActivity", expectSingle: false } - ), - R( - "stimulationActivity", - "input", - [ - S("lookupLabel"), - S("@type"), - L( - "stimulus", - [ - S("lookupLabel"), - S("@type"), - S("description"), - L("epoch", quantValQuery), - S("internalIdentifier"), - L("specification", [S("lookupLabel"), S("configuration")]), - ], - MULTIPLE - ), - ], - { - type: "stimulation/StimulationActivity", - expectSingle: false, - } - ), - ], - MULTIPLE - ), - ], - MULTIPLE - ), - ], - MULTIPLE - ), - ], - MULTIPLE - ), - ], - MULTIPLE - ), - ], - { type: "core/Subject", expectSingle: false } - ), -]); +import { basicDatasetQuery, patchClampDatasetQuery, techniquesQuery } from "./queryLibrary"; export async function loader({ params }) { + const techniques = await datastore.getKGItem( + "datasets techniques", + techniquesQuery, + params.datasetId + ); + console.log(techniques); + let query = basicDatasetQuery; + if (techniques.includes("whole cell patch clamp")) { + console.log("Using patch clamp dataset query"); + query = patchClampDatasetQuery; + } else { + console.log("Using basic dataset query"); + } const datasetPromise = datastore.getKGItem("datasets detail", query, params.datasetId); console.log(datasetPromise); return defer({ dataset: datasetPromise }); diff --git a/apps/nar-v3/src/routes/datasets.jsx b/apps/nar-v3/src/routes/datasets.jsx index 3c4ae3a..5eaa795 100644 --- a/apps/nar-v3/src/routes/datasets.jsx +++ b/apps/nar-v3/src/routes/datasets.jsx @@ -1,35 +1,14 @@ import React from "react"; import { Await, defer, useLoaderData } from "react-router-dom"; -import { - buildKGQuery, - simpleProperty as S, - linkProperty as L, - reverseLinkProperty as R, -} from "../queries"; import { datastore } from "../datastore"; import Navigation from "../components/Navigation"; import DatasetList from "../components/DatasetList"; import ProgressIndicator from "../components/ProgressIndicator"; - -const MULTIPLE = { expectSingle: false }; - -const query = buildKGQuery("core/DatasetVersion", [ - S("@id"), - S("fullName"), - S("description"), - S("shortName"), - S("versionIdentifier"), - R("isVersionOf", "hasVersion", [S("fullName"), S("description"), S("shortName")]), - L("accessibility/name", [], { filter: "free access", required: true }), - L("experimentalApproach/name", [], { filter: "electrophysiology", required: true }), - L("technique/name", [], MULTIPLE), - L("studiedSpecimen", [S("lookupLabel")], { type: "core/Subject", expectSingle: false }), - R("activities", "isPartOf", [S("@id"), S("@type")], MULTIPLE), -]); +import { ephysDatasetsQuery } from "./queryLibrary"; export async function loader() { - const datasetsPromise = datastore.getKGData("datasets summary", query); + const datasetsPromise = datastore.getKGData("datasets summary", ephysDatasetsQuery); console.log(datasetsPromise); return defer({ datasets: datasetsPromise }); } diff --git a/apps/nar-v3/src/routes/queryLibrary.js b/apps/nar-v3/src/routes/queryLibrary.js new file mode 100644 index 0000000..2a15826 --- /dev/null +++ b/apps/nar-v3/src/routes/queryLibrary.js @@ -0,0 +1,273 @@ +import { + buildKGQuery, + simpleProperty as S, + linkProperty as L, + reverseLinkProperty as R, +} from "../queries"; + +const MULTIPLE = { expectSingle: false }; + +const actorProperties = [ + S("@id"), + S("@type"), + S("givenName"), + S("familyName"), + S("fullName"), + S("shortName"), +]; + +const quantValProperties = [ + S("value"), + S("minValue"), + S("maxValue"), + L("unit/name"), + L("minValueUnit/name"), + L("maxValueUnit/name"), +]; + +const solutionProperties = [ + S("name"), + S("@id"), + L( + "hasPart", + [L("amount", quantValProperties), L("chemicalProduct", [S("name"), S("@id"), S("@type")])], + MULTIPLE + ), +]; + +const deviceProperty = L("device", [ + S("lookupLabel"), + S("name"), + S("@type"), + S("internalIdentifier"), + S("description"), + L("deviceType/name"), + L("manufacturer", [S("shortName", S("longName"))]), +]); + +const minimalDatasetProperties = [ + S("@id"), + S("fullName"), + S("description"), + S("shortName"), + S("versionIdentifier"), + L("custodian", actorProperties, MULTIPLE), + L("author", actorProperties, MULTIPLE), + R("isVersionOf", "hasVersion", [ + S("fullName"), + S("description"), + S("shortName"), + L("custodian", actorProperties, MULTIPLE), + L("author", actorProperties, MULTIPLE), + ]), + L("technique/name", [], MULTIPLE), +]; + +const basicDatasetProperties = [ + ...minimalDatasetProperties, + ...[L("ethicsAssessment/name"), L("license/shortName"), S("releaseDate")], +]; + +const ephysDatasetsQuery = buildKGQuery("core/DatasetVersion", [ + ...minimalDatasetProperties, + ...[ + L("accessibility/name", [], { filter: "free access", required: true }), + L("experimentalApproach/name", [], { filter: "electrophysiology", required: true }), + L("studiedSpecimen", [S("lookupLabel")], { type: "core/Subject", expectSingle: false }), + R("activities", "isPartOf", [S("@id"), S("@type")], MULTIPLE), + ], +]); + +const techniquesQuery = buildKGQuery("core/DatasetVersion", [L("technique/name", [], MULTIPLE)]); + +const basicDatasetQuery = buildKGQuery("core/DatasetVersion", [ + ...basicDatasetProperties, + ...[ + L( + "studiedSpecimen", + [ + S("lookupLabel"), + L("species", [S("name"), L("species/name")]), + L("biologicalSex/name"), + L( + "studiedState", + [ + S("lookupLabel"), + L("age", quantValProperties), + L("ageCategory/name"), + L("pathology", [S("name")], MULTIPLE), + ], + MULTIPLE + ), + ], + { type: "core/Subject", expectSingle: false } + ), + ], +]); + +const patchClampDatasetQuery = buildKGQuery("core/DatasetVersion", [ + ...basicDatasetProperties, + ...[ + L( + "studiedSpecimen", + [ + S("lookupLabel"), + L("species", [S("name"), L("species/name")]), + L("biologicalSex/name"), + L( + "studiedState", + [ + S("lookupLabel"), + L("age", quantValProperties), + L("ageCategory/name"), + L("pathology", [S("name")], MULTIPLE), + R( + "slicePreparation", + "input", + [ + // slice preparation + S("lookupLabel"), + S("@type"), + L( + "device", + [ + // device usage + S("lookupLabel"), + deviceProperty, + L("sliceThickness", quantValProperties), + L("slicingPlane/name"), + ], + MULTIPLE + ), + L("studyTarget/name", [], MULTIPLE), + L("temperature", [S("value"), L("unit/name")]), + L("tissueBathSolution", solutionProperties), + L( + "output", + [ + // slices + S("lookupLabel"), + S("internalIdentifier"), + R("slice", "studiedState", [ + S("lookupLabel"), + S("@type"), + S("internalIdentifier"), + L("anatomicalLocation", [S("name"), S("@type")], MULTIPLE), + L("type/name"), + ]), + R( + "cellPatching", + "input", + [ + S("lookupLabel"), + S("@type"), + L( + "device", + [ + // device usage + S("lookupLabel"), + deviceProperty, + L("pipetteSolution", solutionProperties), + L("sealResistance", [L("value", quantValProperties, MULTIPLE)]), + L("seriesResistance", [L("value", quantValProperties, MULTIPLE)]), + L("holdingPotential", [L("value", quantValProperties, MULTIPLE)]), + ], + MULTIPLE + ), + L("tissueBathSolution", solutionProperties), + L("bathTemperature", quantValProperties), + S("description"), + L("variation/name"), + L( + "output", + [ + // patched cells + S("lookupLabel"), + S("@type"), + R("cell", "studiedState", [ + S("internalIdentifier"), + L("anatomicalLocation", [S("name"), S("@type")], MULTIPLE), + L("type/name"), + ]), + R( + "recordingActivity", + "input", + [ + S("lookupLabel"), + S("@type"), + S("description"), + S("internalIdentifier"), + L("device", [ + R("metadata", "recordedWith", [ + S("name"), + S("additionalRemarks"), + L("samplingFrequency", quantValProperties), + L( + "channel", + [S("internalIdentifier"), L("unit/name")], + MULTIPLE + ), + ]), + ]), + L( + "output", + [ + S("@id"), + S("name"), + S("IRI"), + S("dataType/name"), + S("format/name"), + L("hash", [S("algorithm"), S("digest")], MULTIPLE), + L("storageSize", [S("value"), L("unit/name")]), + ], + MULTIPLE + ), + ], + { type: "ephys/RecordingActivity", expectSingle: false } + ), + R( + "stimulationActivity", + "input", + [ + S("lookupLabel"), + S("@type"), + L( + "stimulus", + [ + S("lookupLabel"), + S("@type"), + S("description"), + L("epoch", quantValProperties), + S("internalIdentifier"), + L("specification", [S("lookupLabel"), S("configuration")]), + ], + MULTIPLE + ), + ], + { + type: "stimulation/StimulationActivity", + expectSingle: false, + } + ), + ], + MULTIPLE + ), + ], + MULTIPLE + ), + ], + MULTIPLE + ), + ], + MULTIPLE + ), + ], + MULTIPLE + ), + ], + { type: "core/Subject", expectSingle: false } + ), + ], +]); + +export { ephysDatasetsQuery, techniquesQuery, basicDatasetQuery, patchClampDatasetQuery };