diff --git a/deploy/package-lock.json b/deploy/package-lock.json index 99b93fe79026380a2f1ca7f051b65e97774a31f5..5d707a769ac807f9c1473f3940fe0464dba4657b 100644 --- a/deploy/package-lock.json +++ b/deploy/package-lock.json @@ -257,9 +257,9 @@ }, "dependencies": { "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" } } }, @@ -735,9 +735,9 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "denque": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", - "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" }, "depd": { "version": "1.1.2", @@ -1352,9 +1352,9 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "jose": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.4.tgz", - "integrity": "sha512-EArN9f6aq1LT/fIGGsfghOnNXn4noD+3dG5lL/ljY3LcRjw1u9w+4ahu/4ahsN6N0kRLyyW6zqdoYk7LNx3+YQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", + "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", "requires": { "@panva/asn1.js": "^1.0.0" } @@ -1446,9 +1446,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.defaults": { @@ -1801,9 +1801,9 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" }, "npm-run-path": { "version": "2.0.2", @@ -2194,20 +2194,20 @@ } }, "redis": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/redis/-/redis-3.0.2.tgz", - "integrity": "sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", + "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==", "requires": { - "denque": "^1.4.1", - "redis-commands": "^1.5.0", + "denque": "^1.5.0", + "redis-commands": "^1.7.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0" } }, "redis-commands": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.6.0.tgz", - "integrity": "sha512-2jnZ0IkjZxvguITjFTrGiLyzQZcTvaw8DAaCXxZq/dsHXz7KfMQ3OUJy7Tz9vnRtZRVz6VRCPDvruvU8Ts44wQ==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", + "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" }, "redis-errors": { "version": "1.2.0", @@ -2819,9 +2819,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "yallist": { "version": "3.1.1", diff --git a/deploy/package.json b/deploy/package.json index 95da8df0bd39afe6c3076fe360260e3b4f81995b..8a165a87192525bf0b6bcd9ba86df86fe5ddb30c 100644 --- a/deploy/package.json +++ b/deploy/package.json @@ -26,7 +26,7 @@ "nomiseco": "0.0.2", "openid-client": "^4.4.0", "passport": "^0.4.0", - "redis": "^3.0.2", + "redis": "^3.1.2", "request": "^2.88.0", "showdown": "^1.9.1", "soswrap": "^0.0.2", diff --git a/docs/releases/v2.5.2.md b/docs/releases/v2.5.2.md new file mode 100644 index 0000000000000000000000000000000000000000..200aab57206daa94f58fa4a931e1081adf72380b --- /dev/null +++ b/docs/releases/v2.5.2.md @@ -0,0 +1,5 @@ +# v2.5.2 + +## Bugfixes + +- fix big brain high resolution maps \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 80ad8c9d6d9c41957994b8138aeb124132e78e2e..b7e247316f838021293df1ef5f887cc486abef56 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -40,6 +40,7 @@ pages: - Fetching datasets: 'advanced/datasets.md' - Display non-atlas volumes: 'advanced/otherVolumes.md' - Release notes: + - v2.5.2: 'releases/v2.5.2.md' - v2.5.1: 'releases/v2.5.1.md' - v2.5.0: 'releases/v2.5.0.md' - v2.4.8: 'releases/v2.4.8.md' diff --git a/src/routerModule/util.spec.ts b/src/routerModule/util.spec.ts index ac15ff5981b022ed662be9c7796e07fff9e941a0..b2ed55ea82db7f09f581114c2157a40ad2731bb6 100644 --- a/src/routerModule/util.spec.ts +++ b/src/routerModule/util.spec.ts @@ -6,6 +6,8 @@ import { cvtFullRouteToState, cvtStateToHashedRoutes, DummyCmp, routes } from '. import { encodeNumber } from './cipher' import { Router } from '@angular/router' import { RouterTestingModule } from '@angular/router/testing' +import * as parsedRoute from './parseRouteToTmplParcReg' +import { spaceMiscInfoMap } from 'src/util/pureConstant.service' describe('> util.ts', () => { describe('> cvtFullRouteToState', () => { @@ -61,6 +63,53 @@ describe('> util.ts', () => { }) }) + describe('> navigation', () => { + let parseSpy: jasmine.Spy + let mapGetSpy: jasmine.Spy + beforeEach(() => { + parseSpy = spyOnProperty(parsedRoute, 'parseSearchParamForTemplateParcellationRegion') + mapGetSpy = spyOn(spaceMiscInfoMap, 'get') + }) + it('> if not present, should show something palatable', () => { + parseSpy.and.returnValue(() => ({ + parcellationSelected: { + id: 'dummpy-id-parc' + }, + regionsSelected: [], + templateSelected: { + id: 'dummpy-id-tmpl-sel' + }, + })) + + const scale = 0.25 + + mapGetSpy.and.returnValue({ scale }) + + const router = TestBed.inject(Router) + const route = `/a:juelich:iav:atlas:v1.0.0:1/t:minds:core:referencespace:v1.0.0:dafcffc5-4826-4bf1-8ff6-46b8a31ff8e2/p:minds:core:parcellationatlas:v1.0.0:94c1125b-b87e-45e4-901c-00daee7f2579-290` + const parsedUrl = router.parseUrl(route) + const { viewerState = {} } = cvtFullRouteToState(parsedUrl, {}) || {} + const { navigation } = viewerState + const { + orientation, + perspectiveOrientation, + position, + zoom, + perspectiveZoom, + } = navigation + + expect(orientation).toEqual([0,0,0,1]) + expect(perspectiveOrientation).toEqual([ + 0.3140767216682434, + -0.7418519854545593, + 0.4988985061645508, + -0.3195493221282959 + ]) + expect(position).toEqual([0,0,0]) + expect(zoom).toEqual(350000 * scale) + expect(perspectiveZoom).toEqual(1922235.5293810747 * scale) + }) + }) }) describe('> cvtStateToHashedRoutes', () => { diff --git a/src/routerModule/util.ts b/src/routerModule/util.ts index 21ccdc6e7bbbb9bab69a399a96ac388d5fbc7439..e0115ee6268f033cf55a17e1ddac3c39e1b8839f 100644 --- a/src/routerModule/util.ts +++ b/src/routerModule/util.ts @@ -18,6 +18,7 @@ import { parseSearchParamForTemplateParcellationRegion, encodeId, } from './parseRouteToTmplParcReg' +import { spaceMiscInfoMap } from "src/util/pureConstant.service" const endcodePath = (key: string, val: string|string[]) => key[0] === '?' @@ -34,6 +35,17 @@ const decodePath = (path: string) => { } } +export const DEFAULT_NAV = { + orientation: [0, 0, 0, 1], + perspectiveOrientation: [ + 0.3140767216682434, + -0.7418519854545593, + 0.4988985061645508, + -0.3195493221282959 + ], + position: [0, 0, 0], +} + export const cvtFullRouteToState = (fullPath: UrlTree, state: any, _warnCb?: (arg: string) => void) => { const warnCb = _warnCb || ((...e: any[]) => console.warn(...e)) @@ -78,7 +90,7 @@ export const cvtFullRouteToState = (fullPath: UrlTree, state: any, _warnCb?: (ar // nav obj is almost always defined, regardless if standaloneVolume or not const cViewerState = returnObj['@'] && returnObj['@'][0] - let parsedNavObj = {} + let parsedNavObj: any if (cViewerState) { try { const [ cO, cPO, cPZ, cP, cZ ] = cViewerState.split(`${separator}${separator}`) @@ -171,7 +183,12 @@ export const cvtFullRouteToState = (fullPath: UrlTree, state: any, _warnCb?: (ar returnState['viewerState']['regionsSelected'] = regionsSelected returnState['viewerState']['templateSelected'] = templateSelected - returnState['viewerState']['navigation'] = parsedNavObj + const { scale } = spaceMiscInfoMap.get(templateSelected.id) || { scale: 1 } + returnState['viewerState']['navigation'] = parsedNavObj || ({ + ...DEFAULT_NAV, + zoom: 350000 * scale, + perspectiveZoom: 1922235.5293810747 * scale + }) } catch (e) { // if error, show error on UI? warnCb(`parse template, parc, region error`, e) diff --git a/src/util/patchPureConstants.ts b/src/util/patchPureConstants.ts index 55ff455615c145c59ac2906fba55625fabdf6d1a..681860add48b6393c202f3377f7afc217acd1682 100644 --- a/src/util/patchPureConstants.ts +++ b/src/util/patchPureConstants.ts @@ -46,25 +46,21 @@ async function getInterpolatedPatchObj(targetName: string, labelIndex: number){ '@id': 'minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588' }], "payload": { - "volumeSrc": { - 'minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588': { - "collect": [{ - "@type": "fzj/tmp/volume_type/v0.0.1" as const, - "@id": "fzj/tmp/volume_type/v0.0.1/interpolated", - "name": "Julich Brain v2.5 interpolated map", - "volume_type": "neuroglancer/precomputed" as const, - "url": "https://neuroglancer.humanbrainproject.org/precomputed/BigBrainRelease.2015/2019_05_22_interpolated_areas", - "detail": { - "neuroglancer/precomputed": { - "labelIndex": labelIndex, - "transform": [[1,0,0,-70677184],[0,1,0,-51990000],[0,0,1,-58788284],[0,0,0,1]] - } - }, - "space_id": "minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588", - map_type: 'labelled' - }] - } - } + _dataset_specs: [{ + "@type": "fzj/tmp/volume_type/v0.0.1" as const, + "@id": "fzj/tmp/volume_type/v0.0.1/interpolated", + "name": "Julich Brain v2.5 interpolated map", + "volume_type": "neuroglancer/precomputed" as const, + "url": "https://neuroglancer.humanbrainproject.org/precomputed/BigBrainRelease.2015/2019_05_22_interpolated_areas", + "detail": { + "neuroglancer/precomputed": { + "labelIndex": labelIndex, + "transform": [[1,0,0,-70677184],[0,1,0,-51990000],[0,0,1,-58788284],[0,0,0,1]] + } + }, + "space_id": "minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588", + map_type: 'labelled' + }], } } const hex = await getShaDigest(JSON.stringify(returnObj)) @@ -78,9 +74,9 @@ async function getIndividualMap(parentName: string, regionName: string, url: str const volumeId = await getShaDigest(url) const returnObj: TPatchRegion = { '@id': '', - "@type": 'julich/siibra/append-region/v0.0.1', - "parent": { - "name": parentName + "@type": 'julich/siibra/patch-region/v0.0.1', + "target": { + "name": regionName }, "targetParcellation": [{ "@id": 'minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290' @@ -89,26 +85,21 @@ async function getIndividualMap(parentName: string, regionName: string, url: str '@id': 'minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588' }], "payload": { - "name": regionName, - "volumeSrc": { - 'minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588': { - "collect": [{ - "@type": "fzj/tmp/volume_type/v0.0.1" as const, - "@id": `fzj/tmp/volume_type/v0.0.1/${volumeId}`, - "name": "Julich Brain v2.5 detailed map", - "volume_type": "neuroglancer/precomputed" as const, - "url": url, - "detail": { - "neuroglancer/precomputed": { - "labelIndex": labelIndex, - "transform": transform - } - }, - space_id: 'minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588', - map_type: 'labelled' - }] - } - } + '_dataset_specs': [{ + "@type": "fzj/tmp/volume_type/v0.0.1" as const, + "@id": `fzj/tmp/volume_type/v0.0.1/${volumeId}`, + "name": "Julich Brain v2.5 detailed map", + "volume_type": "neuroglancer/precomputed" as const, + "url": url, + "detail": { + "neuroglancer/precomputed": { + "labelIndex": labelIndex, + "transform": transform + } + }, + space_id: 'minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588', + map_type: 'labelled' + }], } } const hex = await getShaDigest(JSON.stringify(returnObj)) diff --git a/src/util/pureConstant.service.ts b/src/util/pureConstant.service.ts index 09b2e1898137bcedd28fd9a0f3181d17b6d32778..c6145b3d2a7617850815eb6bf9212c81481b5efd 100644 --- a/src/util/pureConstant.service.ts +++ b/src/util/pureConstant.service.ts @@ -52,7 +52,7 @@ type TIAVAtlas = { } & THasId)[] } & THasId -const spaceMiscInfoMap = new Map([ +export const spaceMiscInfoMap = new Map([ ['minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588', { name: 'bigbrain', scale: 1, @@ -532,20 +532,16 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}" * this should work for both fully mapped and interpolated * in the case of interpolated, it sucks that the ngLayerObj will be set multiple times */ - if ( - tmpl.id in (region.volumeSrc || {}) - && 'collect' in region.volumeSrc[tmpl.id] - ) { - const dedicatedMap = region.volumeSrc[tmpl.id]['collect'].filter(v => v.volume_type === 'neuroglancer/precomputed') - if (dedicatedMap.length === 1) { - const ngId = getNgId(atlas['@id'], tmpl.id, parc.id, dedicatedMap[0]['@id']) - region['ngId'] = ngId - region['labelIndex'] = dedicatedMap[0].detail['neuroglancer/precomputed'].labelIndex - ngLayerObj[tmpl.id][ngId] = { - source: `precomputed://${dedicatedMap[0].url}`, - type: "segmentation", - transform: dedicatedMap[0].detail['neuroglancer/precomputed'].transform - } + + const dedicatedMap = region._dataset_specs.filter(spec => spec.space_id === tmpl.id && spec['volume_type'] === 'neuroglancer/precomputed') + if (dedicatedMap.length === 1) { + const ngId = getNgId(atlas['@id'], tmpl.id, parc.id, dedicatedMap[0]['@id']) + region['ngId'] = ngId + region['labelIndex'] = dedicatedMap[0].detail['neuroglancer/precomputed'].labelIndex + ngLayerObj[tmpl.id][ngId] = { + source: `precomputed://${dedicatedMap[0].url}`, + type: "segmentation", + transform: dedicatedMap[0].detail['neuroglancer/precomputed'].transform } } @@ -579,10 +575,11 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}" && hemisphereKey === 'whole brain' ) { region.children = [] - return } - const hemispheredNgId = getNgId(atlas['@id'], tmpl.id, parc.id, hemisphereKey) - region['ngId'] = hemispheredNgId + if (!region['ngId']) { + const hemispheredNgId = getNgId(atlas['@id'], tmpl.id, parc.id, hemisphereKey) + region['ngId'] = hemispheredNgId + } } } ) diff --git a/src/util/siibraApiConstants/types.ts b/src/util/siibraApiConstants/types.ts index 62fc6057d749a4123da76bcce3bf2d6b2fd738be..7f3170ad6f7f665ba13202a833b7342f86d36037 100644 --- a/src/util/siibraApiConstants/types.ts +++ b/src/util/siibraApiConstants/types.ts @@ -180,11 +180,6 @@ export type TRegionDetail = { export type TRegion = { name: string children: TRegion[] - volumeSrc: { - [key: string]: { - [key: string]: TVolumeSrc<keyof IVolumeTypeDetail>[] - } - } labelIndex?: number rgb?: number[] @@ -192,6 +187,8 @@ export type TRegion = { kg: TKgIdentifier } + _dataset_specs: TVolumeSrc<keyof IVolumeTypeDetail>[] + /** * missing */