diff --git a/.gitignore b/.gitignore
index e66fee60..08e66091 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@ docs/.vitepress/cache
docs/components
.DS_Store
/.vitepress
+.env
+.env.local
diff --git a/package-lock.json b/package-lock.json
index 6c804078..8eef7922 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"license": "Apache-2.0",
"dependencies": {
"@abi-software/flatmap-viewer": "3.1.4",
- "@abi-software/map-utilities": "1.1.0",
+ "@abi-software/map-utilities": "^1.1.1-beta.0",
"@abi-software/sparc-annotation": "0.3.1",
"@abi-software/svg-sprite": "1.0.0",
"@element-plus/icons-vue": "^2.3.1",
@@ -71,11 +71,23 @@
"polylabel": "^1.1.0"
}
},
+ "node_modules/@abi-software/gallery": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@abi-software/gallery/-/gallery-1.1.1.tgz",
+ "integrity": "sha512-EOnKEQpL/6R7UZQpjiaBn5g4KPxc8RHrIfyTf4ukA+WJ2SU5T+R5GIYzi8Kuzgh797NehPpe/iFzPa21FvN+HQ==",
+ "dependencies": {
+ "axios": "^1.6.5",
+ "element-plus": "^2.4.4",
+ "unplugin-vue-components": "^0.26.0",
+ "vue": "^3.3.13"
+ }
+ },
"node_modules/@abi-software/map-utilities": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@abi-software/map-utilities/-/map-utilities-1.1.0.tgz",
- "integrity": "sha512-icRE0/VTa4RollDDHSqKsK63gwUAxAepDoAYPJCljgsnW6TxVyXOt9Olacwd3k2u0jfKOaUt1QfdTlpVxY4QpQ==",
+ "version": "1.1.1-beta.0",
+ "resolved": "https://registry.npmjs.org/@abi-software/map-utilities/-/map-utilities-1.1.1-beta.0.tgz",
+ "integrity": "sha512-W0IHpSHiNU4dqB+0tCmZ7qGv8eO/gd9eBgZeCAC2vG6I+l33dImKprWr6SpGq6/97XGmn2v/hyI68ARw8DWqAw==",
"dependencies": {
+ "@abi-software/gallery": "^1.1.0",
"@abi-software/svg-sprite": "^1.0.0",
"@element-plus/icons-vue": "^2.3.1",
"element-plus": "^2.7.3",
@@ -4035,8 +4047,7 @@
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/at-least-node": {
"version": "1.0.0",
@@ -4095,6 +4106,34 @@
"integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==",
"dev": true
},
+ "node_modules/axios": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
+ "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/axios/node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/axios/node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
"node_modules/babel-eslint": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
@@ -4716,7 +4755,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
"dependencies": {
"delayed-stream": "~1.0.0"
},
@@ -5484,7 +5522,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "dev": true,
"engines": {
"node": ">=0.4.0"
}
@@ -7164,7 +7201,6 @@
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
- "dev": true,
"funding": [
{
"type": "individual",
@@ -9711,7 +9747,6 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "dev": true,
"engines": {
"node": ">= 0.6"
}
@@ -9720,7 +9755,6 @@
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "dev": true,
"dependencies": {
"mime-db": "1.52.0"
},
diff --git a/package.json b/package.json
index 15a30fe7..5f531a4e 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
},
"dependencies": {
"@abi-software/flatmap-viewer": "3.1.4",
- "@abi-software/map-utilities": "1.1.0",
+ "@abi-software/map-utilities": "^1.1.1-beta.0",
"@abi-software/sparc-annotation": "0.3.1",
"@abi-software/svg-sprite": "1.0.0",
"@element-plus/icons-vue": "^2.3.1",
diff --git a/src/App.vue b/src/App.vue
index 1713a030..79812b02 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -77,6 +77,7 @@
:displayMinimap="true"
:enableOpenMapUI="true"
:flatmapAPI="flatmapAPI"
+ :sparcAPI="sparcAPI"
:disableUI="disableUI"
@open-pubmed-url="onOpenPubmedUrl"
@pathway-selection-changed="onPathwaySelectionChanged"
@@ -145,6 +146,7 @@ export default {
if (this.consoleOn) console.log(component)
let taxon = component.mapImp.describes
let id = component.mapImp.addMarker('UBERON:0000948')
+
window.flatmapImp = component.mapImp
component.enablePanZoomEvents(true)
//component.showPathwaysDrawer(false);
@@ -285,14 +287,16 @@ export default {
useHelpModeDialog: true,
multiflatmapRef: null,
mapSettings: [],
+ sparcAPI: import.meta.env.VITE_SPARC_API,
+ flatmapAPI: import.meta.env.VITE_FLATMAP_API,
//flatmapAPI: "https://mapcore-demo.org/current/flatmap/v2/"
//flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v3/"
- flatmapAPI: "https://mapcore-demo.org/current/flatmap/v3/",
+ //flatmapAPI: "https://mapcore-demo.org/current/flatmap/v3/",
//flatmapAPI: 'https://mapcore-demo.org/devel/flatmap/v4/',
//flatmapAPI: 'https://mapcore-demo.org/curation/flatmap/',
//flatmapAPI: "https://mapcore-demo.org/fccb/flatmap/"
//flatmapAPI: "https://mapcore-demo.org/staging/flatmap/v1/"
- // flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v1/",
+ //flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v1/",
ElIconSetting: shallowRef(ElIconSetting)
}
},
diff --git a/src/components/FlatmapVuer.vue b/src/components/FlatmapVuer.vue
index db2e17f0..9da157e0 100644
--- a/src/components/FlatmapVuer.vue
+++ b/src/components/FlatmapVuer.vue
@@ -452,6 +452,30 @@ Please use `const` to assign meaningful names to them...
{{ viewingModes[viewingMode] }}
+
+ Images Display
+
+
+
+
+ {{ item }}
+
+
+
+
+
Drawn By*
@@ -604,9 +628,17 @@ Please use `const` to assign meaningful names to them...
v-show="tooltipDisplay"
:annotationEntry="annotationEntry"
:tooltipEntry="tooltipEntry"
+ :tooltipType="tooltipType"
+ :galleryItems="galleryItems"
:annotationDisplay="viewingMode === 'Annotation'"
+ @viewImage="viewIframeImage"
@annotation="commitAnnotationEvent"
/>
+
@@ -639,13 +671,15 @@ import {
FlatmapQueries,
findTaxonomyLabel,
} from '../services/flatmapQueries.js'
+import scicrunchMixin from '../services/scicrunchMixin.js'
+import flatmapImageMixin from '../mixins/flatmapImageMixin.js'
import yellowstar from '../icons/yellowstar'
import ResizeSensor from 'css-element-queries/src/ResizeSensor'
import * as flatmap from '@abi-software/flatmap-viewer'
import { AnnotationService } from '@abi-software/sparc-annotation'
import { mapState } from 'pinia'
import { useMainStore } from '@/store/index'
-import { DrawToolbar, Tooltip, TreeControls } from '@abi-software/map-utilities'
+import { DrawToolbar, Tooltip, TreeControls, IframeImageDialog } from '@abi-software/map-utilities'
import '@abi-software/map-utilities/dist/style.css'
const centroid = (geometry) => {
@@ -735,6 +769,7 @@ const createUnfilledTooltipData = function () {
*/
export default {
name: 'FlatmapVuer',
+ mixins: [scicrunchMixin, flatmapImageMixin],
components: {
Button,
Col,
@@ -754,7 +789,8 @@ export default {
ElIconWarningFilled,
ElIconArrowDown,
ElIconArrowLeft,
- DrawToolbar
+ DrawToolbar,
+ IframeImageDialog
},
beforeCreate: function () {
//The state watcher may triggered before
@@ -1669,7 +1705,12 @@ export default {
}
if (
data &&
- data.type !== 'marker' &&
+ (
+ data.type !== 'marker' ||
+ (
+ data.type === 'marker' && (this.imageType === 'Segmentations' || this.imageType === 'Images')
+ )
+ ) &&
eventType === 'click' &&
!(this.viewingMode === 'Neuron Connection') &&
// Disable popup when drawing
@@ -1703,6 +1744,17 @@ export default {
* @arg data
*/
checkAndCreatePopups: async function (data) {
+ console.log("checkandcreate")
+ if (data.feature.type === 'marker') {
+ this.tooltipType = 'image-gallery'
+ console.log('marker data', data)
+ console.log('saved images', this.images)
+ let filteredImages = this.findImagesForAnatomy(this.images, data.resource[0])
+ console.log('filtered images:',filteredImages)
+ this.galleryItems = filteredImages
+ this.displayTooltip(data.feature.models)
+ } else {
+
// Call flatmap database to get the connection data
if (this.viewingMode === 'Annotation') {
if (data.feature) {
@@ -1710,6 +1762,7 @@ export default {
...data.feature,
resourceId: this.serverURL,
}
+ this.tooltipType = 'annotation'
if (data.feature.featureId && data.feature.models) {
this.displayTooltip(data.feature.models)
} else if (data.feature.feature) {
@@ -1743,9 +1796,11 @@ export default {
results[1] ||
(data.feature.hyperlinks && data.feature.hyperlinks.length > 0)
) {
+ this.tooltipType = 'provenance'
this.resourceForTooltip = data.resource[0]
data.resourceForTooltip = this.resourceForTooltip
this.createTooltipFromNeuronCuration(data)
+ }
}
}
},
@@ -2001,6 +2056,23 @@ export default {
}
this.$emit('connectivity-info-open', this.tooltipEntry);
}
+
+ // Images on Flatmap
+ if (this.imageType === 'Segmentations' || this.imageType === 'Images') {
+ // Images in Sidebar
+ if (this.connectivityInfoSidebar && this.viewingMode !== 'Annotation') {
+ this.$emit('show-flatmap-images', this.galleryItems);
+ }
+ // Images in popup
+ else {
+ this.tooltipDisplay = true;
+ this.$nextTick(() => {
+ this.mapImp.showPopup(featureId, this.$refs.tooltip.$el, options);
+ this.popUpCssHacks();
+ });
+ }
+ }
+
// If UI is not disabled,
// And connectivityInfoSidebar is not set (default) or set to `false`
// Provenance popup will be shown on map
@@ -2334,9 +2406,9 @@ export default {
this.addResizeButtonToMinimap()
this.loading = false
this.computePathControlsMaximumHeight()
- this.drawerOpen = !this.isCentreLine
+ this.drawerOpen = !this.isCentreLine
this.mapResize()
- this.handleMapClick();
+ this.handleMapClick()
/**
* This is ``onFlatmapReady`` event.
* @arg ``this`` (Component Vue Instance)
@@ -2431,6 +2503,29 @@ export default {
if (this.mapImp) return this.mapImp.search(term)
return []
},
+ viewIframeImage: function (url) {
+ this.imageIframeURL = url
+ this.imageIframeOpen = true
+ },
+ closeImageIframe: function () {
+ this.imageIframeURL = ''
+ this.imageIframeOpen = false
+ },
+ setImageType: async function (type) {
+ if (this.mapImp) {
+ this.mapImp.clearMarkers()
+ const anatomicalIdentifiers = this.mapImp.anatomicalIdentifiers
+ if (type === "Segmentations") {
+ let images = await this.getSegmentationsThumbnails("id", anatomicalIdentifiers)
+ this.images = images
+ this.populateFlatmapWithImages(this.mapImp, images, type)
+ } else if (type === "Images") {
+ let images = await this.getBiolucidaThumbnails("id", anatomicalIdentifiers)
+ this.images = images
+ this.populateFlatmapWithImages(this.mapImp, images, type)
+ }
+ }
+ },
},
props: {
/**
@@ -2639,6 +2734,10 @@ export default {
serverURL: undefined,
layers: [],
pathways: [],
+ imageIframeOpen: false,
+ imageIframeURL: '',
+ galleryItems: [],
+ tooltipType: 'provenance',
sckanDisplay: [
{
label: 'Display Path with SCKAN',
@@ -2704,6 +2803,8 @@ export default {
},
drawnType: 'All tools',
drawnTypes: ['All tools', 'Point', 'LineString', 'Polygon', 'None'],
+ imageType: 'None',
+ imageTypes: ['Segmentations', 'Images', 'None'],
annotatedType: 'Anyone',
annotatedTypes: ['Anyone', 'Me', 'Others'],
openMapRef: undefined,
diff --git a/src/components/MultiFlatmapVuer.vue b/src/components/MultiFlatmapVuer.vue
index 5393cfda..e6ebf97d 100644
--- a/src/components/MultiFlatmapVuer.vue
+++ b/src/components/MultiFlatmapVuer.vue
@@ -59,6 +59,7 @@
:connectivityInfoSidebar="connectivityInfoSidebar"
@connectivity-info-open="onConnectivityInfoOpen"
@connectivity-info-close="onConnectivityInfoClose"
+ @show-flatmap-images="onShowFlatmapImages"
@open-map="
/**
* This event is emitted when the user chooses a different map option
@@ -267,6 +268,9 @@ export default {
onSelectionsDataChanged: function (data) {
this.$emit('pathway-selection-changed', data);
},
+ onShowFlatmapImages: function (data) {
+ this.$emit('show-flatmap-images', data);
+ },
/**
* @vuese
* Function to show popup on map.
diff --git a/src/mixins/flatmapImageMixin.js b/src/mixins/flatmapImageMixin.js
new file mode 100644
index 00000000..6d15df92
--- /dev/null
+++ b/src/mixins/flatmapImageMixin.js
@@ -0,0 +1,135 @@
+export default {
+ // Note that the setting store is included in MapContent.vue
+ methods: {
+ downloadAndCreateImageThumbnailMarkerUrl: function(mapImp, key, list, type) {
+ const count = list.length
+ if (count > 0) {
+ //Pick a random image
+ const index = Math.floor(Math.random() * count)
+ const thumbnail = list[index].thumbnail
+ this.getThumbnail(thumbnail, type)
+ .then((wrappedElement) => {
+ this.createImageThumbnailMarkerUrl(mapImp, key, wrappedElement)
+ })
+ .catch(() => {
+ //Failed to download, pick another one
+ list.splice(index)
+ this.downloadAndCreateImageThumbnailMarkerUrl(mapImp, key, list, type)
+ })
+ }
+ },
+ populateFlatmapWithImages: function (mapImp, images = [], type) {
+ for (const [key, list] of Object.entries(images)) {
+ this.downloadAndCreateImageThumbnailMarkerUrl(mapImp, key, list, type)
+ }
+ /*
+ images.forEach((image) => {
+ if (image.value && image.value.length > 0)
+ image.value.forEach((image) => {
+ if (image.anatomy && image.anatomy.length > 0) {
+ image.anatomy.forEach((anatomy) => {
+ if (!anatomyList.includes(anatomy.curie) && ids.includes(anatomy.curie)) {
+ console.log(anatomy.curie)
+ anatomyList.push(anatomy.curie)
+ this.createImageThumbnailMarkerUrl(mapImp, anatomy.curie, image.thumbnail)
+ }
+ })
+ }
+ })
+ })
+ */
+ },
+ findImagesForAnatomy: function (images = [], anatomyToFind) {
+ if (anatomyToFind in images) {
+ return images[anatomyToFind]
+ }
+ return []
+ /*
+ images.forEach((image) => {
+ if (image.value && image.value.length > 0)
+ image.value.forEach((image) => {
+ if (image.anatomy && image.anatomy.length > 0) {
+ image.anatomy.forEach((anatomy) => {
+ if (anatomy.curie === anatomyToFind) {
+ imageList.push(image)
+ }
+ })
+ }
+ })
+ })
+ return imageList
+ */
+ },
+ getThumbnail: async function(url, type) {
+ return new Promise((resolve, reject) => {
+ if (type === "Segmentations" ||
+ type === "Images") {
+ this.getBinaryThumbnail(url)
+ .then((response) => resolve(response))
+ .catch((response) => reject(response))
+ } else {
+ this.getGenericThumbnail(url)
+ .then((response) => resolve(response))
+ .catch((response) => reject(response))
+ }
+ })
+ },
+ getBinaryThumbnail: async function(url) {
+ return new Promise((resolve, reject) => {
+ fetch(url)
+ .then((response) => {
+ if (response.status >= 200 && response.status < 300) {
+ return response.text()
+ } else {
+ reject();
+ }
+ })
+ .then((data) => {
+ if (data) {
+ let img = new Image();
+ let wrapperElement = document.createElement("div")
+ img.style = "height: auto;width: 50px;margin-right: 80px;"
+ img.onload = function() {
+ wrapperElement.appendChild(img);
+ resolve(wrapperElement);
+ }
+ img.onerror = function() {
+ reject(new Error("Failed to load image at " + url));
+ };
+ img.src= `data:'image/png';base64,${data}`
+ } else {
+ reject(new Error("Failed to load image at " + url));
+ }
+ })
+ })
+ },
+ getGenericThumbnail: async function(url) {
+ return new Promise((resolve, reject) => {
+ let img = new Image();
+ let wrapperElement = document.createElement("div");
+ img.style = "height: auto;width: 50px;margin-right: 80px;"
+ img.onload = function() {
+ wrapperElement.appendChild(img);
+ resolve(wrapperElement);
+ }
+ img.onerror = function() {
+ reject(new Error("Failed to load image at " + url));
+ };
+ img.src = url;
+ });
+ },
+ createImageThumbnailMarkerUrl: function (mapImp, id, wrapperElement) {
+ // add it to the flatmap
+ const markerIdentifier = mapImp.addMarker(id, {
+ element: wrapperElement,
+ className: "highlight-marker",
+ cluster: false,
+ type: "image",
+ });
+
+ const marker = mapImp.addMarker(id);
+ return marker
+ }
+
+ }
+}
diff --git a/src/services/scicrunchMixin.js b/src/services/scicrunchMixin.js
new file mode 100644
index 00000000..954d7355
--- /dev/null
+++ b/src/services/scicrunchMixin.js
@@ -0,0 +1,185 @@
+/* eslint-disable no-alert, no-console */
+const imageQuery = '"*jp2* OR *vnd.ome.xml* OR *jpx*"';
+
+const getBiolucidaInfo = async (sparcAPI, datasetId) => {
+ return new Promise((resolve, reject) => {
+ const endpoint = `${sparcAPI}/image_search/${datasetId}`
+ fetch(endpoint)
+ .then((response) => {
+ if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ reject();
+ }
+ })
+ .then((data) => {
+ if (data.status == 'success') {
+ resolve(data);
+ } else {
+ reject();
+ }
+ })
+ })
+}
+
+const getFilesInfo = async (api, key, idsList, types) => {
+ let params = new URLSearchParams();
+ types.forEach((type) => {
+ params.append('arrayparams', type);
+ params.append('arrayparams', type);
+ });
+ let response = await fetch(`${api}/get-organ-curies/?${params}`);
+ let data = await response.json();
+ const identifiers = [];
+ data.uberon.array.forEach(pair => {
+ const identifier = {
+ id: pair.id.toUpperCase(),
+ name: pair.name
+ };
+ if (idsList.includes(identifier[key])) {
+ identifiers.push(identifier);
+ }
+ });
+ const keys = identifiers.map((item) => item[key]);
+ response = await fetch(`${api}/get-files-info-for-curies`, {
+ method: "POST",
+ body: JSON.stringify(
+ {
+ filetypes: types,
+ curies: keys,
+ }
+ ),
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+ data = await response.json();
+ return data;
+}
+
+export default {
+ // Note that the setting store is included in MapContent.vue
+ methods: {
+ getThumbnailURL: function(thumbnailId) {
+ return `${this.sparcAPI}/thumbnail/${thumbnailId}`
+ },
+ getSegmentationThumbnailURL: function(datasetId, datasetVersion, filePath) {
+ return `${this.sparcAPI}/thumbnail/neurolucida?datasetId=${datasetId}&version=${datasetVersion}&path=files/${filePath}`;
+ },
+ getBiolucidaThumbnails: async function (key, idsList) {
+ try {
+ const data = await getFilesInfo(this.sparcAPI, key, idsList, ["biolucida-2d", "biolucida-3d"]);
+ if (data['files_info']) {
+ const images = {};
+ for (const [key, value] of Object.entries(data['files_info'])) {
+ if (value.length > 0) {
+ const list = [];
+ value.forEach((entry) => {
+ if (entry.biolucida_id) {
+ let image = {
+ thumbnail: this.getThumbnailURL(entry.biolucida_id),
+ datasetId: entry.id,
+ }
+ list.push(image);
+ }
+ });
+ images[key] = list;
+ }
+ }
+ return images;
+ }
+ } catch (error) {
+ console.error('Error:', error);
+ }
+ return {};
+ },
+ //Get representative segmentations thumbnails
+ // key - can either be
+ // id - use the uberon id as key or
+ // name - anatomical name as key
+ // idsList - Only id / name from the server matching the one in this list
+ // will be used
+ getSegmentationsThumbnails: async function (key, idsList) {
+ try {
+ const data = await getFilesInfo(this.sparcAPI, key, idsList, ["mbf-segmentation"]);
+ if (data['files_info']) {
+ const images = {};
+ for (const [key, value] of Object.entries(data['files_info'])) {
+ if (value.length > 0) {
+ const list = [];
+ value.forEach((entry) => {
+ let image = {
+ thumbnail: this.getSegmentationThumbnailURL(entry.id,
+ entry.version, entry.file_path),
+ datasetId: entry.id,
+ }
+ list.push(image);
+ });
+ images[key] = list;
+ }
+ }
+ return images;
+ }
+ } catch (error) {
+ console.error('Error:', error);
+ }
+ return {};
+ },
+ getImagesFromScicrunch: async function () {
+ try {
+ const response = await fetch(`${this.sparcAPI}/multiple_dataset_info/using_multiple_mimetype/?${new URLSearchParams({q: imageQuery})}`);
+ const data = await response.json();
+
+ console.log('number of hits:', data.numberOfHits);
+ if (data.numberOfHits >= 1) {
+ let images = await this.processResults(data.results);
+ return {success: true, images: images};
+ }
+ return {success: false};
+ } catch (error) {
+ console.error('Error:', error);
+ return {success: false};
+ }
+ },
+
+ processResults: async function (results) {
+ try {
+ let images = [];
+ const dataType = 'segmentation';
+ console.log('starting promise list')
+ let promiseList = results.map(async (result, i) => {
+ const datasetId = result.dataset_identifier;
+ const datasetVersion = result.dataset_version;
+ const s3uri = result.s3uri;
+ const biolucidaInfo = await getBiolucidaInfo(this.sparcAPI, datasetId);
+ return biolucidaInfo.dataset_images.map(bioImage => {
+ return {
+ resource: {
+ share_link: bioImage.share_link,
+ },
+ title: 'Image',
+ anatomy: result.organs,
+ species: result.organisms,
+ datasetId: datasetId,
+ datasetVersion: datasetVersion,
+ link: bioImage.share_link,
+ s3uri: s3uri,
+ type: dataType,
+ thumbnail: bioImage.thumbnail_url,
+ };
+ });
+ });
+ console.log('promiseList:', promiseList);
+ let biolucidaInfos = await Promise.allSettled(promiseList);
+ images = biolucidaInfos.flat();
+ console.log('biolucidaInfos:', biolucidaInfos);
+ console.log('finished!')
+ return images;
+ } catch (error) {
+ console.error('Error:', error);
+ return [];
+ }
+ }
+ }
+}
+
\ No newline at end of file