diff --git a/deploy/csp/index.js b/deploy/csp/index.js index 7273c69b4e841bc5e0be5aa85d68fb8c10b15e09..898228ce845b95c747d027704c08ab96f8196c30 100644 --- a/deploy/csp/index.js +++ b/deploy/csp/index.js @@ -54,7 +54,9 @@ const connectSrc = [ 'object.cscs.ch', // required for dataset previews - 'hbp-kg-dataset-previewer.apps.hbp.eu/v2/', + + // spatial transform + "hbp-spatial-backend.apps.hbp.eu", // injected by env var ...CSP_CONNECT_SRC @@ -102,7 +104,6 @@ module.exports = { ], imgSrc: [ "'self'", - "hbp-kg-dataset-previewer.apps.hbp.eu/v2/" ], scriptSrc:[ "'self'", @@ -118,6 +119,9 @@ module.exports = { ...WHITE_LIST_SRC, ...defaultAllowedSites ], + frameSrc: [ + "*" + ], reportUri: CSP_REPORT_URI || '/report-violation' }, reportOnly diff --git a/src/atlasComponents/annotations/annotation.service.ts b/src/atlasComponents/annotations/annotation.service.ts index ec352e5fbd3707b63b4da42ca92e9157c36bfb0c..fd67601ee087cf32ddd230d7e42b3ca9fdaea421 100644 --- a/src/atlasComponents/annotations/annotation.service.ts +++ b/src/atlasComponents/annotations/annotation.service.ts @@ -146,7 +146,8 @@ export class AnnotationLayer { } } updateAnnotation(spec: AnnotationSpec) { - const localAnnotations = this.nglayer.layer.localAnnotations + const localAnnotations = this.nglayer?.layer?.localAnnotations + if (!localAnnotations) return const ref = localAnnotations.references.get(spec.id) const _spec = this.parseNgSpecType(spec) if (ref) { diff --git a/src/viewerModule/nehuba/constants.ts b/src/viewerModule/nehuba/constants.ts index 6537a7aef4ea762d6d38c85ac335011551b5767e..ca5ae4be810af998f93318a6348f751555fabff3 100644 --- a/src/viewerModule/nehuba/constants.ts +++ b/src/viewerModule/nehuba/constants.ts @@ -64,3 +64,5 @@ export interface IMeshesToLoad { } export const SET_MESHES_TO_LOAD = new InjectionToken<Observable<IMeshesToLoad>>('SET_MESHES_TO_LOAD') + +export const PMAP_LAYER_NAME = 'regional-pmap' diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts index 6f6d708876773bd84a484d73226fab01066f731a..579f7fb79ab3e65547cc420391f2097587eeff18 100644 --- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts +++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts @@ -11,7 +11,7 @@ import { EnumColorMapName } from "src/util/colorMaps"; import { getShader } from "src/util/constants"; import { getNgLayersFromVolumesATP, getRegionLabelIndex } from "../config.service"; import { ParcVolumeSpec } from "../store/util"; -import { NehubaLayerControlService } from "./layerCtrl.service"; +import { PMAP_LAYER_NAME } from "../constants"; @Injectable() export class LayerCtrlEffects { @@ -22,7 +22,7 @@ export class LayerCtrlEffects { ), mapTo( atlasAppearance.actions.removeCustomLayer({ - id: NehubaLayerControlService.PMAP_LAYER_NAME + id: PMAP_LAYER_NAME }) ) )) @@ -42,7 +42,7 @@ export class LayerCtrlEffects { atlasAppearance.actions.addCustomLayer({ customLayer: { clType: "customlayer/nglayer", - id: NehubaLayerControlService.PMAP_LAYER_NAME, + id: PMAP_LAYER_NAME, source: `nifti://${sapiRegion.getMapUrl(template["@id"])}`, shader: getShader({ colormap: EnumColorMapName.VIRIDIS, @@ -55,7 +55,7 @@ export class LayerCtrlEffects { ), catchError(() => of( atlasAppearance.actions.removeCustomLayer({ - id: NehubaLayerControlService.PMAP_LAYER_NAME + id: PMAP_LAYER_NAME }) )) ) diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts index ba8b1d0adbe40c1c00fb794cac66a0b1890c25ae..5980c76d634265b8d20acac43b548da7d0f293e6 100644 --- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts +++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts @@ -13,6 +13,7 @@ import { arrayEqual } from "src/util/array"; import { ColorMapCustomLayer } from "src/state/atlasAppearance"; import { SapiRegionModel } from "src/atlasComponents/sapi"; import { AnnotationLayer } from "src/atlasComponents/annotations"; +import { PMAP_LAYER_NAME } from "../constants" export const BACKUP_COLOR = { red: 255, @@ -25,8 +26,6 @@ export const BACKUP_COLOR = { }) export class NehubaLayerControlService implements OnDestroy{ - static PMAP_LAYER_NAME = 'regional-pmap' - private selectedRegion$ = this.store$.pipe( select(atlasSelection.selectors.selectedRegions), shareReplay(1), @@ -367,7 +366,7 @@ export class NehubaLayerControlService implements OnDestroy{ */ return customLayers .map(l => l.id) - .filter(name => name !== NehubaLayerControlService.PMAP_LAYER_NAME) + .filter(name => name !== PMAP_LAYER_NAME) }) ), this.customLayers$.pipe( @@ -378,7 +377,7 @@ export class NehubaLayerControlService implements OnDestroy{ }), distinctUntilChanged(), map(flag => flag - ? [ NehubaLayerControlService.PMAP_LAYER_NAME ] + ? [ PMAP_LAYER_NAME ] : [] ) ) diff --git a/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts b/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts index 62a4ce09eb3d14682498812aee8e9e90dd01b253..ef3ac53320fbfa6ee86ec80ac140c105a2534af8 100644 --- a/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts +++ b/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts @@ -7,7 +7,7 @@ import { SapiRegionModel } from "src/atlasComponents/sapi" import * as configSvc from "../config.service" import { LayerCtrlEffects } from "../layerCtrl.service/layerCtrl.effects" import { NEVER, of, pipe } from "rxjs" -import { mapTo } from "rxjs/operators" +import { mapTo, take } from "rxjs/operators" import { selectorAuxMeshes } from "../store" @@ -51,6 +51,12 @@ describe('> mesh.service.ts', () => { ) ) }) + + afterEach(() => { + getParcNgIdSpy.calls.reset() + getRegionLabelIndexSpy.calls.reset() + getATPSpy.calls.reset() + }) describe('> NehubaMeshService', () => { beforeEach(() => { TestBed.configureTestingModule({ @@ -72,37 +78,106 @@ describe('> mesh.service.ts', () => { expect(service).toBeTruthy() }) - it('> mixes in auxillaryMeshIndices', () => { - const mockStore = TestBed.inject(MockStore) - mockStore.overrideSelector(atlasSelection.selectors.selectedRegions, [ fits1 ]) - mockStore.overrideSelector(atlasSelection.selectors.selectedParcAllRegions, []) - mockStore.overrideSelector(selectorAuxMeshes, [auxMesh]) + describe("> loadMeshes$", () => { - const ngId = 'blabla' - const labelIndex = 12 - getParcNgIdSpy.and.returnValue(ngId) - getRegionLabelIndexSpy.and.returnValue(labelIndex) + describe("> auxMesh defined", () => { + + const ngId = 'blabla' + const labelIndex = 12 + + beforeEach(() => { + + const mockStore = TestBed.inject(MockStore) + mockStore.overrideSelector(atlasSelection.selectors.selectedRegions, [ fits1 ]) + mockStore.overrideSelector(atlasSelection.selectors.selectedParcAllRegions, []) + mockStore.overrideSelector(selectorAuxMeshes, [auxMesh]) + + getParcNgIdSpy.and.returnValue(ngId) + getRegionLabelIndexSpy.and.returnValue(labelIndex) - const service = TestBed.inject(NehubaMeshService) - - expect( - service.loadMeshes$ - ).toBeObservable( - hot('(ab)', { - a: { - layer: { - name: ngId - }, - labelIndicies: [ labelIndex ] - }, - b: { - layer: { - name: auxMesh.ngId, - }, - labelIndicies: auxMesh.labelIndicies - } }) - ) + + it("> auxMesh ngId labelIndex emitted", () => { + + const service = TestBed.inject(NehubaMeshService) + expect( + service.loadMeshes$ + ).toBeObservable( + hot('(ab)', { + a: { + layer: { + name: ngId + }, + labelIndicies: [ labelIndex ] + }, + b: { + layer: { + name: auxMesh.ngId, + }, + labelIndicies: auxMesh.labelIndicies + } + }) + ) + }) + }) + + describe("> if multiple ngid and labelindicies are present", () => { + + const ngId1 = 'blabla' + const labelIndex1 = 12 + + const ngId2 = 'foobar' + const labelIndex2 = 13 + + beforeEach(() => { + + const mockStore = TestBed.inject(MockStore) + mockStore.overrideSelector(atlasSelection.selectors.selectedRegions, [ fits1 ]) + mockStore.overrideSelector(atlasSelection.selectors.selectedParcAllRegions, [fits1, fits1]) + mockStore.overrideSelector(selectorAuxMeshes, []) + + getParcNgIdSpy.and.returnValues(ngId1, ngId2, ngId2) + getRegionLabelIndexSpy.and.returnValues(labelIndex1, labelIndex2, labelIndex2) + }) + + it('> should call getParcNgIdSpy and getRegionLabelIndexSpy thrice', () => { + const service = TestBed.inject(NehubaMeshService) + service.loadMeshes$.pipe( + take(1) + ).subscribe(() => { + + expect(getParcNgIdSpy).toHaveBeenCalledTimes(3) + expect(getRegionLabelIndexSpy).toHaveBeenCalledTimes(3) + }) + }) + + /** + * in the case of julich brain 2.9 in colin 27, we expect selecting a region will hide meshes from all relevant ngIds (both left and right) + */ + it('> expect the emitted value to be incl all ngIds', () => { + const service = TestBed.inject(NehubaMeshService) + expect( + service.loadMeshes$ + ).toBeObservable( + hot('(ab)', { + a: { + layer: { + name: ngId1 + }, + labelIndicies: [] + }, + b: { + layer: { + name: ngId2 + }, + labelIndicies: [ labelIndex2 ] + } + }) + ) + + }) + }) + }) }) }) diff --git a/src/viewerModule/nehuba/mesh.service/mesh.service.ts b/src/viewerModule/nehuba/mesh.service/mesh.service.ts index 2585f00224e8729a4434afa568e127a486e66fcb..d372ce460746d01c5cf560518e1532f38616b882 100644 --- a/src/viewerModule/nehuba/mesh.service/mesh.service.ts +++ b/src/viewerModule/nehuba/mesh.service/mesh.service.ts @@ -47,7 +47,40 @@ export class NehubaMeshService implements OnDestroy { ]).pipe( switchMap(([{ atlas, template, parcellation }, regions, selectedRegions]) => { const ngIdRecord: Record<string, number[]> = {} + + const tree = new Tree( + regions, + (c, p) => (c.hasParent || []).some(_p => _p["@id"] === p["@id"]) + ) + + for (const r of regions) { + const regionLabelIndex = getRegionLabelIndex( atlas, template, parcellation, r ) + if (!regionLabelIndex) { + continue + } + if ( + tree.someAncestor(r, anc => !!getRegionLabelIndex(atlas, template, parcellation, anc)) + ) { + continue + } + const ngId = getParcNgId(atlas, template, parcellation, r) + if (!ngIdRecord[ngId]) { + ngIdRecord[ngId] = [] + } + ngIdRecord[ngId].push(regionLabelIndex) + } + if (selectedRegions.length > 0) { + /** + * If regions are selected, reset the meshes + */ + for (const key in ngIdRecord) { + ngIdRecord[key] = [] + } + + /** + * only show selected region + */ for (const r of selectedRegions) { const ngId = getParcNgId(atlas, template, parcellation, r) const regionLabelIndex = getRegionLabelIndex( atlas, template, parcellation, r ) @@ -56,28 +89,6 @@ export class NehubaMeshService implements OnDestroy { } ngIdRecord[ngId].push(regionLabelIndex) } - } else { - const tree = new Tree( - regions, - (c, p) => (c.hasParent || []).some(_p => _p["@id"] === p["@id"]) - ) - - for (const r of regions) { - const regionLabelIndex = getRegionLabelIndex( atlas, template, parcellation, r ) - if (!regionLabelIndex) { - continue - } - if ( - tree.someAncestor(r, (anc) => !!getRegionLabelIndex(atlas, template, parcellation, anc)) - ) { - continue - } - const ngId = getParcNgId(atlas, template, parcellation, r) - if (!ngIdRecord[ngId]) { - ngIdRecord[ngId] = [] - } - ngIdRecord[ngId].push(regionLabelIndex) - } } const arr: IMeshesToLoad[] = []