diff --git a/common/util.js b/common/util.js
index c24a9fd0bc4fe3d9cffb0bba000243a93ccc560b..b69099b6a020a213f76f9498fbf7d56bdb0363dc 100644
--- a/common/util.js
+++ b/common/util.js
@@ -151,6 +151,8 @@
 
   exports.flattenRegions = flattenRegions
 
+  exports.hexToRgb = hex => hex && hex.match(/[a-fA-F0-9]{2}/g).map(v => parseInt(v, 16))
+  exports.rgbToHex = rgb => rgb && `#${rgb.map(color => color.toString(16).padStart(2, '0')).join("")}`
   exports.getRandomHex = (digit = 1024 * 1024 * 1024 * 1024) => Math.round(Math.random() * digit).toString(16)
 
   /**
@@ -193,37 +195,6 @@
     )
   }
 
-  exports.serialiseParcellationRegion = ({ ngId, labelIndex }) => {
-    if (!ngId) {
-      throw new Error(`#serialiseParcellationRegion error: ngId must be defined`)
-    }
-
-    if (!labelIndex) {
-      throw new Error(`#serialiseParcellationRegion error labelIndex must be defined`)
-    }
-
-    return `${ngId}#${labelIndex}`
-  }
-
-  const deserialiseParcRegionId = labelIndexId => {
-    const _ = labelIndexId && labelIndexId.split && labelIndexId.split('#') || []
-    const ngId = _.length > 1
-      ? _[0]
-      : null
-    const labelIndex = _.length > 1
-      ? Number(_[1])
-      : _.length === 0
-        ? null
-        : Number(_[0])
-    return { labelIndex, ngId }
-  }
-
-  exports.deserialiseParcRegionId = deserialiseParcRegionId
-
-  exports.deserialiseParcellationRegion = ({ region, labelIndexId, inheritedNgId = 'root' }) => {
-    const { labelIndex, ngId } = deserialiseParcRegionId(labelIndexId)
-  }
-
   const getPad = ({ length, pad }) => {
     if (pad.length !== 1) throw new Error(`pad needs to be precisely 1 character`)
     return input => {
diff --git a/docs/releases/v2.7.0.md b/docs/releases/v2.7.0.md
new file mode 100644
index 0000000000000000000000000000000000000000..427b35f4b925138ef419e63c6a5acebfd24be727
--- /dev/null
+++ b/docs/releases/v2.7.0.md
@@ -0,0 +1,5 @@
+# v2.7.0
+
+## New feature
+
+- (experimental) Add first implementation of fetching VOI from siibra-api
diff --git a/mkdocs.yml b/mkdocs.yml
index d56285fcb2696c7884fb90844282f9ba87e94d2b..8fe33d7163f9db4af08adf389f2ffbf4b58c179a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -33,6 +33,7 @@ pages:
     - Fetching datasets: 'advanced/datasets.md'
     - Display non-atlas volumes: 'advanced/otherVolumes.md'
   - Release notes:
+    - v2.7.0: 'releases/v2.7.0.md'
     - v2.6.5: 'releases/v2.6.5.md'
     - v2.6.4: 'releases/v2.6.4.md'
     - v2.6.3: 'releases/v2.6.3.md'
diff --git a/package.json b/package.json
index 4ef7b728e472e70f049ec71e0eb77e7893154581..1d6270f7cd6e00c655df94f57cd001413c0c8b37 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "interactive-viewer",
-  "version": "2.6.5",
+  "version": "2.7.0",
   "description": "HBP interactive atlas viewer. Integrating KG query, dataset previews & more. Based on humanbrainproject/nehuba & google/neuroglancer. Built with angular",
   "scripts": {
     "build-aot": "ng build && node ./third_party/matomo/processMatomo.js",
@@ -14,7 +14,8 @@
     "build": "ng build",
     "watch": "ng build --watch --configuration development",
     "test": "ng test",
-    "test-ci": "ng test --progress false --watch false --browsers=ChromeHeadless"
+    "test-ci": "ng test --progress false --watch false --browsers=ChromeHeadless",
+    "sapi-schema": "npx openapi-typescript@5.1.1 http://localhost:5000/v1_0/openapi.json --output ./src/atlasComponents/sapi/schema.ts"
   },
   "keywords": [],
   "author": "FZJ-INM1-BDA <inm1-bda@fz-juelich.de>",
diff --git a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.spec.ts b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.spec.ts
index 6a7449787611327577ac114c5060b7abffb6a9d8..d9ebdd9a94f5727043f4676bb3a433e1418a543b 100644
--- a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.spec.ts
+++ b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.spec.ts
@@ -6,7 +6,7 @@ import {CUSTOM_ELEMENTS_SCHEMA, Directive, Input} from "@angular/core";
 import {provideMockActions} from "@ngrx/effects/testing";
 import {MockStore, provideMockStore} from "@ngrx/store/testing";
 import {Observable, of} from "rxjs";
-import { viewerStateAllRegionsFlattenedRegionSelector, viewerStateOverwrittenColorMapSelector } from "src/services/state/viewerState/selectors";
+import { viewerStateOverwrittenColorMapSelector } from "src/services/state/viewerState/selectors";
 import { ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState.store.helper";
 import {BS_ENDPOINT} from "src/util/constants";
 
@@ -81,7 +81,6 @@ describe('ConnectivityComponent', () => {
 
     beforeEach(() => {
         const mockStore = TestBed.inject(MockStore)
-        mockStore.overrideSelector(viewerStateAllRegionsFlattenedRegionSelector, [])
         mockStore.overrideSelector(viewerStateOverwrittenColorMapSelector, null)
         mockStore.overrideSelector(ngViewerSelectorClearViewEntries, [])
     })
diff --git a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.ts b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.ts
index 638863a0893fc8a064fc1e7482b24b56bf956a39..0458757bbf0bfe396386003660dfe7de83cdc37d 100644
--- a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.ts
+++ b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.ts
@@ -10,19 +10,16 @@ import {
   OnInit, Inject,
 } from "@angular/core";
 import {select, Store} from "@ngrx/store";
-import {fromEvent, Observable, Subscription, Subject, combineLatest} from "rxjs";
-import {distinctUntilChanged, filter, map} from "rxjs/operators";
-
-import { viewerStateNavigateToRegion, viewerStateSetSelectedRegions } from "src/services/state/viewerState.store.helper";
+import {fromEvent, Observable, Subscription, Subject, combineLatest, of} from "rxjs";
+import {distinctUntilChanged, filter, map, switchMap, switchMapTo} from "rxjs/operators";
 import { ngViewerSelectorClearViewEntries, ngViewerActionClearView } from "src/services/state/ngViewerState.store.helper";
-import {
-  viewerStateAllRegionsFlattenedRegionSelector,
-  viewerStateOverwrittenColorMapSelector
-} from "src/services/state/viewerState/selectors";
 import {HttpClient} from "@angular/common/http";
 import {BS_ENDPOINT} from "src/util/constants";
 import {getIdFromKgIdObj} from "common/util";
 import {OVERWRITE_SHOW_DATASET_DIALOG_TOKEN} from "src/util/interfaces";
+import { SAPI, SapiRegionModel } from "src/atlasComponents/sapi";
+import { actions } from "src/state/atlasSelection";
+import { atlasAppearance, atlasSelection } from "src/state";
 
 
 const CONNECTIVITY_NAME_PLATE = 'Connectivity'
@@ -139,8 +136,10 @@ export class ConnectivityBrowserComponent implements OnInit, AfterViewInit, OnDe
     public selectedDatasetKgSchema: string = ''
     public connectedAreas = []
 
+    // TODO this may be incompatible
     private selectedParcellationFlatRegions$ = this.store$.pipe(
-      select(viewerStateAllRegionsFlattenedRegionSelector)
+      select(atlasSelection.selectors.selectedATP),
+      switchMap(({ atlas, template, parcellation }) => this.sapi.getParcRegions(atlas["@id"], parcellation["@id"], template["@id"])) 
     )
     public overwrittenColorMap$: Observable<any>
 
@@ -159,10 +158,11 @@ export class ConnectivityBrowserComponent implements OnInit, AfterViewInit, OnDe
         private changeDetectionRef: ChangeDetectorRef,
         private httpClient: HttpClient,
         @Inject(BS_ENDPOINT) private siibraApiUrl: string,
+        private sapi: SAPI
     ) {
 
       this.overwrittenColorMap$ = this.store$.pipe(
-        select(viewerStateOverwrittenColorMapSelector),
+        select(atlasAppearance.selectors.getOverwrittenColormap),
         distinctUntilChanged()
       )
     }
@@ -188,7 +188,7 @@ export class ConnectivityBrowserComponent implements OnInit, AfterViewInit, OnDe
     public ngAfterViewInit(): void {
       this.subscriptions.push(
         this.store$.pipe(
-          select(viewerStateOverwrittenColorMapSelector),
+          select(atlasAppearance.selectors.getOverwrittenColormap),
         ).subscribe(value => {
           if (this.accordionIsExpanded) {
             this.setColorMap$.next(!!value)
@@ -348,18 +348,18 @@ export class ConnectivityBrowserComponent implements OnInit, AfterViewInit, OnDe
       }
     }
 
-    navigateToRegion(region) {
+    navigateToRegion(region: SapiRegionModel) {
       this.store$.dispatch(
-        viewerStateNavigateToRegion({
-          payload: {region: this.getRegionWithName(region)}
+        atlasSelection.actions.navigateToRegion({
+          region
         })
       )
     }
 
-    selectRegion(region) {
+    selectRegion(region: SapiRegionModel) {
       this.store$.dispatch(
-        viewerStateSetSelectedRegions({
-          selectRegions: [ region ]
+        actions.selectRegions({
+          regions: [ region ]
         })
       )
     }
diff --git a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.template.html b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.template.html
index 9dfdc054e09c6eba8ad1318a37cca2db792a8ef2..dbb5cb03e570d0730eae592c5b270053c8ad34b1 100644
--- a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.template.html
+++ b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.template.html
@@ -36,16 +36,7 @@
                         </mat-select>
                     </mat-form-field>
                 <ng-container *ngIf="selectedDataset && (selectedDatasetDescription || selectedDatasetKgId)" >
-                    <button class="flex-grow-0 flex-shrink-0"
-                            mat-icon-button
-                            iav-dataset-show-dataset-dialog
-                            [iav-dataset-show-dataset-dialog-name]="selectedDatasetName"
-                            [iav-dataset-show-dataset-dialog-description]="selectedDatasetDescription"
-                            [iav-dataset-show-dataset-dialog-kgid]="selectedDatasetKgId? selectedDatasetKgId : null"
-                            [iav-dataset-show-dataset-dialog-kgschema]="selectedDatasetKgSchema? selectedDatasetKgSchema : null"
-                            >
-                        <i class="fas fa-info"></i>
-                    </button>
+                    TODO please reimplmenent button to explore KG dataset
                     <button class="flex-grow-0 flex-shrink-0"
                             mat-icon-button
                             (click)="exportFullConnectivity()"
diff --git a/src/atlasComponents/connectivity/module.ts b/src/atlasComponents/connectivity/module.ts
index a43e558c21da18e5998646bf63578f6ea00d8c28..c9231d4605589eeb8a7e5f2dd1f66a4a2b34089f 100644
--- a/src/atlasComponents/connectivity/module.ts
+++ b/src/atlasComponents/connectivity/module.ts
@@ -3,12 +3,10 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
 import { AngularMaterialModule } from "src/sharedModules";
 import { ConnectivityBrowserComponent } from "./connectivityBrowser/connectivityBrowser.component";
 import {HasConnectivity} from "src/atlasComponents/connectivity/hasConnectivity.directive";
-import {KgDatasetModule} from "src/atlasComponents/regionalFeatures/bsFeatures/kgDataset";
 
 @NgModule({
   imports: [
     CommonModule,
-    KgDatasetModule,
     AngularMaterialModule
   ],
   declarations: [
diff --git a/src/atlasComponents/parcellation/regionHierachy/regionHierarchy.component.ts b/src/atlasComponents/parcellation/regionHierachy/regionHierarchy.component.ts
index 715f000757552e41ee4e67ace06e9de56006e69e..33030c60ba8f26e1283cab7aef1d25a4f1d87181 100644
--- a/src/atlasComponents/parcellation/regionHierachy/regionHierarchy.component.ts
+++ b/src/atlasComponents/parcellation/regionHierachy/regionHierarchy.component.ts
@@ -2,7 +2,7 @@ import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, E
 import { fromEvent, Subject, Subscription } from "rxjs";
 import { buffer, debounceTime } from "rxjs/operators";
 import { FilterNameBySearch } from "./filterNameBySearch.pipe";
-import { serialiseParcellationRegion } from "common/util"
+import { serializeSegment } from "src/viewerModule/nehuba/util";
 
 const insertHighlight: (name: string, searchTerm: string) => string = (name: string, searchTerm: string = '') => {
   const regex = new RegExp(searchTerm, 'gi')
@@ -15,7 +15,7 @@ const getDisplayTreeNode: (searchTerm: string, selectedRegions: any[]) => (item:
   return !!labelIndex
     && !!ngId
     && selectedRegions.findIndex(re =>
-      serialiseParcellationRegion({ labelIndex: re.labelIndex, ngId: re.ngId }) === serialiseParcellationRegion({ ngId, labelIndex }),
+      serializeSegment(re.labelIndex, re.ngId) === serializeSegment(ngId, labelIndex),
     ) >= 0
     ? `<span class="cursor-default regionSelected">${insertHighlight(name, searchTerm)}</span>` + (status ? ` <span class="text-muted">(${insertHighlight(status, searchTerm)})</span>` : ``)
     : `<span class="cursor-default regionNotSelected">${insertHighlight(name, searchTerm)}</span>` + (status ? ` <span class="text-muted">(${insertHighlight(status, searchTerm)})</span>` : ``)
diff --git a/src/atlasComponents/parcellation/regionSearch/regionSearch.component.ts b/src/atlasComponents/parcellation/regionSearch/regionSearch.component.ts
index 6ff6301a2f59a77a959774d31299a679c317bed1..7f98db57dde3788da7a80f1430a86e93f3bbb67f 100644
--- a/src/atlasComponents/parcellation/regionSearch/regionSearch.component.ts
+++ b/src/atlasComponents/parcellation/regionSearch/regionSearch.component.ts
@@ -1,19 +1,18 @@
-import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, Output, TemplateRef, ViewChild } from "@angular/core";
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from "@angular/core";
 import { FormControl } from "@angular/forms";
 import { select, Store } from "@ngrx/store";
 import { combineLatest, Observable, Subject, merge } from "rxjs";
 import { debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith, take, tap, withLatestFrom } from "rxjs/operators";
-import { VIEWER_STATE_ACTION_TYPES } from "src/services/effect/effect";
-import { CHANGE_NAVIGATION, SELECT_REGIONS } from "src/services/state/viewerState.store";
 import { getMultiNgIdsRegionsLabelIndexMap } from "src/services/stateStore.service";
 import { LoggingService } from "src/logging";
 import { MatDialog } from "@angular/material/dialog";
 import { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete";
 import { PureContantService } from "src/util";
-import { viewerStateToggleRegionSelect, viewerStateNavigateToRegion, viewerStateSetSelectedRegions, viewerStateSetSelectedRegionsWithIds } from "src/services/state/viewerState.store.helper";
 import { ARIA_LABELS, CONST } from 'common/constants'
-import { serialiseParcellationRegion } from "common/util"
-import { actionAddToRegionsSelectionWithIds } from "src/services/state/viewerState/actions";
+import { actions } from "src/state/atlasSelection";
+import { SapiRegionModel } from "src/atlasComponents/sapi";
+import { atlasSelection } from "src/state";
+import { serializeSegment } from "src/viewerModule/nehuba/util";
 
 const filterRegionBasedOnText = searchTerm => region => `${region.name.toLowerCase()}${region.status? ' (' + region.status + ')' : null}`.includes(searchTerm.toLowerCase())
   || (region.relatedAreas && region.relatedAreas.some(relatedArea => relatedArea.name && relatedArea.name.toLowerCase().includes(searchTerm.toLowerCase())))
@@ -82,7 +81,7 @@ export class RegionTextSearchAutocomplete {
                 ...region,
                 ngId,
                 labelIndex,
-                labelIndexId: serialiseParcellationRegion({ ngId, labelIndex }),
+                labelIndexId: serializeSegment(ngId, labelIndex),
               })
             }
           }
@@ -95,17 +94,6 @@ export class RegionTextSearchAutocomplete {
       shareReplay(1),
     )
 
-    this.regionsSelected$ = viewerState$.pipe(
-      select('regionsSelected'),
-      distinctUntilChanged(),
-      tap(regions => {
-        const arrLabelIndexId = regions.map(({ ngId, labelIndex }) => serialiseParcellationRegion({ ngId, labelIndex }))
-        this.selectedRegionLabelIndexSet = new Set(arrLabelIndexId)
-      }),
-      startWith([]),
-      shareReplay(1),
-    )
-
     this.autocompleteList$ = combineLatest(
       merge(
         this.manualRenderList$.pipe(
@@ -134,35 +122,10 @@ export class RegionTextSearchAutocomplete {
     )
   }
 
-  public toggleRegionWithId(id: string, removeFlag= false) {
-    if (removeFlag) {
-      this.store$.dispatch({
-        type: VIEWER_STATE_ACTION_TYPES.DESELECT_REGIONS_WITH_ID,
-        deselecRegionIds: [id],
-      })
-    } else {
-      this.store$.dispatch(
-        actionAddToRegionsSelectionWithIds({
-          selectRegionIds : [id],
-        })
-      )
-    }
-  }
-
-  public navigateTo(position) {
-    this.store$.dispatch({
-      type: CHANGE_NAVIGATION,
-      navigation: {
-        position,
-        animation: {},
-      },
-    })
-  }
-
-  public optionSelected(_ev?: MatAutocompleteSelectedEvent) {
+  public optionSelected(_ev: MatAutocompleteSelectedEvent) {
     this.store$.dispatch(
-      viewerStateSetSelectedRegionsWithIds({
-        selectRegionIds: _ev ? [ _ev.option.value ] : []
+      actions.toggleRegionSelectById({
+        id: _ev.option.value
       })
     )
   }
@@ -174,7 +137,9 @@ export class RegionTextSearchAutocomplete {
   public filterNullFn(item: any){
     return !!item
   }
-  public regionsSelected$: Observable<any>
+  public regionsSelected$: Observable<SapiRegionModel[]> = this.store$.pipe(
+    select(atlasSelection.selectors.selectedRegions)
+  )
   public parcellationSelected$: Observable<any>
 
   @Output()
@@ -189,26 +154,25 @@ export class RegionTextSearchAutocomplete {
     return this._focused
   }
 
-  public deselectAllRegions(_event: MouseEvent) {
-    this.store$.dispatch({
-      type: SELECT_REGIONS,
-      selectRegions: [],
-    })
+  public deselectAllRegions() {
+    this.store$.dispatch(
+      actions.clearSelectedRegions()
+    )
   }
 
   // TODO handle mobile
   public handleRegionClick({ mode = null, region = null } = {}) {
     if (mode === 'single') {
       this.store$.dispatch(
-        viewerStateToggleRegionSelect({
-          payload: { region }
+        actions.toggleRegionSelect({
+          region
         })
       )
     }
     if (mode === 'double') {
       this.store$.dispatch(
-        viewerStateNavigateToRegion({
-          payload: { region }
+        actions.navigateToRegion({
+          region
         })
       )
     }
@@ -243,8 +207,8 @@ export class RegionTextSearchAutocomplete {
 
   public deselectAndSelectRegion(region: any) {
     this.store$.dispatch(
-      viewerStateSetSelectedRegions({
-        selectRegions: [ region ]
+      actions.selectRegions({
+        regions: [ region ]
       })
     )
   }
diff --git a/src/atlasComponents/parcellation/regionSearch/regionSearch.template.html b/src/atlasComponents/parcellation/regionSearch/regionSearch.template.html
index 965cc3c65d508042857b48f489afaf00ee6e2364..f9f7e26ad60fbaee9531afc50d6b35cd2d3eace0 100644
--- a/src/atlasComponents/parcellation/regionSearch/regionSearch.template.html
+++ b/src/atlasComponents/parcellation/regionSearch/regionSearch.template.html
@@ -18,7 +18,7 @@
       <button *ngIf="(regionsSelected$ | async)?.length > 0"
         mat-icon-button
         [attr.aria-label]="CLEAR_SELECTED_REGION"
-        (click)="optionSelected()"  
+        (click)="deselectAllRegions()"  
         matSuffix>
         <i class="fas fa-times"></i>
       </button>
@@ -77,7 +77,7 @@
     [selectedRegions]="regionsSelected$ | async | filterArray : filterNullFn"
     (singleClickRegion)="handleRegionClick({ mode: 'single', region: $event })"
     (doubleClickRegion)="handleRegionClick({ mode: 'double', region: $event })"
-    (clearAllRegions)="deselectAllRegions($event)"
+    (clearAllRegions)="deselectAllRegions()"
     [parcellationSelected]="parcellationSelected$ | async">
   
   </region-hierarchy>
diff --git a/src/atlasComponents/parcellationRegion/module.ts b/src/atlasComponents/parcellationRegion/module.ts
index 03aceeb2d6353c60a3bdb08a634fbbd87a4199d8..8c995808ea52f2b2fa72d9e1272b221387d04200 100644
--- a/src/atlasComponents/parcellationRegion/module.ts
+++ b/src/atlasComponents/parcellationRegion/module.ts
@@ -7,13 +7,12 @@ import { RenderViewOriginDatasetLabelPipe } from "./region.base";
 import { RegionDirective } from "./region.directive";
 import { RegionMenuComponent } from "./regionMenu/regionMenu.component";
 import { SimpleRegionComponent } from "./regionSimple/regionSimple.component";
-import { BSFeatureModule } from "../regionalFeatures/bsFeatures";
 import { RegionAccordionTooltipTextPipe } from "./regionAccordionTooltipText.pipe";
 import { AtlasCmptConnModule } from "../connectivity";
 import { HttpClientModule } from "@angular/common/http";
 import { RegionInOtherTmplPipe } from "./regionInOtherTmpl.pipe";
 import { SiibraExplorerTemplateModule } from "../template";
-import { KgDatasetModule } from "../regionalFeatures/bsFeatures/kgDataset";
+import { RegionalFeaturesModule } from "./regionalFeatures/module";
 
 @NgModule({
   imports: [
@@ -21,11 +20,11 @@ import { KgDatasetModule } from "../regionalFeatures/bsFeatures/kgDataset";
     UtilModule,
     AngularMaterialModule,
     ComponentsModule,
-    BSFeatureModule,
     AtlasCmptConnModule,
     HttpClientModule,
     SiibraExplorerTemplateModule,
-    KgDatasetModule,
+
+    RegionalFeaturesModule,
   ],
   declarations: [
     RegionMenuComponent,
diff --git a/src/atlasComponents/parcellationRegion/region.base.spec.ts b/src/atlasComponents/parcellationRegion/region.base.spec.ts
index 3e4085c70e1df483bd89f47e31dda4c3d167f1da..d3ead88e500af377ccbedc9ea0d2447187deddc5 100644
--- a/src/atlasComponents/parcellationRegion/region.base.spec.ts
+++ b/src/atlasComponents/parcellationRegion/region.base.spec.ts
@@ -1,7 +1,7 @@
 import { TestBed } from '@angular/core/testing'
 import { MockStore, provideMockStore } from '@ngrx/store/testing'
 import { viewerStateSelectTemplateWithId } from 'src/services/state/viewerState/actions'
-import { RegionBase, getRegionParentParcRefSpace } from './region.base'
+import { RegionBase } from './region.base'
 import { TSiibraExRegion } from './type'
 
 // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -39,7 +39,6 @@ describe('> region.base.ts', () => {
         ]
       })
       mockStore = TestBed.inject(MockStore)
-      mockStore.overrideSelector(getRegionParentParcRefSpace, { template: null, parcellation: null })
     })
     describe('> position', () => {
       beforeEach(() => {
@@ -116,7 +115,6 @@ describe('> region.base.ts', () => {
       beforeEach(() => {
         strToRgbSpy = spyOn(util, 'strToRgb')
         mockStore = TestBed.inject(MockStore)
-        mockStore.overrideSelector(getRegionParentParcRefSpace, { template: null, parcellation: null })
       })
 
       afterEach(() => {
@@ -278,7 +276,7 @@ describe('> region.base.ts', () => {
       //     })
 
       //     expect(dispatchSpy).toHaveBeenCalledWith(
-      //       viewerStateNewViewer({
+      //       actionViewerStateNewViewer({
       //         selectTemplate: fakeTmpl,
       //         selectParcellation: fakeParc,
       //         navigation: {}
@@ -320,7 +318,7 @@ describe('> region.base.ts', () => {
       //     })
 
       //     expect(dispatchSpy).toHaveBeenCalledWith(
-      //       viewerStateNewViewer({
+      //       actionViewerStateNewViewer({
       //         selectTemplate: fakeTmpl,
       //         selectParcellation: fakeParc,
       //         navigation: {
diff --git a/src/atlasComponents/parcellationRegion/region.base.ts b/src/atlasComponents/parcellationRegion/region.base.ts
index 5f4b7d327e4e1432abb128187ec7c738b6a1bd29..382c288a9a5801a994bcbd086e5a68d4583e3914 100644
--- a/src/atlasComponents/parcellationRegion/region.base.ts
+++ b/src/atlasComponents/parcellationRegion/region.base.ts
@@ -1,16 +1,11 @@
 import { Directive, EventEmitter, Input, Output, Pipe, PipeTransform } from "@angular/core";
-import { select, Store, createSelector } from "@ngrx/store";
-import { uiStateOpenSidePanel, uiStateExpandSidePanel, uiActionShowSidePanelConnectivity } from 'src/services/state/uiState.store.helper'
-import { map, tap } from "rxjs/operators";
-import { Observable, BehaviorSubject, combineLatest } from "rxjs";
-import { rgbToHsl } from 'common/util'
-import { viewerStateSetConnectivityRegion, viewerStateNavigateToRegion, viewerStateToggleRegionSelect, viewerStateSelectTemplateWithId } from "src/services/state/viewerState.store.helper";
-import { viewerStateGetSelectedAtlas, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors";
+import { select, Store } from "@ngrx/store";
+import { Observable, BehaviorSubject } from "rxjs";
+import { rgbToHsl, hexToRgb } from 'common/util'
 import { strToRgb, verifyPositionArg } from 'common/util'
-import { getPosFromRegion } from "src/util/siibraApiConstants/fn";
-import { TRegionDetail } from "src/util/siibraApiConstants/types";
-import { IHasId } from "src/util/interfaces";
-import { TSiibraExTemplate } from "./type";
+import { actions } from "src/state/atlasSelection";
+import { SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "../sapi";
+import { atlasSelection } from "src/state";
 
 @Directive()
 export class RegionBase {
@@ -18,16 +13,9 @@ export class RegionBase {
   public rgbString: string
   public rgbDarkmode: boolean
 
-  private _region: TRegionDetail & {  
-    context?: {
-      atlas: IHasId
-      template: IHasId
-      parcellation: IHasId
-    }
-    ngId?: string
-  }
+  private _region: SapiRegionModel
 
-  private _position: [number, number, number]
+  private _position: number[]
   set position(val){
     if (verifyPositionArg(val)) {
       this._position = val
@@ -40,39 +28,51 @@ export class RegionBase {
     return this._position
   }
 
+  public dois: string[] = []
+
+  @Input()
+  atlas: SapiAtlasModel
+
+  @Input()
+  parcellation: SapiParcellationModel
+
+  @Input()
+  template: SapiSpaceModel
+
   @Input()
   set region(val) {
     this._region = val
     this.region$.next(this._region)
-    this.hasContext$.next(!!this._region?.context)
+    this.hasContext$.next(false)
 
     this.position = null
     // bug the centroid returned is currently nonsense
     // this.position = val?.props?.centroid_mm
-    if (!this._region) return
-    const pos = getPosFromRegion(val)
+    if (!val) return
+    const pos = val?.hasAnnotation?.bestViewPoint?.coordinates?.map(v => v.value * 1e6)
     if (pos) {
       this.position = pos
     }
 
-    const rgb = this._region.rgb
-      || (this._region.labelIndex > 65500 && [255, 255, 255])
-      || strToRgb(`${this._region.ngId || this._region.name}${this._region.labelIndex}`)
-      || [255, 200, 200]
-
+    let rgb = [255, 200, 200]
+    if (val.hasAnnotation?.displayColor) {
+      rgb = hexToRgb(val?.hasAnnotation?.displayColor)
+    } else {
+      rgb = strToRgb(JSON.stringify(val))
+    }
     this.rgbString = `rgb(${rgb.join(',')})`
     const [_h, _s, l] = rgbToHsl(...rgb)
     this.rgbDarkmode = l < 0.4
+
+    this.dois = (val.hasAnnotation?.inspiredBy || [])
+      .map(insp => insp["@id"] as string)
+      .filter(id => /^https?:\/\/doi\.org/.test(id))
   }
 
   get region(){
     return this._region
   }
 
-  get originDatainfos(){
-    if (!this._region) return []
-    return (this._region._dataset_specs || []).filter(spec => spec['@type'] === 'minds/core/dataset/v1.0.0')
-  }
 
   public hasContext$: BehaviorSubject<boolean> = new BehaviorSubject(false)
   public region$: BehaviorSubject<any> = new BehaviorSubject(null)
@@ -84,9 +84,8 @@ export class RegionBase {
 
   @Output() public closeRegionMenu: EventEmitter<boolean> = new EventEmitter()
 
-  public regionOriginDatasetLabels$: Observable<{ name: string }[]>
   public selectedAtlas$: Observable<any> = this.store$.pipe(
-    select(viewerStateGetSelectedAtlas)
+    select(atlasSelection.selectors.selectedAtlas)
   )
 
 
@@ -94,24 +93,19 @@ export class RegionBase {
     private store$: Store<any>,
   ) {
 
-    this.regionOriginDatasetLabels$ = combineLatest([
-      this.store$,
-      this.region$
-    ]).pipe(
-      map(([state, region]) => getRegionParentParcRefSpace(state, { region })),
-      map(({ template }) => (template && template.originalDatasetFormats) || [])
-    )
   }
 
   public selectedTemplate$ = this.store$.pipe(
-    select(viewerStateSelectedTemplatePureSelector),
+    select(atlasSelection.selectors.selectedTemplate),
   )
 
   public navigateToRegion() {
     this.closeRegionMenu.emit()
     const { region } = this
     this.store$.dispatch(
-      viewerStateNavigateToRegion({ payload: { region } })
+      atlasSelection.actions.navigateToRegion({
+        region
+      })
     )
   }
 
@@ -119,101 +113,37 @@ export class RegionBase {
     this.closeRegionMenu.emit()
     const { region } = this
     this.store$.dispatch(
-      viewerStateToggleRegionSelect({ payload: { region } })
+      actions.toggleRegionSelect({
+        region
+      })
     )
   }
 
   public showConnectivity(regionName) {
     this.closeRegionMenu.emit()
     // ToDo trigger side panel opening with effect
-    this.store$.dispatch(uiStateOpenSidePanel())
-    this.store$.dispatch(uiStateExpandSidePanel())
-    this.store$.dispatch(uiActionShowSidePanelConnectivity())
-
-    this.store$.dispatch(
-      viewerStateSetConnectivityRegion({ connectivityRegion: regionName })
-    )
+    // this.store$.dispatch(uiStateOpenSidePanel())
+    // this.store$.dispatch(uiStateExpandSidePanel())
+    // this.store$.dispatch(uiActionShowSidePanelConnectivity())
+
+    // I think we can use viewerMode for this??
+    // this.store$.dispatch(
+    //   viewerStateSetConnectivityRegion({ connectivityRegion: regionName })
+    // )
   }
 
-  changeView(template: TSiibraExTemplate) {
+  changeView(template: SapiSpaceModel) {
 
     this.closeRegionMenu.emit()
-
-    const {
-      parcellation
-    } = (this.region?.context || {})
-    
-    /**
-     * TODO use createAction in future
-     * for now, not importing const because it breaks tests
-     */
     this.store$.dispatch(
-      viewerStateSelectTemplateWithId({
-        payload: {
-          '@id': template['@id'] || template['fullId']
-        },
-        config: {
-          selectParcellation: {
-            '@id': parcellation['@id'] || parcellation['fullId']
-          }
-        }
+      atlasSelection.actions.viewSelRegionInNewSpace({
+        region: this._region,
+        template,
       })
     )
   }
 }
 
-export const getRegionParentParcRefSpace = createSelector(
-  (state: any) => state.viewerState,
-  viewerStateGetSelectedAtlas,
-  (viewerState, selectedAtlas, prop) => {
-    const { region: regionOfInterest } = prop
-    /**
-     * if region is undefined, return null
-     */
-    if (!regionOfInterest || !viewerState.parcellationSelected || !viewerState.templateSelected) {
-      return {
-        template: null,
-        parcellation: null
-      }
-    }
-    /**
-     * first check if the region can be found in the currently selected parcellation
-     */
-    const checkRegions = regions => {
-      for (const region of regions) {
-
-        /**
-         * check ROI to iterating regions
-         */
-        if (region.name === regionOfInterest.name) return true
-
-        if (region && region.children && Array.isArray(region.children)) {
-          const flag = checkRegions(region.children)
-          if (flag) return true
-        }
-      }
-      return false
-    }
-    const regionInParcSelected = checkRegions(viewerState.parcellationSelected.regions)
-
-    if (regionInParcSelected) {
-      const p = selectedAtlas.parcellations.find(p => p['@id'] === viewerState.parcellationSelected['@id'])
-      if (p) {
-        const refSpace = p.availableIn.find(refSpace => refSpace['@id'] === viewerState.templateSelected['@id'])
-        return {
-          template: refSpace,
-          parcellation: p
-        }
-      }
-    }
-
-    return {
-      template: null,
-      parcellation: null
-    }
-  }
-)
-
 @Pipe({
   name: 'renderViewOriginDatasetlabel'
 })
diff --git a/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.template.html b/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.template.html
index 979ed7a4f93b1544066e828425e241e5d341d5bb..ad8c518d75db71e06e2b116fd7ca0c34ff91a5f6 100644
--- a/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.template.html
+++ b/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.template.html
@@ -33,17 +33,13 @@
       </button>
 
       <!-- explore doi -->
-      <ng-template let-infos [ngIf]="originDatainfos">
-        <ng-container *ngFor="let info of infos">
-          <a *ngFor="let url of info.urls"
-            [href]="url.doi | doiParserPipe"
-            [matTooltip]="ARIA_LABELS.EXPLORE_DATASET_IN_KG"
-            target="_blank"
-            mat-icon-button>
-            <i class="fas fa-external-link-alt"></i>
-          </a>
-        </ng-container>
-      </ng-template>
+      <a *ngFor="let doi of dois"
+        [href]="doi | doiParserPipe"
+        [matTooltip]="ARIA_LABELS.EXPLORE_DATASET_IN_KG"
+        target="_blank"
+        mat-icon-button>
+        <i class="fas fa-external-link-alt"></i>
+      </a>
 
     </mat-card-subtitle>
 
@@ -53,7 +49,8 @@
 <mat-accordion class="d-block mt-2">
 
   <!-- description -->
-  <ng-template [ngIf]="(originDatainfos || []).length > 0">
+  <!-- TODO how are we going to get desc for PEV? -->
+  <!-- <ng-template [ngIf]="(originDatainfos || []).length > 0">
     <ng-container *ngFor="let originData of originDatainfos">
       <ng-template #descTmpl>
         <markdown-dom [markdown]="originData.description"
@@ -70,62 +67,22 @@
 
       </ng-container>
     </ng-container>
-  </ng-template>
+  </ng-template> -->
 
 
   <!-- Explore in other template -->
-  <ng-template [ngIf]="region$ | async | regionInOtherTmpl" let-otherTmpls>
-    <ng-template #exploreInOtherTmpl>
-      <mat-grid-list cols="3"
-        rowHeight="2:3"
-        gutterSize="16"
-        class="position-relative">
-        <mat-grid-tile *ngFor="let otherTmpl of otherTmpls">
-          
-          <div [hidden]
-              iav-dataset-show-dataset-dialog
-              [iav-dataset-show-dataset-dialog-name]="otherTmpl.originDatainfos[0]?.name"
-              [iav-dataset-show-dataset-dialog-description]="otherTmpl.originDatainfos[0]?.description"
-              [iav-dataset-show-dataset-dialog-urls]="otherTmpl.originDatainfos[0]?.urls"
-              [iav-dataset-show-dataset-dialog-ignore-overwrite]="true"
-              #kgInfo="iavDatasetShowDatasetDialog">
-          </div>
-          <tile-cmp [tile-image-src]="otherTmpl | getTemplatePreviewUrl"
-              class="cursor-pointer pe-all"
-              tile-image-alt="Preview of this tile"
-              [tile-text]="otherTmpl.displayName || otherTmpl.name"
-              [tile-show-info]="otherTmpl.originDatainfos?.length > 0"
-              [tile-image-darktheme]="otherTmpl | templateIsDarkTheme"
-              [tile-selected]="(selectedTemplate$ | async | getProperty : '@id') === otherTmpl['@id']"
-              (tile-on-click)="(tileCmp.selected || changeView(otherTmpl)); (tileCmp.selected || intentToChgTmpl$.next(true))"
-              (tile-on-info-click)="kgInfo && kgInfo.onClick()"
-              #tileCmp="tileCmp">
-          </tile-cmp>
-        </mat-grid-tile>
-      </mat-grid-list>
-
-      <div *ngIf="lockOtherTmpl$ | async" class="loading-overlay">
-        <spinner-cmp class="spinner"></spinner-cmp>
-      </div>
-
-    </ng-template>
-
-    <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-      title: 'Explore in other templates',
-      desc: otherTmpls.length,
-      iconClass: 'fas fa-brain',
-      iconTooltip: otherTmpls.length | regionAccordionTooltipTextPipe : 'regionInOtherTmpl',
-      iavNgIf: otherTmpls.length > 0,
-      content: exploreInOtherTmpl
-    }">
-    </ng-container>
-  </ng-template>
+  TODO reimplmenent explore in other templates
+  perhaps extract the tile into a separate ui component (?)
 
 
   <!-- kg regional features list -->
   <ng-template #kgRegionalFeatureList>
-    <regional-feature-wrapper [region]="region$ | async">
-    </regional-feature-wrapper>
+    <regional-features-list
+      [region]="region$ | async"
+      [atlas]="atlas"
+      [template]="template"
+      [parcellation]="parcellation">
+    </regional-features-list>
   </ng-template>
 
   <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
@@ -134,7 +91,7 @@
     content: kgRegionalFeatureList,
     desc: '',
     iconTooltip: 'Regional Features',
-    iavNgIf: hasContext$ | async
+    iavNgIf: true
   }">
   </ng-container>
 
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.style.css b/src/atlasComponents/parcellationRegion/regionalFeatures/index.ts
similarity index 100%
rename from src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.style.css
rename to src/atlasComponents/parcellationRegion/regionalFeatures/index.ts
diff --git a/src/atlasComponents/parcellationRegion/regionalFeatures/module.ts b/src/atlasComponents/parcellationRegion/regionalFeatures/module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6ce100730a8d94dd18471110623f89364eab081d
--- /dev/null
+++ b/src/atlasComponents/parcellationRegion/regionalFeatures/module.ts
@@ -0,0 +1,18 @@
+import { CommonModule } from "@angular/common";
+import { NgModule } from "@angular/core";
+import { AngularMaterialModule } from "src/sharedModules";
+import { RegionalFeaturesList } from "./regionalFeaturesList/regionalFeaturesList.component";
+
+@NgModule({
+  imports: [
+    CommonModule,
+    AngularMaterialModule,
+  ],
+  declarations: [
+    RegionalFeaturesList
+  ],
+  exports: [
+    RegionalFeaturesList
+  ]
+})
+export class RegionalFeaturesModule{}
diff --git a/src/atlasComponents/parcellationRegion/regionalFeatures/regionalFeaturesList/regionalFeaturesList.component.ts b/src/atlasComponents/parcellationRegion/regionalFeatures/regionalFeaturesList/regionalFeaturesList.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..07c94787ed920a6c58463c99b11343561813eeec
--- /dev/null
+++ b/src/atlasComponents/parcellationRegion/regionalFeatures/regionalFeaturesList/regionalFeaturesList.component.ts
@@ -0,0 +1,57 @@
+import { Component, Input, OnChanges, OnInit, SimpleChanges } from "@angular/core";
+import { BehaviorSubject, Observable, Subject } from "rxjs";
+import { filter, shareReplay, startWith, switchMap, tap } from "rxjs/operators";
+import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionalFeatureModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
+
+@Component({
+  selector: 'regional-features-list',
+  templateUrl: './regionalFeaturesList.template.html',
+  styleUrls: [
+    './regionalFeaturesList.style.css'
+  ]
+})
+
+export class RegionalFeaturesList implements OnChanges, OnInit{
+
+  @Input()
+  atlas: SapiAtlasModel
+
+  @Input()
+  template: SapiSpaceModel
+
+  @Input()
+  parcellation: SapiParcellationModel
+
+  @Input()
+  region: SapiRegionModel
+
+  private ATPR$ = new BehaviorSubject<{
+    atlas: SapiAtlasModel
+    template: SapiSpaceModel
+    parcellation: SapiParcellationModel
+    region: SapiRegionModel
+  }>(null)
+
+  public listOfFeatures$: Observable<SapiRegionalFeatureModel[]> = this.ATPR$.pipe(
+    filter(arg => {
+      if (!arg) return false
+      const { atlas, parcellation, region, template } = arg
+      return !!atlas && !!parcellation && !!region && !!template 
+    }),
+    switchMap(({ atlas, parcellation, region, template }) => this.sapi.getRegionFeatures(atlas["@id"], parcellation["@id"], template["@id"], region.name)),
+    startWith([]),
+    shareReplay(1),
+  )
+
+  ngOnChanges(): void {
+    const { atlas, template, parcellation, region } = this
+    this.ATPR$.next({ atlas, template, parcellation, region })
+  }
+
+  ngOnInit(): void {
+    // this.ngOnChanges()
+  }
+
+  constructor(private sapi: SAPI){
+  }
+}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.style.css b/src/atlasComponents/parcellationRegion/regionalFeatures/regionalFeaturesList/regionalFeaturesList.style.css
similarity index 100%
rename from src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.style.css
rename to src/atlasComponents/parcellationRegion/regionalFeatures/regionalFeaturesList/regionalFeaturesList.style.css
diff --git a/src/atlasComponents/parcellationRegion/regionalFeatures/regionalFeaturesList/regionalFeaturesList.template.html b/src/atlasComponents/parcellationRegion/regionalFeatures/regionalFeaturesList/regionalFeaturesList.template.html
new file mode 100644
index 0000000000000000000000000000000000000000..b6f9f0fb993a884b38b63cd050cd05f30331273a
--- /dev/null
+++ b/src/atlasComponents/parcellationRegion/regionalFeatures/regionalFeaturesList/regionalFeaturesList.template.html
@@ -0,0 +1,9 @@
+<ng-template ngFor let-first="first" let-feature [ngForOf]="listOfFeatures$ | async">
+  
+  <mat-divider *ngIf="!first">
+  </mat-divider>
+
+  <div mat-ripple class="pt-4 cursor-default">
+    {{ feature.metadata.fullName }}
+  </div>
+</ng-template>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/bsRegionInputBase.ts b/src/atlasComponents/regionalFeatures/bsFeatures/bsRegionInputBase.ts
deleted file mode 100644
index 85d2e6d005bca99c7d003f148bc6a93fe7e2acb7..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/bsRegionInputBase.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { BehaviorSubject, throwError } from "rxjs";
-import { map, switchMap } from "rxjs/operators";
-import { TRegion, IBSSummaryResponse, IBSDetailResponse } from "./type";
-import { BsFeatureService, TFeatureCmpInput } from "./service";
-import { flattenReducer } from 'common/util'
-import { Directive, Input } from "@angular/core";
-
-@Directive()
-export class BsRegionInputBase{
-
-  protected region$ = new BehaviorSubject<TRegion>(null)
-  private _region: TRegion
-
-  @Input()
-  set region(val: TRegion) {
-    this._region = val
-    this.region$.next(val)
-  }
-
-  get region() {
-    return this._region
-  }
-
-  constructor(
-    private svc: BsFeatureService,
-    data?: TFeatureCmpInput
-  ){
-    if (data) {
-      this.region = data.region
-    }
-  }
-
-  protected featuresList$ = this.region$.pipe(
-    switchMap(region => this.svc.listFeatures(region)),
-    map(result => result.features.map(obj => Object.keys(obj).reduce(flattenReducer, [])))
-  )
-
-  protected getFeatureInstancesList<T extends keyof IBSSummaryResponse>(feature: T){
-    if (!this._region) return throwError('#getFeatureInstancesList region needs to be defined')
-    return this.svc.getFeatures<T>(feature, this._region)
-  }
-
-  protected getFeatureInstance<T extends keyof IBSDetailResponse>(feature: T, id: string) {
-    if (!this._region) return throwError('#getFeatureInstance region needs to be defined')
-    return this.svc.getFeature<T>(feature, this._region, id)
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/constants.ts b/src/atlasComponents/regionalFeatures/bsFeatures/constants.ts
deleted file mode 100644
index 3746ac94431b1b414a26a5e5fb1d6aa3b46ab0a4..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/constants.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { InjectionToken } from "@angular/core";
-import { Observable } from "rxjs";
-export { BS_ENDPOINT } from 'src/util/constants'
-
-export const BS_DARKTHEME = new InjectionToken<Observable<boolean>>('BS_DARKTHEME')
-export const REGISTERED_FEATURE_INJECT_DATA = new InjectionToken('REGISTERED_FEATURE_INJECT_DATA')
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.component.ts
deleted file mode 100644
index ca0d7c57c1c17a4fe011b05d05bd5d1cea13f6f5..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.component.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-import { AfterViewInit, ChangeDetectorRef, Component, Inject, Input, OnChanges, OnDestroy, Optional, TemplateRef, ViewChild, ViewContainerRef, ViewRef } from "@angular/core";
-import { BsRegionInputBase } from "../../bsRegionInputBase";
-import { KG_REGIONAL_FEATURE_KEY, TBSDetail, UNDER_REVIEW } from "../../kgRegionalFeature/type";
-import { ARIA_LABELS, CONST } from 'common/constants'
-import { TBSSummary } from "../../kgDataset";
-import { BsFeatureService } from "../../service";
-import { MAT_DIALOG_DATA } from "@angular/material/dialog";
-import { TDatainfosDetail } from "src/util/siibraApiConstants/types";
-import { TRegion } from "../../type";
-
-/**
- * this component is specifically used to render side panel ebrains dataset view
- */
-
-export type TInjectableData = TDatainfosDetail & {
-  dataType?: string
-  view?: ViewRef | TemplateRef<any>
-  region?: TRegion
-  summary?: TBSSummary
-  isGdprProtected?: boolean
-}
-
-@Component({
-  selector: 'generic-info-cmp',
-  templateUrl: './genericInfo.template.html',
-  styleUrls: [
-    './genericInfo.style.css'
-  ]
-})
-
-export class GenericInfoCmp extends BsRegionInputBase implements OnChanges, AfterViewInit, OnDestroy {
-
-  public ARIA_LABELS = ARIA_LABELS
-  public CONST = CONST
-
-  @Input()
-  public summary: TBSSummary
-
-  @Input()
-  public detail: TBSDetail
-
-  public loadingFlag = false
-  public error = null
-
-  public nameFallback = `[This dataset cannot be fetched right now]`
-  public isGdprProtected = false
-
-  public descriptionFallback = `[This dataset cannot be fetched right now]`
-  public useClassicUi = false
-  public dataType = 'ebrains regional dataset'
-
-  public description: string
-  public name: string
-  public urls: {
-    cite: string
-    doi: string
-  }[]
-
-  public doiUrls: {
-    cite: string
-    doi: string
-  }[]
-
-  template: TemplateRef<any>
-  viewref: ViewRef
-
-  @ViewChild('insertViewTarget', { read: ViewContainerRef })
-  insertedViewVCR: ViewContainerRef
-
-  constructor(
-    svc: BsFeatureService,
-    private cdr: ChangeDetectorRef,
-    @Optional() @Inject(MAT_DIALOG_DATA) data: TInjectableData
-  ){
-    super(svc)
-    if (data) {
-      const { dataType, description, name, urls, useClassicUi, view, region, summary, isGdprProtected } = data
-      this.description = description
-      this.name = name
-      this.urls = urls || []
-      this.doiUrls = this.urls.filter(d => !!d.doi)
-      this.useClassicUi = useClassicUi
-      if (dataType) this.dataType = dataType
-      if (typeof isGdprProtected !== 'undefined') this.isGdprProtected = isGdprProtected
-
-      if (!!view) {
-        if (view instanceof TemplateRef){
-          this.template = view
-        } else {
-          this.viewref = view
-        }
-      }
-
-      if (region && summary) {
-        this.region = region
-        this.summary = summary
-        this.ngOnChanges()
-      }
-    }
-  }
-
-  ngOnDestroy(){
-    this.insertedViewVCR.clear()
-  }
-
-  ngAfterViewInit(){
-    if (this.insertedViewVCR && this.viewref) {
-      this.insertedViewVCR.insert(this.viewref)
-    }
-  }
-
-  ngOnChanges(){
-    if (!this.region) return
-    if (!this.summary) return
-    if (!!this.detail) return
-    this.loadingFlag = true
-    this.getFeatureInstance(KG_REGIONAL_FEATURE_KEY, this.summary['@id']).subscribe(
-      detail => {
-        this.detail = detail
-
-        this.name = this.detail.src_name
-        this.description = this.detail.__detail?.description
-        this.urls = this.detail.__detail.kgReference.map(url => {
-          return { cite: null, doi: url }
-        })
-        
-        this.isGdprProtected = detail.__detail.embargoStatus && detail.__detail.embargoStatus.some(status => status["@id"] === UNDER_REVIEW["@id"])
-      },
-      err => {
-        this.error = err.toString()
-      },
-      () => {
-        this.loadingFlag = false
-        this.cdr.markForCheck()
-      }
-    )
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/index.ts b/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/index.ts
deleted file mode 100644
index d38b8440733fc665a74c75e3d9fa574ec90dfe26..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { GenericInfoModule } from './module'
-export { GenericInfoCmp, TInjectableData } from './genericInfoCmp/genericInfo.component'
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/module.ts b/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/module.ts
deleted file mode 100644
index 7f1391e10a378a65c95fd3c8261a5d35509106bf..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/module.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { Component, Inject, NgModule, Optional } from "@angular/core";
-import { MAT_DIALOG_DATA } from "@angular/material/dialog";
-import { ComponentsModule } from "src/components";
-import { AngularMaterialModule } from "src/sharedModules";
-import { UtilModule } from "src/util";
-import { IAV_DATASET_SHOW_DATASET_DIALOG_CMP } from "../kgDataset/showDataset/showDataset.directive";
-import { GenericInfoCmp } from "./genericInfoCmp/genericInfo.component";
-
-@Component({
-  selector: 'show-ds-dialog-cmp',
-  template: `
-<ng-template [ngIf]="useClassicUi" [ngIfElse]="modernUiTmpl">
-  <generic-info-cmp></generic-info-cmp>
-</ng-template>
-
-<ng-template #modernUiTmpl>
-
-  <mat-dialog-content class="m-0 p-0">
-    <generic-info-cmp></generic-info-cmp>
-  </mat-dialog-content>
-
-  <mat-dialog-actions align="center">
-    <button mat-button mat-dialog-close>
-      Close
-    </button>
-  </mat-dialog-actions>
-
-</ng-template>
-`
-})
-
-export class ShowDsDialogCmp{
-  public useClassicUi = false
-  constructor(
-    @Optional() @Inject(MAT_DIALOG_DATA) data: any
-  ){
-    this.useClassicUi = data.useClassicUi
-  }
-}
-
-@NgModule({
-  imports: [
-    CommonModule,
-    AngularMaterialModule,
-    UtilModule,
-    ComponentsModule,
-  ],
-  declarations: [
-    GenericInfoCmp,
-    ShowDsDialogCmp,
-  ],
-  exports: [
-    GenericInfoCmp,
-  ],
-
-  providers: [
-    {
-      provide: IAV_DATASET_SHOW_DATASET_DIALOG_CMP,
-      useValue: ShowDsDialogCmp
-    }
-  ]
-})
-
-export class GenericInfoModule{}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.component.ts
deleted file mode 100644
index 1694e857d446519312a46d43254edd66323627ee..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.component.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import { Component, Inject, OnDestroy, Optional } from "@angular/core";
-import { Store } from "@ngrx/store";
-import { BehaviorSubject, forkJoin, merge, Observable, of, Subscription } from "rxjs";
-import { catchError, mapTo, switchMap } from "rxjs/operators";
-import { viewerStateAddUserLandmarks, viewerStateChangeNavigation, viewreStateRemoveUserLandmarks } from "src/services/state/viewerState/actions";
-import { BsRegionInputBase } from "../../bsRegionInputBase";
-import { REGISTERED_FEATURE_INJECT_DATA } from "../../constants";
-import { BsFeatureService, TFeatureCmpInput } from "../../service";
-import { SIIBRA_FEATURE_KEY, TContactPoint, TElectrode, TBSIeegSessionDetail } from '../type'
-import { ARIA_LABELS, CONST } from 'common/constants'
-
-@Component({
-  selector: 'bs-feature-ieeg.cmp',
-  templateUrl: './ieeg.template.html',
-  styleUrls: [
-    './ieeg.style.css'
-  ]
-})
-
-export class BsFeatureIEEGCmp extends BsRegionInputBase implements OnDestroy{
-
-  public ARIA_LABELS = ARIA_LABELS
-  public CONST = CONST
-
-  private featureId: string
-
-  private results: TBSIeegSessionDetail[] = []
-  constructor(
-    private store: Store<any>,
-    svc: BsFeatureService,
-    @Optional() @Inject(REGISTERED_FEATURE_INJECT_DATA) data: TFeatureCmpInput,
-  ){
-    super(svc, data)
-    if (data.featureId) this.featureId = data.featureId
-    this.subs.push(
-      this.results$.subscribe(results => {
-        this.results = results
-        this.loadLandmarks()
-      })
-    )
-  }
-
-  public results$: Observable<TBSIeegSessionDetail[]>  = this.region$.pipe(
-    switchMap(() => this.getFeatureInstancesList(SIIBRA_FEATURE_KEY).pipe(
-      switchMap(arr => forkJoin(arr.filter(it => {
-        if (!this.featureId) return true
-        return it['@id'] === this.featureId
-      }).map(it => this.getFeatureInstance(SIIBRA_FEATURE_KEY, it["@id"])))),
-      catchError(() => of([]))
-    )),
-  )
-
-  public busy$ = this.region$.pipe(
-    switchMap(() => merge(
-      of(true),
-      this.results$.pipe(
-        mapTo(false)
-      )
-    )),
-  )
-  
-  private subs: Subscription[] = []
-  ngOnDestroy(){
-    this.unloadLandmarks()
-    while(this.subs.length) this.subs.pop().unsubscribe()
-  }
-  private openElectrodeSet = new Set<TElectrode>() 
-  public openElectrode$ = new BehaviorSubject<TElectrode[]>([])
-  handleDatumExpansion(electrode: TElectrode, state: boolean) {
-    if (state) this.openElectrodeSet.add(electrode)
-    else this.openElectrodeSet.delete(electrode)
-    this.openElectrode$.next(Array.from(this.openElectrodeSet))
-    this.loadLandmarks()
-  }
-
-  private loadedLms: {
-    '@id': string
-    id: string
-    name: string
-    position: [number, number, number]
-    color: [number, number, number]
-    showInSliceView: boolean
-  }[] = []
-
-  private unloadLandmarks(){
-    /**
-     * unload all the landmarks first
-     */
-    this.store.dispatch(
-      viewreStateRemoveUserLandmarks({
-        payload: {
-          landmarkIds: this.loadedLms.map(l => l['@id'])
-        }
-      })
-    )
-  }
-
-  private loadLandmarks(){
-    this.unloadLandmarks()
-    this.loadedLms = []
-
-    const lms = [] as {
-      '@id': string
-      id: string
-      name: string
-      position: [number, number, number]
-      color: [number, number, number]
-      showInSliceView: boolean
-    }[]
-
-    for (const detail of this.results) {
-      const subjectKey = detail.sub_id
-      for (const electrodeId in detail.electrodes){
-        const electrode = detail.electrodes[electrodeId]
-        if (!electrode.inRoi) continue
-        for (const cpKey in electrode.contact_points) {
-          const cp = electrode.contact_points[cpKey]
-          const id=`${detail.name}:${subjectKey}#${cpKey}`
-          lms.push({
-            "@id": id,
-            id: id,
-            name: id,
-            position: cp.location,
-            color: cp.inRoi ? [255, 100, 100]: [255, 255, 255],
-            showInSliceView: this.openElectrodeSet.has(electrode)
-          })
-        }
-      }
-    }
-    this.loadedLms = lms
-
-    this.store.dispatch(
-      viewerStateAddUserLandmarks({
-        landmarks: lms
-      })
-    )
-  }
-
-  handleContactPtClk(cp: TContactPoint) {
-    const { location } = cp
-    this.store.dispatch(
-      viewerStateChangeNavigation({
-        navigation: {
-          position: location.map(v => v * 1e6),
-          positionReal: true,
-          animation: {}
-        },
-      })
-    )
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.template.html
deleted file mode 100644
index 2622d200acae890dc47352ef6f0859ccc7125369..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.template.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<ng-template [ngIf]="busy$ | async" [ngIfElse]="contenttmpl">
-  <spinner-cmp></spinner-cmp>
-</ng-template>
-
-<ng-template #contenttmpl>
-  <ng-container *ngFor="let result of results$ | async">
-    <ng-container *ngFor="let electrodeKeyVal of result | getProperty : 'electrodes' | keyvalue">
-      <ng-template [ngIf]="electrodeKeyVal.value.inRoi">
-        <ng-container *ngTemplateOutlet="electrodeTmpl; context: { $implicit: electrodeKeyVal.value }">
-        </ng-container>
-      </ng-template>
-
-    </ng-container>
-  </ng-container>
-</ng-template>
-
-<!-- template for electrode -->
-<ng-template #electrodeTmpl let-electrode>
-
-  <mat-expansion-panel
-    [expanded]="openElectrode$ | async | includes : electrode"
-    (opened)="handleDatumExpansion(electrode, true)"
-    (closed)="handleDatumExpansion(electrode, false)"
-    togglePosition="before">
-    <mat-expansion-panel-header>
-      <mat-panel-title>
-        Electrode
-      </mat-panel-title>
-      <mat-panel-description class="text-nowrap">
-        {{ electrode.electrode_id }}
-      </mat-panel-description>
-    </mat-expansion-panel-header>
-
-
-    <!-- <label for="task-list" class="d-block mat-h4 mt-4 text-muted">
-      Tasks
-    </label>
-    <section class="d-flex align-items-center mt-1">
-      <section id="task-list" class="flex-grow-1 flex-shrink-1 overflow-x-auto">
-        <div role="list">
-          <mat-chip *ngFor="let task of datum['tasks']" class="ml-1">
-            {{ task }}
-          </mat-chip>
-        </div>
-      </section>
-    </section> -->
-
-    <mat-divider></mat-divider>
-
-    <label for="contact-points-list" class="d-block mat-h4 mt-4 text-muted">
-      Contact Points
-    </label>
-    <section class="d-flex align-items-center mt-1">
-      <section id="contact-points-list" class="flex-grow-1 flex-shrink-1 overflow-x-auto">
-        <div role="list">
-          <mat-chip *ngFor="let cp_kv of electrode.contact_points | keyvalue"
-            [matTooltip]="cp_kv['value']['location']"
-            (click)="handleContactPtClk(cp_kv['value'])"
-            class="ml-1">
-            {{ cp_kv['key'] }}
-          </mat-chip>
-        </div>
-      </section>
-    </section>
-
-  </mat-expansion-panel>
-</ng-template>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCtrl.directive.ts b/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCtrl.directive.ts
deleted file mode 100644
index e7e79ef4a97103ec38993712490cd0ebbb6ebb1b..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCtrl.directive.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Directive, Inject, OnDestroy, Optional } from "@angular/core";
-import { merge, Observable, of, Subscription } from "rxjs";
-import { catchError, mapTo, switchMap } from "rxjs/operators";
-import { BsRegionInputBase } from "../bsRegionInputBase";
-import { REGISTERED_FEATURE_INJECT_DATA } from "../constants";
-import { BsFeatureService, TFeatureCmpInput } from "../service";
-import { IBSSummaryResponse, IRegionalFeatureReadyDirective } from "../type";
-import { SIIBRA_FEATURE_KEY } from './type'
-
-@Directive({
-  selector: '[bs-features-ieeg-directive]',
-  exportAs: 'bsFeatureIeegDirective'
-})
-
-export class BsFeatureIEEGDirective extends BsRegionInputBase implements IRegionalFeatureReadyDirective, OnDestroy{
-
-  public results$: Observable<IBSSummaryResponse['IEEG_Session'][]>  = this.region$.pipe(
-    switchMap(() => this.getFeatureInstancesList(SIIBRA_FEATURE_KEY).pipe(
-      catchError(() => of([]))
-    )),
-  )
-  public busy$ = this.region$.pipe(
-    switchMap(() => merge(
-      of(true),
-      this.results$.pipe(
-        mapTo(false)
-      )
-    ))
-  )
-
-  constructor(
-    svc: BsFeatureService,
-    @Optional() @Inject(REGISTERED_FEATURE_INJECT_DATA) data: TFeatureCmpInput,
-  ){
-    super(svc, data)
-  }
-
-  private sub: Subscription[] = []
-  ngOnDestroy(){
-    while(this.sub.length) this.sub.pop().unsubscribe()
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/index.ts b/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/index.ts
deleted file mode 100644
index e4e8322a07b0f6a2a25ce0b8522e5d2550b2f09b..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export {
-  BsFeatureIEEGModule
-} from './module'
-
-export {
-  IEEG_FEATURE_NAME,
-  SIIBRA_FEATURE_KEY,
-} from './type'
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/module.ts b/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/module.ts
deleted file mode 100644
index 50ea68c3c313509efacea5473ad554e181bddc40..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/module.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { NgModule } from "@angular/core";
-import { ComponentsModule } from "src/components";
-import { AngularMaterialModule } from "src/sharedModules";
-import { UtilModule } from "src/util";
-import { BsFeatureService } from "../service";
-import { BsFeatureIEEGCmp } from "./ieegCmp/ieeg.component";
-import { BsFeatureIEEGDirective } from "./ieegCtrl.directive";
-import { IEEG_FEATURE_NAME } from "./type";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    ComponentsModule,
-    UtilModule,
-    AngularMaterialModule,
-  ],
-  declarations: [
-    BsFeatureIEEGCmp,
-    BsFeatureIEEGDirective
-  ]
-})
-
-export class BsFeatureIEEGModule{
-  constructor(svc: BsFeatureService){
-    svc.registerFeature({
-      name: IEEG_FEATURE_NAME,
-      icon: 'fas fa-info',
-      View: BsFeatureIEEGCmp,
-      Ctrl: BsFeatureIEEGDirective
-    })
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/type.ts b/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/type.ts
deleted file mode 100644
index 8300f694dde812df13206c56c403bd06ebb59be7..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/type.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-export type TBSSummary = {
-  '@id': string
-  name: string
-  description: string
-}
-
-export type TContactPoint = {
-  id: string
-  location: [number, number, number]
-  inRoi?: boolean
-}
-
-export type TElectrode = {
-  electrode_id: string
-  subject_id: string
-  contact_points: {
-    [key: string]: TContactPoint
-  }
-  inRoi?: boolean
-}
-
-export type TBSIeegSessionSummary = {
-  '@id': string
-  name: string
-  description: string
-  origin_datainfos: {
-    urls: {
-      doi: string
-    }[]
-  }[]
-}
-
-type TDetail = {
-  sub_id: string
-  electrodes: {
-    [key: string]: TElectrode
-  }
-  inRoi?: boolean
-}
-
-export type TBSIeegSessionDetail = TBSIeegSessionSummary & TDetail
-
-export const SIIBRA_FEATURE_KEY = 'IEEG_Session'
-export const _SIIBRA_FEATURE_KEY = 'IEEG_Electrode'
-export const IEEG_FEATURE_NAME = 'iEEG recordings'
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/index.ts b/src/atlasComponents/regionalFeatures/bsFeatures/index.ts
deleted file mode 100644
index e571d3c4272b3c27af2343832de0f8d8aabd2399..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export { BSFeatureModule } from './module'
-export { BS_ENDPOINT, BS_DARKTHEME } from './constants'
-export { TRegion } from './type'
-// nb do not export BsRegionInputBase from here
-// will result in cyclic imports
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/getTrailingHex.pipe.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/getTrailingHex.pipe.ts
deleted file mode 100644
index 5314267e7e1f31b8226ab6eea1ac890277781a68..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/getTrailingHex.pipe.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-
-@Pipe({
-  name: 'getTrailingHex',
-  pure: true
-})
-
-export class GetTrailingHexPipe implements PipeTransform{
-  public transform(input: string) {
-    const match = /[0-9a-f-]+$/.exec(input)
-    return match && match[0]
-  }
-}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/index.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/index.ts
deleted file mode 100644
index 337cdf646dd4827cc0f0a9a14f6637d0f4cb129e..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { KgDatasetModule } from './module'
-export { TCountedDataModality, TBSDetail, TBSSummary } from './type'
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.component.spec.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.component.spec.ts
deleted file mode 100644
index 9618701aaa39492065095230cc37d7b524d3fbec..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.component.spec.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { TCountedDataModality } from "../type"
-import { SortModalityAlphabeticallyPipe } from "./modalityPicker.component"
-
-describe('> modalityPicker.component.ts', () => {
-  describe('> ModalityPicker', () => {
-    // TODO
-  })
-
-  describe('> SortModalityAlphabeticallyPipe', () => {
-
-    const mods: TCountedDataModality[] = [{
-      name: 'bbb',
-      occurance: 0,
-      visible: false
-    }, {
-      name: 'AAA',
-      occurance: 1,
-      visible: false
-    }, {
-      name: '007',
-      occurance: 17,
-      visible: false
-    }]
-    const beforeInput = [...mods]
-    const pipe = new SortModalityAlphabeticallyPipe()
-
-    const output = pipe.transform(mods)
-
-    it('> does not mutate', () => {
-      expect(mods).toEqual(beforeInput)
-    })
-    it('> should sort modalities as expected', () => {
-      expect(output).toEqual([
-        mods[2], mods[1], mods[0]
-      ])
-    })
-  })
-})
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.component.ts
deleted file mode 100644
index c00a636533018ec616110d4f366d967144254afa..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.component.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { Component, EventEmitter, Input, OnChanges, Output, Pipe, PipeTransform } from "@angular/core";
-import { TCountedDataModality } from "../type";
-import { ARIA_LABELS } from 'common/constants'
-
-
-@Component({
-  selector: 'modality-picker',
-  templateUrl: './modalityPicker.template.html',
-  styleUrls: [
-    './modalityPicker.style.css',
-  ],
-  host:{
-    'aria-label': ARIA_LABELS.LIST_OF_MODALITIES
-  }
-})
-
-export class ModalityPicker implements OnChanges {
-
-  public modalityVisibility: Set<string> = new Set()
-
-  @Input()
-  public countedDataM: TCountedDataModality[] = []
-
-  public checkedModality: TCountedDataModality[] = []
-
-  @Output()
-  public modalityFilterEmitter: EventEmitter<TCountedDataModality[]> = new EventEmitter()
-
-  // filter(dataentries:DataEntry[]) {
-  //   return this.modalityVisibility.size === 0
-  //     ? dataentries
-  //     : dataentries.filter(de => de.activity.some(a => a.methods.some(m => this.modalityVisibility.has(this.dbService.temporaryFilterDataentryName(m)))))
-  // }
-
-  public ngOnChanges() {
-    this.checkedModality = this.countedDataM.filter(d => d.visible)
-  }
-
-  /**
-   * TODO
-   * togglemodailty should emit event, and let parent handle state
-   */
-  public toggleModality(modality: Partial<TCountedDataModality>) {
-    this.modalityFilterEmitter.emit(
-      this.countedDataM.map(d => d.name === modality.name
-        ? {
-          ...d,
-          visible: !d.visible,
-        }
-        : d),
-    )
-  }
-
-  public uncheckModality(modality: string) {
-    this.toggleModality({name: modality})
-  }
-
-  public clearAll() {
-    this.modalityFilterEmitter.emit(
-      this.countedDataM.map(d => {
-        return {
-          ...d,
-          visible: false,
-        }
-      }),
-    )
-  }
-}
-
-const sortByFn = (a: TCountedDataModality, b: TCountedDataModality) => (a.name || '0').toLowerCase().charCodeAt(0) - (b.name || '0').toLowerCase().charCodeAt(0) 
-
-@Pipe({
-  name: 'sortModalityAlphabetically',
-  pure: true
-})
-
-export class SortModalityAlphabeticallyPipe implements PipeTransform{
-  public transform(arr: TCountedDataModality[]): TCountedDataModality[]{
-    return [...arr].sort(sortByFn)
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.style.css b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.style.css
deleted file mode 100644
index 85feb59e81b8a38ede569688b605d82e39932cca..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.style.css
+++ /dev/null
@@ -1,10 +0,0 @@
-:host
-{
-  display: flex;
-  flex-direction: column;
-}
-
-div
-{
-  white-space: nowrap;
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.template.html
deleted file mode 100644
index 7bde04e8b2cc46f0872d978914bf9c254e79113a..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/modalityPicker/modalityPicker.template.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<fieldset>
-  <legend class="sr-only">
-    Dataset modalities
-  </legend>
-
-  <mat-checkbox
-    
-    [checked]="datamodality.visible"
-    (change)="toggleModality(datamodality)"
-    [ngClass]="{'muted': datamodality.occurance === 0}"
-    *ngFor="let datamodality of countedDataM | sortModalityAlphabetically">
-    {{ datamodality.name }} <span class="text-muted">({{ datamodality.occurance }})</span>
-  </mat-checkbox>
-</fieldset>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/module.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/module.ts
deleted file mode 100644
index 232dba3734ce321bc2fd3a9fb1a5c52d0d4c9256..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/module.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { NgModule } from "@angular/core";
-import { ShowDatasetDialogDirective } from "./showDataset/showDataset.directive";
-import { AngularMaterialModule } from "src/sharedModules";
-import { GetTrailingHexPipe } from "./getTrailingHex.pipe";
-import { ModalityPicker, SortModalityAlphabeticallyPipe } from "./modalityPicker/modalityPicker.component";
-
-// TODO break down into smaller components
-@NgModule({
-  imports: [
-    CommonModule,
-    AngularMaterialModule,
-  ],
-  declarations: [
-    ShowDatasetDialogDirective,
-    GetTrailingHexPipe,
-    ModalityPicker,
-    SortModalityAlphabeticallyPipe,
-  ],
-  exports: [
-    ShowDatasetDialogDirective,
-    GetTrailingHexPipe,
-    ModalityPicker,
-  ]
-})
-
-export class KgDatasetModule{}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.spec.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.spec.ts
deleted file mode 100644
index e37fa07aa72c7366814b10ecdbebb458118795c5..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.spec.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-import { Component } from "@angular/core";
-import { async, TestBed } from "@angular/core/testing";
-import { AngularMaterialModule } from "src/sharedModules";
-import { ShowDatasetDialogDirective, IAV_DATASET_SHOW_DATASET_DIALOG_CMP } from "./showDataset.directive";
-import { By } from "@angular/platform-browser";
-import { MatDialog } from "@angular/material/dialog";
-import { MatSnackBar } from "@angular/material/snack-bar";
-
-@Component({
-  template: ''
-})
-
-class TestCmp{}
-
-const dummyMatDialog = {
-  open: val => {}
-}
-
-const dummyMatSnackBar = {
-  open: val => {}
-}
-
-class DummyDialogCmp{}
-
-describe('ShowDatasetDialogDirective', () => {
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      imports: [
-        AngularMaterialModule
-      ],
-      declarations: [
-        TestCmp,
-        ShowDatasetDialogDirective,
-      ],
-      providers: [
-        {
-          provide: MatDialog,
-          useValue: dummyMatDialog
-        },
-        {
-          provide: MatSnackBar,
-          useValue: dummyMatSnackBar
-        },
-        {
-          provide: IAV_DATASET_SHOW_DATASET_DIALOG_CMP,
-          useValue: DummyDialogCmp
-        }
-      ]
-    })
-  }))
-
-  it('should be able to test directiv,', () => {
-
-    TestBed.overrideComponent(TestCmp, {
-      set: {
-        template: '<div iav-dataset-show-dataset-dialog></div>'
-      }
-    }).compileComponents()
-
-    const fixutre = TestBed.createComponent(TestCmp)
-    const directive = fixutre.debugElement.query( By.directive( ShowDatasetDialogDirective ) )
-
-    expect(directive).not.toBeNull()
-  })
-
-  it('if neither kgId nor fullId is defined, should not call dialog', () => {
-
-    TestBed.overrideComponent(TestCmp, {
-      set: {
-        template: '<div iav-dataset-show-dataset-dialog></div>'
-      }
-    }).compileComponents()
-
-    const snackbarOpenSpy = spyOn(dummyMatSnackBar, 'open').and.callThrough()
-    const dialogOpenSpy = spyOn(dummyMatDialog, 'open').and.callThrough()
-
-    const fixutre = TestBed.createComponent(TestCmp)
-    fixutre.detectChanges()
-
-    const directive = fixutre.debugElement.query( By.directive( ShowDatasetDialogDirective ) )
-    directive.nativeElement.click()
-
-    expect(snackbarOpenSpy).toHaveBeenCalled()
-    expect(dialogOpenSpy).not.toHaveBeenCalled()
-
-    snackbarOpenSpy.calls.reset()
-    dialogOpenSpy.calls.reset()
-  })
-
-  it('if kgId is defined, should call dialogOpen', () => {
-    
-    TestBed.overrideComponent(TestCmp, {
-      set: {
-        template: `
-        <div iav-dataset-show-dataset-dialog
-          iav-dataset-show-dataset-dialog-kgid="aaa-bbb">
-        </div>
-        `
-      }
-    }).compileComponents()
-
-    const snackbarOpenSpy = spyOn(dummyMatSnackBar, 'open').and.callThrough()
-    const dialogOpenSpy = spyOn(dummyMatDialog, 'open').and.callThrough()
-
-    const fixutre = TestBed.createComponent(TestCmp)
-    fixutre.detectChanges()
-
-    const directive = fixutre.debugElement.query( By.directive( ShowDatasetDialogDirective ) )
-    directive.nativeElement.click()
-
-    expect(snackbarOpenSpy).not.toHaveBeenCalled()
-    const mostRecentCall = dialogOpenSpy.calls.mostRecent()
-    const args = mostRecentCall.args as any[]
-
-    expect(args[0]).toEqual(DummyDialogCmp)
-    expect(args[1]).toEqual({
-      ...ShowDatasetDialogDirective.defaultDialogConfig,
-      panelClass: ['no-padding-dialog'],
-      data: {
-        fullId: `minds/core/dataset/v1.0.0/aaa-bbb`
-      }
-    })
-
-    snackbarOpenSpy.calls.reset()
-    dialogOpenSpy.calls.reset()
-  })
-
-  it('if fullId is defined, should call dialogOpen', () => {
-
-    TestBed.overrideComponent(TestCmp, {
-      set: {
-        template: `
-        <div iav-dataset-show-dataset-dialog
-          iav-dataset-show-dataset-dialog-fullid="abc/ccc-ddd">
-        </div>
-        `
-      }
-    }).compileComponents()
-
-    const snackbarOpenSpy = spyOn(dummyMatSnackBar, 'open').and.callThrough()
-    const dialogOpenSpy = spyOn(dummyMatDialog, 'open').and.callThrough()
-
-    const fixutre = TestBed.createComponent(TestCmp)
-    fixutre.detectChanges()
-
-    const directive = fixutre.debugElement.query( By.directive( ShowDatasetDialogDirective ) )
-    directive.nativeElement.click()
-
-    expect(snackbarOpenSpy).not.toHaveBeenCalled()
-    const mostRecentCall = dialogOpenSpy.calls.mostRecent()
-    const args = mostRecentCall.args as any[]
-    expect(args[0]).toEqual(DummyDialogCmp)
-    expect(args[1]).toEqual({
-      ...ShowDatasetDialogDirective.defaultDialogConfig,
-      panelClass: ['no-padding-dialog'],
-      data: {
-        fullId: `abc/ccc-ddd`
-      }
-    })
-
-    snackbarOpenSpy.calls.reset()
-    dialogOpenSpy.calls.reset()
-  })
-})
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/type.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/type.ts
deleted file mode 100644
index e56921ce5c5e1e9adc110ba666dcf1d2eb192be3..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/type.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-export type TCountedDataModality = {
-  name: string
-  occurance: number
-  visible: boolean
-}
-
-export type TBSSummary = {
-  ['@id']: string
-  src_name: string
-}
-
-export type TBSDetail = TBSSummary & {
-  __detail: {
-    formats: string[]
-    datasetDOI: {
-      cite: string
-      doi: string
-    }[]
-    activity: {
-      protocols: string[]
-      preparation: string[]
-    }[]
-    referenceSpaces: {
-      name: string
-      fullId: string
-    }[]
-    methods: string[]
-    custodians: {
-      "schema.org/shortName": string
-      identifier: string
-      name: string
-      '@id': string
-      shortName: string
-    }[]
-    project: string[]
-    description: string
-    parcellationAtlas: {
-      name: string
-      fullId: string
-      id: string[]
-    }[]
-    licenseInfo: {
-      name: string
-      url: string
-    }[]
-    embargoStatus: {
-      identifier: string[]
-      name: string
-      '@id': string
-    }[]
-    license: any[]
-    parcellationRegion: {
-      species: any[]
-      name: string
-      alias: string
-      fullId: string
-    }[]
-    species: string[]
-    name: string
-    files: {
-      byteSize: number
-      name: string
-      absolutePath: string
-      contentType: string
-    }[]
-    fullId: string
-    contributors: {
-      "schema.org/shortName": string
-      identifier: string
-      name: string
-      '@id': string
-      shortName: string
-    }[]
-    id: string
-    kgReference: string[] // aka doi
-    publications: {
-      name: string
-      cite: string
-      doi: string
-    }[]
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/index.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/index.ts
deleted file mode 100644
index 3efa1d80ed5927d3777da4cc28faad043ce7795b..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/index.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-export {
-  KgRegionalFeatureModule
-} from './module'
-
-export {
-  EbrainsRegionalFeatureName,
-  KG_REGIONAL_FEATURE_KEY,
-  UNDER_REVIEW,
-  TBSDetail,
-  TBSSummary
-} from './type'
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.component.ts
deleted file mode 100644
index fd5b0afac18cbfd515e7ef21718e71084f75c0b2..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.component.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { ChangeDetectionStrategy, Component, Inject, Input, OnDestroy, Optional } from "@angular/core";
-import { BehaviorSubject, Subscription } from "rxjs";
-import { filter, switchMap, tap } from "rxjs/operators";
-import { TCountedDataModality } from '../../kgDataset'
-import { BsRegionInputBase } from "../../bsRegionInputBase";
-import { BsFeatureService, TFeatureCmpInput } from "../../service";
-import { KG_REGIONAL_FEATURE_KEY, TBSDetail, TBSSummary } from "../type";
-import { ARIA_LABELS } from 'common/constants'
-import { REGISTERED_FEATURE_INJECT_DATA } from "../../constants";
-
-@Component({
-  selector: 'kg-regional-features-list',
-  templateUrl: './kgRegList.template.html',
-  styleUrls: [
-    './kgRegList.style.css'
-  ],
-  changeDetection: ChangeDetectionStrategy.OnPush
-})
-
-export class KgRegionalFeaturesList extends BsRegionInputBase implements OnDestroy{
-
-  public ARIA_LABELS = ARIA_LABELS
-
-  public dataModalities: TCountedDataModality[] = []
-
-  @Input()
-  public disableVirtualScroll = false
-  
-  public visibleRegionalFeatures: TBSSummary[] = []
-  public kgRegionalFeatures: TBSSummary[] = []
-  public kgRegionalFeatures$ = this.region$.pipe(
-    filter(v => {
-      this.busy$.next(false)
-      return !!v
-    }),
-    // must not use switchmapto here
-    switchMap(() => {
-      this.busy$.next(true)
-      return this.getFeatureInstancesList(KG_REGIONAL_FEATURE_KEY).pipe(
-        tap(() => {
-          this.busy$.next(false)
-        })
-      )
-    })
-  )
-  constructor(
-    svc: BsFeatureService,
-    @Optional() @Inject(REGISTERED_FEATURE_INJECT_DATA) data: TFeatureCmpInput
-  ){
-    super(svc, data)
-    this.sub.push(
-      this.kgRegionalFeatures$.subscribe(val => {
-        this.kgRegionalFeatures = val
-        this.visibleRegionalFeatures = val
-      })
-    )
-  }
-  private sub: Subscription[] = []
-  ngOnDestroy(){
-    while (this.sub.length) this.sub.pop().unsubscribe()
-  }
-
-  public trackByFn(_index: number, dataset: TBSSummary) {
-    return dataset['@id']
-  }
-
-  public detailDict: {
-    [key: string]: TBSDetail
-  } = {}
-
-  public handlePopulatedDetailEv(detail: TBSDetail){
-    this.detailDict = {
-      ...this.detailDict,
-      [detail["@id"]]: detail
-    }
-    for (const method of detail.__detail.methods) {
-      const found = this.dataModalities.find(v => v.name === method)
-      if (found) found.occurance = found.occurance + 1
-      else this.dataModalities.push({
-        name: method,
-        occurance: 1,
-        visible: false
-      })
-    }
-    this.dataModalities = [...this.dataModalities]
-  }
-
-  public busy$ = new BehaviorSubject(false)
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.style.css b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.style.css
deleted file mode 100644
index a0d49c32422a4789531e0cdaf7bf02fd4d43e20f..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.style.css
+++ /dev/null
@@ -1,9 +0,0 @@
-cdk-virtual-scroll-viewport
-{
-  min-height: 24rem;
-}
-
-modality-picker
-{
-  font-size: 90%;
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.template.html
deleted file mode 100644
index 010f4c85971f683525a8f3a6ca7026d648ea0e45..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgRegList.template.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<spinner-cmp *ngIf="busy$ | async; else contentTmpl"></spinner-cmp>
-
-<ng-template #contentTmpl>
-  <cdk-virtual-scroll-viewport
-    [attr.aria-label]="ARIA_LABELS.LIST_OF_DATASETS_ARIA_LABEL"
-    class="h-100"
-    minBufferPx="200"
-    maxBufferPx="400"
-    itemSize="50">
-    <div *cdkVirtualFor="let dataset of visibleRegionalFeatures; trackBy: trackByFn; templateCacheSize: 20; let index = index"
-      class="h-50px overflow-hidden">
-
-      <!-- divider, show if not first -->
-      <mat-divider class="mt-1" *ngIf="index !== 0"></mat-divider>
-
-      <kg-regional-feature-summary
-        mat-ripple
-        iav-dataset-show-dataset-dialog
-        [iav-dataset-show-dataset-dialog-fullid]="dataset['@id']"
-        [iav-dataset-show-dataset-dialog-contexted-region]="region"
-        class="d-block pb-1 pt-1"
-        [region]="region"
-        [loadFull]="false"
-        [summary]="dataset"
-        (loadedDetail)="handlePopulatedDetailEv($event)">
-      </kg-regional-feature-summary>
-
-    </div>
-  </cdk-virtual-scroll-viewport>
-</ng-template>
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgReglist.directive.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgReglist.directive.ts
deleted file mode 100644
index df51bbb7f7c90d589e6e5c843d25f3a7f711f027..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegList/kgReglist.directive.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Directive, EventEmitter, Inject, OnDestroy, Optional, Output } from "@angular/core";
-import { KG_REGIONAL_FEATURE_KEY, TBSSummary } from "../type";
-import { BsFeatureService, TFeatureCmpInput } from "../../service";
-import { BsRegionInputBase } from "../../bsRegionInputBase";
-import { merge, of, Subscription } from "rxjs";
-import { catchError, mapTo, startWith, switchMap, tap } from "rxjs/operators";
-import { IRegionalFeatureReadyDirective } from "../../type";
-import { REGISTERED_FEATURE_INJECT_DATA } from "../../constants";
-
-@Directive({
-  selector: '[kg-regional-features-list-directive]',
-  exportAs: 'kgRegionalFeaturesListDirective'
-})
-
-export class KgRegionalFeaturesListDirective extends BsRegionInputBase implements IRegionalFeatureReadyDirective, OnDestroy {
-  public kgRegionalFeatures: TBSSummary[] = []
-  public kgRegionalFeatures$ = this.region$.pipe(
-    // must not use switchmapto here
-    switchMap(() => {
-      this.busyEmitter.emit(true)
-      return this.getFeatureInstancesList(KG_REGIONAL_FEATURE_KEY).pipe(
-        catchError(() => of([])),
-        tap(() => {
-          this.busyEmitter.emit(false)
-        }),
-      )
-    }),
-    startWith([])
-  )
-  
-  constructor(
-    svc: BsFeatureService,
-    @Optional() @Inject(REGISTERED_FEATURE_INJECT_DATA) data: TFeatureCmpInput,  
-  ){
-    super(svc, data)
-    this.sub.push(
-      this.kgRegionalFeatures$.subscribe(val => {
-        this.kgRegionalFeatures = val
-      })
-    )
-  }
-  private sub: Subscription[] = []
-  ngOnDestroy(){
-    while (this.sub.length) this.sub.pop().unsubscribe()
-  }
-
-  results$ = this.kgRegionalFeatures$
-  busy$ = this.region$.pipe(
-    switchMap(() => merge(
-      of(true),
-      this.results$.pipe(
-        mapTo(false)
-      )
-    ))
-  )
-
-  @Output('kg-regional-features-list-directive-busy')
-  busyEmitter = new EventEmitter<boolean>()
-}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegSummary/kgRegSummary.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegSummary/kgRegSummary.component.ts
deleted file mode 100644
index 841226ad69f75fd821954f624878c4e1a4081de6..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegSummary/kgRegSummary.component.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Component, EventEmitter, Input, OnChanges, Output } from "@angular/core";
-import { BsRegionInputBase } from "../../bsRegionInputBase";
-import { BsFeatureService } from "../../service";
-import { KG_REGIONAL_FEATURE_KEY, TBSDetail, TBSSummary } from '../type'
-
-@Component({
-  selector: 'kg-regional-feature-summary',
-  templateUrl: './kgRegSummary.template.html',
-  styleUrls: [
-    './kgRegSummary.style.css'
-  ],
-  exportAs: 'kgRegionalFeatureSummary'
-})
-
-export class KgRegSummaryCmp extends BsRegionInputBase implements OnChanges{
-
-  @Input()
-  public loadFull = false
-
-  @Input()
-  public summary: TBSSummary = null
-
-  public detailLoaded = false
-  public loadingDetail = false
-  public detail: TBSDetail = null
-  @Output()
-  public loadedDetail = new EventEmitter<TBSDetail>()
-
-  public error: string = null
-  @Output()
-  public errorEmitter = new EventEmitter<string>()
-
-  constructor(svc: BsFeatureService){
-    super(svc)
-  }
-
-  ngOnChanges(){
-    if (this.loadFull && !!this.summary) {
-      if (this.loadingDetail || this.detailLoaded) {
-        return
-      }
-      this.loadingDetail = true
-      this.getFeatureInstance(KG_REGIONAL_FEATURE_KEY, this.summary["@id"]).subscribe(
-        detail => {
-          this.detail = detail
-          this.loadedDetail.emit(detail)
-        },
-        err => {
-          this.error = err
-          this.errorEmitter.emit(err)
-        },
-        () => {
-          this.detailLoaded = true
-          this.loadingDetail = false
-        } 
-      )
-    }
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegSummary/kgRegSummary.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegSummary/kgRegSummary.template.html
deleted file mode 100644
index 5fcb11b2b8f7a550e66a3491430a0629d62f7533..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegSummary/kgRegSummary.template.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<small>
-  {{ summary.src_name }}
-</small>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/module.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/module.ts
deleted file mode 100644
index 878eed872ca8ce48c90e6931eeb4351a2fd44892..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/module.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { Inject, NgModule, Optional } from "@angular/core";
-import { AngularMaterialModule } from "src/sharedModules";
-import { KgRegSummaryCmp } from "./kgRegSummary/kgRegSummary.component";
-import { KgRegionalFeaturesList } from "./kgRegList/kgRegList.component";
-import { KgRegionalFeaturesListDirective } from "./kgRegList/kgReglist.directive";
-import { KgDatasetModule } from "../kgDataset";
-import { UtilModule } from "src/util";
-import { ComponentsModule } from "src/components";
-import { BsFeatureService } from "../service";
-import { EbrainsRegionalFeatureName } from "./type";
-import { GENERIC_INFO_INJ_TOKEN } from "../type";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    AngularMaterialModule,
-    KgDatasetModule,
-    UtilModule,
-    ComponentsModule,
-  ],
-  declarations:[
-    KgRegSummaryCmp,
-    KgRegionalFeaturesList,
-    KgRegionalFeaturesListDirective,
-  ],
-  exports:[
-    KgRegSummaryCmp,
-    KgRegionalFeaturesList,
-    KgRegionalFeaturesListDirective,
-  ],
-})
-
-export class KgRegionalFeatureModule{
-  constructor(
-    svc: BsFeatureService,
-    @Optional() @Inject(GENERIC_INFO_INJ_TOKEN) Cmp: any
-  ){
-    if (!Cmp) {
-      console.warn(`GENERIC_INFO_INJ_TOKEN not injected!`)
-      return
-    }
-    svc.registerFeature({
-      name: EbrainsRegionalFeatureName,
-      icon: 'fas fa-ellipsis-h',
-      View: null,
-      Ctrl: KgRegionalFeaturesListDirective,
-    })
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/type.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/type.ts
deleted file mode 100644
index f7ebe60367da3805b95b90c03237f31d4a23b4f2..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/type.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export {
-  TBSDetail, TBSSummary
-} from '../kgDataset'
-
-export const EbrainsRegionalFeatureName = 'EBRAINS datasets'
-export const KG_REGIONAL_FEATURE_KEY = 'EbrainsRegionalDataset'
-
-export const UNDER_REVIEW = {
-  ['@id']: "https://nexus.humanbrainproject.org/v0/data/minds/core/embargostatus/v1.0.0/1d726b76-b176-47ed-96f0-b4f2e17d5f19"
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/module.ts b/src/atlasComponents/regionalFeatures/bsFeatures/module.ts
deleted file mode 100644
index 20939be689ba1885ac2129c9d8f24e10743df630..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/module.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { NgModule } from "@angular/core";
-import { ComponentsModule } from "src/components";
-import { AngularMaterialModule } from "src/sharedModules";
-import { GenericInfoCmp, GenericInfoModule } from "./genericInfo";
-import { BsFeatureIEEGModule } from "./ieeg/module";
-import { KgRegionalFeatureModule } from "./kgRegionalFeature";
-import { GetBadgeFromFeaturePipe } from "./pipes/getBadgeFromFeature.pipe";
-import { RenderRegionalFeatureSummaryPipe } from "./pipes/renderRegionalFeatureSummary.pipe";
-import { BSFeatureReceptorModule } from "./receptor";
-import { RegionalFeatureWrapperCmp } from "./regionalFeatureWrapper/regionalFeatureWrapper.component";
-import { BsFeatureService } from "./service";
-import { GENERIC_INFO_INJ_TOKEN } from "./type";
-
-@NgModule({
-  imports: [
-    AngularMaterialModule,
-    CommonModule,
-    KgRegionalFeatureModule,
-    BSFeatureReceptorModule,
-    BsFeatureIEEGModule,
-    ComponentsModule,
-    GenericInfoModule,
-  ],
-  declarations: [
-    RegionalFeatureWrapperCmp,
-    RenderRegionalFeatureSummaryPipe,
-    GetBadgeFromFeaturePipe,
-  ],
-  providers: [
-    BsFeatureService,
-    {
-      provide: GENERIC_INFO_INJ_TOKEN,
-      useValue: GenericInfoCmp
-    }
-  ],
-  exports: [
-    RegionalFeatureWrapperCmp,
-    GenericInfoModule,
-  ]
-})
-
-export class BSFeatureModule{}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/pipes/getBadgeFromFeature.pipe.ts b/src/atlasComponents/regionalFeatures/bsFeatures/pipes/getBadgeFromFeature.pipe.ts
deleted file mode 100644
index 8fe67e163d116fb68ccbbff6524cb21d544db3f2..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/pipes/getBadgeFromFeature.pipe.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { IBSSummaryResponse, TContextedFeature } from "../type";
-import {
-  IEEG_FEATURE_NAME
-} from '../ieeg'
-import {
-  RECEPTOR_FEATURE_NAME
-} from '../receptor'
-
-export type TBadge = {
-  text: string
-  color: 'primary' | 'warn' | 'accent'
-}
-
-@Pipe({
-  name: 'getBadgeFromFeaturePipe',
-  pure: true
-})
-
-export class GetBadgeFromFeaturePipe implements PipeTransform{
-  public transform(input: TContextedFeature<keyof IBSSummaryResponse>): TBadge[]{
-    if (input.featureName === IEEG_FEATURE_NAME) {
-      return [{
-        text: IEEG_FEATURE_NAME,
-        color: 'primary',
-      }]
-    }
-    if (input.featureName === RECEPTOR_FEATURE_NAME) {
-      return [{
-        text: RECEPTOR_FEATURE_NAME,
-        color: 'accent',
-      }]
-    }
-    return []
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/pipes/renderRegionalFeatureSummary.pipe.ts b/src/atlasComponents/regionalFeatures/bsFeatures/pipes/renderRegionalFeatureSummary.pipe.ts
deleted file mode 100644
index 829ed01981e3fb5a2061a058892f67742327dbb0..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/pipes/renderRegionalFeatureSummary.pipe.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { IBSSummaryResponse, TContextedFeature } from "../type";
-import {
-  IEEG_FEATURE_NAME
-} from '../ieeg'
-import {
-  RECEPTOR_FEATURE_NAME
-} from '../receptor'
-import {
-  EbrainsRegionalFeatureName
-} from '../kgRegionalFeature'
-
-@Pipe({
-  name: 'renderRegionalFeatureSummaryPipe',
-  pure: true,
-})
-
-export class RenderRegionalFeatureSummaryPipe implements PipeTransform{
-  public transform(input: TContextedFeature<keyof IBSSummaryResponse>): string{
-    if (input.featureName === IEEG_FEATURE_NAME) {
-      return input.result['name']
-    }
-    if (input.featureName === RECEPTOR_FEATURE_NAME) {
-      return input.result['name']
-    }
-    if (input.featureName === EbrainsRegionalFeatureName) {
-      return input.result['src_name']
-    }
-    return `[Unknown feature type]`
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.component.ts
deleted file mode 100644
index 83054ac26c45903d6e5cef7c64015a57454f2cf1..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.component.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-import { Component, ElementRef, Input, OnChanges, ViewChild } from "@angular/core";
-import { BsFeatureReceptorBase } from "../base";
-import { CONST } from 'common/constants'
-import { TBSDetail } from "../type";
-import { environment } from 'src/environments/environment'
-import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
-
-const { RECEPTOR_AR_CAPTION } = CONST
-
-export function isAr(detail: TBSDetail, label: string){
-  if (label) return !!detail.__data.__autoradiographs[label]
-  return !!detail.__data.__autoradiographs
-}
-
-@Component({
-  selector: 'bs-features-receptor-autoradiograph',
-  templateUrl: './autoradiograph.template.html',
-  styleUrls: [
-    './autoradiograph.style.css'
-  ]
-})
-
-export class BsFeatureReceptorAR extends BsFeatureReceptorBase implements OnChanges {
-
-  public RECEPTOR_AR_CAPTION = RECEPTOR_AR_CAPTION
-  private DS_PREVIEW_URL = environment.DATASET_PREVIEW_URL
-
-  @Input()
-  bsLabel: string
-
-  @ViewChild('arContainer', { read: ElementRef })
-  arContainer: ElementRef
-
-  private renderBuffer: Uint8ClampedArray
-  private width: number
-  private height: number
-  private pleaseRender = false
-
-  constructor(private worker: AtlasWorkerService){
-    super()
-  }
-  async ngOnChanges(){
-    this.error = null
-    this.urls = []
-    if (!this.bsFeature) {
-      this.error = `bsFeature not populated`
-      return
-    }
-    if (!this.bsLabel) {
-      this.error = `bsLabel not populated`
-      return
-    }
-
-    try {
-      const {
-        "x-channel": channel,
-        "x-height": height,
-        "x-width": width,
-        content_type: contentType,
-        content_encoding: contentEncoding,
-        content,
-      } = this.bsFeature.__data.__autoradiographs[this.bsLabel]
-
-      if (contentType !== "application/octet-stream") {
-        throw new Error(`contentType expected to be application/octet-stream, but is instead ${contentType}`)
-      }
-      if (contentEncoding !== "gzip; base64") {
-        throw new Error(`contentEncoding expected to be gzip; base64, but is ${contentEncoding} instead.`)
-      }
-
-      const bin = atob(content)
-      const { pako } = (window as any).export_nehuba
-      const uint8array: Uint8Array = pako.inflate(bin)
-
-      this.width = width
-      this.height = height
-
-      const rgbaBuffer = await this.worker.sendMessage({
-        method: "PROCESS_TYPED_ARRAY",
-        param: {
-          inputArray: uint8array,
-          width,
-          height,
-          channel
-        },
-        transfers: [ uint8array.buffer ]
-      })
-
-      this.renderBuffer = rgbaBuffer.result.buffer
-      this.renderCanvas()
-    } catch (e) {
-      this.error = e.toString()
-    }
-  }
-
-  private renderCanvas(){
-    if (!this.arContainer) {
-      this.pleaseRender = true
-      return
-    }
-
-    const arContainer = (this.arContainer.nativeElement as HTMLElement)
-    while (arContainer.firstChild) {
-      arContainer.removeChild(arContainer.firstChild)
-    }
-
-    const canvas = document.createElement("canvas")
-    canvas.height = this.height
-    canvas.width = this.width
-    arContainer.appendChild(canvas)
-    const ctx = canvas.getContext("2d")
-    const imgData = ctx.createImageData(this.width, this.height)
-    imgData.data.set(this.renderBuffer)
-    ctx.putImageData(imgData, 0, 0)
-  }
-
-  ngAfterViewChecked(){
-    if (this.pleaseRender) this.renderCanvas()
-  }
-}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.style.css b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.style.css
deleted file mode 100644
index c7ebabfec67ff4346377d1dfed4a4ce63a40c066..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.style.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/* canvas created by createElement does not have encapsulation applied */
-.ar-container >>> canvas
-{
-  width: 100%;
-}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.template.html
deleted file mode 100644
index ad467adc5a5f15bf37343c49a0c02fbb96a2c4d7..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/ar/autoradiograph.template.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<ng-template [ngIf]="error">
-  {{ error }}
-</ng-template>
-
-<a *ngFor="let url of urls"
-  [href]="url.url"
-  class="no-hover"
-  download>
-  <i class="fas fa-download"></i>
-  <span>
-    {{ url.text || (url.url | getFilenamePipe) }}
-  </span>
-</a>
-
-<figure>
-  <figcaption class="text-muted">
-    Autoradiograph: {{ RECEPTOR_AR_CAPTION }}
-  </figcaption>
-  <div class="ar-container" #arContainer>
-  </div>
-</figure>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/base.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/base.ts
deleted file mode 100644
index b149e359d7dca68da294e98e9138a557bfedf41a..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/base.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Directive, Input } from "@angular/core";
-import { TBSDetail } from "./type";
-
-@Directive()
-export class BsFeatureReceptorBase {
-  @Input()
-  bsFeature: TBSDetail
-
-  public urls: {
-    url: string
-    text?: string
-  }[] = []
-
-  public error = null
-
-  // eslint-disable-next-line @typescript-eslint/no-empty-function
-  constructor(){}
-}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.component.ts
deleted file mode 100644
index 33bc2bbde0ce20039d5bcf33de72782da242cc21..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.component.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import { ChangeDetectorRef, Component, Inject, OnDestroy, Optional } from "@angular/core";
-import { BehaviorSubject, Observable, of, Subscription } from "rxjs";
-import { filter, map, shareReplay, startWith, switchMap, tap } from "rxjs/operators";
-import { BsRegionInputBase } from "../../bsRegionInputBase";
-import { REGISTERED_FEATURE_INJECT_DATA } from "../../constants";
-import { BsFeatureService, TFeatureCmpInput } from "../../service";
-import { TBSDetail } from "../type";
-import { ARIA_LABELS } from 'common/constants'
-
-@Component({
-  selector: 'bs-features-receptor-entry',
-  templateUrl: './entry.template.html',
-  styleUrls: [
-    './entry.style.css'
-  ],
-})
-
-export class BsFeatureReceptorEntry extends BsRegionInputBase implements OnDestroy{
-
-  private sub: Subscription[] = []
-  public ARIA_LABELS = ARIA_LABELS
-
-  private selectedREntryId$ = new BehaviorSubject<string>(null)
-  private _selectedREntryId: string
-  set selectedREntryId(id: string){
-    this.selectedREntryId$.next(id)
-    this._selectedREntryId = id
-  }
-  get selectedREntryId(){
-    return this._selectedREntryId
-  }
-
-  public selectedReceptor$: Observable<TBSDetail> = this.selectedREntryId$.pipe(
-    switchMap(id => id
-      ? this.getFeatureInstance('ReceptorDistribution', id)
-      : of(null)
-    ),
-    shareReplay(1),
-  )
-
-  public hasPrAr$: Observable<boolean> = this.selectedReceptor$.pipe(
-    map(detail => !!detail.__data.__profiles),
-  )
-
-  ngOnDestroy(){
-    while (this.sub.length > 0) this.sub.pop().unsubscribe()
-  }
-
-  public receptorsSummary$ = this.region$.pipe(
-    filter(v => !!v),
-    switchMap(() => this.getFeatureInstancesList('ReceptorDistribution')),
-    startWith([]),
-    shareReplay(1),
-  )
-
-  public onSelectReceptor(receptor: string){
-    this.selectedReceptor = receptor
-  }
-
-  public selectedReceptor = null
-  public allReceptors$ = this.selectedReceptor$.pipe(
-    map(rec => {
-      if (!rec) return []
-      return Object.keys(rec.__receptor_symbols || {})
-    })
-  )
-
-  constructor(
-    svc: BsFeatureService,
-    cdr: ChangeDetectorRef,
-    @Optional() @Inject(REGISTERED_FEATURE_INJECT_DATA) data: TFeatureCmpInput
-  ){
-    super(svc, data)
-    this.sub.push(
-      this.selectedReceptor$.subscribe(() => {
-        cdr.markForCheck()
-      }),
-      this.receptorsSummary$.subscribe(arr => {
-        if (arr && arr.length > 0) {
-          this.selectedREntryId = arr[0]['@id']
-        } else {
-          this.selectedREntryId = null
-        }
-      })
-    )
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.style.css b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.style.css
deleted file mode 100644
index 71beb4683eec695ddf613bfcf2eecac35e79773d..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.style.css
+++ /dev/null
@@ -1,8 +0,0 @@
-:host
-{
-  display: block;
-  width: 100%;
-  height: 100%;
-  padding-left:24px;
-  padding-right:24px;
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.template.html
deleted file mode 100644
index 48a24c834f0ef7e943434a6242c12fe49b0f5b91..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.template.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<mat-divider class="mt-2 mb-2"></mat-divider>
-
-<!-- potential selector for receptor data -->
-<mat-select class="invisible" [(value)]="selectedREntryId">
-  <mat-option *ngFor="let rec of receptorsSummary$ | async"
-    [value]="rec['@id']">
-    {{ rec.name }}
-  </mat-option>
-</mat-select>
-
-<ng-template [ngIf]="!(selectedReceptor$ | async)">
-  <spinner-cmp></spinner-cmp>
-</ng-template>
-
-<ng-template let-selectedRec [ngIf]="selectedReceptor$ | async">
-  <bs-features-receptor-fingerprint
-    (onSelectReceptor)="onSelectReceptor($event)"
-    [bsFeature]="selectedRec">
-  </bs-features-receptor-fingerprint>
-
-  <ng-template [ngIf]="hasPrAr$ | async">
-    <mat-divider></mat-divider>
-
-    <mat-form-field class="mt-2 w-100">
-      <mat-label>
-        Select a receptor
-      </mat-label>
-      <mat-select [(value)]="selectedReceptor">
-        <mat-option
-          *ngFor="let receptorName of (allReceptors$ | async)"
-          [value]="receptorName">
-          {{ receptorName }}
-        </mat-option>
-      </mat-select>
-    </mat-form-field>
-  
-    <bs-features-receptor-profile
-      *ngIf="selectedReceptor"
-      [bsFeature]="selectedRec"
-      [bsLabel]="selectedReceptor">
-    </bs-features-receptor-profile>
-  
-    <bs-features-receptor-autoradiograph
-      *ngIf="selectedReceptor"
-      [bsFeature]="selectedRec"
-      [bsLabel]="selectedReceptor">
-    </bs-features-receptor-autoradiograph>
-  </ng-template>
-
-</ng-template>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.component.ts
deleted file mode 100644
index a061221118bf8420bbf6883b14c15f18680c4fb8..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.component.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, HostListener, Inject, OnChanges, OnDestroy, OnInit, Optional, Output } from "@angular/core";
-import { fromEvent, Observable, Subscription } from "rxjs";
-import { distinctUntilChanged, map } from "rxjs/operators";
-import { BS_DARKTHEME } from "../../constants";
-import { BsFeatureReceptorBase } from "../base";
-import { CONST } from 'common/constants'
-
-const { RECEPTOR_FP_CAPTION } = CONST
-
-@Component({
-  selector: 'bs-features-receptor-fingerprint',
-  templateUrl: './fp.template.html',
-  styleUrls: [
-    './fp.style.css'
-  ],
-  changeDetection: ChangeDetectionStrategy.OnPush
-})
-
-export class BsFeatureReceptorFingerprint extends BsFeatureReceptorBase implements OnChanges, OnInit, OnDestroy{
-
-  public RECEPTOR_FP_CAPTION = RECEPTOR_FP_CAPTION
-  private sub: Subscription[] = []
-
-  @HostListener('click')
-  onClick(){
-    if (this.selectedReceptor) {
-      this.onSelectReceptor.emit(this.selectedReceptor)
-    }
-  }
-
-  @Output()
-  public onSelectReceptor = new EventEmitter()
-  private selectedReceptor: any
-
-  constructor(
-    private elRef: ElementRef,
-    @Optional() @Inject(BS_DARKTHEME) public darktheme$: Observable<boolean>,
-  ){
-    super()
-  }
-
-  ngOnInit(){
-    // without, when devtool is out, runs sluggishly
-    // informing angular that change occurs here will be handled by programmer, and not angular
-
-    this.sub.push(
-      fromEvent<CustomEvent>(this.elRef.nativeElement, 'kg-ds-prv-regional-feature-mouseover').pipe(
-        map(ev => ev.detail?.data?.receptor?.label),
-        distinctUntilChanged(),
-      ).subscribe(label => {
-        this.selectedReceptor = label
-      })
-    )
-  }
-
-  ngOnDestroy() {
-    while (this.sub.length > 0) this.sub.pop().unsubscribe()
-  }
-
-  ngOnChanges(){
-    this.error = null
-    this.urls = []
-
-    if (!this.bsFeature) {
-      this.error = `bsFeature is not populated`
-      return
-    }
-
-    this.urls.push(
-      ...this.bsFeature.__files
-        .filter(u => /_fp_/.test(u))
-        .map(url => {
-          return {
-            url,
-          }
-        }),
-      ...this.bsFeature.__files
-        .filter(u => !/_pr_|_ar_/.test(u) && /receptors\.tsv$/.test(u))
-        .map(url => {
-          return {
-            url,
-          }
-        })
-    )
-
-    const radarEl = (this.elRef.nativeElement as HTMLElement).querySelector<any>('kg-dataset-dumb-radar')
-    radarEl.radarBs = this.bsFeature.__data.__fingerprint
-    radarEl.metaBs = this.bsFeature.__receptor_symbols
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.style.css b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.style.css
deleted file mode 100644
index e2a98b2709c53c5853eebdbfc84370f371d84868..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.style.css
+++ /dev/null
@@ -1,18 +0,0 @@
-kg-dataset-dumb-radar
-{
-  display: block;
-  min-height: 20em;
-}
-
-/* figure
-{
-  width: 100%;
-  height: 100%;
-}
-
-kg-dataset-dumb-radar
-{
-  display: block;
-  width: 100%;
-  height: 100%;
-} */
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.template.html
deleted file mode 100644
index 50d505459bb9893b0d7b98ce20f596ba2ba241a9..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/fp/fp.template.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<ng-template [ngIf]="error">
-  {{ error }}
-</ng-template>
-
-<a *ngFor="let url of urls"
-  [href]="url.url"
-  class="no-hover"
-  download>
-  <i class="fas fa-download"></i>
-  <span>
-    {{ url.text || (url.url | getFilenamePipe) }}
-  </span>
-</a>
-
-<figure>
-  <figcaption class="text-muted">
-    Fingerprint : {{ RECEPTOR_FP_CAPTION }}
-  </figcaption>
-  <kg-dataset-dumb-radar
-    [attr.kg-ds-prv-darkmode]="darktheme$ && (darktheme$ | async)">
-  </kg-dataset-dumb-radar>
-</figure>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/hasReceptor.directive.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/hasReceptor.directive.ts
deleted file mode 100644
index 6ef215934ac65dda3977d9e938d328ca45956f22..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/hasReceptor.directive.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { Directive, EventEmitter, Inject, OnDestroy, Optional, Output } from "@angular/core";
-import { merge, Observable, of, Subscription } from "rxjs";
-import { catchError, map, mapTo, switchMap } from "rxjs/operators";
-import { BsRegionInputBase } from "../bsRegionInputBase";
-import { REGISTERED_FEATURE_INJECT_DATA } from "../constants";
-import { BsFeatureService, TFeatureCmpInput } from "../service";
-import { IBSSummaryResponse, IRegionalFeatureReadyDirective } from "../type";
-
-@Directive({
-  selector: '[bs-features-receptor-directive]',
-  exportAs: 'bsFeatureReceptorDirective'
-})
-
-export class BsFeatureReceptorDirective extends BsRegionInputBase implements IRegionalFeatureReadyDirective, OnDestroy {
-  
-  private sub: Subscription[] = []
-
-  ngOnDestroy(){
-    while (this.sub.length > 0) this.sub.pop().unsubscribe()
-  }
-  public results$: Observable<IBSSummaryResponse['ReceptorDistribution'][]>  = this.region$.pipe(
-    switchMap(() => merge(
-      of([]),
-      this.getFeatureInstancesList('ReceptorDistribution').pipe(
-        catchError(() => of([]))
-      )
-    )),
-  )
-
-  public hasReceptor$ = this.results$.pipe(
-    map(arr => arr.length > 0)
-  )
-
-  public busy$ = this.region$.pipe(
-    switchMap(() => merge(
-      of(true),
-      this.results$.pipe(
-        mapTo(false)
-      )
-    ))
-  )
-  
-  constructor(
-    svc: BsFeatureService,
-    @Optional() @Inject(REGISTERED_FEATURE_INJECT_DATA) data: TFeatureCmpInput,
-  ){
-    super(svc, data)
-    this.sub.push(
-      this.busy$.subscribe(flag => this.fetchingFlagEmitter.emit(flag))
-    )
-  }
-
-  @Output('bs-features-receptor-directive-fetching-flag')
-  public fetchingFlagEmitter = new EventEmitter<boolean>()
-}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/index.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/index.ts
deleted file mode 100644
index 79f8e55d97df512175ef1be0f913512bff41a16f..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { BSFeatureReceptorModule } from './module'
-export { RECEPTOR_FEATURE_NAME } from './type'
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/module.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/module.ts
deleted file mode 100644
index 94f11b9df04e239090ed67a1bca192d2bd924b9c..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/module.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
-import { FormsModule } from "@angular/forms";
-import { AngularMaterialModule } from "src/sharedModules";
-import { UtilModule } from "src/util";
-import { BsFeatureService } from "../service";
-import { BsFeatureReceptorAR } from "./ar/autoradiograph.component";
-import { BsFeatureReceptorEntry } from "./entry/entry.component";
-import { BsFeatureReceptorFingerprint } from "./fp/fp.component";
-import { BsFeatureReceptorDirective } from "./hasReceptor.directive";
-import { BsFeatureReceptorProfile } from "./profile/profile.component";
-import { RECEPTOR_FEATURE_NAME } from "./type";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    UtilModule,
-    AngularMaterialModule,
-    FormsModule,
-  ],
-  declarations: [
-    BsFeatureReceptorProfile,
-    BsFeatureReceptorAR,
-    BsFeatureReceptorFingerprint,
-    BsFeatureReceptorEntry,
-    BsFeatureReceptorDirective,
-  ],
-  exports: [
-    BsFeatureReceptorEntry,
-    BsFeatureReceptorDirective,
-  ],
-  schemas: [
-    CUSTOM_ELEMENTS_SCHEMA
-  ]
-})
-
-export class BSFeatureReceptorModule{
-  constructor(svc: BsFeatureService){
-    svc.registerFeature({
-      name: RECEPTOR_FEATURE_NAME,
-      icon: 'fas fa-info',
-      View: BsFeatureReceptorEntry,
-      Ctrl: BsFeatureReceptorDirective,
-    })
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/profile/profile.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/profile/profile.component.ts
deleted file mode 100644
index 6b33a73b4810c5828752a783b006b0dbb6928b94..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/profile/profile.component.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { ChangeDetectionStrategy, Component, ElementRef, Inject, Input, OnChanges, Optional } from "@angular/core";
-import { Observable } from "rxjs";
-import { BS_DARKTHEME } from "../../constants";
-import { BsFeatureReceptorBase } from "../base";
-import { CONST } from 'common/constants'
-
-export function isPr(filename: string, label: string = ''){
-  return filename.indexOf(`_pr_${label}`) >= 0
-}
-
-const { RECEPTOR_PR_CAPTION } = CONST
-
-@Component({
-  selector: 'bs-features-receptor-profile',
-  templateUrl: './profile.template.html',
-  styleUrls: [
-    './profile.style.css'
-  ],
-  changeDetection: ChangeDetectionStrategy.OnPush
-})
-
-export class BsFeatureReceptorProfile extends BsFeatureReceptorBase implements OnChanges{
-  
-  public RECEPTOR_PR_CAPTION = RECEPTOR_PR_CAPTION
-
-  @Input()
-  bsLabel: string
-
-  constructor(
-    private elRef: ElementRef,
-    @Optional() @Inject(BS_DARKTHEME) public darktheme$: Observable<boolean>,
-  ){
-    super()
-  }
-
-  ngOnChanges(){
-    this.error = null
-    this.urls = []
-
-    if (!this.bsFeature) {
-      this.error = `bsFeature not populated`
-      return
-    }
-    if (!this.bsLabel) {
-      this.error = `bsLabel not populated`
-      return
-    }
-
-    this.urls = this.bsFeature.__files
-      .filter(url => isPr(url, this.bsLabel))
-      .map(url => {
-        return { url }
-      })
-
-    const profileBs = this.bsFeature.__data.__profiles[this.bsLabel]
-    const lineEl = (this.elRef.nativeElement as HTMLElement).querySelector<any>('kg-dataset-dumb-line')
-    lineEl.profileBs = profileBs
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/profile/profile.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/profile/profile.template.html
deleted file mode 100644
index 0b71d2ac46cb92527b2a44af80a94a69961568b5..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/profile/profile.template.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<ng-template [ngIf]="error">
-  {{ error }}
-</ng-template>
-
-<a *ngFor="let url of urls"
-  [href]="url.url"
-  class="no-hover"
-  download>
-  <i class="fas fa-download"></i>
-  <span>
-    {{ url.text || (url.url | getFilenamePipe) }}
-  </span>
-</a>
-
-<figure>
-  <figcaption class="text-muted">
-    Profile: {{ RECEPTOR_PR_CAPTION }}
-  </figcaption>
-  <kg-dataset-dumb-line
-    [attr.kg-ds-prv-darkmode]="darktheme$ && (darktheme$ | async)">
-  </kg-dataset-dumb-line>
-</figure>
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/type.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/type.ts
deleted file mode 100644
index 9ef1efe8b17727ded7f382784c035d780d323fc6..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/type.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-type TReceptorCommon = {
-  latex: string
-  markdown: string
-  name: string
-}
-
-type TReceptor = string // TODO complete all possible neuroreceptor
-
-type TReceptorSymbol = {
-  [key: string]: {
-    receptor: TReceptorCommon
-    neurotransmitter: TReceptorCommon & { label: string }
-  }
-}
-
-type TProfile = {
-  [key: number]: number
-}
-
-type TBSFingerprint = {
-  unit: string
-  labels: TReceptor[]
-  meanvals: number[]
-  stdvals: number[]
-  n: 1
-}
-
-export type TBSSummary = {
-  ['@id']: string
-  name: string
-  info: string
-  origin_datainfos?: ({
-    name: string
-    description: string
-    urls: {
-      doi: string
-      cite?: string
-    }[]
-  })[]
-}
-
-export type TBSDetail = TBSSummary & {
-  __files: string[]
-  __receptor_symbols: TReceptorSymbol
-  __data: {
-    __profiles: {
-      [key: string]: TProfile
-    }
-    __autoradiographs: {
-      [key: string]: {
-        content_type: string
-        content_encoding: string
-        ['x-width']: number
-        ['x-height']: number
-        ['x-channel']: number
-        content: string
-      }
-    }
-    __fingerprint: TBSFingerprint
-  }
-}
-
-export const RECEPTOR_FEATURE_NAME = 'receptor density'
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.component.ts
deleted file mode 100644
index 76a2ad1f2f9bdffbbb598992d542989a48127279..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.component.ts
+++ /dev/null
@@ -1,211 +0,0 @@
-import { Component, ComponentFactory, ComponentFactoryResolver, Inject, Injector, Input, OnChanges, OnDestroy, Optional, ViewChild, ViewContainerRef } from "@angular/core";
-import { IBSSummaryResponse, TContextedFeature, TRegion } from "../type";
-import { BsFeatureService, TFeatureCmpInput } from "../service";
-import { combineLatest, Observable, Subject } from "rxjs";
-import { debounceTime, map, shareReplay, startWith } from "rxjs/operators";
-import { REGISTERED_FEATURE_INJECT_DATA } from "../constants";
-import { ARIA_LABELS } from 'common/constants'
-import {
-  IEEG_FEATURE_NAME
-} from '../ieeg'
-import {
-  RECEPTOR_FEATURE_NAME
-} from '../receptor'
-import {
-  EbrainsRegionalFeatureName
-} from '../kgRegionalFeature'
-import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN, TOverwriteShowDatasetDialog } from "src/util/interfaces";
-
-@Component({
-  selector: 'regional-feature-wrapper',
-  templateUrl: './regionalFeatureWrapper.template.html',
-  styleUrls: [
-    './regionalFeatureWrapper.style.css'
-  ]
-})
-
-export class RegionalFeatureWrapperCmp implements OnChanges, OnDestroy{
-
-  public useVirtualScroll = false
-
-  public ARIA_LABELS = ARIA_LABELS
-
-  @Input()
-  region: TRegion
-
-  @ViewChild('regionalFeatureContainerTmpl', { read: ViewContainerRef })
-  regionalFeatureContainerRef: ViewContainerRef
-
-  private weakmap = new WeakMap<(new () => any),  ComponentFactory<any>>()
-
-  private ondestroyCb: (() => void)[] = []
-  constructor(
-    private svc: BsFeatureService,
-    private cfr: ComponentFactoryResolver,
-    @Optional() @Inject(OVERWRITE_SHOW_DATASET_DIALOG_TOKEN) private overwriteFn: TOverwriteShowDatasetDialog
-  ){
-    const sub = this.registeredFeatures$.subscribe(arr => this.registeredFeatures = arr)
-    this.ondestroyCb.push(() => sub.unsubscribe())
-  }
-
-  private regionOnDestroyCb: (() => void)[] = []
-  private setupRegionalFeatureCtrl(){
-    if (!this.region) return
-    const { region } = this
-    for (const feat of this.svc.registeredFeatures){
-      const { name, icon } = feat
-      const ctrl = new feat.Ctrl(this.svc, { region })
-      const sub = combineLatest([
-        ctrl.busy$,
-        ctrl.results$.pipe(
-          startWith([])
-        )
-      ]).subscribe(
-        ([busy, results]) => {
-          this.registeredFeatureRawRegister[name] = { busy, results, icon }
-          this.registeredFeatureFireStream$.next(true)
-        }
-      )
-      this.regionOnDestroyCb.push(() => sub.unsubscribe())
-    }
-  }
-  private cleanUpRegionalFeature(){
-    while (this.regionOnDestroyCb.length) this.regionOnDestroyCb.pop()()
-    /**
-     * emit null to signify flush out of existing scan map
-     */
-    this.registeredFeatureRawRegister = {}
-    this.registeredFeatureFireStream$.next(true)
-  }
-
-  private registeredFeatureRawRegister: {
-    [key: string]: {
-      icon: string
-      busy: boolean
-      results: any[]
-    }
-  } = {}
-  private registeredFeatureFireStream$ = new Subject()
-  private registeredFeatureMasterStream$ = this.registeredFeatureFireStream$.pipe(
-    debounceTime(16),
-    /**
-     * must not use mapTo operator
-     * otherwise the emitted value will not change
-     */
-    map(() => this.registeredFeatureRawRegister),
-    shareReplay(1),
-  )
-  public busy$: Observable<boolean> = this.registeredFeatureMasterStream$.pipe(
-    map(obj => {
-      for (const key in obj) {
-        if(obj[key].busy) return true
-      }
-      return false
-    }),
-  )
-
-  public registeredFeatures: TContextedFeature<keyof IBSSummaryResponse>[] = []
-  private registeredFeatures$: Observable<TContextedFeature<keyof IBSSummaryResponse>[]> = this.registeredFeatureMasterStream$.pipe(
-    map(obj => {
-      const returnArr = []
-      for (const name in obj) {
-        if (obj[name].busy || obj[name].results.length === 0) {
-          continue
-        }
-        for (const result of obj[name].results) {
-          const objToBeInserted = {
-            featureName: name,
-            icon: obj[name].icon,
-            result
-          }
-          /**
-           * place ebrains regional features at the end
-           */
-          if (name === EbrainsRegionalFeatureName) {
-            returnArr.push(objToBeInserted)
-          } else {
-            returnArr.unshift(objToBeInserted)
-          }
-        }
-      }
-
-      return returnArr
-    }),
-  )
-
-  ngOnChanges(){
-    this.cleanUpRegionalFeature()
-    this.setupRegionalFeatureCtrl()
-  }
-
-  ngOnDestroy(){
-    this.cleanUpRegionalFeature()
-    while(this.ondestroyCb.length) this.ondestroyCb.pop()()
-  }
-
-  public handleFeatureClick(contextedFeature: TContextedFeature<any>){
-    if (!this.overwriteFn) {
-      console.warn(`show dialog function not overwritten!`)
-      return
-    }
-    
-    const featureId = contextedFeature.result['@id']
-    const arg = {}
-    if (contextedFeature.featureName === RECEPTOR_FEATURE_NAME) {
-      arg['name'] = contextedFeature.result['name']
-      arg['description'] = contextedFeature.result['info']
-      arg['urls'] = []
-      for (const info of contextedFeature.result['origin_datainfos']) {
-        arg['urls'].push(...info.urls)
-      }
-    }
-
-    if (contextedFeature.featureName === IEEG_FEATURE_NAME) {
-      arg['name'] = contextedFeature.result['name']
-      arg['description'] = contextedFeature.result['description'] || ' '
-      arg['isGdprProtected'] = true
-      arg['urls'] = []
-      for (const info of contextedFeature.result['origin_datainfos']) {
-        arg['urls'].push(...(info.urls || []))
-      }
-    }
-
-    if (contextedFeature.featureName === EbrainsRegionalFeatureName) {
-      arg['summary'] = contextedFeature.result
-    }
-
-    const { region } = this
-    
-    const feat = this.svc.registeredFeatures.find(f => f.name === contextedFeature.featureName)
-    if (!feat) {
-      console.log(`cannot find feature with name ${contextedFeature.featureName}`)
-      return
-    }
-    
-    const cf = (() => {
-      if (!feat.View) return null
-      const mapped = this.weakmap.get(feat.View)
-      if (mapped) return mapped
-      const _cf = this.cfr.resolveComponentFactory(feat.View)
-      this.weakmap.set(feat.View ,_cf)
-      return _cf
-    })()
-
-    this.overwriteFn({
-      region,
-      dataType: contextedFeature.featureName,
-      view: (() => {
-        if (!cf) return null
-        const injector = Injector.create({
-          providers: [{
-            provide: REGISTERED_FEATURE_INJECT_DATA,
-            useValue: { region, featureId } as TFeatureCmpInput
-          }],
-        })
-        const cmp = cf.create(injector)
-        return cmp.hostView
-      })(),
-      ...arg,
-    })
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.style.css b/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.style.css
deleted file mode 100644
index 816e7ba25d2192ebd17900e60655db92bf17063b..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.style.css
+++ /dev/null
@@ -1,19 +0,0 @@
-.button-text
-{
-  white-space: normal;
-  line-height: 1.5rem;
-  text-align: center;
-}
-
-.feature-container,
-cdk-virtual-scroll-viewport
-{
-  min-height: 24rem;
-}
-
-
-.feature-container
-{
-  height: 24rem;
-  overflow-y: scroll;
-}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.template.html
deleted file mode 100644
index 020145c3c36c406a74c3575422068d0b43700892..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.template.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<ng-template [ngTemplateOutlet]="resultTmpl">
-</ng-template>
-
-<ng-template #busyTmpl>
-  <spinner-cmp></spinner-cmp>
-</ng-template>
-
-<ng-template #resultTmpl>
-  
-  <!-- virtual scroll. do not activate until autosize is supported -->
-  <cdk-virtual-scroll-viewport
-    *ngIf="useVirtualScroll; else regularScrollTmpl"
-    [attr.aria-label]="ARIA_LABELS.LIST_OF_DATASETS_ARIA_LABEL"
-    class="h-100"
-    minBufferPx="200"
-    maxBufferPx="400"
-    itemSize="50">
-    <div *cdkVirtualFor="let feature of registeredFeatures; templateCacheSize: 20; let index = index"
-      class="h-50px overflow-hidden">
-
-      <!-- divider, show if not first -->
-      <mat-divider *ngIf="index !== 0"></mat-divider>
-      <ng-container *ngTemplateOutlet="itemContainer; context: { $implicit: feature }">
-      </ng-container>
-
-    </div>
-  </cdk-virtual-scroll-viewport>
-
-  <!-- fallback, regular scroll -->
-  <!-- less efficient on large list, but for now should do -->
-  <ng-template #regularScrollTmpl>
-    <div class="feature-container"
-      [attr.aria-label]="ARIA_LABELS.LIST_OF_DATASETS_ARIA_LABEL">
-
-      <!-- if busy, show spinner -->
-      <ng-template [ngIf]="busy$ | async" [ngIfElse]="notBusyTmpl">
-        <ng-template [ngTemplateOutlet]="busyTmpl"></ng-template>
-      </ng-template>
-
-      <ng-template #notBusyTmpl>
-        <ng-template [ngIf]="registeredFeatures.length === 0">
-          <span class="text-muted">
-            No regional features found.
-          </span>
-        </ng-template>
-      </ng-template>
-      <div *ngFor="let feature of registeredFeatures; let index = index"
-        class="overflow-hidden">
-
-        <!-- divider, show if not first -->
-        <mat-divider *ngIf="index !== 0"></mat-divider>
-        <ng-container *ngTemplateOutlet="itemContainer; context: { $implicit: feature }">
-        </ng-container>
-
-      </div>
-    </div>
-  </ng-template>
-  
-</ng-template>
-
-<!-- feature template -->
-<ng-template #itemContainer let-feature>
-  <div class="d-block pt-4 cursor-default"
-    (click)="handleFeatureClick(feature)"
-    mat-ripple>
-
-    <!-- mat-chip container -->
-    <!-- do not use mat-chip-list to avoid adding incorrect a11y info -->
-    <div class="transform-origin-left-center scale-80">
-      <mat-chip *ngFor="let badge of feature | getBadgeFromFeaturePipe"
-        [color]="badge.color"
-        selected>
-        {{ badge.text }}
-      </mat-chip>
-    </div>
-
-    <small>
-      {{ feature | renderRegionalFeatureSummaryPipe }}
-    </small>
-  </div>
-</ng-template>
-
-<!-- dummy container -->
-<ng-template #regionalFeatureContainerTmpl>
-</ng-template>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/service.ts b/src/atlasComponents/regionalFeatures/bsFeatures/service.ts
deleted file mode 100644
index 7f52201e0619227b8ba17f23d0b4ce6cb710ce23..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/service.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-import { HttpClient } from "@angular/common/http";
-import { Inject, Injectable } from "@angular/core";
-import { BehaviorSubject } from "rxjs";
-import { shareReplay } from "rxjs/operators";
-import { CachedFunction } from "src/util/fn";
-import { BS_ENDPOINT } from "./constants";
-import { IBSSummaryResponse, IBSDetailResponse, TRegion, IFeatureList, IRegionalFeatureReadyDirective } from './type'
-import { SIIBRA_FEATURE_KEY as IEEG_FEATURE_KEY } from '../bsFeatures/ieeg/type'
-
-function processRegion(region: TRegion) {
-  return `${region.name} ${region.status ? region.status : '' }`
-}
-
-export type TFeatureCmpInput = {
-  region: TRegion
-  featureId?: string
-}
-
-export type TRegisteredFeature<V = any> = {
-  name: string
-  icon: string // fontawesome font class, e.g. `fas fa-link-alt`
-  View: new (...arg: any[]) => V
-  Ctrl: new (svc: BsFeatureService, data: TFeatureCmpInput) => IRegionalFeatureReadyDirective
-}
-
-@Injectable({
-  providedIn: 'root'
-})
-export class BsFeatureService{
-
-  static SpaceFeatureSet = new Set([
-    IEEG_FEATURE_KEY
-  ])
-
-  public registeredFeatures: TRegisteredFeature[] = []
-  public registeredFeatures$ = new BehaviorSubject<TRegisteredFeature[]>(this.registeredFeatures)
-  public getAllFeatures$ = this.http.get(`${this.bsEndpoint}/features`).pipe(
-    shareReplay(1)
-  )
-
-  public listFeatures(region: TRegion){
-    const { context } = region
-    const { atlas, parcellation } = context
-    return this.http.get<IFeatureList>(
-      `${this.bsEndpoint}/atlases/${encodeURIComponent(atlas["@id"])}/parcellations/${encodeURIComponent(parcellation['@id'])}/regions/${encodeURIComponent(processRegion(region))}/features`
-    )
-  }
-
-  private getUrl(arg: {
-    atlasId: string
-    parcId: string
-    spaceId: string
-    region: TRegion
-    featureName: string
-    featureId?: string
-  }){
-    const { 
-      atlasId,
-      parcId,
-      spaceId,
-      region,
-      featureName,
-      featureId,
-    } = arg
-
-    if (BsFeatureService.SpaceFeatureSet.has(featureName)) {
-      
-      const url = new URL(`${this.bsEndpoint}/atlases/${encodeURIComponent(atlasId)}/spaces/${encodeURIComponent(spaceId)}/features/${encodeURIComponent(featureName)}${ featureId ? ('/' + encodeURIComponent(featureId)) : '' }`)
-      url.searchParams.set('parcellation_id', parcId)
-      url.searchParams.set('region', processRegion(region))
-
-      return url.toString()
-    }
-    
-    if (!featureId) {
-      return `${this.bsEndpoint}/atlases/${encodeURIComponent(atlasId)}/parcellations/${encodeURIComponent(parcId)}/regions/${encodeURIComponent(processRegion(region))}/features/${encodeURIComponent(featureName)}`
-    }
-    return `${this.bsEndpoint}/atlases/${encodeURIComponent(atlasId)}/parcellations/${encodeURIComponent(parcId)}/regions/${encodeURIComponent(processRegion(region))}/features/${encodeURIComponent(featureName)}/${encodeURIComponent(featureId)}`
-  }
-
-  @CachedFunction({
-    serialization: (featureName, region) => `${featureName}::${processRegion(region)}`
-  })
-  public getFeatures<T extends keyof IBSSummaryResponse>(featureName: T, region: TRegion){
-    const { context } = region
-    const { atlas, parcellation, template } = context
-    const url = this.getUrl({
-      atlasId: atlas['@id'],
-      parcId: parcellation['@id'],
-      region,
-      featureName,
-      spaceId: template['@id']
-    })
-    
-    return this.http.get<IBSSummaryResponse[T][]>(
-      url
-    ).pipe(
-      shareReplay(1)
-    )
-  }
-
-  @CachedFunction({
-    serialization: (featureName, region, featureId) => `${featureName}::${processRegion(region)}::${featureId}`
-  })
-  public getFeature<T extends keyof IBSDetailResponse>(featureName: T, region: TRegion, featureId: string) {
-    const { context } = region
-    const { atlas, parcellation, template } = context
-    const url = this.getUrl({
-      atlasId: atlas['@id'],
-      parcId: parcellation['@id'],
-      spaceId: template['@id'],
-      region,
-      featureName,
-      featureId
-    })
-    return this.http.get<IBSSummaryResponse[T]&IBSDetailResponse[T]>(url).pipe(
-      shareReplay(1)
-    )
-  }
-
-  public registerFeature(feature: TRegisteredFeature){
-    if (this.registeredFeatures.find(v => v.name === feature.name)) {
-      throw new Error(`feature ${feature.name} already registered`)
-    }
-    this.registeredFeatures.push(feature)
-    this.registeredFeatures$.next(this.registeredFeatures)
-  }
-
-  public deregisterFeature(name: string){
-    this.registeredFeatures = this.registeredFeatures.filter(v => v.name !== name)
-    this.registeredFeatures$.next(this.registeredFeatures)
-  }
-  
-  constructor(
-    private http: HttpClient,
-    @Inject(BS_ENDPOINT) private bsEndpoint: string,
-  ){
-
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/type.ts b/src/atlasComponents/regionalFeatures/bsFeatures/type.ts
deleted file mode 100644
index 84731e48984af2dd020be92f5d06e3b91429f558..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/bsFeatures/type.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { IHasId } from "src/util/interfaces";
-import { TBSDetail as TReceptorDetail, TBSSummary as TReceptorSummary } from "./receptor/type";
-import { KG_REGIONAL_FEATURE_KEY, TBSDetail as TKGDetail, TBSSummary as TKGSummary } from './kgRegionalFeature/type'
-import { SIIBRA_FEATURE_KEY, TBSSummary as TIEEGSummary, TBSIeegSessionDetail as TIEEGDetail } from './ieeg/type'
-import { Observable } from "rxjs";
-import { InjectionToken } from "@angular/core";
-
-/**
- * change KgRegionalFeature -> EbrainsRegionalDataset in prod
- */
-
-export interface IBSSummaryResponse {
-  'ReceptorDistribution': TReceptorSummary
-  [KG_REGIONAL_FEATURE_KEY]: TKGSummary
-  [SIIBRA_FEATURE_KEY]: TIEEGSummary
-}
-
-export interface IBSDetailResponse {
-  'ReceptorDistribution': TReceptorDetail
-  [KG_REGIONAL_FEATURE_KEY]: TKGDetail
-  [SIIBRA_FEATURE_KEY]: TIEEGDetail
-}
-
-export type TRegion = {
-  name: string
-  status?: string
-  context: {
-    atlas: IHasId
-    template: IHasId
-    parcellation: IHasId
-  }
-}
-
-export interface IFeatureList {
-  features: {
-    [key: string]: string
-  }[]
-}
-
-export interface IRegionalFeatureReadyDirective {
-  ngOnDestroy(): void
-  busy$: Observable<boolean>
-  results$: Observable<IBSSummaryResponse[keyof IBSSummaryResponse][]>
-}
-
-export type TContextedFeature<T extends keyof IBSSummaryResponse> = {
-  featureName: string
-  icon: string
-  result: IBSSummaryResponse[T]
-}
-
-export const GENERIC_INFO_INJ_TOKEN = new InjectionToken('GENERIC_INFO_INJ_TOKEN')
diff --git a/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.spec.ts b/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.spec.ts
deleted file mode 100644
index 6821e237ff0aae95e6eaa42c99989dec7d5e9b65..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.spec.ts
+++ /dev/null
@@ -1,155 +0,0 @@
-import { CommonModule } from "@angular/common"
-import { ChangeDetectorRef, Component, ComponentRef, EventEmitter, NgModule } from "@angular/core"
-import { async, TestBed } from "@angular/core/testing"
-import { By } from "@angular/platform-browser"
-import { RegionalFeaturesService } from "../regionalFeature.service"
-import { ISingleFeature } from "../singleFeatures/interfaces"
-import { FeatureContainer } from "./featureContainer.component"
-
-const dummyCmpType = 'dummyType'
-
-@Component({
-  template: `{{ text }}`
-})
-
-class DummyComponent implements ISingleFeature{
-  text = 'hello world'
-  feature: any
-  region: any
-  viewChanged = new EventEmitter<boolean>()
-}
-
-@Component({
-  template: ''
-})
-
-class HostCmp{
-  public feature: any
-  public region: any
-
-  constructor(public cdr: ChangeDetectorRef){
-
-  }
-
-  detectChange(){
-    this.cdr.detectChanges()
-  }
-}
-
-const serviceStub = {
-  mapFeatToCmp: new Map([
-    [dummyCmpType, DummyComponent]
-  ])
-}
-
-describe('> featureContainer.component.ts', () => {
-  describe('> FeatureContainer', () => {
-
-    beforeEach(async () => {
-
-      await TestBed.configureTestingModule({
-        imports: [
-          CommonModule,
-        ],
-        declarations: [
-          FeatureContainer,
-          DummyComponent,
-          HostCmp,
-        ],
-        providers: [
-          {
-            provide: RegionalFeaturesService,
-            useValue: serviceStub
-          }
-        ]
-      }).overrideComponent(HostCmp, {
-        set: {
-          template: `
-          <feature-container
-            [feature]="feature"
-            [region]="region"
-            (viewChanged)="detectChange()">
-          </feature-container>`
-        }
-      }).compileComponents()
-
-    })
-
-    it('> can be created', () => {
-      const fixture = TestBed.createComponent(HostCmp)
-      expect(fixture).toBeTruthy()
-      const featContainer = fixture.debugElement.query(By.directive(FeatureContainer))
-      expect(featContainer).toBeTruthy()
-    })
-
-    describe('> if inputs change', () => {
-      it('> if input changed, but feature is not one of them, map.get will not be called', () => {
-        const fixture = TestBed.createComponent(HostCmp)
-        // const featContainer = fixture.debugElement.query(By.directive(FeatureContainer))
-        spyOn(serviceStub.mapFeatToCmp, 'get').and.callThrough()
-        fixture.componentInstance.region = {
-          name: 'tesla'
-        }
-        fixture.detectChanges()
-        expect(serviceStub.mapFeatToCmp.get).not.toHaveBeenCalled()
-      })
-
-      it('> if input changed, feature is one of them, will not call map.get', () => {
-        const fixture = TestBed.createComponent(HostCmp)
-        const dummyFeature = {
-          type: dummyCmpType
-        }
-        spyOn(serviceStub.mapFeatToCmp, 'get').and.callThrough()
-        fixture.componentInstance.feature = dummyFeature
-        fixture.detectChanges()
-        expect(serviceStub.mapFeatToCmp.get).toHaveBeenCalledWith(dummyCmpType)
-      })
-
-      it('> should render default txt', () => {
-        const fixture = TestBed.createComponent(HostCmp)
-        const dummyFeature = {
-          type: dummyCmpType
-        }
-        fixture.componentInstance.feature = dummyFeature
-        fixture.detectChanges()
-        const text = fixture.nativeElement.textContent
-        expect(text).toContain('hello world')
-      })
-
-      it('> if inner component changes, if view changed does not emit, will not change ui', () => {
-
-        const fixture = TestBed.createComponent(HostCmp)
-        const dummyFeature = {
-          type: dummyCmpType
-        }
-        fixture.componentInstance.feature = dummyFeature
-        fixture.detectChanges()
-        const featureContainer = fixture.debugElement.query(
-          By.directive(FeatureContainer)
-        )
-        const cr = (featureContainer.componentInstance as FeatureContainer)['cr'] as ComponentRef<DummyComponent>
-        cr.instance.text = 'foo bar'
-        const text = fixture.nativeElement.textContent
-        expect(text).toContain('hello world')
-      })
-
-      it('> if inner component changes, and viewChanged is emitted, ui should change accordingly', () => {
-
-        const fixture = TestBed.createComponent(HostCmp)
-        const dummyFeature = {
-          type: dummyCmpType
-        }
-        fixture.componentInstance.feature = dummyFeature
-        fixture.detectChanges()
-        const featureContainer = fixture.debugElement.query(
-          By.directive(FeatureContainer)
-        )
-        const cr = (featureContainer.componentInstance as FeatureContainer)['cr'] as ComponentRef<DummyComponent>
-        cr.instance.text = 'foo bar'
-        cr.instance.viewChanged.emit(true)
-        const text = fixture.nativeElement.textContent
-        expect(text).toContain('foo bar')
-      })
-    })
-  })
-})
diff --git a/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.ts b/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.ts
deleted file mode 100644
index 2b2391599494ac22cadc250fa479255fa39d2179..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { ChangeDetectionStrategy, Component, ComponentFactoryResolver, ComponentRef, Input, OnChanges, Output, SimpleChanges, ViewContainerRef, EventEmitter } from "@angular/core";
-import { Subscription } from "rxjs";
-import { IFeature, RegionalFeaturesService } from "../regionalFeature.service";
-import { ISingleFeature } from "../singleFeatures/interfaces";
-
-@Component({
-  selector: 'feature-container',
-  template: '',
-  changeDetection: ChangeDetectionStrategy.OnPush,
-})
-
-export class FeatureContainer implements OnChanges{
-  @Input()
-  feature: IFeature
-
-  @Input()
-  region: any
-
-  @Output()
-  viewChanged: EventEmitter<boolean> = new EventEmitter()
-
-  private cr: ComponentRef<ISingleFeature>
-  
-  constructor(
-    private vCRef: ViewContainerRef,
-    private rService: RegionalFeaturesService,
-    private cfr: ComponentFactoryResolver,
-  ){
-  }
-
-  private viewChangedSub: Subscription
-
-  ngOnChanges(simpleChanges: SimpleChanges){
-    if (!simpleChanges.feature) return
-    const { currentValue, previousValue } = simpleChanges.feature
-    if (currentValue === previousValue) return
-    this.clear()
-
-    /**
-     * catching instances where currentValue for feature is falsy
-     */
-    if (!currentValue) return
-
-    /**
-     * TODO catch if map is undefined
-     */
-    const comp = this.rService.mapFeatToCmp.get(currentValue.type)
-    if (!comp) throw new Error(`mapFeatToCmp for ${currentValue.type} not defined`)
-    const cf = this.cfr.resolveComponentFactory<ISingleFeature>(comp)
-    this.cr = this.vCRef.createComponent(cf)
-    this.cr.instance.feature = this.feature
-    this.cr.instance.region = this.region
-    this.viewChangedSub = this.cr.instance.viewChanged.subscribe(() => this.viewChanged.emit(true))
-  }
-
-  clear(){
-    if (this.viewChangedSub) this.viewChangedSub.unsubscribe()
-    this.vCRef.clear()
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/index.ts b/src/atlasComponents/regionalFeatures/index.ts
deleted file mode 100644
index a71230d7107939f7da63d18d843339937ed89290..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { RegionalFeaturesModule } from './module'
-export { IFeature } from './regionalFeature.service'
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/module.ts b/src/atlasComponents/regionalFeatures/module.ts
deleted file mode 100644
index 573acb57dfd9b3f0f0e303a622be2926f8013f27..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/module.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { HttpClientModule } from "@angular/common/http";
-import { NgModule } from "@angular/core";
-import { UtilModule } from "src/util";
-import { AngularMaterialModule } from "src/sharedModules";
-import { FeatureContainer } from "./featureContainer/featureContainer.component";
-import { FilterRegionalFeaturesByTypePipe } from "./pipes/filterRegionalFeaturesByType.pipe";
-import { FilterRegionFeaturesById } from "./pipes/filterRegionFeaturesById.pipe";
-import { FindRegionFEatureById } from "./pipes/findRegionFeatureById.pipe";
-import { RegionalFeaturesService } from "./regionalFeature.service";
-import { RegionGetAllFeaturesDirective } from "./regionGetAllFeatures.directive";
-import { FeatureIEEGRecordings } from "./singleFeatures/iEEGRecordings/module";
-import { ReceptorDensityModule } from "./singleFeatures/receptorDensity/module";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    UtilModule,
-    AngularMaterialModule,
-    FeatureIEEGRecordings,
-    ReceptorDensityModule,
-    HttpClientModule,
-  ],
-  declarations: [
-    /**
-     * components
-     */
-    FeatureContainer,
-
-    /**
-     * Directives
-     */
-    RegionGetAllFeaturesDirective,
-
-    /**
-     * pipes
-     */
-    FilterRegionalFeaturesByTypePipe,
-    FindRegionFEatureById,
-    FilterRegionFeaturesById,
-  ],
-  exports: [
-    RegionGetAllFeaturesDirective,
-    FilterRegionFeaturesById,
-    FeatureContainer,
-  ],
-  providers: [
-    RegionalFeaturesService,
-  ]
-})
-
-export class RegionalFeaturesModule{}
diff --git a/src/atlasComponents/regionalFeatures/pipes/filterRegionFeaturesById.pipe.ts b/src/atlasComponents/regionalFeatures/pipes/filterRegionFeaturesById.pipe.ts
deleted file mode 100644
index ed20ef67cfc96dcf3f21b1789cc7cdf82ac2fa01..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/pipes/filterRegionFeaturesById.pipe.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { IFeature } from "../regionalFeature.service";
-import { getIdFromFullId } from 'common/util'
-@Pipe({
-  name: 'filterRegionFeaturesById',
-  pure: true
-})
-
-export class FilterRegionFeaturesById implements PipeTransform{
-  public transform(features: IFeature[], id: string){
-    const filterId = getIdFromFullId(id)
-    return features.filter(f => getIdFromFullId(f['@id']) === filterId)
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/pipes/filterRegionalFeaturesByType.pipe.ts b/src/atlasComponents/regionalFeatures/pipes/filterRegionalFeaturesByType.pipe.ts
deleted file mode 100644
index f5bf231bddf4cbb5fa1ae97121c6315074b2305e..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/pipes/filterRegionalFeaturesByType.pipe.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { IFeature } from "../regionalFeature.service";
-
-@Pipe({
-  name: 'filterRegionalFeaturesBytype',
-  pure: true,
-})
-
-export class FilterRegionalFeaturesByTypePipe implements PipeTransform{
-  public transform(array: IFeature[], featureType: string){
-    return array.filter(f => featureType ? f.type === featureType : true )
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/pipes/findRegionFeatureById.pipe.ts b/src/atlasComponents/regionalFeatures/pipes/findRegionFeatureById.pipe.ts
deleted file mode 100644
index a083a28a5a843ef36c47c29183efd72ed7e28936..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/pipes/findRegionFeatureById.pipe.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { IFeature } from "../regionalFeature.service";
-
-@Pipe({
-  name: 'findRegionFeaturebyId',
-  pure: true
-})
-
-export class FindRegionFEatureById implements PipeTransform{
-  public transform(features: IFeature[], id: string){
-    return features.find(f => f['@id'] === id)
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/regionGetAllFeatures.directive.ts b/src/atlasComponents/regionalFeatures/regionGetAllFeatures.directive.ts
deleted file mode 100644
index 920e1f0a98c7cd791514755d48351b63d4005684..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/regionGetAllFeatures.directive.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Directive, EventEmitter, OnDestroy, OnInit, Output } from "@angular/core";
-import { Subscription } from "rxjs";
-import { RegionalFeaturesService } from "./regionalFeature.service";
-import { RegionFeatureBase } from "./singleFeatures/base/regionFeature.base";
-
-@Directive({
-  selector: '[region-get-all-features-directive]',
-  exportAs: 'rfGetAllFeatures'
-})
-
-export class RegionGetAllFeaturesDirective extends RegionFeatureBase implements OnDestroy, OnInit{
-  @Output()
-  loadingStateChanged: EventEmitter<boolean> = new EventEmitter()
-
-  private subscriptions: Subscription[] = []
-
-  /**
-   * since the base class has DI
-   * sub class needs to call super() with the correct DI
-   */
-  constructor(
-    rfService: RegionalFeaturesService
-  ){
-    super(rfService)
-  }
-
-  ngOnInit(){
-    this.subscriptions.push(
-      this.isLoading$.subscribe(val => {
-        this.loadingStateChanged.emit(val)
-      })
-    )
-  }
-  ngOnDestroy(){
-    while (this.subscriptions.length > 0) this.subscriptions.pop().unsubscribe()
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/regionalFeature.service.ts b/src/atlasComponents/regionalFeatures/regionalFeature.service.ts
deleted file mode 100644
index 0525ba80e033d9db9245d54f368b152b210fda11..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/regionalFeature.service.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-import { HttpClient } from "@angular/common/http";
-import { Inject, Injectable, OnDestroy, Optional } from "@angular/core";
-import { PureContantService } from "src/util";
-import { getIdFromFullId, getRegionHemisphere, getStringIdsFromRegion, flattenReducer } from 'common/util'
-import { forkJoin, from, Observable, of, Subject, Subscription, throwError } from "rxjs";
-import { catchError, map, mapTo, shareReplay, switchMap } from "rxjs/operators";
-import { IHasId } from "src/util/interfaces";
-import { select, Store } from "@ngrx/store";
-import { viewerStateSelectedTemplateSelector } from "src/services/state/viewerState/selectors";
-import { viewerStateAddUserLandmarks, viewreStateRemoveUserLandmarks } from "src/services/state/viewerState/actions";
-import { uiStateMouseoverUserLandmark } from "src/services/state/uiState/selectors";
-import { APPEND_SCRIPT_TOKEN } from "src/util/constants";
-
-const libraries = [
-  'https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js',
-  'https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.1.2/es5/tex-svg.js'
-]
-
-export interface IFeature extends IHasId{
-  type: string
-  name: string
-  data?: IHasId[]
-}
-
-@Injectable({
-  providedIn: 'root'
-})
-
-export class RegionalFeaturesService implements OnDestroy{
-
-  public depScriptLoaded$: Observable<boolean>
-
-  private subs: Subscription[] = []
-  private templateSelected: any
-  constructor(
-    private http: HttpClient,
-    private pureConstantService: PureContantService,
-    private store$: Store<any>,
-    @Optional() @Inject(APPEND_SCRIPT_TOKEN) private appendScript: (src: string) => Promise<HTMLScriptElement>
-  ){
-    this.subs.push(
-      this.store$.pipe(
-        select(viewerStateSelectedTemplateSelector)
-      ).subscribe(val => this.templateSelected = val)
-    )
-
-    this.depScriptLoaded$ = this.appendScript
-      ? from(
-        libraries.map(this.appendScript)
-      ).pipe(
-        mapTo(true),
-        catchError(() => of(false)),
-        shareReplay(1),
-      )
-      : of(false)
-  }
-
-  public mapFeatToCmp = new Map<string, any>()
-
-  ngOnDestroy(){
-    while (this.subs.length > 0) this.subs.pop().unsubscribe()
-  }
-
-  public onHoverLandmarks$ = this.store$.pipe(
-    select(uiStateMouseoverUserLandmark)
-  )
-
-  public getAllFeaturesByRegion(_region: {['fullId']: string} | { id: { kg: {kgSchema: string, kgId: string} } }){
-    
-    const region = {
-      ..._region,
-    }
-    if (!region['fullId']) {
-      const { kgSchema, kgId } = region['id']?.kg || {}
-      if (kgSchema && kgId) region['fullId'] = `${kgSchema}/${kgId}`
-    }
-
-    if (!region['fullId']) throw new Error(`getAllFeaturesByRegion - region does not have fullId defined`)
-    const regionFullIds = getStringIdsFromRegion(region)
-    const hemisphereObj = (() => {
-      const hemisphere = getRegionHemisphere(region)
-      return hemisphere ? { hemisphere } : {}
-    })()
-
-    const refSpaceObj = this.templateSelected && this.templateSelected.fullId
-      ? { referenceSpaceId: getIdFromFullId(this.templateSelected.fullId) }
-      : {}
-    
-    return forkJoin(
-      regionFullIds.map(regionFullId => this.http.get<{features: IHasId[]}>(
-        `${this.pureConstantService.backendUrl}regionalFeatures/byRegion/${encodeURIComponent( regionFullId )}`,
-        {
-          params: {
-            ...hemisphereObj,
-            ...refSpaceObj,
-          },
-          responseType: 'json'
-        }
-      ).pipe(
-        switchMap(({ features }) => forkJoin(
-          features.map(({ ['@id']: featureId }) => 
-            this.http.get<IFeature>(
-              `${this.pureConstantService.backendUrl}regionalFeatures/byRegion/${encodeURIComponent( regionFullId )}/${encodeURIComponent( featureId )}`,
-              {
-                params: {
-                  ...hemisphereObj,
-                  ...refSpaceObj,
-                },
-                responseType: 'json'
-              }
-            )
-          )
-        )),
-      ))
-    ).pipe(
-      map((arr: IFeature[][]) => arr.reduce(flattenReducer, []))
-    )
-  }
-
-  public getFeatureData(region: any,feature: IFeature, data: IHasId){
-    if (!feature['@id']) throw new Error(`@id attribute for feature is required`)
-    if (!data['@id']) throw new Error(`@id attribute for data is required`)
-    const refSpaceObj = this.templateSelected && this.templateSelected.fullId
-      ? { referenceSpaceId: getIdFromFullId(this.templateSelected.fullId) }
-      : {}
-    const hemisphereObj = (() => {
-      const hemisphere = getRegionHemisphere(region)
-      return hemisphere ? { hemisphere } : {}
-    })()
-
-    const regionId = getIdFromFullId(region && region.fullId)
-    const url = regionId
-      ? `${this.pureConstantService.backendUrl}regionalFeatures/byRegion/${encodeURIComponent(regionId)}/${encodeURIComponent(feature['@id'])}/${encodeURIComponent(data['@id'])}`
-      : `${this.pureConstantService.backendUrl}regionalFeatures/byFeature/${encodeURIComponent(feature['@id'])}/${encodeURIComponent(data['@id'])}`
-    return this.http.get<IHasId>(
-      url,
-      {
-        params: {
-          ...hemisphereObj,
-          ...refSpaceObj,
-        },
-        responseType: 'json'
-      }
-    )
-  }
-
-  public addLandmarks(lms: IHasId[]) {
-    this.store$.dispatch(
-      viewerStateAddUserLandmarks({
-        landmarks: lms.map(lm => ({
-          ...lm,
-          id: lm['@id'],
-          name: `region feature: ${lm['@id']}`
-        }))
-      })
-    )
-  }
-
-  public removeLandmarks(lms: IHasId[]) {
-    this.store$.dispatch(
-      viewreStateRemoveUserLandmarks({
-        payload: {
-          landmarkIds: lms.map(l => l['@id'])
-        }
-      })
-    )
-  }
-
-  showDatafeatureInfo$ = new Subject<{ fullId: string } | { name: string, description: string }>()
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/base/regionFeature.base.ts b/src/atlasComponents/regionalFeatures/singleFeatures/base/regionFeature.base.ts
deleted file mode 100644
index 21dde06920b0ddf29f384683c5851de9a171445f..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/base/regionFeature.base.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import { Directive, EventEmitter, Input, Output, SimpleChanges } from "@angular/core"
-import { BehaviorSubject, forkJoin, Observable, of } from "rxjs"
-import { catchError, shareReplay, switchMap, tap } from "rxjs/operators"
-import { IHasId } from "src/util/interfaces"
-import { IFeature, RegionalFeaturesService } from "../../regionalFeature.service"
-
-@Directive()
-export class RegionFeatureBase{
-
-  private _feature: IFeature
-
-  private feature$ = new BehaviorSubject(null)
-  @Input()
-  set feature(val) {
-    this._feature = val
-    this.feature$.next(val)
-  }
-  get feature(){
-    return this._feature
-  }
-
-  @Input()
-  public region: any
-
-  @Output('feature-explorer-is-loading')
-  public dataIsLoadingEventEmitter: EventEmitter<boolean> = new EventEmitter()
-
-  public features: IFeature[] = []
-  public data$: Observable<IHasId[]>
-
-  /**
-   * using isLoading flag for conditional rendering of root element (or display loading spinner)
-   * this is necessary, or the transcluded tab will always be the active tab,
-   * as this.features as populated via async
-   */
-  public isLoading$ = new BehaviorSubject(false)
-  private _isLoading: boolean = false
-  get isLoading(){
-    return this._isLoading
-  }
-  set isLoading(val){
-    if (val !== this._isLoading)
-      this._isLoading = val
-    this.isLoading$.next(val)
-  }
-
-  public dataIsLoading$ = new BehaviorSubject(false)
-  private _dataIsLoading = false
-  set dataIsLoading(val) {
-    if (val === this._dataIsLoading) return
-    this._dataIsLoading = val
-    this.dataIsLoading$.next(val)
-    this.dataIsLoadingEventEmitter.emit(val)
-  }
-  get dataIsLoading(){
-    return this._dataIsLoading
-  }
-
-  ngOnChanges(changes: SimpleChanges){
-    if (changes.region && changes.region.previousValue !== changes.region.currentValue) {
-      this.isLoading = true
-      this.features = []
-      
-      const _ = (changes.region.currentValue
-        ? this._regionalFeatureService.getAllFeaturesByRegion(changes.region.currentValue)
-        : of([])
-      ).pipe(
-        /**
-         * region may have no fullId defined
-         * in this case, just emit []
-         */
-        catchError(() => of([]))
-      ).subscribe({
-        next: features => this.features = features,
-        complete: () => this.isLoading = false
-      })
-    }
-  }
-
-  constructor(
-    private _regionalFeatureService: RegionalFeaturesService
-  ){
-
-    /**
-    * once feature stops loading, watch for input feature
-    */
-    this.data$ = this.feature$.pipe(
-      tap(() => this.dataIsLoading = true),
-      switchMap((feature: IFeature) => forkJoin(
-        feature.data.map(datum => this._regionalFeatureService.getFeatureData(this.region, feature, datum)))
-      ),
-      tap(() => this.dataIsLoading = false),
-      shareReplay(1),
-    )
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts b/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts
deleted file mode 100644
index 11fd197fbd45b569e35f15f5a9ae54ab13f07777..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts
+++ /dev/null
@@ -1,167 +0,0 @@
-import { Component, Inject, Optional, EventEmitter } from "@angular/core";
-import { Store } from "@ngrx/store";
-import { merge, Subject, Subscription } from "rxjs";
-import { debounceTime, map, scan, take } from "rxjs/operators";
-import { viewerStateChangeNavigation } from "src/services/state/viewerState/actions";
-import { RegionalFeaturesService } from "src/atlasComponents/regionalFeatures/regionalFeature.service";
-import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
-import { IHasId } from "src/util/interfaces";
-import { RegionFeatureBase } from "../../base/regionFeature.base";
-import { ISingleFeature } from '../../interfaces'
-
-const selectedColor = [ 255, 0, 0 ]
-
-@Component({
-  templateUrl: './iEEGRecordings.template.html',
-  styleUrls: [
-    './iEEGRecordings.style.css'
-  ]
-})
-
-export class IEEGRecordingsCmp extends RegionFeatureBase implements ISingleFeature{
-  private landmarksLoaded: IHasId[] = []
-  private onDestroyCb: (() => void)[] = []
-  private sub: Subscription[] = []
-
-  constructor(
-    private regionFeatureService: RegionalFeaturesService,
-    private store: Store<any>,
-    @Optional() @Inject(CLICK_INTERCEPTOR_INJECTOR) private regClickIntp: ClickInterceptor,
-  ){
-    super(regionFeatureService)
-  }
-
-  public viewChanged = new EventEmitter<boolean>()
-
-  ngOnInit(){
-    if (this.regClickIntp) {
-      const { deregister, register } = this.regClickIntp
-      const clickIntp = this.clickIntp.bind(this)
-      register(clickIntp)
-      this.onDestroyCb.push(() => {
-        deregister(clickIntp)
-      })
-    }
-    this.sub.push(
-      this.data$.subscribe(data => {
-        const landmarksTobeLoaded: IHasId[] = []
-        
-        for (const datum of data) {
-          const electrodeId = datum['@id']
-          landmarksTobeLoaded.push(
-            ...datum['contactPoints'].map(({ ['@id']: contactPtId, position }) => {
-              return {
-                _: {
-                  electrodeId,
-                  contactPtId
-                },
-                ['@id']: `${electrodeId}#${contactPtId}`,
-                position
-              }
-            })
-          )
-        }
-        /**
-         * remove first, then add
-         */
-        if (this.landmarksLoaded.length > 0) this.regionFeatureService.removeLandmarks(this.landmarksLoaded)
-        if (landmarksTobeLoaded.length > 0) this.regionFeatureService.addLandmarks(landmarksTobeLoaded)
-        this.landmarksLoaded = landmarksTobeLoaded
-      })
-    )
-
-    this.sub.push(
-      this.dataIsLoading$.subscribe(() => this.viewChanged.emit(true))
-    )
-
-    this.onDestroyCb.push(() => {
-      if (this.landmarksLoaded.length > 0) this.regionFeatureService.removeLandmarks(this.landmarksLoaded)
-    })
-
-    this.sub.push(
-      this.openElectrodeId$.pipe(
-        debounceTime(200)
-      ).subscribe(arr => {
-
-        if (this.landmarksLoaded.length > 0) {
-          this.regionFeatureService.removeLandmarks(this.landmarksLoaded)
-          this.regionFeatureService.addLandmarks(this.landmarksLoaded.map(lm => {
-            const selected = arr.some(id => id === lm['_']['electrodeId'])
-            return {
-              ...lm,
-              color: selected ? selectedColor : null,
-              showInSliceView: selected
-            }
-          }))
-        }
-      })
-    )
-  }
-
-
-  ngOnDestroy(){
-    while(this.onDestroyCb.length > 0) this.onDestroyCb.pop()()
-    while(this.sub.length > 0) this.sub.pop().unsubscribe()
-  }
-
-  handleContactPtClk(contactPt: IHasId & { position: number[] }){
-    const { position } = contactPt
-    this.store.dispatch(
-      viewerStateChangeNavigation({
-        navigation: {
-          position: position.map(v => v * 1e6),
-          positionReal: true,
-          animation: {}
-        },
-      })
-    )
-  }
-
-  handleDatumExpansion(electrodeId: string, open: boolean){
-    /**
-     * TODO either debounce call here, or later down stream
-     */
-    if (open) this.exploreElectrode$.next(electrodeId)
-    else this.unExploreElectrode$.next(electrodeId)
-  }
-
-  private unExploreElectrode$ = new Subject<string>()
-  private exploreElectrode$ = new Subject<string>()
-  public openElectrodeId$ = merge(
-    this.unExploreElectrode$.pipe(
-      map(id => ({
-        add: null,
-        remove: id
-      }))
-    ),
-    this.exploreElectrode$.pipe(
-      map(id => ({
-        add: id,
-        remove: null
-      }))
-    )
-  ).pipe(
-    scan((acc, curr) => {
-      const { add, remove } = curr
-      const set = new Set(acc)
-      if (add) set.add(add)
-      if (remove) set.delete(remove)
-      return Array.from(set)
-    }, [])
-  )
-
-  private clickIntp(ev: any): boolean {
-    let hoveredLandmark = null
-    this.regionFeatureService.onHoverLandmarks$.pipe(
-      take(1)
-    ).subscribe(val => {
-      hoveredLandmark = val
-    })
-    if (!hoveredLandmark) return true
-    const isOne = this.landmarksLoaded.some(lm => {
-      return lm['_']['electrodeId'] === hoveredLandmark['_']['electrodeId']
-    })
-    if (!isOne) return true
-    this.exploreElectrode$.next(hoveredLandmark['_']['electrodeId'])
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.template.html b/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.template.html
deleted file mode 100644
index 7a4b70d88a55e2e8325446c946c2035ed29d59bf..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.template.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<ng-container *ngIf="!dataIsLoading; else loadingTmpl">
-  
-  <mat-accordion
-    class="ml-24px-n mr-24px-n d-block">
-    <mat-expansion-panel *ngFor="let datum of (data$ | async)"
-      [expanded]="openElectrodeId$ | async | includes : datum['@id']"
-      (opened)="handleDatumExpansion(datum['@id'], true)"
-      (closed)="handleDatumExpansion(datum['@id'], false)"
-      togglePosition="before">
-      <mat-expansion-panel-header>
-        <mat-panel-title>
-          Electrode
-        </mat-panel-title>
-        <mat-panel-description class="text-nowrap">
-          {{ datum['@id'] }}
-        </mat-panel-description>
-      </mat-expansion-panel-header>
-
-      <label for="task-list" class="d-block mat-h4 mt-4 text-muted">
-        Tasks
-      </label>
-      <section class="d-flex align-items-center mt-1">
-        <section id="task-list" class="flex-grow-1 flex-shrink-1 overflow-x-auto">
-          <div role="list">
-            <mat-chip *ngFor="let task of datum['tasks']" class="ml-1">
-              {{ task }}
-            </mat-chip>
-          </div>
-        </section>
-      </section>
-
-      <label for="contact-points-list" class="d-block mat-h4 mt-4 text-muted">
-        Contact Points
-      </label>
-      <section class="d-flex align-items-center mt-1">
-        <section id="contact-points-list" class="flex-grow-1 flex-shrink-1 overflow-x-auto">
-          <div role="list">
-            <mat-chip *ngFor="let contactPt of datum['contactPoints']"
-              [matTooltip]="contactPt['position']"
-              (click)="handleContactPtClk(contactPt)"
-              class="ml-1">
-              {{ contactPt['@id'] }}
-            </mat-chip>
-          </div>
-        </section>
-      </section>
-  
-    </mat-expansion-panel>
-  </mat-accordion>
-
-</ng-container>
-
-<!-- loading template -->
-<ng-template #loadingTmpl>
-  <spinner-cmp></spinner-cmp>
-</ng-template>
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/module.ts b/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/module.ts
deleted file mode 100644
index 76d6cd9f67dba1c93bc6e51ee9c845bb035d4766..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/module.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { NgModule } from "@angular/core";
-import { ComponentsModule } from "src/components";
-import { AngularMaterialModule } from "src/sharedModules";
-import { UtilModule } from "src/util";
-import { RegionalFeaturesService } from "../../regionalFeature.service";
-import { IEEGRecordingsCmp } from "./iEEGRecordings/iEEGRecordings.component";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    UtilModule,
-    AngularMaterialModule,
-    ComponentsModule,
-  ],
-  declarations: [
-    IEEGRecordingsCmp
-  ],
-  exports: [
-    IEEGRecordingsCmp
-  ]
-})
-
-export class FeatureIEEGRecordings{
-  constructor(
-    rService: RegionalFeaturesService
-  ){
-    rService.mapFeatToCmp.set('iEEG recording', IEEGRecordingsCmp)
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/interfaces.ts b/src/atlasComponents/regionalFeatures/singleFeatures/interfaces.ts
deleted file mode 100644
index bd3861d391b4bcc90d262ee16e124b51e4affee2..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/interfaces.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { EventEmitter } from "@angular/core";
-import { IFeature } from "../regionalFeature.service";
-
-export interface ISingleFeature{
-  feature: IFeature
-  region: any
-  viewChanged: EventEmitter<boolean>
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/filterReceptorBytype.pipe.ts b/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/filterReceptorBytype.pipe.ts
deleted file mode 100644
index 1b0a91dd80079acf6e3cc6709c4ac3cc74ec5f97..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/filterReceptorBytype.pipe.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { IHasId } from "src/util/interfaces";
-
-@Pipe({
-  name: 'filterReceptorByType',
-  pure: true
-})
-
-export class FilterReceptorByType implements PipeTransform{
-  public transform(arr: IHasId[], qualifer: string): IHasId[]{
-    return (arr || []).filter(({ ['@id']: dId }) => dId.indexOf(qualifer) >= 0)
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getAllReceptors.pipe.ts b/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getAllReceptors.pipe.ts
deleted file mode 100644
index ba3016186957b4851e469792cc834110152ddb1b..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getAllReceptors.pipe.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { IHasId } from "src/util/interfaces";
-
-@Pipe({
-  name: 'getAllReceptors',
-  pure: true
-})
-
-export class GetAllReceptorsPipe implements PipeTransform{
-  public transform(arr: IHasId[]): string[]{
-    return (arr || []).reduce((acc, curr) => {
-      const thisType = /_(pr|ar)_([a-zA-Z0-9_]+)\./.exec(curr['@id'])
-      if (!thisType) return acc
-      return new Set(acc).has(thisType) ? acc : acc.concat(thisType[2])
-    }, [])
-  }
-}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getId.pipe.ts b/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getId.pipe.ts
deleted file mode 100644
index 3af1a02bd4a98455bc9b0166ff4adfc5afa53646..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getId.pipe.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-
-@Pipe({
-  name: 'getId',
-  pure: true
-})
-
-export class GetIdPipe implements PipeTransform{
-  public transform(fullId: string): string{
-    const re = /\/([a-f0-9-]+)$/.exec(fullId)
-    return (re && re[1]) || null
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getUrl.pipe.ts b/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getUrl.pipe.ts
deleted file mode 100644
index f4fdfab5613c225aa293a05b45c9d0ab8be666ab..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/getUrl.pipe.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { IHasId } from "src/util/interfaces";
-
-interface IReceptorDatum extends IHasId{
-  ['@context']: {
-    [key: string]: string
-  }
-  filename: string
-  mimetype: string
-  url: string | {
-    url: string
-    ['receptors.tsv']: string
-  }
-}
-
-interface IHRef{
-  url: string
-  filename: string
-}
-
-@Pipe({
-  name: 'getUrls',
-  pure: true
-})
-
-export class GetUrlsPipe implements PipeTransform{
-  public transform(input: IReceptorDatum): IHRef[]{
-    const output: IHRef[] = []
-    let _url = typeof input.url === 'string'
-      ? input.url
-      : input.url.url
-
-    for (const key in (input['@context'] || {})) {
-      _url = _url.replace(`${key}:`, input['@context'][key])
-    }
-
-    const match = /\/([\w-.]+)$/.exec(_url)
-    output.push({
-      url: _url,
-      filename: match ? match[1] : 'download'
-    })
-    return output
-  }
-}
-
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/module.ts b/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/module.ts
deleted file mode 100644
index e8ab67e4273b33310171ba1b36f7199bf5286008..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/module.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
-import { AngularMaterialModule } from "src/sharedModules";
-import { RegionalFeaturesService } from "../../regionalFeature.service";
-import { FilterReceptorByType } from "./filterReceptorBytype.pipe";
-import { GetAllReceptorsPipe } from "./getAllReceptors.pipe";
-import { GetIdPipe } from "./getId.pipe";
-import { GetUrlsPipe } from "./getUrl.pipe";
-import { ReceptorDensityFeatureCmp } from "./receptorDensity/receptorDensity.component";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    AngularMaterialModule,
-  ],
-  declarations: [
-    ReceptorDensityFeatureCmp,
-    FilterReceptorByType,
-    GetIdPipe,
-    GetAllReceptorsPipe,
-    GetUrlsPipe,
-  ],
-  schemas: [
-    CUSTOM_ELEMENTS_SCHEMA
-  ]
-})
-
-export class ReceptorDensityModule{
-  constructor(
-    rService: RegionalFeaturesService
-  ){
-    rService.mapFeatToCmp.set(`Receptor density measurement`, ReceptorDensityFeatureCmp)
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.component.ts b/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.component.ts
deleted file mode 100644
index 52cda125d7aa02bfaa062a121b62b94d365fa612..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.component.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { Component, ElementRef, EventEmitter, HostListener, OnDestroy, Optional } from "@angular/core";
-import { fromEvent, Observable, of, Subscription } from "rxjs";
-import { RegionalFeaturesService } from "src/atlasComponents/regionalFeatures/regionalFeature.service";
-import { PureContantService } from "src/util";
-import { RegionFeatureBase } from "../../base/regionFeature.base";
-import { ISingleFeature } from "../../interfaces";
-import { CONST } from 'common/constants'
-import { environment } from 'src/environments/environment'
-
-const {
-  RECEPTOR_FP_CAPTION,
-  RECEPTOR_PR_CAPTION,
-  RECEPTOR_AR_CAPTION,
-} = CONST
-@Component({
-  templateUrl: './receptorDensity.template.html',
-  styleUrls: [
-    './receptorDensity.style.css'
-  ]
-})
-
-export class ReceptorDensityFeatureCmp extends RegionFeatureBase implements ISingleFeature, OnDestroy{
-
-  public RECEPTOR_FP_CAPTION = RECEPTOR_FP_CAPTION
-  public RECEPTOR_PR_CAPTION = RECEPTOR_PR_CAPTION
-  public RECEPTOR_AR_CAPTION = RECEPTOR_AR_CAPTION
-
-  public DS_PREVIEW_URL = environment.DATASET_PREVIEW_URL
-  viewChanged: EventEmitter<null> = new EventEmitter()
-
-  private WEB_COMPONENT_MOUSEOVER_EVENT_NAME = 'kg-ds-prv-regional-feature-mouseover'
-  private webComponentOnHover: string = null
-
-  public selectedReceptor: string
-
-  public darktheme$: Observable<boolean>
-
-  private subs: Subscription[] = []
-  public depScriptLoaded$: Observable<boolean>
-  constructor(
-    regService: RegionalFeaturesService,
-    el: ElementRef,
-    @Optional() pureConstantService: PureContantService
-  ){
-    super(regService)
-    this.depScriptLoaded$ = regService.depScriptLoaded$
-    if (pureConstantService) {
-      this.darktheme$ = pureConstantService.darktheme$
-    } else {
-      this.darktheme$ = of(false)
-    }
-
-    this.subs.push(
-      fromEvent(el.nativeElement, this.WEB_COMPONENT_MOUSEOVER_EVENT_NAME).subscribe((ev: CustomEvent) => {
-        this.webComponentOnHover = ev.detail?.data?.receptor?.label
-      })
-    )
-  }
-
-  @HostListener('click')
-  onClick(){
-    if (this.webComponentOnHover) {
-      this.selectedReceptor = this.webComponentOnHover
-    }
-  }
-
-  ngOnDestroy(){
-    while(this.subs.length > 0) this.subs.pop().unsubscribe()
-  }
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.style.css b/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.style.css
deleted file mode 100644
index 0437be86256eb2a7039e72e33e80de0a92ea62ef..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.style.css
+++ /dev/null
@@ -1,11 +0,0 @@
-kg-dataset-previewer
-{
-  display: block;
-  height: 20em;
-}
-
-kg-ds-prv-regional-feature-view
-{
-  display: block;
-  min-height: 20em;
-}
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.template.html b/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.template.html
deleted file mode 100644
index f1454e06ca2bef47d6629a80a3907497b650ed76..0000000000000000000000000000000000000000
--- a/src/atlasComponents/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.template.html
+++ /dev/null
@@ -1,143 +0,0 @@
-<label for="fingerprint-cmp" class="d-inline mat-h4 mt-4 text-muted">
-  Fingerprint :
-</label>
-
-<ng-container *ngFor="let datum of (data$ | async | filterReceptorByType : '_fp_')">
-
-  <ng-container *ngTemplateOutlet="labelTmpl; context: {
-    for: 'fingerprint-cmp',
-    label: RECEPTOR_FP_CAPTION
-  }">
-  </ng-container>
-
-  <div class="d-block">
-    <ng-container *ngTemplateOutlet="datasetPreviewTmpl; context: {
-      id: 'fingerprint-cmp',
-      kgId: (feature['@id'] | getId),
-      filename: datum['@id'],
-      datum: datum
-    }">
-    </ng-container>
-  </div>
-
-</ng-container>
-
-<mat-divider></mat-divider>
-
-<ng-container *ngIf="data$ | async | getAllReceptors as allReceptors; else selectPlaceHolderTmpl">
-
-  <mat-form-field class="mt-2 w-100" *ngIf="allReceptors.length > 0; else selectPlaceHolderTmpl">
-    <mat-label>
-      Select a receptor
-    </mat-label>
-    <mat-select [(value)]="selectedReceptor">
-      <mat-option
-        *ngFor="let receptor of allReceptors"
-        [value]="receptor">
-        {{ receptor }}
-      </mat-option>
-    </mat-select>
-  </mat-form-field>
-
-</ng-container>
-
-<ng-template #selectPlaceHolderTmpl>
-  <span class="text-muted">No profile or autoradiographs available.</span>
-</ng-template>
-
-<ng-template [ngIf]="selectedReceptor">
-  <ng-container *ngTemplateOutlet="prArTmpl; context: { filter: '_pr_', label: 'Profile' }">
-  </ng-container>
-  <ng-container *ngTemplateOutlet="prArTmpl; context: { filter: '_ar_', label: 'Autoradiograph' }">
-  </ng-container>
-</ng-template>
-
-<!-- ar/pr template -->
-<ng-template #prArTmpl let-label="label" let-filter="filter">
-  <ng-container *ngFor="let datum of (data$ | async | filterReceptorByType : selectedReceptor | filterReceptorByType : filter); let first = first">
-    <ng-template [ngIf]="first">
-      <label [attr.for]="label + '-cmp'" class="d-inline mat-h4 mt-4 text-muted">
-        {{ label }} : 
-      </label>
-    </ng-template>
-
-    <ng-container *ngTemplateOutlet="labelTmpl; context: {
-      for: label + '-cmp',
-      label: 'Autoradiograph' ? RECEPTOR_AR_CAPTION : RECEPTOR_PR_CAPTION
-    }">
-    </ng-container>
-
-    <div class="d-block">
-      <ng-container *ngTemplateOutlet="datasetPreviewTmpl; context: {
-        id: label + '-cmp',
-        kgId: (feature['@id'] | getId),
-        filename: datum['@id'],
-        datum: datum
-      }">
-      </ng-container>
-    </div>
-
-  </ng-container>
-</ng-template>
-
-
-<!-- display preview tmpl -->
-<ng-template #datasetPreviewTmpl
-  let-id="id"
-  let-kgId="kgId"
-  let-filename="filename"
-  let-datum="datum">
-
-  <!-- download btns -->
-  <ng-container *ngFor="let urlObj of datum | getUrls">
-    <ng-container *ngTemplateOutlet="downloadBtnTmpl; context: {
-      url: urlObj.url,
-      filename: urlObj.filename,
-      tooltip: 'download ' + urlObj.filename
-    }">
-    </ng-container>
-  </ng-container>
-
-  <!-- render preview -->
-  <kg-ds-prv-regional-feature-view
-    *ngIf="depScriptLoaded$ | async; else fallbackTmpl"
-    [attr.id]="id"
-    [darkmode]="darktheme$ | async"
-    (renderEvent)="viewChanged.emit()"
-    [backendUrl]="DS_PREVIEW_URL"
-    [kgId]="kgId"
-    [filename]="filename">
-  </kg-ds-prv-regional-feature-view>
-
-  <ng-template #fallbackTmpl>
-    <kg-dataset-previewer
-      [attr.id]="id"
-      (renderEvent)="viewChanged.emit()"
-      [backendUrl]="DS_PREVIEW_URL"
-      [kgId]="kgId"
-      [filename]="filename">
-    </kg-dataset-previewer>
-  </ng-template>
-</ng-template>
-
-<ng-template #downloadBtnTmpl
-  let-url="url"
-  let-filename="filename"
-  let-tooltip="tooltip">
-  <a [href]="url"
-    class="d-inline-block"
-    [download]="filename"
-    [matTooltip]="tooltip">
-    <button mat-icon-button>
-      <i class="fas fa-download"></i>
-    </button>
-  </a>
-</ng-template>
-
-<ng-template #labelTmpl let-label="label" let-for="for">
-  <label [attr.for]="for" class="d-inline text-muted">
-    <span>
-      {{ label }}
-    </span>
-  </label>
-</ng-template>
\ No newline at end of file
diff --git a/src/atlasComponents/sapi/core/index.ts b/src/atlasComponents/sapi/core/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a7fc4cbb696db25e9fa2159b5862e23c0bdb260e
--- /dev/null
+++ b/src/atlasComponents/sapi/core/index.ts
@@ -0,0 +1,4 @@
+export { SAPIAtlas } from "./sapiAtlas"
+export { SAPISpace } from "./sapiSpace"
+export { SAPIParcellation } from "./sapiParcellation"
+export { SAPIRegion } from "./sapiRegion"
diff --git a/src/atlasComponents/sapi/core/sapiAtlas.ts b/src/atlasComponents/sapi/core/sapiAtlas.ts
new file mode 100644
index 0000000000000000000000000000000000000000..788a803bd32eb8cf8b5dcc98545284abbf4fe056
--- /dev/null
+++ b/src/atlasComponents/sapi/core/sapiAtlas.ts
@@ -0,0 +1,5 @@
+import { SAPI } from "../sapi.service";
+
+export class SAPIAtlas{
+  constructor(private sapi: SAPI, public id: string){}
+}
diff --git a/src/atlasComponents/sapi/core/sapiParcellation.ts b/src/atlasComponents/sapi/core/sapiParcellation.ts
new file mode 100644
index 0000000000000000000000000000000000000000..05e367a54c71aa42f312c5232ff69dab251f8ccf
--- /dev/null
+++ b/src/atlasComponents/sapi/core/sapiParcellation.ts
@@ -0,0 +1,29 @@
+import { SapiVolumeModel } from ".."
+import { SAPI } from "../sapi.service"
+import { SapiParcellationModel, SapiRegionModel } from "../type"
+
+export class SAPIParcellation{
+  constructor(private sapi: SAPI, public atlasId: string, public id: string){
+
+  }
+  getDetail(): Promise<SapiParcellationModel>{
+    return this.sapi.cachedGet<SapiParcellationModel>(
+      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.id)}`
+    )
+  }
+  getRegions(spaceId: string): Promise<SapiRegionModel[]> {
+    return this.sapi.cachedGet<SapiRegionModel[]>(
+      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.id)}/regions`,
+      {
+        params: {
+          space_id: spaceId
+        }
+      }
+    )
+  }
+  getVolumes(): Promise<SapiVolumeModel[]>{
+    return this.sapi.cachedGet<SapiVolumeModel[]>(
+      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.id)}/volumes`
+    )
+  }
+}
diff --git a/src/atlasComponents/sapi/core/sapiRegion.ts b/src/atlasComponents/sapi/core/sapiRegion.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6eb6996df0868ee07edbd65e8e7c30e79fba79eb
--- /dev/null
+++ b/src/atlasComponents/sapi/core/sapiRegion.ts
@@ -0,0 +1,35 @@
+import { SAPI } from "..";
+import { SapiRegionalFeatureModel } from "../type";
+
+export class SAPIRegion{
+  constructor(
+    private sapi: SAPI,
+    public atlasId: string,
+    public parcId: string,
+    public id: string,
+  ){
+
+  }
+
+  getFeatures(spaceId: string): Promise<SapiRegionalFeatureModel[]> {
+    return this.sapi.http.get<SapiRegionalFeatureModel[]>(
+      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.parcId)}/regions/${encodeURIComponent(this.id)}/features`,
+      {
+        params: {
+          space_id: spaceId
+        }
+      }
+    ).toPromise()
+  }
+
+  getFeatureInstance(instanceId: string, spaceId: string): Promise<SapiRegionalFeatureModel> {
+    return this.sapi.http.get<SapiRegionalFeatureModel>(
+      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.parcId)}/regions/${encodeURIComponent(this.id)}/features/${encodeURIComponent(instanceId)}`,
+      {
+        params: {
+          space_id: spaceId
+        }
+      }
+    ).toPromise()
+  }
+}
diff --git a/src/atlasComponents/sapi/sapiSpace.ts b/src/atlasComponents/sapi/core/sapiSpace.ts
similarity index 55%
rename from src/atlasComponents/sapi/sapiSpace.ts
rename to src/atlasComponents/sapi/core/sapiSpace.ts
index 9999a6d3e3332a8909981ac72719ab4e9a06af72..1b3ef810f646100f381e4d847013e4354b3cc8bb 100644
--- a/src/atlasComponents/sapi/sapiSpace.ts
+++ b/src/atlasComponents/sapi/core/sapiSpace.ts
@@ -1,7 +1,8 @@
 import { Observable } from "rxjs"
-import { SAPI } from './sapi'
+import { SAPI } from '../sapi.service'
 import { camelToSnake } from 'common/util'
 import { IVolumeTypeDetail } from "src/util/siibraApiConstants/types"
+import { SapiSpaceModel, SapiSpatialFeatureModel, SapiVolumeModel } from "../type"
 
 type FeatureResponse = {
   features: {
@@ -32,47 +33,38 @@ type Volume = {
   }
 }
 
-type SapiVoiResponse = {
-  "@id": string
-  name: string
-  description: string
-  urls: {
-    cite?: string
-    doi: string
-  }[]
-  location: {
-    space: {
-      "@id": string
-      center: Point
-      minpoint: Point
-      maxpoint: Point
-    }
-  }
-  volumes: Volume[]
-}
-
-type SapiSpatialResp = SapiVoiResponse
-
 export class SAPISpace{
 
-  constructor(private sapi: SAPI, private atlasId: string, public id: string){}
+  constructor(private sapi: SAPI, public atlasId: string, public id: string){}
 
   getModalities(): Observable<FeatureResponse> {
     return this.sapi.http.get<FeatureResponse>(
-      `${this.sapi.bsEndpoint}/atlases/${this.atlasId}/spaces/${this.id}/features`
+      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/spaces/${encodeURIComponent(this.id)}/features`
     )
   }
 
-  getFeatures(modalityId: string, opts: SpatialFeatureOpts): Observable<SapiSpatialResp[]> {
+  getFeatures(modalityId: string, opts: SpatialFeatureOpts): Promise<SapiSpatialFeatureModel[]> {
     const query = {}
     for (const [key, value] of Object.entries(opts)) {
       query[camelToSnake(key)] = value
     }
-    return this.sapi.http.get<SapiSpatialResp[]>(
+    return this.sapi.cachedGet<SapiSpatialFeatureModel[]>(
       `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/spaces/${encodeURIComponent(this.id)}/features/${encodeURIComponent(modalityId)}`,
       {
         params: query
       }
     )
   }
+
+  getDetail(): Promise<SapiSpaceModel>{
+    return this.sapi.cachedGet<SapiSpaceModel>(
+      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/spaces/${encodeURIComponent(this.id)}`,
+    )
+  }
+
+  getVolumes(): Promise<SapiVolumeModel[]>{
+    return this.sapi.cachedGet<SapiVolumeModel[]>(
+      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/spaces/${encodeURIComponent(this.id)}/volumes`,
+    )
+  }
 }
diff --git a/src/atlasComponents/sapi/directives/spatialFeatureBBox.directive.ts b/src/atlasComponents/sapi/directives/spatialFeatureBBox.directive.ts
index 88a23c7f1a227c7e02044ceeda54f467cdc0b9f5..bdd15c9b221c01dc699d1959de3eade353c416c9 100644
--- a/src/atlasComponents/sapi/directives/spatialFeatureBBox.directive.ts
+++ b/src/atlasComponents/sapi/directives/spatialFeatureBBox.directive.ts
@@ -1,8 +1,8 @@
 import { combineLatest, Observable, BehaviorSubject, Subject, Subscription, of, merge } from 'rxjs';
 import { debounceTime, map, distinctUntilChanged, switchMap, tap, startWith, filter } from 'rxjs/operators';
 import { Directive, EventEmitter, Input, OnDestroy, Output } from "@angular/core";
-import { BoundingBoxConcept, SapiVoiResponse } from '../type'
-import { SAPI } from '../sapi'
+import { BoundingBoxConcept, SapiSpatialFeatureModel, SapiVOIDataResponse } from '../type'
+import { SAPI } from '../sapi.service'
 import { environment } from "src/environments/environment"
 
 function validateBbox(input: any): boolean {
@@ -52,8 +52,8 @@ export class SpatialFeatureBBox implements OnDestroy{
   }
 
   @Output('sii-xp-spatial-feat-bbox-features')
-  featureOutput = new EventEmitter<SapiVoiResponse[]>()
-  features$ = new BehaviorSubject<SapiVoiResponse[]>([])
+  featureOutput = new EventEmitter<SapiVOIDataResponse[]>()
+  features$ = new BehaviorSubject<SapiVOIDataResponse[]>([])
 
   @Output('sii-xp-spatial-feat-bbox-busy')
   busy$ = new EventEmitter<boolean>()
@@ -96,12 +96,12 @@ export class SpatialFeatureBBox implements OnDestroy{
         }) => {
           if (!atlasId || !spaceId || !bbox) {
             this.busy$.emit(false)
-            return of([])
+            return of([] as SapiSpatialFeatureModel[])
           }
           const space = this.svc.getSpace(atlasId, spaceId)
           return space.getFeatures(SpatialFeatureBBox.FEATURE_NAME, { bbox: JSON.stringify(bbox) })
         })
-      ).subscribe(results => {
+      ).subscribe((results: SapiVOIDataResponse[]) => {
         this.featureOutput.emit(results)
         this.features$.next(results)
         this.busy$.emit(false)
diff --git a/src/atlasComponents/sapi/index.ts b/src/atlasComponents/sapi/index.ts
index 00d79eee47547d480e353d9d29a062b65fc37420..092ebd6e947b5c63cad8074d1e3d311539f62a10 100644
--- a/src/atlasComponents/sapi/index.ts
+++ b/src/atlasComponents/sapi/index.ts
@@ -1,8 +1,21 @@
 export { SAPIModule } from './module'
 export { SpatialFeatureBBox } from './directives/spatialFeatureBBox.directive'
-import { SapiVoiResponse } from './type'
 
-export type SpatialFeatureResponse = SapiVoiResponse
-
-export type FeatureResponse = SpatialFeatureResponse
+export {
+  SapiAtlasModel,
+  SapiParcellationModel,
+  SapiSpaceModel,
+  SapiRegionModel,
+  SapiVolumeModel,
+  SapiDatasetModel,
+  SapiRegionalFeatureModel,
+  SapiSpatialFeatureModel
+} from "./type"
 
+export { SAPI } from "./sapi.service"
+export {
+  SAPIAtlas,
+  SAPISpace,
+  SAPIParcellation,
+  SAPIRegion
+} from "./core"
diff --git a/src/atlasComponents/sapi/module.ts b/src/atlasComponents/sapi/module.ts
index 85957778367792123a5eb321082fb30f7e3346ae..452d71f70804eedce57e4c5b051e3c3abdff4be4 100644
--- a/src/atlasComponents/sapi/module.ts
+++ b/src/atlasComponents/sapi/module.ts
@@ -1,11 +1,18 @@
 import { NgModule } from "@angular/core";
-import { SAPI } from "./sapi";
+import { SAPI } from "./sapi.service";
 import { SpatialFeatureBBox } from "./directives/spatialFeatureBBox.directive"
 import { CommonModule } from "@angular/common";
+import { EffectsModule } from "@ngrx/effects";
+import { SapiEffects } from "./sapi.effects";
+import { HTTP_INTERCEPTORS } from "@angular/common/http";
+import { PriorityHttpInterceptor } from "src/util/priority";
 
 @NgModule({
   imports: [
     CommonModule,
+    EffectsModule.forFeature([
+      SapiEffects
+    ])
   ],
   declarations: [
     SpatialFeatureBBox,
@@ -14,7 +21,12 @@ import { CommonModule } from "@angular/common";
     SpatialFeatureBBox,
   ],
   providers: [
-    SAPI
+    SAPI,
+    {
+      provide: HTTP_INTERCEPTORS,
+      useClass: PriorityHttpInterceptor,
+      multi: true
+    }
   ]
 })
 export class SAPIModule{}
diff --git a/src/atlasComponents/sapi/sapi.effects.ts b/src/atlasComponents/sapi/sapi.effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c1cb06fb33676d803368afaac8f39bbd0c7887ef
--- /dev/null
+++ b/src/atlasComponents/sapi/sapi.effects.ts
@@ -0,0 +1,12 @@
+import { Injectable } from "@angular/core";
+import { SAPI } from "./sapi.service"
+
+@Injectable()
+export class SapiEffects{
+
+  constructor(
+    private sapiSvc: SAPI
+  ){
+
+  }
+}
diff --git a/src/atlasComponents/sapi/sapi.service.ts b/src/atlasComponents/sapi/sapi.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aacc57ee38a39d2a8fc27395fa85216ed25dcd13
--- /dev/null
+++ b/src/atlasComponents/sapi/sapi.service.ts
@@ -0,0 +1,133 @@
+import { Inject, Injectable } from "@angular/core";
+import { HttpClient } from '@angular/common/http';
+import { BS_ENDPOINT } from 'src/util/constants';
+import { map, shareReplay, take, tap } from "rxjs/operators";
+import { SAPIAtlas, SAPISpace } from './core'
+import { SapiAtlasModel, SapiParcellationModel, SapiRegionalFeatureModel, SapiRegionModel, SapiSpaceModel } from "./type";
+import { CachedFunction } from "src/util/fn";
+import { SAPIParcellation } from "./core/sapiParcellation";
+import { SAPIRegion } from "./core/sapiRegion"
+import { MatSnackBar } from "@angular/material/snack-bar";
+
+export const SIIBRA_API_VERSION_HEADER_KEY='x-siibra-api-version'
+export const SIIBRA_API_VERSION = '0.2.0'
+
+type RegistryType = SAPIAtlas | SAPISpace | SAPIParcellation
+
+@Injectable()
+export class SAPI{
+
+  public bsEndpoint = 'https://siibra-api-dev.apps-dev.hbp.eu/v1_0'
+  
+  registry = {
+    _map: {} as Record<string, {
+      func: (...arg: any[]) => RegistryType,
+      args: string[]
+    }>,
+    get<T>(id: string): T {
+      if (!this._map[id]) return null
+      const { func, args } = this._map[id]
+      return func(...args)
+    },
+    set(id: string, func: (...args: any[]) => RegistryType, args: string[]) {
+      if (this._map[id]) {
+        console.warn(`id ${id} already mapped as ${this._map[id]}`)
+      }
+      this._map[id] = { func, args }
+    }
+  }
+
+  getAtlas(atlasId: string): SAPIAtlas {
+    return new SAPIAtlas(this, atlasId)
+  }
+
+  getSpace(atlasId: string, spaceId: string): SAPISpace {
+    return new SAPISpace(this, atlasId, spaceId)
+  }
+
+  getParcellation(atlasId: string, parcId: string): SAPIParcellation {
+    return new SAPIParcellation(this, atlasId, parcId)
+  }
+
+  getRegion(atlasId: string, parcId: string, regionId: string): SAPIRegion{
+    return new SAPIRegion(this, atlasId, parcId, regionId)
+  }
+
+  @CachedFunction({
+    serialization: (atlasId, spaceId, ...args) => `sapi::getSpaceDetail::${atlasId}::${spaceId}`
+  })
+  getSpaceDetail(atlasId: string, spaceId: string, priority = 0): Promise<SapiSpaceModel> {
+    return this.getSpace(atlasId, spaceId).getDetail()
+  }
+
+  @CachedFunction({
+    serialization: (atlasId, parcId, ...args) => `sapi::getParcDetail::${atlasId}::${parcId}`
+  })
+  getParcDetail(atlasId: string, parcId: string, priority = 0): Promise<SapiParcellationModel> {
+    return this.getParcellation(atlasId, parcId).getDetail()
+  }
+
+  @CachedFunction({
+    serialization: (atlasId, parcId, spaceId, ...args) => `sapi::getRegions::${atlasId}::${parcId}::${spaceId}`
+  })
+  getParcRegions(atlasId: string, parcId: string, spaceId: string, priority = 0): Promise<SapiRegionModel[]> {
+    const parc = this.getParcellation(atlasId, parcId)
+    return parc.getRegions(spaceId)
+  }
+
+  @CachedFunction({
+    serialization: (atlasId, parcId, spaceId, regionId, ...args) => `sapi::getRegions::${atlasId}::${parcId}::${spaceId}::${regionId}`
+  })
+  getRegionFeatures(atlasId: string, parcId: string, spaceId: string, regionId: string, priority = 0): Promise<SapiRegionalFeatureModel[]>{
+
+    const reg = this.getRegion(atlasId, parcId, regionId)
+    return reg.getFeatures(spaceId)
+  }
+
+  @CachedFunction({
+    serialization: (url, params) => `sapi::cachedGet::${url}::${JSON.stringify(params)}`
+  })
+  cachedGet<T>(url: string, option?: Record<string, any>) {
+    return this.http.get<T>(url, option).toPromise()
+  }
+
+
+  public atlases$ = this.http.get<SapiAtlasModel[]>(
+    `${this.bsEndpoint}/atlases`,
+    {
+      observe: "response"
+    }
+  ).pipe(
+    tap(resp => {
+
+      const respVersion = resp.headers.get(SIIBRA_API_VERSION_HEADER_KEY)
+      if (respVersion !== SIIBRA_API_VERSION) {
+        this.snackbar.open(`Expecting ${SIIBRA_API_VERSION}, got ${respVersion}. Some functionalities may not work as expected.`, 'Dismiss', {
+          duration: 5000
+        })
+      }
+      console.log(`siibra-api::version::${respVersion}, expecting::${SIIBRA_API_VERSION}`)
+    }),
+    map(resp => resp.body),
+    shareReplay(1)
+  )
+
+  constructor(
+    public http: HttpClient,
+    private snackbar: MatSnackBar,
+    // @Inject(BS_ENDPOINT) public bsEndpoint: string,
+  ){
+    this.atlases$.subscribe(atlases => {
+      for (const atlas of atlases) {
+        for (const space of atlas.spaces) {
+          this.registry.set(space["@id"], this.getSpace.bind(this), [atlas["@id"], space["@id"]])
+          this.getSpaceDetail(atlas["@id"], space["@id"])
+        }
+        for (const parc of atlas.parcellations) {
+          this.registry.set(parc["@id"], this.getParcellation.bind(this), [atlas["@id"], parc["@id"]])
+          this.getParcDetail(atlas["@id"], parc["@id"])
+        }
+      }
+    })
+  }
+}
diff --git a/src/atlasComponents/sapi/sapi.ts b/src/atlasComponents/sapi/sapi.ts
deleted file mode 100644
index 0e3e141e01c8ae9e18f4ad0c211b64af3feff4d9..0000000000000000000000000000000000000000
--- a/src/atlasComponents/sapi/sapi.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { BS_ENDPOINT } from 'src/util/constants';
-import { Inject, Injectable } from "@angular/core";
-import { SAPISpace } from './sapiSpace'
-import { HttpClient } from '@angular/common/http';
-
-@Injectable()
-export class SAPI{
-
-  getSpace(atlasId: string, spaceId: string): SAPISpace {
-    return new SAPISpace(this, atlasId, spaceId)
-  }
-
-  constructor(
-    public http: HttpClient,
-    @Inject(BS_ENDPOINT) public bsEndpoint: string,
-  ){
-
-  }
-}
diff --git a/src/atlasComponents/sapi/schema.ts b/src/atlasComponents/sapi/schema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c1f52d82ee9d74a9687466aa12867ad3ee4f54fa
--- /dev/null
+++ b/src/atlasComponents/sapi/schema.ts
@@ -0,0 +1,1769 @@
+/**
+ * This file was auto-generated by openapi-typescript.
+ * Do not make direct changes to the file.
+ */
+
+export interface paths {
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/regions": {
+    /** Returns all regions for a given parcellation id. */
+    get: operations["get_all_regions_from_atlas_parc_space_atlases__atlas_id__parcellations__parcellation_id__regions_get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/regions/{region_id}/features": {
+    /** Returns all regional features for a region. */
+    get: operations["get_all_features_for_region_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__features_get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/regions/{region_id}/features/{feature_id}": {
+    /** Returns a feature for a region, as defined by by the modality and feature ID */
+    get: operations["get_regional_modality_by_id_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__features__feature_id__get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/regions/{region_id}/regional_map/info": {
+    /** Returns information about a regional map for given region name. */
+    get: operations["get_regional_map_info_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__regional_map_info_get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/regions/{region_id}/regional_map/map": {
+    /** Returns a regional map for given region name. */
+    get: operations["get_regional_map_file_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__regional_map_map_get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/regions/{region_id}": {
+    get: operations["get_single_region_detail_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__get"];
+  };
+  "/atlases/{atlas_id}/parcellations": {
+    /** Returns all parcellations that are defined in the siibra client for given atlas. */
+    get: operations["get_all_parcellations_atlases__atlas_id__parcellations_get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/features/{feature_id}": {
+    /** Returns a global feature for a specific modality id. */
+    get: operations["get_single_global_feature_detail_atlases__atlas_id__parcellations__parcellation_id__features__feature_id__get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/features": {
+    /** Returns all global features for a parcellation. */
+    get: operations["get_global_features_names_atlases__atlas_id__parcellations__parcellation_id__features_get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}/volumes": {
+    /** Returns one parcellation for given id. */
+    get: operations["get_volumes_by_id_atlases__atlas_id__parcellations__parcellation_id__volumes_get"];
+  };
+  "/atlases/{atlas_id}/parcellations/{parcellation_id}": {
+    /** Returns one parcellation for given id. */
+    get: operations["get_parcellation_by_id_atlases__atlas_id__parcellations__parcellation_id__get"];
+  };
+  "/atlases/{atlas_id}/spaces": {
+    /** Returns all spaces that are defined in the siibra client. */
+    get: operations["get_all_spaces_atlases__atlas_id__spaces_get"];
+  };
+  "/atlases/{atlas_id}/spaces/{space_id}/templates": {
+    /** Returns a template for a given space id. */
+    get: operations["get_template_by_space_id_atlases__atlas_id__spaces__space_id__templates_get"];
+  };
+  "/atlases/{atlas_id}/spaces/{space_id}/parcellation_maps": {
+    /** Returns all parcellation maps for a given space id. */
+    get: operations["get_parcellation_map_for_space_atlases__atlas_id__spaces__space_id__parcellation_maps_get"];
+  };
+  "/atlases/{atlas_id}/spaces/{space_id}/features/{feature_id}": {
+    /**
+     * Get a detailed view on a single spatial feature.
+     * A parcellation id and region id can be provided optional to get more details.
+     */
+    get: operations["get_single_spatial_feature_detail_atlases__atlas_id__spaces__space_id__features__feature_id__get"];
+  };
+  "/atlases/{atlas_id}/spaces/{space_id}/features": {
+    /** Return all possible feature names and links to get more details */
+    get: operations["get_spatial_features_from_space_atlases__atlas_id__spaces__space_id__features_get"];
+  };
+  "/atlases/{atlas_id}/spaces/{space_id}/volumes": {
+    get: operations["get_one_space_volumes_atlases__atlas_id__spaces__space_id__volumes_get"];
+  };
+  "/atlases/{atlas_id}/spaces/{space_id}": {
+    /** Returns one space for given id, with links to further resources */
+    get: operations["get_one_space_by_id_atlases__atlas_id__spaces__space_id__get"];
+  };
+  "/atlases": {
+    /** Get all atlases known by siibra. */
+    get: operations["get_all_atlases_atlases_get"];
+  };
+  "/atlases/{atlas_id}": {
+    /** Get more information for a specific atlas with links to further objects. */
+    get: operations["get_atlas_by_id_atlases__atlas_id__get"];
+  };
+  "/genes": {
+    /** Return all genes (name, acronym) in siibra */
+    get: operations["get_gene_names_genes_get"];
+  };
+  "/features": {
+    /** Return all possible modalities */
+    get: operations["get_all_available_modalities_features_get"];
+  };
+}
+
+export interface components {
+  schemas: {
+    /** AutoradiographyDataModel */
+    AutoradiographyDataModel: {
+      /**
+       * Content Type
+       * @default application/octet-stream
+       */
+      content_type?: string;
+      /**
+       * Content Encoding
+       * @default gzip; base64
+       */
+      content_encoding?: string;
+      /** X-Width */
+      "x-width": number;
+      /** X-Height */
+      "x-height": number;
+      /** X-Channel */
+      "x-channel": number;
+      /** Dtype */
+      dtype: string;
+      /** Content */
+      content: string;
+    };
+    /** AxesOrigin */
+    AxesOrigin: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * typeOfUncertainty
+       * @description Distinct technique used to quantify the uncertainty of a measurement.
+       */
+      typeOfUncertainty?: unknown;
+      /**
+       * uncertainty
+       * @description Quantitative value range defining the uncertainty of a measurement.
+       */
+      uncertainty?: number[];
+      /**
+       * unit
+       * @description Determinate quantity adopted as a standard of measurement.
+       */
+      unit?: unknown;
+      /**
+       * value
+       * @description Entry for a property.
+       */
+      value: number;
+    };
+    /** BaseDatasetJsonModel */
+    BaseDatasetJsonModel: {
+      /** @Id */
+      "@id": string;
+      /**
+       * Type
+       * @constant
+       */
+      type?: "siibra/base-dataset";
+      metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
+      /** Urls */
+      urls: components["schemas"]["Url"][];
+    };
+    /** BestViewPoint */
+    BestViewPoint: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * coordinateSpace
+       * @description Two or three dimensional geometric setting.
+       */
+      coordinateSpace: unknown;
+      /**
+       * Coordinates
+       * @description Structured information on a quantitative value.
+       */
+      coordinates: components["schemas"]["siibra__openminds__SANDS__v3__atlas__parcellationEntityVersion__Coordinates"][];
+    };
+    /** BoundingBoxModel */
+    BoundingBoxModel: {
+      /** Space */
+      space: { [key: string]: string };
+      center: components["schemas"]["siibra__openminds__SANDS__v3__miscellaneous__coordinatePoint__Model"];
+      minpoint: components["schemas"]["siibra__openminds__SANDS__v3__miscellaneous__coordinatePoint__Model"];
+      maxpoint: components["schemas"]["siibra__openminds__SANDS__v3__miscellaneous__coordinatePoint__Model"];
+      /** Shape */
+      shape: number[];
+      /** Is Planar */
+      is_planar: boolean;
+    };
+    /** ConnectivityMatrixDataModel */
+    ConnectivityMatrixDataModel: {
+      /** @Id */
+      "@id": string;
+      /** Name */
+      name: string;
+      matrix: components["schemas"]["NpArrayDataModel"];
+      /** Columns */
+      columns: string[];
+      /** Parcellations */
+      parcellations: { [key: string]: string }[];
+    };
+    /** DatasetJsonModel */
+    DatasetJsonModel: {
+      /** @Id */
+      "@id": string;
+      /**
+       * Type
+       * @constant
+       */
+      type?: "siibra/base-dataset";
+      metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
+      /** Urls */
+      urls: components["schemas"]["Url"][];
+    };
+    /** FingerPrintDataModel */
+    FingerPrintDataModel: {
+      /** Mean */
+      mean: number;
+      /** Std */
+      std: number;
+      /** Unit */
+      unit: string;
+    };
+    /** HTTPValidationError */
+    HTTPValidationError: {
+      /** Detail */
+      detail?: components["schemas"]["ValidationError"][];
+    };
+    /** HasAnnotation */
+    HasAnnotation: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * Bestviewpoint
+       * @description Structured information on a coordinate point.
+       */
+      bestViewPoint?: components["schemas"]["BestViewPoint"];
+      /**
+       * criteria
+       * @description Aspects or standards on which a judgement or decision is based.
+       */
+      criteria?: unknown;
+      /**
+       * criteriaQualityType
+       * @description Distinct class that defines how the judgement or decision was made for a particular criteria.
+       */
+      criteriaQualityType: unknown;
+      /**
+       * displayColor
+       * @description Preferred coloring.
+       */
+      displayColor?: string;
+      /**
+       * inspiredBy
+       * @description Reference to an inspiring element.
+       */
+      inspiredBy?: unknown[];
+      /**
+       * internalIdentifier
+       * @description Term or code that identifies someone or something within a particular product.
+       */
+      internalIdentifier: string;
+      /**
+       * laterality
+       * @description Differentiation between a pair of lateral homologous parts of the body.
+       */
+      laterality?: unknown[];
+      /**
+       * visualizedIn
+       * @description Reference to an image in which something is visible.
+       */
+      visualizedIn?: unknown;
+    };
+    /** HasTerminologyVersion */
+    HasTerminologyVersion: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * definedIn
+       * @description Reference to a file instance in which something is stored.
+       */
+      definedIn?: unknown[];
+      /** hasEntityVersion */
+      hasEntityVersion: unknown[];
+      /**
+       * ontologyIdentifier
+       * @description Term or code used to identify something or someone registered within a particular ontology.
+       */
+      ontologyIdentifier?: string[];
+    };
+    /** HrefModel */
+    HrefModel: {
+      /** Href */
+      href: string;
+    };
+    /** IEEGContactPointModel */
+    IEEGContactPointModel: {
+      /** Id */
+      id: string;
+      point: components["schemas"]["siibra__openminds__SANDS__v3__miscellaneous__coordinatePoint__Model"];
+    };
+    /** IEEGElectrodeModel */
+    IEEGElectrodeModel: {
+      /** Electrode Id */
+      electrode_id: string;
+      /** Contact Points */
+      contact_points: {
+        [key: string]: components["schemas"]["IEEGContactPointModel"];
+      };
+    };
+    /** IEEGSessionModel */
+    IEEGSessionModel: {
+      /** @Id */
+      "@id": string;
+      dataset: components["schemas"]["DatasetJsonModel"];
+      /** Sub Id */
+      sub_id: string;
+      /** Electrodes */
+      electrodes: {
+        [key: string]: components["schemas"]["IEEGElectrodeModel"];
+      };
+    };
+    /** NiiMetadataModel */
+    NiiMetadataModel: {
+      /** Min */
+      min: number;
+      /** Max */
+      max: number;
+    };
+    /** NpArrayDataModel */
+    NpArrayDataModel: {
+      /**
+       * Content Type
+       * @default application/octet-stream
+       */
+      content_type?: string;
+      /**
+       * Content Encoding
+       * @default gzip; base64
+       */
+      content_encoding?: string;
+      /** X-Width */
+      "x-width": number;
+      /** X-Height */
+      "x-height": number;
+      /** X-Channel */
+      "x-channel": number;
+      /** Dtype */
+      dtype: string;
+      /** Content */
+      content: string;
+    };
+    /** ProfileDataModel */
+    ProfileDataModel: {
+      density: components["schemas"]["NpArrayDataModel"];
+      /** Unit */
+      unit: string;
+    };
+    /** QuantitativeOverlapItem */
+    QuantitativeOverlapItem: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * typeOfUncertainty
+       * @description Distinct technique used to quantify the uncertainty of a measurement.
+       */
+      typeOfUncertainty?: unknown;
+      /**
+       * uncertainty
+       * @description Quantitative value range defining the uncertainty of a measurement.
+       */
+      uncertainty?: number[];
+      /**
+       * unit
+       * @description Determinate quantity adopted as a standard of measurement.
+       */
+      unit?: unknown;
+      /**
+       * value
+       * @description Entry for a property.
+       */
+      value: number;
+    };
+    /** QuantitativeOverlapItem1 */
+    QuantitativeOverlapItem1: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * maxValue
+       * @description Greatest quantity attained or allowed.
+       */
+      maxValue: number;
+      /** maxValueUnit */
+      maxValueUnit?: unknown;
+      /**
+       * minValue
+       * @description Smallest quantity attained or allowed.
+       */
+      minValue: number;
+      /** minValueUnit */
+      minValueUnit?: unknown;
+    };
+    /** ReceptorDataModel */
+    ReceptorDataModel: {
+      /** Autoradiographs */
+      autoradiographs: {
+        [key: string]: components["schemas"]["AutoradiographyDataModel"];
+      };
+      /** Profiles */
+      profiles: { [key: string]: components["schemas"]["ProfileDataModel"] };
+      /** Fingerprints */
+      fingerprints: {
+        [key: string]: components["schemas"]["FingerPrintDataModel"];
+      };
+    };
+    /** ReceptorDatasetModel */
+    ReceptorDatasetModel: {
+      /** @Id */
+      "@id": string;
+      /**
+       * Type
+       * @constant
+       */
+      type?: "siibra/receptor";
+      metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
+      /** Urls */
+      urls: components["schemas"]["Url"][];
+      data?: components["schemas"]["ReceptorDataModel"];
+    };
+    /** RelationAssessmentItem */
+    RelationAssessmentItem: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * criteria
+       * @description Aspects or standards on which a judgement or decision is based.
+       */
+      criteria?: unknown;
+      /**
+       * inRelationTo
+       * @description Reference to a related element.
+       */
+      inRelationTo: unknown;
+      /**
+       * qualitativeOverlap
+       * @description Semantic characterization of how much two things occupy the same space.
+       */
+      qualitativeOverlap: unknown;
+    };
+    /** RelationAssessmentItem1 */
+    RelationAssessmentItem1: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * criteria
+       * @description Aspects or standards on which a judgement or decision is based.
+       */
+      criteria?: unknown;
+      /**
+       * inRelationTo
+       * @description Reference to a related element.
+       */
+      inRelationTo: unknown;
+      /** Quantitativeoverlap */
+      quantitativeOverlap: Partial<
+        components["schemas"]["QuantitativeOverlapItem"]
+      > &
+        Partial<components["schemas"]["QuantitativeOverlapItem1"]>;
+    };
+    /** SapiAtlasModel */
+    SapiAtlasModel: {
+      /** Links */
+      links: { [key: string]: components["schemas"]["HrefModel"] };
+      /** @Id */
+      "@id": string;
+      /** Name */
+      name: string;
+      /**
+       * @Type
+       * @constant
+       */
+      "@type"?: "juelich/iav/atlas/v1.0.0";
+      /** Spaces */
+      spaces: components["schemas"]["SiibraAtIdModel"][];
+      /** Parcellations */
+      parcellations: components["schemas"]["SiibraAtIdModel"][];
+      species: components["schemas"]["SpeciesModel"];
+    };
+    /** SapiParcellationModel */
+    SapiParcellationModel: {
+      /** Links */
+      links: { [key: string]: components["schemas"]["HrefModel"] };
+      /** @Id */
+      "@id": string;
+      /**
+       * @Type
+       * @constant
+       */
+      "@type"?: "minds/core/parcellationatlas/v1.0.0";
+      /** Name */
+      name: string;
+      /** Datasets */
+      datasets: components["schemas"]["DatasetJsonModel"][];
+      /** Brainatlasversions */
+      brainAtlasVersions: components["schemas"]["siibra__openminds__SANDS__v3__atlas__brainAtlasVersion__Model"][];
+    };
+    /** SapiSpaceModel */
+    SapiSpaceModel: {
+      /** Links */
+      links: { [key: string]: components["schemas"]["HrefModel"] };
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * @Id
+       * @description Metadata node identifier.
+       */
+      "@id": string;
+      /** @Type */
+      "@type": string;
+      /**
+       * anatomicalAxesOrientation
+       * @description Relation between reference planes used in anatomy and mathematics.
+       */
+      anatomicalAxesOrientation: { [key: string]: unknown };
+      /**
+       * Axesorigin
+       * @description Structured information on a quantitative value.
+       */
+      axesOrigin: components["schemas"]["AxesOrigin"][];
+      /**
+       * defaultImage
+       * @description Two or three dimensional image that particluarly represents a specific coordinate space.
+       */
+      defaultImage?: unknown[];
+      /**
+       * digitalIdentifier
+       * @description Digital handle to identify objects or legal persons.
+       */
+      digitalIdentifier?: { [key: string]: unknown };
+      /**
+       * fullName
+       * @description Whole, non-abbreviated name of something or somebody.
+       */
+      fullName: string;
+      /**
+       * homepage
+       * @description Main website of something or someone.
+       */
+      homepage?: { [key: string]: unknown };
+      /**
+       * howToCite
+       * @description Preferred format for citing a particular object or legal person.
+       */
+      howToCite?: string;
+      /**
+       * nativeUnit
+       * @description Determinate quantity used in the original measurement.
+       */
+      nativeUnit: { [key: string]: unknown };
+      /**
+       * ontologyIdentifier
+       * @description Term or code used to identify something or someone registered within a particular ontology.
+       */
+      ontologyIdentifier?: string[];
+      /**
+       * releaseDate
+       * Format: date
+       * @description Fixed date on which a product is due to become or was made available for the general public to see or buy
+       */
+      releaseDate: string;
+      /**
+       * shortName
+       * @description Shortened or fully abbreviated name of something or somebody.
+       */
+      shortName: string;
+      /**
+       * versionIdentifier
+       * @description Term or code used to identify the version of something.
+       */
+      versionIdentifier: string;
+    };
+    /** SiibraAtIdModel */
+    SiibraAtIdModel: {
+      /** @Id */
+      "@id": string;
+    };
+    /** SpeciesModel */
+    SpeciesModel: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * @Id
+       * @description Metadata node identifier.
+       */
+      "@id": string;
+      /** @Type */
+      "@type": string;
+      /**
+       * definition
+       * @description Short, but precise statement of the meaning of a word, word group, sign or a symbol.
+       */
+      definition?: string;
+      /**
+       * description
+       * @description Longer statement or account giving the characteristics of someone or something.
+       */
+      description?: string;
+      /**
+       * interlexIdentifier
+       * @description Persistent identifier for a term registered in the InterLex project.
+       */
+      interlexIdentifier?: string;
+      /**
+       * knowledgeSpaceLink
+       * @description Persistent link to an encyclopedia entry in the Knowledge Space project.
+       */
+      knowledgeSpaceLink?: string;
+      /**
+       * name
+       * @description Word or phrase that constitutes the distinctive designation of a being or thing.
+       */
+      name: string;
+      /**
+       * preferredOntologyIdentifier
+       * @description Persistent identifier of a preferred ontological term.
+       */
+      preferredOntologyIdentifier?: string;
+      /**
+       * synonym
+       * @description Words or expressions used in the same language that have the same or nearly the same meaning in some or all senses.
+       */
+      synonym?: string[];
+      /** Kgv1Id */
+      kgV1Id: string;
+    };
+    /** Url */
+    Url: {
+      /** Doi */
+      doi: string;
+      /** Cite */
+      cite?: string;
+    };
+    /** VOIDataModel */
+    VOIDataModel: {
+      /** @Id */
+      "@id": string;
+      /**
+       * Type
+       * @constant
+       */
+      type?: "siibra/base-dataset";
+      metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
+      /** Urls */
+      urls: components["schemas"]["Url"][];
+      /** Volumes */
+      volumes: components["schemas"]["VolumeModel"][];
+      location: components["schemas"]["BoundingBoxModel"];
+    };
+    /** ValidationError */
+    ValidationError: {
+      /** Location */
+      loc: string[];
+      /** Message */
+      msg: string;
+      /** Error Type */
+      type: string;
+    };
+    /** VocabModel */
+    VocabModel: {
+      /** @Vocab */
+      "@vocab": string;
+    };
+    /** VolumeDataModel */
+    VolumeDataModel: {
+      /** Type */
+      type: string;
+      /** Is Volume */
+      is_volume: boolean;
+      /** Is Surface */
+      is_surface: boolean;
+      /** Detail */
+      detail: { [key: string]: unknown };
+      space: components["schemas"]["SiibraAtIdModel"];
+      /** Url */
+      url?: string;
+      /** Url Map */
+      url_map?: { [key: string]: string };
+      /** Map Type */
+      map_type?: string;
+      /** Volume Type */
+      volume_type?: string;
+    };
+    /** VolumeModel */
+    VolumeModel: {
+      /** @Id */
+      "@id": string;
+      /**
+       * Type
+       * @constant
+       */
+      type?: "siibra/base-dataset";
+      metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
+      /** Urls */
+      urls: components["schemas"]["Url"][];
+      data: components["schemas"]["VolumeDataModel"];
+    };
+    /** Copyright */
+    siibra__openminds__SANDS__v3__atlas__brainAtlasVersion__Copyright: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * holder
+       * @description Legal person in possession of something.
+       */
+      holder: unknown[];
+      /**
+       * year
+       * @description Cycle in the Gregorian calendar specified by a number and comprised of 365 or 366 days divided into 12 months beginning with January and ending with December.
+       */
+      year: string;
+    };
+    /** Model */
+    siibra__openminds__SANDS__v3__atlas__brainAtlasVersion__Model: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * @Id
+       * @description Metadata node identifier.
+       */
+      "@id": string;
+      /** @Type */
+      "@type": string;
+      /** abbreviation */
+      abbreviation?: string;
+      /**
+       * accessibility
+       * @description Level to which something is accessible to someone or something.
+       */
+      accessibility: { [key: string]: unknown };
+      /** atlasType */
+      atlasType?: { [key: string]: unknown };
+      /**
+       * author
+       * @description Creator of a literary or creative work, as well as a dataset publication.
+       */
+      author?: unknown[];
+      /**
+       * coordinateSpace
+       * @description Two or three dimensional geometric setting.
+       */
+      coordinateSpace: { [key: string]: unknown };
+      /**
+       * Copyright
+       * @description Structured information on the copyright.
+       */
+      copyright?: components["schemas"]["siibra__openminds__SANDS__v3__atlas__brainAtlasVersion__Copyright"];
+      /**
+       * custodian
+       * @description The 'custodian' is a legal person who is responsible for the content and quality of the data, metadata, and/or code of a research product.
+       */
+      custodian?: unknown[];
+      /**
+       * description
+       * @description Longer statement or account giving the characteristics of someone or something.
+       */
+      description?: string;
+      /**
+       * digitalIdentifier
+       * @description Digital handle to identify objects or legal persons.
+       */
+      digitalIdentifier?: { [key: string]: unknown };
+      /**
+       * fullDocumentation
+       * @description Non-abridged instructions, comments, and information for using a particular product.
+       */
+      fullDocumentation: { [key: string]: unknown };
+      /**
+       * fullName
+       * @description Whole, non-abbreviated name of something or somebody.
+       */
+      fullName?: string;
+      /**
+       * funding
+       * @description Money provided by a legal person for a particular purpose.
+       */
+      funding?: unknown[];
+      hasTerminologyVersion: components["schemas"]["HasTerminologyVersion"];
+      /**
+       * homepage
+       * @description Main website of something or someone.
+       */
+      homepage?: { [key: string]: unknown };
+      /**
+       * howToCite
+       * @description Preferred format for citing a particular object or legal person.
+       */
+      howToCite?: string;
+      /**
+       * isAlternativeVersionOf
+       * @description Reference to an original form where the essence was preserved, but presented in an alternative form.
+       */
+      isAlternativeVersionOf?: unknown[];
+      /**
+       * isNewVersionOf
+       * @description Reference to a previous (potentially outdated) particular form of something.
+       */
+      isNewVersionOf?: { [key: string]: unknown };
+      /**
+       * keyword
+       * @description Significant word or concept that are representative of something or someone.
+       */
+      keyword?: unknown[];
+      /**
+       * license
+       * @description Grant by a party to another party as an element of an agreement between those parties that permits to do, use, or own something.
+       */
+      license: { [key: string]: unknown };
+      /**
+       * ontologyIdentifier
+       * @description Term or code used to identify something or someone registered within a particular ontology.
+       */
+      ontologyIdentifier?: string[];
+      /**
+       * Othercontribution
+       * @description Structured information on the contribution made to a research product.
+       */
+      otherContribution?: components["schemas"]["siibra__openminds__SANDS__v3__atlas__brainAtlasVersion__OtherContribution"];
+      /**
+       * relatedPublication
+       * @description Reference to something that was made available for the general public to see or buy.
+       */
+      relatedPublication?: unknown[];
+      /**
+       * releaseDate
+       * Format: date
+       * @description Fixed date on which a product is due to become or was made available for the general public to see or buy
+       */
+      releaseDate: string;
+      /**
+       * repository
+       * @description Place, room, or container where something is deposited or stored.
+       */
+      repository?: { [key: string]: unknown };
+      /**
+       * shortName
+       * @description Shortened or fully abbreviated name of something or somebody.
+       */
+      shortName: string;
+      /**
+       * supportChannel
+       * @description Way of communication used to interact with users or customers.
+       */
+      supportChannel?: string[];
+      /**
+       * versionIdentifier
+       * @description Term or code used to identify the version of something.
+       */
+      versionIdentifier: string;
+      /**
+       * versionInnovation
+       * @description Documentation on what changed in comparison to a previously published form of something.
+       */
+      versionInnovation: string;
+    };
+    /** OtherContribution */
+    siibra__openminds__SANDS__v3__atlas__brainAtlasVersion__OtherContribution: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * contributionType
+       * @description Distinct class of what was given or supplied as a part or share.
+       */
+      contributionType: unknown[];
+      /**
+       * contributor
+       * @description Legal person that gave or supplied something as a part or share.
+       */
+      contributor: unknown;
+    };
+    /** Coordinates */
+    siibra__openminds__SANDS__v3__atlas__parcellationEntityVersion__Coordinates: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * typeOfUncertainty
+       * @description Distinct technique used to quantify the uncertainty of a measurement.
+       */
+      typeOfUncertainty?: unknown;
+      /**
+       * uncertainty
+       * @description Quantitative value range defining the uncertainty of a measurement.
+       */
+      uncertainty?: number[];
+      /**
+       * unit
+       * @description Determinate quantity adopted as a standard of measurement.
+       */
+      unit?: unknown;
+      /**
+       * value
+       * @description Entry for a property.
+       */
+      value: number;
+    };
+    /** Model */
+    siibra__openminds__SANDS__v3__atlas__parcellationEntityVersion__Model: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * @Id
+       * @description Metadata node identifier.
+       */
+      "@id": string;
+      /** @Type */
+      "@type": string;
+      hasAnnotation?: components["schemas"]["HasAnnotation"];
+      /**
+       * hasParent
+       * @description Reference to a parent object or legal person.
+       */
+      hasParent?: unknown[];
+      /** lookupLabel */
+      lookupLabel?: string;
+      /**
+       * name
+       * @description Word or phrase that constitutes the distinctive designation of a being or thing.
+       */
+      name?: string;
+      /**
+       * ontologyIdentifier
+       * @description Term or code used to identify something or someone registered within a particular ontology.
+       */
+      ontologyIdentifier?: string[];
+      /** Relationassessment */
+      relationAssessment?: Partial<
+        components["schemas"]["RelationAssessmentItem"]
+      > &
+        Partial<components["schemas"]["RelationAssessmentItem1"]>;
+      /**
+       * versionIdentifier
+       * @description Term or code used to identify the version of something.
+       */
+      versionIdentifier: string;
+      /**
+       * versionInnovation
+       * @description Documentation on what changed in comparison to a previously published form of something.
+       */
+      versionInnovation?: string;
+    };
+    /** Coordinates */
+    siibra__openminds__SANDS__v3__miscellaneous__coordinatePoint__Coordinates: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * typeOfUncertainty
+       * @description Distinct technique used to quantify the uncertainty of a measurement.
+       */
+      typeOfUncertainty?: unknown;
+      /**
+       * uncertainty
+       * @description Quantitative value range defining the uncertainty of a measurement.
+       */
+      uncertainty?: number[];
+      /**
+       * unit
+       * @description Determinate quantity adopted as a standard of measurement.
+       */
+      unit?: unknown;
+      /**
+       * value
+       * @description Entry for a property.
+       */
+      value: number;
+    };
+    /** Model */
+    siibra__openminds__SANDS__v3__miscellaneous__coordinatePoint__Model: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * @Id
+       * @description Metadata node identifier.
+       */
+      "@id": string;
+      /** @Type */
+      "@type": string;
+      /**
+       * coordinateSpace
+       * @description Two or three dimensional geometric setting.
+       */
+      coordinateSpace: { [key: string]: unknown };
+      /**
+       * Coordinates
+       * @description Structured information on a quantitative value.
+       */
+      coordinates: components["schemas"]["siibra__openminds__SANDS__v3__miscellaneous__coordinatePoint__Coordinates"][];
+    };
+    /** Copyright */
+    siibra__openminds__core__v4__products__datasetVersion__Copyright: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * holder
+       * @description Legal person in possession of something.
+       */
+      holder: unknown[];
+      /**
+       * year
+       * @description Cycle in the Gregorian calendar specified by a number and comprised of 365 or 366 days divided into 12 months beginning with January and ending with December.
+       */
+      year: string;
+    };
+    /** Model */
+    siibra__openminds__core__v4__products__datasetVersion__Model: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * @Id
+       * @description Metadata node identifier.
+       */
+      "@id": string;
+      /** @Type */
+      "@type": string;
+      /**
+       * accessibility
+       * @description Level to which something is accessible to someone or something.
+       */
+      accessibility: { [key: string]: unknown };
+      /**
+       * author
+       * @description Creator of a literary or creative work, as well as a dataset publication.
+       */
+      author?: unknown[];
+      /** behavioralProtocol */
+      behavioralProtocol?: unknown[];
+      /**
+       * Copyright
+       * @description Structured information on the copyright.
+       */
+      copyright?: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Copyright"];
+      /**
+       * custodian
+       * @description The 'custodian' is a legal person who is responsible for the content and quality of the data, metadata, and/or code of a research product.
+       */
+      custodian?: unknown[];
+      /** dataType */
+      dataType: unknown[];
+      /**
+       * description
+       * @description Longer statement or account giving the characteristics of someone or something.
+       */
+      description?: string;
+      /**
+       * digitalIdentifier
+       * @description Digital handle to identify objects or legal persons.
+       */
+      digitalIdentifier: { [key: string]: unknown };
+      /**
+       * ethicsAssessment
+       * @description Judgment about the applied principles of conduct governing an individual or a group.
+       */
+      ethicsAssessment: { [key: string]: unknown };
+      /** experimentalApproach */
+      experimentalApproach: unknown[];
+      /**
+       * fullDocumentation
+       * @description Non-abridged instructions, comments, and information for using a particular product.
+       */
+      fullDocumentation: { [key: string]: unknown };
+      /**
+       * fullName
+       * @description Whole, non-abbreviated name of something or somebody.
+       */
+      fullName?: string;
+      /**
+       * funding
+       * @description Money provided by a legal person for a particular purpose.
+       */
+      funding?: unknown[];
+      /**
+       * homepage
+       * @description Main website of something or someone.
+       */
+      homepage?: { [key: string]: unknown };
+      /**
+       * howToCite
+       * @description Preferred format for citing a particular object or legal person.
+       */
+      howToCite?: string;
+      /**
+       * inputData
+       * @description Data that is put into a process or machine.
+       */
+      inputData?: unknown[];
+      /**
+       * isAlternativeVersionOf
+       * @description Reference to an original form where the essence was preserved, but presented in an alternative form.
+       */
+      isAlternativeVersionOf?: unknown[];
+      /**
+       * isNewVersionOf
+       * @description Reference to a previous (potentially outdated) particular form of something.
+       */
+      isNewVersionOf?: { [key: string]: unknown };
+      /**
+       * keyword
+       * @description Significant word or concept that are representative of something or someone.
+       */
+      keyword?: unknown[];
+      /**
+       * license
+       * @description Grant by a party to another party as an element of an agreement between those parties that permits to do, use, or own something.
+       */
+      license: { [key: string]: unknown };
+      /**
+       * Othercontribution
+       * @description Structured information on the contribution made to a research product.
+       */
+      otherContribution?: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__OtherContribution"];
+      /** preparationDesign */
+      preparationDesign?: unknown[];
+      /**
+       * relatedPublication
+       * @description Reference to something that was made available for the general public to see or buy.
+       */
+      relatedPublication?: unknown[];
+      /**
+       * releaseDate
+       * Format: date
+       * @description Fixed date on which a product is due to become or was made available for the general public to see or buy
+       */
+      releaseDate: string;
+      /**
+       * repository
+       * @description Place, room, or container where something is deposited or stored.
+       */
+      repository?: { [key: string]: unknown };
+      /**
+       * shortName
+       * @description Shortened or fully abbreviated name of something or somebody.
+       */
+      shortName: string;
+      /** studiedSpecimen */
+      studiedSpecimen?: unknown[];
+      /**
+       * studyTarget
+       * @description Structure or function that was targeted within a study.
+       */
+      studyTarget?: unknown[];
+      /**
+       * supportChannel
+       * @description Way of communication used to interact with users or customers.
+       */
+      supportChannel?: string[];
+      /**
+       * technique
+       * @description Method of accomplishing a desired aim.
+       */
+      technique: unknown[];
+      /**
+       * versionIdentifier
+       * @description Term or code used to identify the version of something.
+       */
+      versionIdentifier: string;
+      /**
+       * versionInnovation
+       * @description Documentation on what changed in comparison to a previously published form of something.
+       */
+      versionInnovation: string;
+    };
+    /** OtherContribution */
+    siibra__openminds__core__v4__products__datasetVersion__OtherContribution: {
+      /**
+       * @Context
+       * @default [object Object]
+       */
+      "@context"?: components["schemas"]["VocabModel"];
+      /**
+       * contributionType
+       * @description Distinct class of what was given or supplied as a part or share.
+       */
+      contributionType: unknown[];
+      /**
+       * contributor
+       * @description Legal person that gave or supplied something as a part or share.
+       */
+      contributor: unknown;
+    };
+  };
+}
+
+export interface operations {
+  /** Returns all regions for a given parcellation id. */
+  get_all_regions_from_atlas_parc_space_atlases__atlas_id__parcellations__parcellation_id__regions_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+      };
+      query: {
+        space_id?: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["siibra__openminds__SANDS__v3__atlas__parcellationEntityVersion__Model"][];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns all regional features for a region. */
+  get_all_features_for_region_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__features_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+        region_id: string;
+      };
+      query: {
+        space_id?: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": (Partial<
+            components["schemas"]["ReceptorDatasetModel"]
+          > &
+            Partial<components["schemas"]["BaseDatasetJsonModel"]>)[];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns a feature for a region, as defined by by the modality and feature ID */
+  get_regional_modality_by_id_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__features__feature_id__get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+        region_id: string;
+        feature_id: string;
+      };
+      query: {
+        space_id?: string;
+        gene?: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": Partial<
+            components["schemas"]["ReceptorDatasetModel"]
+          > &
+            Partial<components["schemas"]["BaseDatasetJsonModel"]>;
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns information about a regional map for given region name. */
+  get_regional_map_info_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__regional_map_info_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+        region_id: string;
+      };
+      query: {
+        space_id?: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["NiiMetadataModel"];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns a regional map for given region name. */
+  get_regional_map_file_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__regional_map_map_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+        region_id: string;
+      };
+      query: {
+        space_id?: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": unknown;
+          "application/octet-stream": string;
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  get_single_region_detail_atlases__atlas_id__parcellations__parcellation_id__regions__region_id__get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+        region_id: string;
+      };
+      query: {
+        space_id?: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["siibra__openminds__SANDS__v3__atlas__parcellationEntityVersion__Model"];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns all parcellations that are defined in the siibra client for given atlas. */
+  get_all_parcellations_atlases__atlas_id__parcellations_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["SapiParcellationModel"][];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns a global feature for a specific modality id. */
+  get_single_global_feature_detail_atlases__atlas_id__parcellations__parcellation_id__features__feature_id__get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+        feature_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["ConnectivityMatrixDataModel"];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns all global features for a parcellation. */
+  get_global_features_names_atlases__atlas_id__parcellations__parcellation_id__features_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["ConnectivityMatrixDataModel"][];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns one parcellation for given id. */
+  get_volumes_by_id_atlases__atlas_id__parcellations__parcellation_id__volumes_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["VolumeModel"][];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns one parcellation for given id. */
+  get_parcellation_by_id_atlases__atlas_id__parcellations__parcellation_id__get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        parcellation_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["SapiParcellationModel"];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns all spaces that are defined in the siibra client. */
+  get_all_spaces_atlases__atlas_id__spaces_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["SapiSpaceModel"][];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns a template for a given space id. */
+  get_template_by_space_id_atlases__atlas_id__spaces__space_id__templates_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        space_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": unknown;
+          "application/octet-stream": string;
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns all parcellation maps for a given space id. */
+  get_parcellation_map_for_space_atlases__atlas_id__spaces__space_id__parcellation_maps_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        space_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": unknown;
+          "application/octet-stream": string;
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /**
+   * Get a detailed view on a single spatial feature.
+   * A parcellation id and region id can be provided optional to get more details.
+   */
+  get_single_spatial_feature_detail_atlases__atlas_id__spaces__space_id__features__feature_id__get: {
+    parameters: {
+      path: {
+        feature_id: string;
+        atlas_id: string;
+        space_id: string;
+      };
+      query: {
+        parcellation_id: string;
+        region: string;
+        bbox?: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": Partial<
+            components["schemas"]["IEEGSessionModel"]
+          > &
+            Partial<components["schemas"]["VOIDataModel"]>;
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Return all possible feature names and links to get more details */
+  get_spatial_features_from_space_atlases__atlas_id__spaces__space_id__features_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        space_id: string;
+      };
+      query: {
+        parcellation_id?: string;
+        region?: string;
+        bbox?: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": (Partial<
+            components["schemas"]["IEEGSessionModel"]
+          > &
+            Partial<components["schemas"]["VOIDataModel"]>)[];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  get_one_space_volumes_atlases__atlas_id__spaces__space_id__volumes_get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        space_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["VolumeModel"][];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Returns one space for given id, with links to further resources */
+  get_one_space_by_id_atlases__atlas_id__spaces__space_id__get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+        space_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["SapiSpaceModel"];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Get all atlases known by siibra. */
+  get_all_atlases_atlases_get: {
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["SapiAtlasModel"][];
+        };
+      };
+    };
+  };
+  /** Get more information for a specific atlas with links to further objects. */
+  get_atlas_by_id_atlases__atlas_id__get: {
+    parameters: {
+      path: {
+        atlas_id: string;
+      };
+    };
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": components["schemas"]["SapiAtlasModel"];
+        };
+      };
+      /** Validation Error */
+      422: {
+        content: {
+          "application/json": components["schemas"]["HTTPValidationError"];
+        };
+      };
+    };
+  };
+  /** Return all genes (name, acronym) in siibra */
+  get_gene_names_genes_get: {
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": unknown;
+        };
+      };
+    };
+  };
+  /** Return all possible modalities */
+  get_all_available_modalities_features_get: {
+    responses: {
+      /** Successful Response */
+      200: {
+        content: {
+          "application/json": unknown;
+        };
+      };
+    };
+  };
+}
+
+export interface external {}
diff --git a/src/atlasComponents/sapi/type.ts b/src/atlasComponents/sapi/type.ts
index 803c294d8e219030fbc6184034488919e652b974..dba9a4897300b90b3c45d058501ee0f928c41ad1 100644
--- a/src/atlasComponents/sapi/type.ts
+++ b/src/atlasComponents/sapi/type.ts
@@ -1,4 +1,7 @@
+import { OperatorFunction } from "rxjs"
+import { map } from "rxjs/operators"
 import { IVolumeTypeDetail } from "src/util/siibraApiConstants/types"
+import { components } from "./schema"
 
 export type IdName = {
   id: string
@@ -18,21 +21,39 @@ type Volume = {
 
 export type BoundingBoxConcept = [Point, Point]
 
-export type SapiVoiResponse = {
-  "@id": string
-  name: string
-  description: string
-  url: {
-    cite?: string
-    doi: string
-  }[]
-  location: {
-    space: {
-      "@id": string
-    }
-    center: Point
-    minpoint: Point
-    maxpoint: Point
-  }
-  volumes: Volume[]
+export type SapiAtlasModel = components["schemas"]["SapiAtlasModel"]
+export type SapiSpaceModel = components["schemas"]["SapiSpaceModel"]
+export type SapiParcellationModel = components["schemas"]["SapiParcellationModel"]
+export type SapiRegionModel = components["schemas"]["siibra__openminds__SANDS__v3__atlas__parcellationEntityVersion__Model"]
+
+export type SapiSpatialFeatureModel = components["schemas"]["VOIDataModel"]
+export type SapiVOIDataResponse = components["schemas"]["VOIDataModel"]
+
+export type SapiVolumeModel = components["schemas"]["VolumeModel"]
+export type SapiDatasetModel = components["schemas"]["DatasetJsonModel"]
+
+export const guards = {
+  isSapiVolumeModel: (val: SapiVolumeModel) => val.type === "siibra/base-dataset"
+    && val.data.detail["neuroglancer/precomputed"]
+}
+
+/**
+ * datafeatures
+ */
+export type SapiRegionalFeatureModel = components["schemas"]["BaseDatasetJsonModel"] | components["schemas"]["ReceptorDatasetModel"]
+
+export function guardPipe<
+  InputType,
+  GuardType extends InputType
+>(
+  guardFn: (input: InputType) => input is GuardType
+): OperatorFunction<InputType, GuardType> {
+  return src => src.pipe(
+    map(val => {
+      if (guardFn(val)) {
+        return val
+      }
+      throw new Error(`TypeGuard Error`)
+    })
+  )
 }
diff --git a/src/atlasComponents/sapiViews/features/ieeg/ieegSession/ieegSession.component.ts b/src/atlasComponents/sapiViews/features/ieeg/ieegSession/ieegSession.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9725ac61ea28969bf932c600e7b82521b9b0ab5f
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/ieeg/ieegSession/ieegSession.component.ts
@@ -0,0 +1,26 @@
+import { Component } from "@angular/core";
+
+type Landmark = {} & {
+  showInSliceView
+}
+
+@Component({
+  templateUrl: `./ieegSession.template.html`,
+  styleUrls: [
+    `./ieegSession.style.css`
+  ]
+})
+
+export class IEEGSessionCmp{
+  private loadedLms: Landmark[]
+
+  private unloadLandmarks(){}
+  private loadlandmarks(lms: Landmark[]){}
+  private handleDatumExpansion(dataset: any){
+
+  }
+  private handleContactPtClick(contactPt){
+    // navigate there
+
+  }
+}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegSummary/kgRegSummary.style.css b/src/atlasComponents/sapiViews/features/ieeg/ieegSession/ieegSession.style.css
similarity index 100%
rename from src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature/kgRegSummary/kgRegSummary.style.css
rename to src/atlasComponents/sapiViews/features/ieeg/ieegSession/ieegSession.style.css
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/profile/profile.style.css b/src/atlasComponents/sapiViews/features/ieeg/ieegSession/ieegSession.template.html
similarity index 100%
rename from src/atlasComponents/regionalFeatures/bsFeatures/receptor/profile/profile.style.css
rename to src/atlasComponents/sapiViews/features/ieeg/ieegSession/ieegSession.template.html
diff --git a/src/atlasComponents/sapiViews/features/ieeg/index.ts b/src/atlasComponents/sapiViews/features/ieeg/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..663fabd8603621b891428afeb0d68e861690cfd4
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/ieeg/index.ts
@@ -0,0 +1 @@
+export { IEEGSessionCmp } from "./ieegSession/ieegSession.component"
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/index.ts b/src/atlasComponents/sapiViews/features/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..19e30dcb1873aa37868be5e8944eaad3a9b0ce05
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/index.ts
@@ -0,0 +1,3 @@
+export {
+  SapiViewsFeaturesModule
+} from "./module"
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/module.ts b/src/atlasComponents/sapiViews/features/module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..87dbbcd9db1587bb2b121e8d144f384656f2b7f8
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/module.ts
@@ -0,0 +1,34 @@
+import { CommonModule } from "@angular/common"
+import { NgModule } from "@angular/core"
+import { AngularMaterialModule } from "src/sharedModules"
+import * as ieeg from "./ieeg"
+import * as receptor from "./receptors"
+
+const {
+  IEEGSessionCmp
+} = ieeg
+const {
+  Autoradiography,
+  Fingerprint,
+  Profile,
+} = receptor
+
+@NgModule({
+  imports: [
+    CommonModule,
+    AngularMaterialModule
+  ],
+  declarations: [
+    IEEGSessionCmp,
+    Autoradiography,
+    Fingerprint,
+    Profile,
+  ],
+  exports: [
+    IEEGSessionCmp,
+    Autoradiography,
+    Fingerprint,
+    Profile,
+  ]
+})
+export class SapiViewsFeaturesModule{}
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiography.component.ts b/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiography.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f7d764069608079a7c893d4df7aaa3662ae6f3c0
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiography.component.ts
@@ -0,0 +1,11 @@
+import { Component } from "@angular/core";
+import { BaseReceptor } from "../base";
+
+@Component({
+  templateUrl: './autoradiography.template.html',
+  styleUrls: [
+    './autoradiography.style.css'
+  ]
+})
+
+export class Autoradiography extends BaseReceptor{}
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.style.css b/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiography.style.css
similarity index 100%
rename from src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.style.css
rename to src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiography.style.css
diff --git a/src/atlasComponents/regionalFeatures/util.ts b/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiography.template.html
similarity index 100%
rename from src/atlasComponents/regionalFeatures/util.ts
rename to src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiography.template.html
diff --git a/src/atlasComponents/sapiViews/features/receptors/base.ts b/src/atlasComponents/sapiViews/features/receptors/base.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7bff16e25247fa50c55ca4accf8d605d210f3611
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/receptors/base.ts
@@ -0,0 +1,7 @@
+import { Input } from "@angular/core";
+
+export class BaseReceptor{
+  
+  @Input()
+  featureId: string
+}
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.component.ts b/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a99e111980e482baf88d925d93133a2361d664b8
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.component.ts
@@ -0,0 +1,11 @@
+import { Component } from "@angular/core";
+import { BaseReceptor } from "../base";
+
+@Component({
+  templateUrl: './fingerprint.template.html',
+  styleUrls: [
+    './fingerprint.style.css'
+  ]
+})
+
+export class Fingerprint extends BaseReceptor{}
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.style.css b/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.style.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.template.html b/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.template.html
new file mode 100644
index 0000000000000000000000000000000000000000..000884f59613304a5f5b600272fb7b157b327536
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.template.html
@@ -0,0 +1,3 @@
+
+<kg-dataset-dumb-radar [attr.kg-ds-prv-darkmode]="true">
+</kg-dataset-dumb-radar>
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/receptors/index.ts b/src/atlasComponents/sapiViews/features/receptors/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b82f950a1ab09f3d27b4cf990cbecea0ac06902d
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/receptors/index.ts
@@ -0,0 +1,3 @@
+export { Autoradiography } from "./autoradiography/autoradiography.component";
+export { Fingerprint } from "./fingerprint/fingerprint.component"
+export { Profile } from "./profile/profile.component"
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/receptors/profile/profile.component.ts b/src/atlasComponents/sapiViews/features/receptors/profile/profile.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2a62d72eb74b28b6c413d0e59c7de2bce0828148
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/receptors/profile/profile.component.ts
@@ -0,0 +1,11 @@
+import { Component } from "@angular/core";
+import { BaseReceptor } from "../base";
+
+@Component({
+  templateUrl: './profile.template.html',
+  styleUrls: [
+    './profile.style.css'
+  ]
+})
+
+export class Profile extends BaseReceptor{}
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/receptors/profile/profile.style.css b/src/atlasComponents/sapiViews/features/receptors/profile/profile.style.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/atlasComponents/sapiViews/features/receptors/profile/profile.template.html b/src/atlasComponents/sapiViews/features/receptors/profile/profile.template.html
new file mode 100644
index 0000000000000000000000000000000000000000..a143d8a0e325953339a1771a3a6b5036d826148e
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/receptors/profile/profile.template.html
@@ -0,0 +1,4 @@
+
+<kg-dataset-dumb-line
+  [attr.kg-ds-prv-darkmode]="true">
+</kg-dataset-dumb-line>
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/index.ts b/src/atlasComponents/sapiViews/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1afef564d73a7aaa4f0923b2ba62656418d76ca8
--- /dev/null
+++ b/src/atlasComponents/sapiViews/index.ts
@@ -0,0 +1,3 @@
+export {
+  SapiViewsModule
+} from "./module"
diff --git a/src/atlasComponents/sapiViews/module.ts b/src/atlasComponents/sapiViews/module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6da0504892874497880c399b7df6e8426ef8baa9
--- /dev/null
+++ b/src/atlasComponents/sapiViews/module.ts
@@ -0,0 +1,9 @@
+import { NgModule } from "@angular/core";
+import { SapiViewsFeaturesModule } from "./features";
+
+@NgModule({
+  imports: [
+    SapiViewsFeaturesModule
+  ],
+})
+export class SapiViewsModule{}
\ No newline at end of file
diff --git a/src/atlasComponents/splashScreen/index.ts b/src/atlasComponents/splashScreen/index.ts
index 5927a7b64a7f19529a4998770dd5f27a3d3a2546..0750a03038aaecc1a9de8097d87ecd240121e418 100644
--- a/src/atlasComponents/splashScreen/index.ts
+++ b/src/atlasComponents/splashScreen/index.ts
@@ -1,2 +1,2 @@
-export { GetTemplateImageSrcPipe, SplashScreen } from "./splashScreen/splashScreen.component";
+export { SplashScreen } from "./splashScreen/splashScreen.component";
 export { SplashUiModule } from './module'
\ No newline at end of file
diff --git a/src/atlasComponents/splashScreen/module.ts b/src/atlasComponents/splashScreen/module.ts
index cafa61559313528ffe6a1e74c2b4a88c240f8329..587e1217dad6d50acbe9f78b7f9074b3c0e844c8 100644
--- a/src/atlasComponents/splashScreen/module.ts
+++ b/src/atlasComponents/splashScreen/module.ts
@@ -4,7 +4,7 @@ import { ComponentsModule } from "src/components";
 import { KgTosModule } from "src/ui/kgtos/module";
 import { AngularMaterialModule } from "src/sharedModules";
 import { UtilModule } from "src/util";
-import { GetTemplateImageSrcPipe, SplashScreen } from "./splashScreen/splashScreen.component";
+import { SplashScreen } from "./splashScreen/splashScreen.component";
 
 @NgModule({
   imports: [
@@ -16,7 +16,6 @@ import { GetTemplateImageSrcPipe, SplashScreen } from "./splashScreen/splashScre
   ],
   declarations: [
     SplashScreen,
-    GetTemplateImageSrcPipe,
   ],
   exports: [
     SplashScreen,
diff --git a/src/atlasComponents/splashScreen/splashScreen/splashScreen.component.ts b/src/atlasComponents/splashScreen/splashScreen/splashScreen.component.ts
index 3df8c71c099444e4be81158e3093c8c9e6d3dcde..775b1a486bc18ec333ce8aec1a32ccdcc8c14091 100644
--- a/src/atlasComponents/splashScreen/splashScreen/splashScreen.component.ts
+++ b/src/atlasComponents/splashScreen/splashScreen/splashScreen.component.ts
@@ -1,11 +1,9 @@
-import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Pipe, PipeTransform, ViewChild } from "@angular/core";
-import { MatSnackBar } from "@angular/material/snack-bar";
-import { select, Store } from "@ngrx/store";
-import { Observable, Subject, Subscription } from "rxjs";
-import { filter } from 'rxjs/operators'
-import { viewerStateHelperStoreName, viewerStateSelectAtlas } from "src/services/state/viewerState.store.helper";
-import { PureContantService } from "src/util";
-import { CONST } from 'common/constants'
+import { ChangeDetectionStrategy, Component } from "@angular/core";
+import { Store } from "@ngrx/store";
+import { tap } from 'rxjs/operators'
+import { SAPI } from "src/atlasComponents/sapi/sapi.service";
+import { SapiAtlasModel } from "src/atlasComponents/sapi/type";
+import { atlasSelection } from "src/state"
 
 @Component({
   selector : 'ui-splashscreen',
@@ -20,56 +18,21 @@ export class SplashScreen {
 
   public finishedLoading: boolean = false
 
-  public loadedAtlases$: Observable<any[]>
-
-  public filterNullFn(atlas: any){
-    return !!atlas
-  }
-
-  @ViewChild('parentContainer', {read: ElementRef})
-  public activatedTemplate$: Subject<any> = new Subject()
-
-  private subscriptions: Subscription[] = []
+  public atlases$ = this.sapiSvc.atlases$.pipe(
+    tap(() => this.finishedLoading = true)
+  )
 
   constructor(
     private store: Store<any>,
-    private snack: MatSnackBar,
-    private pureConstantService: PureContantService,
-    private cdr: ChangeDetectorRef,
+    private sapiSvc: SAPI,
   ) {
-    this.subscriptions.push(
-      this.pureConstantService.allFetchingReady$.subscribe(flag => {
-        this.finishedLoading = flag
-        this.cdr.markForCheck()
-      })
-    )
-
-    this.loadedAtlases$ = this.store.pipe(
-      select(state => state[viewerStateHelperStoreName]),
-      select(state => state.fetchedAtlases),
-      filter(v => !!v)
-    )
   }
 
-  public selectAtlas(atlas: any){
-    if (!this.finishedLoading) {
-      this.snack.open(CONST.DATA_NOT_READY, null, {
-        duration: 3000
-      })
-      return
-    }
+  public selectAtlas(atlas: SapiAtlasModel){
     this.store.dispatch(
-      viewerStateSelectAtlas({ atlas })
+      atlasSelection.actions.selectAtlas({
+        atlas
+      })
     )
   }
 }
-
-@Pipe({
-  name: 'getTemplateImageSrcPipe',
-})
-
-export class GetTemplateImageSrcPipe implements PipeTransform {
-  public transform(name: string): string {
-    return `./res/image/${name.replace(/[|&;$%@()+,\s./]/g, '')}.png`
-  }
-}
diff --git a/src/atlasComponents/splashScreen/splashScreen/splashScreen.template.html b/src/atlasComponents/splashScreen/splashScreen/splashScreen.template.html
index 6236bd010201f3b334dc28c58df491acdd3017d2..7c38d86fd400e559f57e07faa1babef2d13de84a 100644
--- a/src/atlasComponents/splashScreen/splashScreen/splashScreen.template.html
+++ b/src/atlasComponents/splashScreen/splashScreen/splashScreen.template.html
@@ -7,7 +7,7 @@
     <mat-card
       (click)="selectAtlas(atlas)"
       matRipple
-      *ngFor="let atlas of loadedAtlases$ | async | filterArray : filterNullFn"
+      *ngFor="let atlas of atlases$ | async"
       class="m-3 col-md-12 col-lg-12 pe-all">
       <mat-card-header>
         <mat-card-title class="text-nowrap font-stretch">
diff --git a/src/atlasComponents/template/templateIsDarkTheme.pipe.ts b/src/atlasComponents/template/templateIsDarkTheme.pipe.ts
index 8454fd96e81e9815f8ab0bb627eb1e01d18b95b0..01590156217afe114936a0c2609e0a28c812ae61 100644
--- a/src/atlasComponents/template/templateIsDarkTheme.pipe.ts
+++ b/src/atlasComponents/template/templateIsDarkTheme.pipe.ts
@@ -1,7 +1,4 @@
-import { OnDestroy, Pipe, PipeTransform } from "@angular/core";
-import { select, Store } from "@ngrx/store";
-import { Subscription } from "rxjs";
-import { viewerStateSelectedTemplateFullInfoSelector } from "src/services/state/viewerState/selectors";
+import { Pipe, PipeTransform } from "@angular/core";
 import { IHasId } from "src/util/interfaces";
 
 @Pipe({
@@ -9,25 +6,9 @@ import { IHasId } from "src/util/interfaces";
   pure: true,
 })
 
-export class TemplateIsDarkThemePipe implements OnDestroy, PipeTransform{
-
-  private templateFullInfo: any[] = []
-  constructor(store: Store<any>){
-    this.sub.push(
-      store.pipe(
-        select(viewerStateSelectedTemplateFullInfoSelector)
-      ).subscribe(val => this.templateFullInfo = val)
-    )
-  }
-
-  private sub: Subscription[] = []
-
-  ngOnDestroy(){
-    while(this.sub.length) this.sub.pop().unsubscribe()
-  }
+export class TemplateIsDarkThemePipe implements PipeTransform{
 
   public transform(template: IHasId): boolean{
-    const found = this.templateFullInfo.find(t => t['@id'] === template["@id"])
-    return found && found.darktheme
+    return template["@id"] !== "minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588"
   }
 }
\ No newline at end of file
diff --git a/src/atlasComponents/uiSelectors/atlasDropdown/atlasDropdown.component.ts b/src/atlasComponents/uiSelectors/atlasDropdown/atlasDropdown.component.ts
index c44816155bcbb23701aa04e7a9de767b70dd056f..d3ef7a4d602c0b4298f1dff7caabbdbdce9aa3f4 100644
--- a/src/atlasComponents/uiSelectors/atlasDropdown/atlasDropdown.component.ts
+++ b/src/atlasComponents/uiSelectors/atlasDropdown/atlasDropdown.component.ts
@@ -1,10 +1,9 @@
 import { Component } from "@angular/core";
 import { Store, select } from "@ngrx/store";
 import { Observable } from "rxjs";
-import { distinctUntilChanged } from "rxjs/operators";
-import { viewerStateHelperStoreName, viewerStateSelectAtlas } from "src/services/state/viewerState.store.helper";
 import { ARIA_LABELS } from 'common/constants'
-import { viewerStateGetSelectedAtlas } from "src/services/state/viewerState/selectors";
+import { atlasSelection } from "src/state"
+import { SAPI } from "src/atlasComponents/sapi";
 
 @Component({
   selector: 'atlas-dropdown-selector',
@@ -21,23 +20,20 @@ export class AtlasDropdownSelector{
 
   public SELECT_ATLAS_ARIA_LABEL = ARIA_LABELS.SELECT_ATLAS
 
-  constructor(private store$: Store<any>){
-    this.fetchedAtlases$ = this.store$.pipe(
-      select(viewerStateHelperStoreName),
-      select('fetchedAtlases'),
-      distinctUntilChanged()
-    )
+  constructor(
+    private store$: Store<any>,
+    private sapi: SAPI,
+  ){
+    this.fetchedAtlases$ = this.sapi.atlases$
     this.selectedAtlas$ = this.store$.pipe(
-      select(viewerStateGetSelectedAtlas)
+      select(atlasSelection.selectors.selectedAtlas)
     )
   }
 
   handleChangeAtlas({ value }) {
     this.store$.dispatch(
-      viewerStateSelectAtlas({
-        atlas: {
-          ['@id']: value
-        }
+      atlasSelection.actions.selectATPById({
+        atlasId: value
       })
     )
   }
diff --git a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.spec.ts b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.spec.ts
index 730f7b258819bf92a3a678976bead30a75817452..ac1cba2b02e1210747c708aadf634cd3ec219cf1 100644
--- a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.spec.ts
+++ b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.spec.ts
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"
 import { NoopAnimationsModule } from "@angular/platform-browser/animations"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
 import { ComponentsModule } from "src/components"
-import { viewerStateSelectTemplateWithId, viewerStateToggleLayer } from "src/services/state/viewerState.store.helper"
+import { viewerStateSelectTemplateWithId } from "src/services/state/viewerState.store.helper"
 import { AngularMaterialModule } from "src/sharedModules"
 import { QuickTourModule } from "src/ui/quickTour"
 import { GetGroupedParcPipe } from "../pipes/getGroupedParc.pipe"
diff --git a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.ts b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.ts
index 9fbca8cce700ba9ef5bef01581a618e451308df3..927d62cb3d5fed7d12a1d3a5361aa0fd280a9883 100644
--- a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.ts
+++ b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.ts
@@ -1,15 +1,19 @@
-import { Component, OnInit, ViewChildren, QueryList, HostBinding, ViewChild, ElementRef, OnDestroy } from "@angular/core";
+import { Component, ViewChildren, QueryList, HostBinding, ViewChild, ElementRef, OnDestroy } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { distinctUntilChanged, map, withLatestFrom, shareReplay, mapTo } from "rxjs/operators";
 import { merge, Observable, Subject, Subscription } from "rxjs";
-import { viewerStateSelectTemplateWithId, viewerStateToggleLayer } from "src/services/state/viewerState.store.helper";
 import { MatMenuTrigger } from "@angular/material/menu";
-import { viewerStateGetSelectedAtlas, viewerStateAtlasLatestParcellationSelector, viewerStateSelectedTemplateFullInfoSelector, viewerStateSelectedTemplatePureSelector, viewerStateSelectedParcellationSelector } from "src/services/state/viewerState/selectors";
 import { ARIA_LABELS, CONST, QUICKTOUR_DESC } from 'common/constants'
 import { IQuickTourData } from "src/ui/quickTour/constrants";
 import { animate, state, style, transition, trigger } from "@angular/animations";
 import { IHasId, OVERWRITE_SHOW_DATASET_DIALOG_TOKEN } from "src/util/interfaces";
 import { CurrentTmplSupportsParcPipe } from "../pipes/currTmplSupportsParc.pipe";
+import {
+  actions,
+  fromRootStore
+} from "src/state/atlasSelection"
+import { SAPI } from "src/atlasComponents/sapi";
+import { atlasSelection } from "src/state";
 
 @Component({
   selector: 'atlas-layer-selector',
@@ -43,7 +47,7 @@ import { CurrentTmplSupportsParcPipe } from "../pipes/currTmplSupportsParc.pipe"
     }
   ]
 })
-export class AtlasLayerSelector implements OnInit, OnDestroy {
+export class AtlasLayerSelector implements OnDestroy {
 
   public ARIA_LABELS = ARIA_LABELS
   public CONST = CONST
@@ -55,23 +59,22 @@ export class AtlasLayerSelector implements OnInit, OnDestroy {
   selectorPanelTemplateRef: ElementRef
 
   public selectedAtlas$: Observable<any> = this.store$.pipe(
-    select(viewerStateGetSelectedAtlas),
+    select(atlasSelection.selectors.selectedAtlas),
     distinctUntilChanged(),
     shareReplay(1)
   )
 
   public atlasLayersLatest$ = this.store$.pipe(
-    select(viewerStateAtlasLatestParcellationSelector),
+    fromRootStore.allAvailParcs(this.sapi),
     shareReplay(1),
   )
 
-  public availableTemplates$ = this.store$.pipe<any[]>(
-    select(viewerStateSelectedTemplateFullInfoSelector),
+  public availableTemplates$ = this.store$.pipe(
+    fromRootStore.allAvailSpaces(this.sapi),
   )
 
-  private selectedTemplate: any
   public selectedTemplate$ = this.store$.pipe(
-    select(viewerStateSelectedTemplatePureSelector),
+    select(atlasSelection.selectors.selectedTemplate),
     withLatestFrom(this.availableTemplates$),
     map(([selectedTmpl, fullInfoTemplates]) => {
       return fullInfoTemplates.find(t => t['@id'] === selectedTmpl['@id'])
@@ -90,7 +93,7 @@ export class AtlasLayerSelector implements OnInit, OnDestroy {
   )
 
   public selectedParcellation$ = this.store$.pipe(
-    select(viewerStateSelectedParcellationSelector),
+    select(atlasSelection.selectors.selectedParcellation),
   )
 
   private subscriptions: Subscription[] = []
@@ -103,15 +106,10 @@ export class AtlasLayerSelector implements OnInit, OnDestroy {
     description: QUICKTOUR_DESC.LAYER_SELECTOR,
   }
 
-  constructor(private store$: Store<any>) {}
-
-  ngOnInit(): void {
-    this.subscriptions.push(
-      this.selectedTemplate$.subscribe(st => {
-        this.selectedTemplate = st
-      }),
-    )
-  }
+  constructor(
+    private store$: Store<any>,
+    private sapi: SAPI,
+  ) {}
 
   ngOnDestroy() {
     while(this.subscriptions.length) this.subscriptions.pop().unsubscribe()
@@ -124,32 +122,21 @@ export class AtlasLayerSelector implements OnInit, OnDestroy {
 
   selectTemplatewithId(templateId: string) {
     this.showOverlayIntent$.next(true)
-    this.store$.dispatch(viewerStateSelectTemplateWithId({
-      payload: {
-        '@id': templateId
-      }
-    }))
+    this.store$.dispatch(
+      actions.selectATPById({
+        templateId
+      })
+    )
   }
 
   private currTmplSupportParcPipe = new CurrentTmplSupportsParcPipe()
 
-  selectParcellationWithName(layer: any) {
-    const tmplChangeReq = !this.currTmplSupportParcPipe.transform(this.selectedTemplate, layer)
-    if (!tmplChangeReq) {
-      this.store$.dispatch(
-        viewerStateToggleLayer({ payload: layer })
-      )
-    } else {
-      this.showOverlayIntent$.next(true)
-      this.store$.dispatch(
-        viewerStateSelectTemplateWithId({
-          payload: layer.availableIn[0],
-          config: {
-            selectParcellation: layer
-          }
-        })
-      )
-    }
+  selectParcellationWithId(id: string) {
+    this.store$.dispatch(
+      actions.selectATPById({
+        parcellationId: id
+      })
+    )
   }
 
   collapseExpandedGroup(){
diff --git a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html
index ed78029cd9c644c84e4c809e9498ff21a5eece81..b93e61fe24b492d47d332d594cdc4d129caa4bee 100644
--- a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html
+++ b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html
@@ -22,9 +22,7 @@
                 
                 <div [hidden]
                     iav-dataset-show-dataset-dialog
-                    [iav-dataset-show-dataset-dialog-name]="template.originDatainfos[0]?.name"
-                    [iav-dataset-show-dataset-dialog-description]="template.originDatainfos[0]?.description"
-                    [iav-dataset-show-dataset-dialog-urls]="template.originDatainfos[0]?.urls"
+                    [iav-dataset-show-dataset-dialog-name]="template.fullName"
                     #kgInfo="iavDatasetShowDatasetDialog">
                 </div>
                 <tile-cmp [tile-image-src]="template | getPreviewUrlPipe"
@@ -53,10 +51,10 @@
             gutterSize="16">
 
             <!-- non grouped layers -->
-            <mat-grid-tile *ngFor="let layer of (atlasLayersLatest$ | async | getNonbaseParc | getIndividualParc); trackBy: trackbyAtId"
+            <mat-grid-tile *ngFor="let layer of (atlasLayersLatest$ | async ); trackBy: trackbyAtId"
                 [attr.aria-checked]="selectedParcellation$ | async | groupParcSelected : layer">
-
-                <div [hidden]
+                {{ layer.name }}
+                <!-- <div [hidden]
                     iav-dataset-show-dataset-dialog
                     [iav-dataset-show-dataset-dialog-name]="layer.originDatainfos[0]?.name"
                     [iav-dataset-show-dataset-dialog-description]="layer.originDatainfos[0]?.description"
@@ -75,7 +73,7 @@
 
                     (tile-on-click)="selectParcellationWithName(layer)"
                     (tile-on-info-click)="kgInfo && kgInfo.onClick()">
-                </tile-cmp>
+                </tile-cmp> -->
 
             </mat-grid-tile>
 
@@ -159,8 +157,7 @@
                     [tile-image-darktheme]="layer.darktheme"
 
                     [tile-selected]="selectedParcellation$ | async | groupParcSelected : layer"
-
-                    (tile-on-click)="selectParcellationWithName(layer)"
+                    (tile-on-click)="selectParcellationWithId(layer)"
                     (tile-on-info-click)="kgInfo && kgInfo.onClick()">
                 </tile-cmp>
 
diff --git a/src/atlasComponents/uiSelectors/module.ts b/src/atlasComponents/uiSelectors/module.ts
index b6994ea3003f3dbe9815b2986507cd7fdeea20a5..2ab98df7ca53d16da552731ba4b67abb725e4301 100644
--- a/src/atlasComponents/uiSelectors/module.ts
+++ b/src/atlasComponents/uiSelectors/module.ts
@@ -5,7 +5,6 @@ import { UtilModule } from "src/util";
 import { AtlasDropdownSelector } from "./atlasDropdown/atlasDropdown.component";
 import { AtlasLayerSelector } from "./atlasLayerSelector/atlasLayerSelector.component";
 import {QuickTourModule} from "src/ui/quickTour/module";
-import { KgDatasetModule } from "../regionalFeatures/bsFeatures/kgDataset";
 import { AtlaslayerTooltipPipe } from "./pipes/atlasLayerTooltip.pipe";
 import { ComponentsModule } from "src/components";
 import { GetNonbaseParcPipe } from "./pipes/getNonBaseParc.pipe";
@@ -17,6 +16,7 @@ import { GetPreviewUrlPipe } from "./pipes/getPreviewUrl.pipe";
 import { CurrParcSupportsTmplPipe } from "./pipes/currParcSupportsTmpl.pipe";
 import { AtlasCmpParcellationModule } from "../parcellation";
 import { SiibraExplorerTemplateModule } from "../template";
+import { DialogInfoModule } from "src/ui/dialogInfo";
 
 @NgModule({
   imports: [
@@ -24,10 +24,10 @@ import { SiibraExplorerTemplateModule } from "../template";
     AngularMaterialModule,
     UtilModule,
     QuickTourModule,
-    KgDatasetModule,
     ComponentsModule,
     AtlasCmpParcellationModule,
     SiibraExplorerTemplateModule,
+    DialogInfoModule,
   ],
   declarations: [
     AtlasDropdownSelector,
diff --git a/src/atlasComponents/uiSelectors/pipes/getNonBaseParc.pipe.ts b/src/atlasComponents/uiSelectors/pipes/getNonBaseParc.pipe.ts
index e0b7997bfa191ee6e790fc935a541e7c8d9a5bb1..71e236bb56d6846458553c4e310e8f48829c60dc 100644
--- a/src/atlasComponents/uiSelectors/pipes/getNonBaseParc.pipe.ts
+++ b/src/atlasComponents/uiSelectors/pipes/getNonBaseParc.pipe.ts
@@ -1,4 +1,5 @@
 import { Pipe, PipeTransform } from "@angular/core";
+import { SapiParcellationModel } from "src/atlasComponents/sapi";
 
 @Pipe({
   name: 'getNonbaseParc',
@@ -6,7 +7,8 @@ import { Pipe, PipeTransform } from "@angular/core";
 })
 export class GetNonbaseParcPipe implements PipeTransform{
 
-  public transform(arr: any[]){
-    return arr.filter(p => !p['baseLayer'])
+  public transform(arr: SapiParcellationModel[]){
+    if (!arr) return []
+    return arr.filter(p => p.name.toLowerCase().indexOf("julich") < 0)
   }
 }
diff --git a/src/atlasComponents/userAnnotations/singleAnnotationUnit/singleAnnotationUnit.component.ts b/src/atlasComponents/userAnnotations/singleAnnotationUnit/singleAnnotationUnit.component.ts
index 8c9a11566b9f7f27350a684cc9ffc3976525c32e..327439092987a0dae77a60d0d409f5200f6b60c6 100644
--- a/src/atlasComponents/userAnnotations/singleAnnotationUnit/singleAnnotationUnit.component.ts
+++ b/src/atlasComponents/userAnnotations/singleAnnotationUnit/singleAnnotationUnit.component.ts
@@ -5,10 +5,11 @@ import { Polygon } from '../tools/poly'
 import { FormControl, FormGroup } from "@angular/forms";
 import { Subscription } from "rxjs";
 import { select, Store } from "@ngrx/store";
-import { viewerStateFetchedAtlasesSelector } from "src/services/state/viewerState/selectors";
 import { ModularUserAnnotationToolService } from "../tools/service";
 import { MatSnackBar } from "@angular/material/snack-bar";
 import { Line } from "../tools/line";
+import { atlasSelection } from "src/state";
+import { map } from "rxjs/operators";
 
 @Component({
   selector: 'single-annotation-unit',
@@ -31,7 +32,6 @@ export class SingleAnnotationUnit implements OnDestroy, AfterViewInit{
   private subs: Subscription[] = []
   public templateSpaces: {
     ['@id']: string
-    name: string
   }[] = []
   ngOnChanges(){
     while(this.chSubs.length > 0) this.chSubs.pop().unsubscribe()
@@ -52,30 +52,22 @@ export class SingleAnnotationUnit implements OnDestroy, AfterViewInit{
         this.managedAnnotation.desc = desc
       })
     )
-
   }
 
+  public tmpls$ = this.store.pipe(
+    select(atlasSelection.selectors.selectedTemplate),
+    map(val => {
+      return [val]
+    })
+  )
+
   constructor(
-    store: Store<any>,
+    private store: Store<any>,
     private snackbar: MatSnackBar,
     private svc: ModularUserAnnotationToolService,
     private cfr: ComponentFactoryResolver,
     private injector: Injector,
   ){
-    this.subs.push(
-      store.pipe(
-        select(viewerStateFetchedAtlasesSelector),
-      ).subscribe(atlases => {
-        for (const atlas of atlases) {
-          for (const tmpl of atlas.templateSpaces) {
-            this.templateSpaces.push({
-              '@id': tmpl['@id'],
-              name: tmpl.name
-            })
-          }
-        }
-      })
-    )
   }
 
   ngAfterViewInit(){
diff --git a/src/atlasComponents/userAnnotations/singleAnnotationUnit/singleAnnotationUnit.template.html b/src/atlasComponents/userAnnotations/singleAnnotationUnit/singleAnnotationUnit.template.html
index e03b3068ebc2360cc9e6a08c537c73c750c4ece9..51f1c004700f834b92c3afd81d6cd93ee3d01026 100644
--- a/src/atlasComponents/userAnnotations/singleAnnotationUnit/singleAnnotationUnit.template.html
+++ b/src/atlasComponents/userAnnotations/singleAnnotationUnit/singleAnnotationUnit.template.html
@@ -4,8 +4,8 @@
       Space
     </mat-label>
     <mat-select formControlName="spaceId">
-      <mat-option *ngFor="let tmpl of templateSpaces" [value]="tmpl['@id']">
-        {{ tmpl.name }}
+      <mat-option *ngFor="let tmpl of tmpls$ | async" [value]="tmpl['@id']">
+        {{ tmpl.fullName }}
       </mat-option>
     </mat-select>
   </mat-form-field>
diff --git a/src/atlasComponents/userAnnotations/tools/line/line.component.ts b/src/atlasComponents/userAnnotations/tools/line/line.component.ts
index bf3d32401fc9cfc2378b2a4d17000e53cef2390d..a98e126c64223483c2bbaf9131f9db091d3cb2f2 100644
--- a/src/atlasComponents/userAnnotations/tools/line/line.component.ts
+++ b/src/atlasComponents/userAnnotations/tools/line/line.component.ts
@@ -4,10 +4,10 @@ import { Store } from "@ngrx/store";
 import { Line, LINE_ICON_CLASS } from "../line";
 import { ToolCmpBase } from "../toolCmp.base";
 import { IAnnotationGeometry, TExportFormats, UDPATE_ANNOTATION_TOKEN } from "../type";
-import { viewerStateChangeNavigation } from "src/services/state/viewerState/actions";
 import { Point } from "../point";
 import { ARIA_LABELS } from 'common/constants'
 import { ComponentStore } from "src/viewerModule/componentStore";
+import { actions } from "src/state/atlasSelection";
 
 @Component({
   selector: 'line-update-cmp',
@@ -59,12 +59,12 @@ export class LineUpdateCmp extends ToolCmpBase implements OnDestroy{
       const { x, y, z } = roi
 
       this.store.dispatch(
-        viewerStateChangeNavigation({
+        actions.navigateTo({
           navigation: {
-            position: [x, y, z],
-            positionReal: true,
-            animation: {}
-          }
+            position: [x, y, z]
+          },
+          physical: true,
+          animation: true
         })
       )
       return
@@ -79,12 +79,12 @@ export class LineUpdateCmp extends ToolCmpBase implements OnDestroy{
     const { x, y, z } = this.updateAnnotation.points[0]
     
     this.store.dispatch(
-      viewerStateChangeNavigation({
+      actions.navigateTo({
         navigation: {
-          position: [x, y, z],
-          positionReal: true,
-          animation: {}
-        }
+          position: [x, y, z]
+        },
+        physical: true,
+        animation: true
       })
     )
   }
diff --git a/src/atlasComponents/userAnnotations/tools/point/point.component.ts b/src/atlasComponents/userAnnotations/tools/point/point.component.ts
index c28152125a1a006ac1f69d8543792364dcb8b4ab..b4ef51006975e34cdcc753ad85cf1dc10056a9dd 100644
--- a/src/atlasComponents/userAnnotations/tools/point/point.component.ts
+++ b/src/atlasComponents/userAnnotations/tools/point/point.component.ts
@@ -3,9 +3,9 @@ import { Point, POINT_ICON_CLASS } from "../point";
 import { IAnnotationGeometry, TExportFormats, UDPATE_ANNOTATION_TOKEN } from "../type";
 import { ToolCmpBase } from "../toolCmp.base";
 import { Store } from "@ngrx/store";
-import { viewerStateChangeNavigation } from "src/services/state/viewerState/actions";
 import { ComponentStore } from "src/viewerModule/componentStore";
 import { ARIA_LABELS } from 'common/constants'
+import { actions } from "src/state/atlasSelection";
 
 @Component({
   selector: 'point-update-cmp',
@@ -55,12 +55,12 @@ export class PointUpdateCmp extends ToolCmpBase implements OnDestroy{
     }
     const { x, y, z } = this.updateAnnotation
     this.store.dispatch(
-      viewerStateChangeNavigation({
+      actions.navigateTo({
         navigation: {
-          position: [x, y, z],
-          positionReal: true,
-          animation: {}
-        }
+          position: [x, y, z]
+        },
+        physical: true,
+        animation: true
       })
     )
   }
diff --git a/src/atlasComponents/userAnnotations/tools/poly/poly.component.ts b/src/atlasComponents/userAnnotations/tools/poly/poly.component.ts
index 9d8371b404a5eec8d4bc4ca60bbcf07cdfac2c5e..6e8852d88b665d2b988ed59f1340c311d0086515 100644
--- a/src/atlasComponents/userAnnotations/tools/poly/poly.component.ts
+++ b/src/atlasComponents/userAnnotations/tools/poly/poly.component.ts
@@ -3,11 +3,11 @@ import { MatSnackBar } from "@angular/material/snack-bar";
 import { Polygon, POLY_ICON_CLASS } from "../poly";
 import { ToolCmpBase } from "../toolCmp.base";
 import { IAnnotationGeometry, TExportFormats, UDPATE_ANNOTATION_TOKEN } from "../type";
-import { viewerStateChangeNavigation } from "src/services/state/viewerState/actions";
 import { Store } from "@ngrx/store";
 import { Point } from "../point";
 import { ARIA_LABELS } from 'common/constants'
 import { ComponentStore } from "src/viewerModule/componentStore";
+import { actions } from "src/state/atlasSelection";
 
 @Component({
   selector: 'poly-update-cmp',
@@ -68,12 +68,12 @@ export class PolyUpdateCmp extends ToolCmpBase implements OnDestroy{
       const { x, y, z } = roi
 
       this.store.dispatch(
-        viewerStateChangeNavigation({
+        actions.navigateTo({
           navigation: {
-            position: [x, y, z],
-            positionReal: true,
-            animation: {}
-          }
+            position: [x, y, z]
+          },
+          physical: true,
+          animation: true
         })
       )
       return
@@ -88,12 +88,12 @@ export class PolyUpdateCmp extends ToolCmpBase implements OnDestroy{
     const { x, y, z } = this.updateAnnotation.points[0]
     
     this.store.dispatch(
-      viewerStateChangeNavigation({
+      actions.navigateTo({
         navigation: {
-          position: [x, y, z],
-          positionReal: true,
-          animation: {}
-        }
+          position: [x, y, z]
+        },
+        physical: true,
+        animation: true
       })
     )
   }
diff --git a/src/atlasComponents/userAnnotations/tools/service.ts b/src/atlasComponents/userAnnotations/tools/service.ts
index 26fc809549b7f7fd59740539aaaec0e09ae66a4a..c6f075adc864af1874b54662caab6eea5a362066 100644
--- a/src/atlasComponents/userAnnotations/tools/service.ts
+++ b/src/atlasComponents/userAnnotations/tools/service.ts
@@ -4,7 +4,6 @@ import { Inject, Optional } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { BehaviorSubject, combineLatest, fromEvent, merge, Observable, of, Subject, Subscription } from "rxjs";
 import {map, switchMap, filter, shareReplay, pairwise } from "rxjs/operators";
-import { viewerStateSelectedTemplatePureSelector, viewerStateViewerModeSelector } from "src/services/state/viewerState/selectors";
 import { NehubaViewerUnit } from "src/viewerModule/nehuba";
 import { NEHUBA_INSTANCE_INJTKN } from "src/viewerModule/nehuba/util";
 import { AbsToolClass, ANNOTATION_EVENT_INJ_TOKEN, IAnnotationEvents, IAnnotationGeometry, INgAnnotationTypes, INJ_ANNOT_TARGET, TAnnotationEvent, ClassInterface, TCallbackFunction, TSands, TGeometryJson, TNgAnnotationLine, TCallback } from "./type";
@@ -15,7 +14,8 @@ import { Point } from "./point";
 import { FilterAnnotationsBySpace } from "../filterAnnotationBySpace.pipe";
 import { retry } from 'common/util'
 import { MatSnackBar } from "@angular/material/snack-bar";
-import { viewerStateSetViewerMode } from "src/services/state/viewerState.store.helper";
+import { actions } from "src/state/atlasSelection";
+import { atlasSelection } from "src/state";
 
 const LOCAL_STORAGE_KEY = 'userAnnotationKey'
 
@@ -91,7 +91,7 @@ export class ModularUserAnnotationToolService implements OnDestroy{
 
   private selectedTmpl: any
   private selectedTmpl$ = this.store.pipe(
-    select(viewerStateSelectedTemplatePureSelector),
+    select(atlasSelection.selectors.selectedTemplate),
   )
   public moduleAnnotationTypes: {instance: {name: string, iconClass: string, toolSelected$: Observable<boolean>}, onClick: () => void}[] = []
   private managedAnnotationsStream$ = new Subject<{
@@ -502,7 +502,7 @@ export class ModularUserAnnotationToolService implements OnDestroy{
      */
     this.subscription.push(
       store.pipe(
-        select(viewerStateViewerModeSelector)
+        select(atlasSelection.selectors.viewerMode)
       ).subscribe(viewerMode => {
         this.currMode = viewerMode
         if (viewerMode === ModularUserAnnotationToolService.VIEWER_MODE) {
@@ -761,7 +761,9 @@ export class ModularUserAnnotationToolService implements OnDestroy{
         : ARIA_LABELS.VIEWER_MODE_ANNOTATING
     }
     this.store.dispatch(
-      viewerStateSetViewerMode({ payload })
+      actions.setViewerMode({
+        viewerMode: "annotating"
+      })
     )
   }
 }
diff --git a/src/atlasViewer/atlasViewer.apiService.service.ts b/src/atlasViewer/atlasViewer.apiService.service.ts
index ad6d2fb7e7057784edadb8b227f015f4e83f74ac..48906afedcd635979c4713c7f104c5f00a23b03f 100644
--- a/src/atlasViewer/atlasViewer.apiService.service.ts
+++ b/src/atlasViewer/atlasViewer.apiService.service.ts
@@ -3,23 +3,20 @@ import {Injectable, NgZone, Optional, Inject, OnDestroy, InjectionToken} from "@
 import { MatSnackBar } from "@angular/material/snack-bar";
 import { select, Store } from "@ngrx/store";
 import { Observable, Subject, Subscription, from, race, of, } from "rxjs";
-import { distinctUntilChanged, map, filter, startWith, switchMap, catchError, mapTo, take } from "rxjs/operators";
+import { distinctUntilChanged, map, filter, startWith, switchMap, catchError, mapTo, take, shareReplay } from "rxjs/operators";
 import { DialogService } from "src/services/dialogService.service";
-import { uiStateMouseOverSegmentsSelector } from "src/services/state/uiState/selectors";
-import {
-  viewerStateFetchedTemplatesSelector,
-} from "src/services/state/viewerState/selectors";
 import {
   getLabelIndexMap,
   getMultiNgIdsRegionsLabelIndexMap,
   IavRootStoreInterface,
-  safeFilter
 } from "src/services/stateStore.service";
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
 import { FRAGMENT_EMIT_RED } from "src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component";
 import { IPluginManifest, PluginServices } from "src/plugin";
 import { ILoadMesh } from 'src/messaging/types'
 import { CANCELLABLE_DIALOG } from "src/util/interfaces";
+import { atlasSelection, userInteraction } from "src/state"
+import { SapiRegionModel } from "src/atlasComponents/sapi";
 
 declare let window
 
@@ -88,9 +85,11 @@ export class AtlasViewerAPIServices implements OnDestroy{
     const { rs, spec } = this.getNextUserRegionSelectHandler() || {}
     if (!!rs) {
 
-      let moSegments
+      let moSegments: SapiRegionModel
       this.store.pipe(
-        select(uiStateMouseOverSegmentsSelector),
+        select(userInteraction.selectors.mousingOverRegions),
+        filter(val => val.length > 0),
+        map(val => val[0]),
         take(1)
       ).subscribe(val => moSegments = val)
 
@@ -203,38 +202,29 @@ export class AtlasViewerAPIServices implements OnDestroy{
       )
     }
 
-    this.loadedTemplates$ = this.store.pipe(
-      select(viewerStateFetchedTemplatesSelector)
-    )
-
     this.selectParcellation$ = this.store.pipe(
-      select('viewerState'),
-      safeFilter('parcellationSelected'),
-      map(state => state.parcellationSelected),
+      select(atlasSelection.selectors.selectedParcellation),
+      shareReplay(1),
     )
 
     this.interactiveViewer = {
       metadata : {
         selectedTemplateBSubject : this.store.pipe(
-          select('viewerState'),
-          safeFilter('templateSelected'),
-          map(state => state.templateSelected)),
+          select(atlasSelection.selectors.selectedTemplate),
+          shareReplay(1),
+        ),
 
-        selectedParcellationBSubject : this.store.pipe(
-          select('viewerState'),
-          safeFilter('parcellationSelected'),
-          map(state => state.parcellationSelected)),
+        selectedParcellationBSubject : this.selectParcellation$,
 
         selectedRegionsBSubject : this.store.pipe(
-          select('viewerState'),
-          safeFilter('regionsSelected'),
-          map(state => state.regionsSelected),
-          distinctUntilChanged((arr1, arr2) =>
-            arr1.length === arr2.length &&
-            (arr1 as any[]).every((item, index) => item.name === arr2[index].name)),
+          select(atlasSelection.selectors.selectedRegions),
+          shareReplay(1),
         ),
 
-        loadedTemplates : [],
+        get loadedTemplates(){
+          throw new Error(`loadedTemplates is being deprecated`)
+          return []
+        },
 
         // TODO deprecate
         regionsLabelIndexMap : new Map(),
@@ -338,7 +328,6 @@ export class AtlasViewerAPIServices implements OnDestroy{
   }
 
   private init() {
-    this.loadedTemplates$.subscribe(templates => this.interactiveViewer.metadata.loadedTemplates = templates)
     this.selectParcellation$.pipe(
       filter(p => !!p && p.regions),
       distinctUntilChanged()
@@ -454,8 +443,7 @@ export interface IVIewerHandle {
 
   mouseEvent: Observable<{eventName: string, event: MouseEvent}>
   mouseOverNehuba: Observable<{labelIndex: number, foundRegion: any | null}>
-  mouseOverNehubaLayers: Observable<Array<{layer: {name: string}, segment: any | number }>>
-  mouseOverNehubaUI: Observable<{ annotation: any, segments: any, landmark: any, customLandmark: any }>
+  mouseOverNehubaUI: Observable<{ annotation: any, landmark: any, customLandmark: any }>
   getNgHash: () => string
 }
 
diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index f407f68944dad36fb049901fcc59e9e91fc77f47..341b6c2688a33d045f589cbb154cb72e08e19721 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -12,18 +12,14 @@ import {
 } from "@angular/core";
 import { Store, select } from "@ngrx/store";
 import { Observable, Subscription, merge, timer, fromEvent } from "rxjs";
-import { map, filter, distinctUntilChanged, delay, switchMapTo, take, startWith } from "rxjs/operators";
+import { map, filter, delay, switchMapTo, take, startWith } from "rxjs/operators";
 
 import {
   IavRootStoreInterface,
   isDefined,
-  safeFilter,
 } from "../services/stateStore.service";
-import { WidgetServices } from "src/widget";
 
-import { LocalFileService } from "src/services/localFile.service";
 import { AGREE_COOKIE } from "src/services/state/uiState.store";
-import { isSame } from "src/util/fn";
 import { colorAnimation } from "./atlasViewer.animation"
 import { MouseHoverDirective } from "src/mouseoverModule";
 import {MatSnackBar, MatSnackBarRef} from "@angular/material/snack-bar";
@@ -71,27 +67,22 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   public meetsRequirement: boolean = true
 
   public sidePanelView$: Observable<string|null>
-  private newViewer$: Observable<any>
 
   private snackbarRef: MatSnackBarRef<any>
-  public snackbarMessage$: Observable<symbol>
 
   public onhoverLandmark$: Observable<{landmarkName: string, datasets: any} | null>
 
   private subscriptions: Subscription[] = []
 
-  private selectedParcellation$: Observable<any>
   public selectedParcellation: any
 
   private cookieDialogRef: MatDialogRef<any>
 
   constructor(
     private store: Store<IavRootStoreInterface>,
-    private widgetServices: WidgetServices,
     private pureConstantService: PureContantService,
     private matDialog: MatDialog,
     private rd: Renderer2,
-    public localFileService: LocalFileService,
     private snackbar: MatSnackBar,
     private el: ElementRef,
     private slService: SlServiceService,
@@ -99,36 +90,12 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
     @Inject(DOCUMENT) private document,
   ) {
 
-    this.snackbarMessage$ = this.store.pipe(
-      select('uiState'),
-      select("snackbarMessage"),
-    )
-
     this.sidePanelView$ = this.store.pipe(
       select('uiState'),
       filter(state => isDefined(state)),
       map(state => state.focusedSidePanel),
     )
 
-    this.newViewer$ = this.store.pipe(
-      select('viewerState'),
-      select('templateSelected'),
-      distinctUntilChanged(isSame),
-    )
-
-    this.selectedParcellation$ = this.store.pipe(
-      select('viewerState'),
-      safeFilter('parcellationSelected'),
-      map(state => state.parcellationSelected),
-      distinctUntilChanged(),
-    )
-
-    this.subscriptions.push(
-      this.selectedParcellation$.subscribe(parcellation => {
-        this.selectedParcellation = parcellation
-      }),
-
-    )
 
     const error = this.el.nativeElement.getAttribute('data-error')
 
@@ -168,30 +135,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
       this.pureConstantService.useTouchUI$.subscribe(bool => this.ismobile = bool),
     )
 
-    this.subscriptions.push(
-      this.snackbarMessage$.pipe(
-        // angular material issue
-        // see https://github.com/angular/angular/issues/15634
-        // and https://github.com/angular/components/issues/11357
-        delay(0),
-      ).subscribe(messageSymbol => {
-        if (this.snackbarRef) { this.snackbarRef.dismiss() }
-
-        if (!messageSymbol) { return }
-
-        const message = messageSymbol.description
-        this.snackbarRef = this.snackbar.open(message, 'Dismiss', {
-          duration: 5000,
-        })
-      }),
-    )
-
-    this.subscriptions.push(
-      this.newViewer$.subscribe(() => {
-        this.widgetServices.clearAllWidgets()
-      }),
-    )
-
     this.subscriptions.push(
       this.pureConstantService.darktheme$.subscribe(flag => {
         this.rd.setAttribute(this.document.body, 'darktheme', this.meetsRequirement && flag.toString())
diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html
index 5549a8e38914948e7157fcfc6cde6a4f63bd9153..0e1a5b2450c1f945d1487ba79b57c495ed225728 100644
--- a/src/atlasViewer/atlasViewer.template.html
+++ b/src/atlasViewer/atlasViewer.template.html
@@ -47,6 +47,7 @@
       (iav-captureClickListenerDirective-onUnmovedClick)="mouseClickDocument($event)">
     </iav-cmp-viewer-container>
 
+    <!-- TODO move to viewerCmp.template.html -->
     <layout-floating-container
       zIndex="13"
       #floatingOverlayContainer>
diff --git a/src/atlasViewerExports/export.html b/src/atlasViewerExports/export.html
index b4a41a088e065668815706796260dc8f76e1faf9..7d8ff5f05bab2139e9889b98b6d1b06e4ed4ca9f 100644
--- a/src/atlasViewerExports/export.html
+++ b/src/atlasViewerExports/export.html
@@ -156,9 +156,6 @@ console.log('GOTCHA')
       </div>
       <div class = "col-md-3">
 <sample-box sample-box-title = "tree component" id = "tree-element-sample-box">
-<tree-element children-expanded = "true" id = 'tree-element' treebase>
-
-</tree-element>
 </sample-box>
       </div>
     </div>
diff --git a/src/components/components.module.ts b/src/components/components.module.ts
index c8d9ff210b5530a6e001dcd983a3fb8487c560cf..1ed9c40fe619fa0a10e851d89206e4b4e93d0b09 100644
--- a/src/components/components.module.ts
+++ b/src/components/components.module.ts
@@ -19,8 +19,6 @@ import { FlattenTreePipe } from './flatTree/flattener.pipe';
 import { FlatTreeComponent } from './flatTree/flatTree.component';
 import { HighlightPipe } from './flatTree/highlight.pipe';
 import { RenderPipe } from './flatTree/render.pipe';
-import { TreeComponent } from './tree/tree.component';
-import { TreeBaseDirective } from './tree/treeBase.directive';
 import { IAVVerticalButton } from './vButton/vButton.component';
 import { DynamicMaterialBtn } from './dynamicMaterialBtn/dynamicMaterialBtn.component';
 import { SpinnerCmp } from './spinner/spinner.component';
@@ -40,7 +38,6 @@ import { TileCmp } from './tile/tile.component';
   declarations : [
     /* components */
     MarkdownDom,
-    TreeComponent,
     FlatTreeComponent,
     DialogComponent,
     ConfirmDialogComponent,
@@ -49,9 +46,6 @@ import { TileCmp } from './tile/tile.component';
     SpinnerCmp,
     TileCmp,
 
-    /* directive */
-    TreeBaseDirective,
-
     /* pipes */
     SafeHtmlPipe,
     TreeSearchPipe,
@@ -67,7 +61,6 @@ import { TileCmp } from './tile/tile.component';
     ReadmoreModule,
 
     MarkdownDom,
-    TreeComponent,
     FlatTreeComponent,
     DialogComponent,
     ConfirmDialogComponent,
@@ -77,7 +70,6 @@ import { TileCmp } from './tile/tile.component';
     TileCmp,
 
     TreeSearchPipe,
-    TreeBaseDirective,
   ],
 })
 
diff --git a/src/components/tree/tree.animation.ts b/src/components/tree/tree.animation.ts
deleted file mode 100644
index eca9be9c9530b480c4fdc7e696cfa252c61e2728..0000000000000000000000000000000000000000
--- a/src/components/tree/tree.animation.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { animate, state, style, transition, trigger } from "@angular/animations";
-
-export const treeAnimations = trigger('collapseState', [
-  state('collapsed',
-    style({
-      'margin-top' : '-{{ fullHeight }}px',
-    }),
-    { params : { fullHeight : 0 } },
-  ),
-  state('visible',
-    style({
-      'margin-top' : '0px',
-    }),
-    { params : { fullHeight : 0 } },
-  ),
-  transition('collapsed => visible', [
-    animate('180ms'),
-  ]),
-  transition('visible => collapsed', [
-    animate('180ms'),
-  ]),
-])
diff --git a/src/components/tree/tree.component.ts b/src/components/tree/tree.component.ts
deleted file mode 100644
index b462dbc2c314626f1052bc552af39ed62ae5b6db..0000000000000000000000000000000000000000
--- a/src/components/tree/tree.component.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-import { AfterContentChecked, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Input, OnChanges, OnDestroy, OnInit, Optional, Output, QueryList, ViewChild, ViewChildren } from "@angular/core";
-import { Subscription } from "rxjs";
-import { ParseAttributeDirective } from "../parseAttribute.directive";
-import { treeAnimations } from "./tree.animation";
-import { TreeService } from "./treeService.service";
-
-@Component({
-  selector : 'tree-component',
-  templateUrl : './tree.template.html',
-  styleUrls : [
-    './tree.style.css',
-  ],
-  animations : [
-    treeAnimations,
-  ],
-  changeDetection: ChangeDetectionStrategy.OnPush,
-})
-
-export class TreeComponent extends ParseAttributeDirective implements OnChanges, OnInit, OnDestroy, AfterContentChecked {
-  @Input() public inputItem: any = {
-    name : 'Untitled',
-    children : [],
-  }
-  @Input() public childrenExpanded: boolean = true
-
-  @Output() public mouseentertree: EventEmitter<any> = new EventEmitter()
-  @Output() public mouseleavetree: EventEmitter<any> = new EventEmitter()
-  @Output() public mouseclicktree: EventEmitter<any> = new EventEmitter()
-
-  @ViewChildren(TreeComponent) public treeChildren: QueryList<TreeComponent>
-  @ViewChild('childrenContainer', { read : ElementRef }) public childrenContainer: ElementRef
-
-  constructor(
-    private cdr: ChangeDetectorRef,
-    @Optional() public treeService: TreeService,
-  ) {
-    super()
-  }
-
-  public subscriptions: Subscription[] = []
-
-  public ngOnInit() {
-    if ( this.treeService ) {
-      this.subscriptions.push(
-        this.treeService.markForCheck.subscribe(() => this.cdr.markForCheck()),
-      )
-    }
-  }
-
-  public ngOnDestroy() {
-    this.subscriptions.forEach(s => s.unsubscribe())
-  }
-
-  public _fullHeight: number = 9999
-
-  set fullHeight(num: number) {
-    this._fullHeight = num
-  }
-
-  get fullHeight() {
-    return this._fullHeight
-  }
-
-  public ngAfterContentChecked() {
-    this.fullHeight = this.childrenContainer ? this.childrenContainer.nativeElement.offsetHeight : 0
-    this.cdr.detectChanges()
-  }
-
-  public mouseenter(ev: MouseEvent) {
-    this.treeService.mouseenter.next({
-      inputItem : this.inputItem,
-      node : this,
-      event : ev,
-    })
-  }
-
-  public mouseleave(ev: MouseEvent) {
-    this.treeService.mouseleave.next({
-      inputItem : this.inputItem,
-      node : this,
-      event : ev,
-    })
-  }
-
-  public mouseclick(ev: MouseEvent) {
-    this.treeService.mouseclick.next({
-      inputItem : this.inputItem,
-      node : this,
-      event : ev,
-    })
-  }
-
-  get chevronClass(): string {
-    return this.children ?
-      this.children.length > 0 ?
-        this.childrenExpanded ?
-          'fa-chevron-down' :
-          'fa-chevron-right' :
-        'fa-none' :
-      'fa-none'
-  }
-
-  public handleEv(event: Event) {
-    event.preventDefault();
-    event.stopPropagation();
-  }
-
-  public toggleChildrenShow(event: Event) {
-    this.childrenExpanded = !this.childrenExpanded
-    event.stopPropagation()
-    event.preventDefault()
-  }
-
-  get children(): any[] {
-    return this.treeService ?
-      this.treeService.findChildren(this.inputItem) :
-      this.inputItem.children
-  }
-
-  @HostBinding('attr.filterHidden')
-  get visibilityOnFilter(): boolean {
-    return this.treeService ?
-      this.treeService.searchFilter(this.inputItem) :
-      true
-  }
-  public handleMouseEnter(fullObj: any) {
-
-    this.mouseentertree.emit(fullObj)
-
-    if (this.treeService) {
-      this.treeService.mouseenter.next(fullObj)
-    }
-  }
-
-  public handleMouseLeave(fullObj: any) {
-
-    this.mouseleavetree.emit(fullObj)
-
-    if (this.treeService) {
-      this.treeService.mouseleave.next(fullObj)
-    }
-  }
-
-  public handleMouseClick(fullObj: any) {
-
-    this.mouseclicktree.emit(fullObj)
-
-    if (this.treeService) {
-      this.treeService.mouseclick.next(fullObj)
-    }
-  }
-
-  public defaultSearchFilter = () => true
-}
diff --git a/src/components/tree/tree.style.css b/src/components/tree/tree.style.css
deleted file mode 100644
index b05982290b10f2674d9868aa9d958274d762979d..0000000000000000000000000000000000000000
--- a/src/components/tree/tree.style.css
+++ /dev/null
@@ -1,111 +0,0 @@
-tree-component
-{
-  display:block;
-  margin-left:1em;
-}
-
-div[itemContainer]
-{
-  display:flex;
-}
-
-div[itemContainer] > [fas]
-{
-  flex: 0 0 1.2em;
-  align-self: center;
-  text-align: center;
-  z-index: 1;
-}
-
-div[itemContainer] > [itemName]
-{
-  flex: 1 1 0px;
-  white-space: nowrap;
-}
-
-div[itemContainer] > span[itemName]:hover
-{
-  cursor:default;
-  color:rgba(219, 181, 86,1);
-}
-
-/* dashed guiding line */
-
-tree-component:not(:last-child) > div[itemMasterContainer]:before
-{
-  
-  pointer-events: none;
-  top:-0.8em;
-  left:-0.5em;
-  height:100%;
-  box-sizing: border-box;
-
-  border-left: rgba(255,255,255,1) 1px dashed;
-}
-
-tree-component:not(:last-child) div[itemMasterContainer] > [itemContainer]
-{
-  position:relative;
-}
-
-
-tree-component:not(:last-child) div[itemMasterContainer] > [itemContainer]:before
-{
-  pointer-events: none;
-  content : '';
-  position:absolute;
-  width:1.5em;
-  height:100%;
-  top:-50%;
-  left:-0.5em;
-  z-index: 0;
-}
-
-tree-component:last-child div[itemMasterContainer] > [itemContainer]
-{
-  position:relative;
-}
-
-tree-component:last-child div[itemMasterContainer] > [itemContainer]:before
-{
-  pointer-events: none;
-  content : '';
-  position:absolute;
-  width:1.5em;
-  height:100%;
-  top:-50%;
-  left:-0.5em;
-  z-index: 0;
-}
-
-tree-component:not(:last-child) div[itemMasterContainer]:before
-{
-  border-left: rgba(128,128,128,0.6) 1px dashed;
-}
-
-tree-component:not(:last-child) div[itemMasterContainer] > [itemContainer]:before
-{
-  border-bottom: rgba(128,128,128,0.6) 1px dashed;
-}
-
-tree-component div[itemMasterContainer]:last-child > [itemContainer]:before
-{
-  border-bottom: rgba(128,128,128,0.6) 1px dashed;
-  border-left : rgba(128,128,128,0.6) 1px dashed;
-}
-
-div[itemMasterContainer]
-{
-  position:relative;
-}
-div[itemMasterContainer]:before
-{
-  content:' ';
-  position:absolute;
-  z-index: 0;
-}
-
-div[childrenOverflowContainer]
-{
-  overflow:hidden;
-}
\ No newline at end of file
diff --git a/src/components/tree/tree.template.html b/src/components/tree/tree.template.html
deleted file mode 100644
index 10b6318bfe862cd8da5813da78aabd16e3ff6782..0000000000000000000000000000000000000000
--- a/src/components/tree/tree.template.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<div
-  itemMasterContainer>
-  <div itemContainer>
-    <i
-      (click) = "toggleChildrenShow($event)"
-      [ngClass] = "chevronClass"
-      class = "fas"
-      fas>
-    </i>
-    <span 
-      (mouseleave)="handleMouseLeave({inputItem:inputItem,node:this});handleEv($event)"
-      (mouseenter)="handleMouseEnter({inputItem:inputItem,node:this});handleEv($event)"
-      (click)="handleMouseClick({inputItem:inputItem,node:this});handleEv($event)"
-      [innerHTML] = "treeService ? treeService.renderNode(inputItem) : inputItem.name"
-      itemName>
-    </span>
-  </div>
-  <div childrenOverflowContainer>
-    <div
-      [@collapseState] = "{ value :  childrenExpanded ? 'visible' : 'collapsed' , params : { fullHeight : fullHeight }}"
-      #childrenContainer>
-      <tree-component
-        *ngFor = "let child of ( treeService ? (treeService.findChildren(inputItem) | treeSearch : treeService.searchFilter : treeService.findChildren ) : inputItem.children )"
-        [childrenExpanded] = "childrenExpanded"
-        [inputItem] = "child">
-    
-      </tree-component>
-    </div>
-  </div>
-</div>
\ No newline at end of file
diff --git a/src/components/tree/treeBase.directive.ts b/src/components/tree/treeBase.directive.ts
deleted file mode 100644
index 43fdd5954cb1b4c0145aa5a9ffb10c4d5979f46f..0000000000000000000000000000000000000000
--- a/src/components/tree/treeBase.directive.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { ChangeDetectorRef, Directive, EventEmitter, Input, OnChanges, OnDestroy, Output } from "@angular/core";
-import { Subscription } from "rxjs";
-import { TreeService } from "./treeService.service";
-
-@Directive({
-  selector : '[treebase]',
-  host : {
-    style : `
-
-    `,
-  },
-  providers : [
-    TreeService,
-  ],
-})
-
-export class TreeBaseDirective implements OnDestroy, OnChanges {
-  @Output() public treeNodeClick: EventEmitter<any> = new EventEmitter()
-  @Output() public treeNodeEnter: EventEmitter<any> = new EventEmitter()
-  @Output() public treeNodeLeave: EventEmitter<any> = new EventEmitter()
-
-  @Input() public renderNode: (item: any) => string = (item) => item.name
-  @Input() public findChildren: (item: any) => any[] = (item) => item.children
-  @Input() public searchFilter: (item: any) => boolean | null = () => true
-
-  private subscriptions: Subscription[] = []
-
-  constructor(
-    public changeDetectorRef: ChangeDetectorRef,
-    public treeService: TreeService,
-  ) {
-    this.subscriptions.push(
-      this.treeService.mouseclick.subscribe((obj) => this.treeNodeClick.emit(obj)),
-    )
-    this.subscriptions.push(
-      this.treeService.mouseenter.subscribe((obj) => this.treeNodeEnter.emit(obj)),
-    )
-    this.subscriptions.push(
-      this.treeService.mouseleave.subscribe((obj) => this.treeNodeLeave.emit(obj)),
-    )
-  }
-
-  public ngOnChanges() {
-    this.treeService.findChildren = this.findChildren
-    this.treeService.renderNode = this.renderNode
-    this.treeService.searchFilter = this.searchFilter
-
-    this.treeService.markForCheck.next(true)
-  }
-
-  public ngOnDestroy() {
-    this.subscriptions.forEach(s => s.unsubscribe())
-  }
-}
diff --git a/src/components/tree/treeService.service.ts b/src/components/tree/treeService.service.ts
deleted file mode 100644
index 2dc6bfc4dc1810038bdb008907a5d2dd5e0c27d9..0000000000000000000000000000000000000000
--- a/src/components/tree/treeService.service.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Injectable } from "@angular/core";
-import { Subject } from "rxjs";
-
-@Injectable()
-export class TreeService {
-  public mouseclick: Subject<any> = new Subject()
-  public mouseenter: Subject<any> = new Subject()
-  public mouseleave: Subject<any> = new Subject()
-
-  public findChildren: (item: any) => any[] = (item) => item.children
-  public searchFilter: (item: any) => boolean | null = () => true
-  public renderNode: (item: any) => string = (item) => item.name
-
-  public searchTerm: string = ``
-
-  public markForCheck: Subject<any> = new Subject()
-}
diff --git a/src/databrowser.fallback.ts b/src/databrowser.fallback.ts
index 86c9c626f104954b9f28f9b3992894c6b2ea3a71..6d23e7fb4ec9d40e35c4b2c8cafed9578b68db64 100644
--- a/src/databrowser.fallback.ts
+++ b/src/databrowser.fallback.ts
@@ -6,8 +6,6 @@ import { IHasId } from "./util/interfaces"
  * TODO gradually move to relevant.
  */
 
-export const OVERRIDE_IAV_DATASET_PREVIEW_DATASET_FN = new InjectionToken<(file: any, dataset: any) => void>('OVERRIDE_IAV_DATASET_PREVIEW_DATASET_FN')
-export const GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME = new InjectionToken<({ datasetSchema, datasetId, filename }) => Observable<any|null>>('GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME')
 export const kgTos = `The interactive viewer queries HBP Knowledge Graph Data Platform ("KG") for published datasets.
 
 
@@ -85,7 +83,6 @@ export interface IKgDataEntry {
 }
 
 export type TypePreviewDispalyed = (file, dataset) => Observable<boolean>
-export const IAV_DATASET_PREVIEW_ACTIVE = new InjectionToken<TypePreviewDispalyed>('IAV_DATASET_PREVIEW_ACTIVE')
 
 
 export enum EnumPreviewFileTypes{
diff --git a/src/environments/environment.common.ts b/src/environments/environment.common.ts
index 85a5e68ae63408c740790bd514fb6ad3fdbe8bb2..7634811836054d36fb8d6c38e622993b4d2ca2df 100644
--- a/src/environments/environment.common.ts
+++ b/src/environments/environment.common.ts
@@ -5,7 +5,7 @@ export const environment = {
   PRODUCTION: true,
   BACKEND_URL: null,
   DATASET_PREVIEW_URL: 'https://hbp-kg-dataset-previewer.apps.hbp.eu/v2',
-  BS_REST_URL: 'https://siibra-api-latest.apps-dev.hbp.eu/v1_0',
+  BS_REST_URL: 'http://localhost:5000/v1_0',
   SPATIAL_TRANSFORM_BACKEND: 'https://hbp-spatial-backend.apps.hbp.eu',
   MATOMO_URL: null,
   MATOMO_ID: null,
diff --git a/src/glue.spec.ts b/src/glue.spec.ts
index 63009e7a8914a09f7bf31672669438cce70cb4f2..e398540319d21c6cf282f31bbe73359a39e760c6 100644
--- a/src/glue.spec.ts
+++ b/src/glue.spec.ts
@@ -1,16 +1,5 @@
-import { TestBed, tick, fakeAsync, discardPeriodicTasks } from "@angular/core/testing"
-import { DatasetPreviewGlue, glueSelectorGetUiStatePreviewingFiles, glueActionRemoveDatasetPreview, datasetPreviewMetaReducer, glueActionAddDatasetPreview, GlueEffects, ClickInterceptorService } from "./glue"
-import { provideMockStore, MockStore } from "@ngrx/store/testing"
-import { getRandomHex, getIdObj } from 'common/util'
-import { EnumWidgetTypes, TypeOpenedWidget, uiActionSetPreviewingDatasetFiles, uiStatePreviewingDatasetFilesSelector } from "./services/state/uiState.store.helper"
-import { hot } from "jasmine-marbles"
-import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing"
-import { glueActionToggleDatasetPreview } from './glue'
-import { DS_PREVIEW_URL } from 'src/util/constants'
-import { NgLayersService } from "./ui/layerbrowser/ngLayerService.service"
-import { GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME } from "./databrowser.fallback"
-import { viewerStateSelectedTemplateSelector } from "./services/state/viewerState/selectors"
-import { generalActionError } from "./services/stateStore.helper"
+import { ClickInterceptorService } from "./glue"
+import { getRandomHex } from 'common/util'
 
 const mockActionOnSpyReturnVal0 = { 
   id: getRandomHex(),
@@ -91,587 +80,6 @@ const dataset1 = {
 }
 
 describe('> glue.ts', () => {
-  describe('> DatasetPreviewGlue', () => {
-
-    const initialState = {
-      uiState: {
-        previewingDatasetFiles: []
-      },
-      viewerState: {
-        regionsSelected: []
-      }
-    }
-    beforeEach(() => {
-      actionOnWidgetSpy = jasmine.createSpy('actionOnWidget').and.returnValues(
-        mockActionOnSpyReturnVal0,
-        mockActionOnSpyReturnVal1
-      )
-
-      TestBed.configureTestingModule({
-        imports: [
-          HttpClientTestingModule,
-        ],
-        providers: [
-          DatasetPreviewGlue,
-          provideMockStore({
-            initialState
-          }),
-          NgLayersService
-        ]
-      })
-    })
-
-    afterEach(() => {
-      actionOnWidgetSpy.calls.reset()
-      const ctrl = TestBed.inject(HttpTestingController)
-      ctrl.verify()
-    })
-
-    describe('> #datasetPreviewDisplayed', () => {
-
-      it('> correctly emits true when store changes', () => {
-        const glue = TestBed.inject(DatasetPreviewGlue)
-        const store = TestBed.inject(MockStore)
-
-        const obs = glue.datasetPreviewDisplayed(file1)
-
-        store.setState({
-          uiState: {
-            previewingDatasetFiles: []
-          }
-        })
-        const uiStateSelector = store.overrideSelector(
-          glueSelectorGetUiStatePreviewingFiles,
-          []
-        )
-
-        uiStateSelector.setResult([ file1 ] )
-        store.refreshState()
-        expect(obs).toBeObservable(
-          hot('a', {
-            a: true,
-            b: false
-          })
-        )
-      })
-
-
-      it('> correctly emits false when store changes', () => {
-        const store = TestBed.inject(MockStore)
-
-        const glue = TestBed.inject(DatasetPreviewGlue)
-        store.setState({
-          uiState: {
-            previewingDatasetFiles: [ file2 ]
-          }
-        })
-        const obs = glue.datasetPreviewDisplayed(file1)
-        store.refreshState()
-        
-        expect(obs).toBeObservable(
-          hot('b', {
-            a: true,
-            b: false
-          })
-        )
-      })
-    })
-
-    describe('> #displayDatasetPreview', () => {
-
-      it('> calls dispatch', () => {
-
-        const glue = TestBed.inject(DatasetPreviewGlue)
-        const mockStore = TestBed.inject(MockStore)
-        const dispatchSpy = spyOn(mockStore, 'dispatch').and.callThrough()
-
-        glue.displayDatasetPreview(file1, dataset1 as any)
-        
-        expect(dispatchSpy).toHaveBeenCalled()
-      })
-
-      it('> dispatches glueActionToggleDatasetPreview with the correct filename', () => {
-
-        const glue = TestBed.inject(DatasetPreviewGlue)
-        const mockStore = TestBed.inject(MockStore)
-        const dispatchSpy = spyOn(mockStore, 'dispatch').and.callThrough()
-
-        glue.displayDatasetPreview(file1, dataset1 as any)
-        
-        const args = dispatchSpy.calls.allArgs()
-        const [ action ] = args[0]
-
-        expect(action.type).toEqual(glueActionToggleDatasetPreview.type)
-        expect((action as any).datasetPreviewFile.filename).toEqual(file1.filename)
-      })
-
-      it('> uses datasetId of file if present', () => {
-        
-        const glue = TestBed.inject(DatasetPreviewGlue)
-        const mockStore = TestBed.inject(MockStore)
-        const dispatchSpy = spyOn(mockStore, 'dispatch').and.callThrough()
-
-        glue.displayDatasetPreview(file1, dataset1 as any)
-        
-        const args = dispatchSpy.calls.allArgs()
-        const [ action ] = args[0]
-
-        expect((action as any).datasetPreviewFile.datasetId).toEqual(file1.datasetId)
-      })
-
-      it('> falls back to dataset fullId if datasetId not present on file', () => {
-
-        const glue = TestBed.inject(DatasetPreviewGlue)
-        const mockStore = TestBed.inject(MockStore)
-        const dispatchSpy = spyOn(mockStore, 'dispatch').and.callThrough()
-
-        const { datasetId, ...noDsIdFile1 } = file1
-        glue.displayDatasetPreview(noDsIdFile1 as any, dataset1 as any)
-        
-        const { fullId } = dataset1
-        const { kgId } = getIdObj(fullId)
-
-        const args = dispatchSpy.calls.allArgs()
-        const [ action ] = args[0]
-
-        expect((action as any).datasetPreviewFile.datasetId).toEqual(kgId)
-      })
-    })
-
-    describe('> http interceptor', () => {
-      it('> on no state, does not call', fakeAsync(() => {
-        
-        const store = TestBed.inject(MockStore)
-        const ctrl = TestBed.inject(HttpTestingController)
-        const glue = TestBed.inject(DatasetPreviewGlue)
-
-        store.setState({
-          uiState: {
-            previewingDatasetFiles: []
-          }
-        })
-
-        const { datasetId, filename } = file1
-        // debounce at 100ms
-        tick(200)
-        ctrl.expectNone({})
-
-        discardPeriodicTasks()
-      }))
-      it('> on set state, calls end point to fetch full data', fakeAsync(() => {
-
-        const store = TestBed.inject(MockStore)
-        const ctrl = TestBed.inject(HttpTestingController)
-        const glue = TestBed.inject(DatasetPreviewGlue)
-
-        store.setState({
-          uiState: {
-            previewingDatasetFiles: [ file1 ]
-          }
-        })
-
-        const { datasetId, filename } = file1
-        // debounce at 100ms
-        tick(200)
-
-        const req = ctrl.expectOne(`${DS_PREVIEW_URL}/${encodeURIComponent('minds/core/dataset/v1.0.0')}/${datasetId}/${encodeURIComponent(filename)}`)
-        req.flush(nifti)
-        discardPeriodicTasks()
-      }))
-
-      it('> if returns 404, should be handled gracefully', fakeAsync(() => {
-
-        const ctrl = TestBed.inject(HttpTestingController)
-        const glue = TestBed.inject(DatasetPreviewGlue)
-
-        const { datasetId, filename } = file3
-
-        const obs$ = glue.getDatasetPreviewFromId({ datasetId, filename })
-        let expectedVal = 'defined'
-        obs$.subscribe(val => expectedVal = val)
-        tick(200)
-
-        const req = ctrl.expectOne(`${DS_PREVIEW_URL}/${encodeURIComponent('minds/core/dataset/v1.0.0')}/${encodeURIComponent(datasetId)}/${encodeURIComponent(filename)}`)
-        req.flush(null, { status: 404, statusText: 'Not found' })
-
-        expect(expectedVal).toBeNull()
-        discardPeriodicTasks()
-      }))
-    })
-  })
-
-
-  describe('> datasetPreviewMetaReducer', () => {
-    
-    const obj1: TypeOpenedWidget = {
-      type: EnumWidgetTypes.DATASET_PREVIEW,
-      data: file1
-    }
-
-    const stateEmpty = {
-      uiState: {
-        previewingDatasetFiles: []
-      }
-    } as { uiState: { previewingDatasetFiles: {datasetId: string, filename: string}[] } }
-
-    const stateObj1 = {
-      uiState: {
-        previewingDatasetFiles: [ file1 ]
-      }
-    } as { uiState: { previewingDatasetFiles: {datasetId: string, filename: string}[] } }
-
-    const reducer = jasmine.createSpy('reducer')
-    const metaReducer = datasetPreviewMetaReducer(reducer)
-
-    afterEach(() => {
-      reducer.calls.reset()
-    })
-    describe('> on glueActionAddDatasetPreview', () => {
-      describe('> if preview does not yet exist in state', () => {
-        beforeEach(() => {
-          metaReducer(stateEmpty, glueActionAddDatasetPreview({ datasetPreviewFile: file1 }))
-        })
-
-        it('> expect reducer to be called once', () => {
-          expect(reducer).toHaveBeenCalled()
-          expect(reducer.calls.count()).toEqual(1)
-        })
-
-        it('> expect call sig of reducer call to be correct', () => {
-
-          const [ args ] = reducer.calls.allArgs()
-          expect(args[0]).toEqual(stateEmpty)
-          expect(args[1].type).toEqual(uiActionSetPreviewingDatasetFiles.type)
-          expect(args[1].previewingDatasetFiles).toEqual([ file1 ])
-        })
-      })
-      
-      describe('> if preview already exist in state', () => {
-        beforeEach(() => {
-          metaReducer(stateObj1, glueActionAddDatasetPreview({ datasetPreviewFile: file1 }))
-        })
-        it('> should still call reducer', () => {
-          expect(reducer).toHaveBeenCalled()
-          expect(reducer.calls.count()).toEqual(1)
-        })
-
-        it('> there should now be two previews in dispatched action', () => {
-          
-          const [ args ] = reducer.calls.allArgs()
-          expect(args[0]).toEqual(stateObj1)
-          expect(args[1].type).toEqual(uiActionSetPreviewingDatasetFiles.type)
-          expect(args[1].previewingDatasetFiles).toEqual([ file1, file1 ])
-        })
-      })
-    })
-    describe('> on glueActionRemoveDatasetPreview', () => {
-      it('> removes id as expected', () => {
-        metaReducer(stateObj1, glueActionRemoveDatasetPreview({ datasetPreviewFile: file1 }))
-        expect(reducer).toHaveBeenCalled()
-        expect(reducer.calls.count()).toEqual(1)
-        const [ args ] = reducer.calls.allArgs()
-        expect(args[0]).toEqual(stateObj1)
-        expect(args[1].type).toEqual(uiActionSetPreviewingDatasetFiles.type)
-        expect(args[1].previewingDatasetFiles).toEqual([ ])
-      })
-    })
-  })
-
-  describe('> GlueEffects', () => {
-
-    /**
-     * related to previews
-     */
-    const mockTemplate = {
-      fullId: 'bar'
-    }
-    const mockPreviewFileIds = {
-      datasetId: 'foo',
-      filename: 'bar'
-    }
-    const mockPreviewFileIds2 = {
-      datasetId: 'foo2',
-      filename: 'bar2'
-    }
-    const mockPreviewFileIds3 = {
-      datasetId: 'foo3',
-      filename: 'bar3'
-    }
-    const mockPreviewFileIds4 = {
-      datasetId: 'foo4',
-      filename: 'bar4'
-    }
-    const previewFileNoRefSpace = {
-      name: 'bla bla 4',
-      datasetId: 'foo4',
-      filename: 'bar4'
-    }
-    const fittingMockPreviewFile = {
-      name: 'bla bla2',
-      datasetId: 'foo2',
-      filename: 'bar2',
-      referenceSpaces: [{
-        fullId: 'bar'
-      }]
-    }
-    const mockPreviewFile = {
-      name: 'bla bla',
-      datasetId: 'foo',
-      filename: 'bar',
-      referenceSpaces: [{
-        fullId: 'hello world'
-      }]
-    }
-
-    const defaultState = {
-      viewerState: {
-        templateSelected: null,
-        parcellationSelected: null,
-        regionsSelected: []
-      },
-      uiState: {
-        previewingDatasetFiles: []
-      }
-    }
-
-    const mockGetDatasetPreviewFromId = jasmine.createSpy('getDatasetPreviewFromId')
-
-    beforeEach(() => {
-      TestBed.configureTestingModule({
-        providers: [
-          GlueEffects,
-          provideMockStore({
-            initialState: defaultState
-          }),
-          {
-            provide: GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME,
-            useValue: mockGetDatasetPreviewFromId
-          }
-        ]
-      })
-      mockGetDatasetPreviewFromId.withArgs(mockPreviewFileIds2).and.returnValue(
-        hot('(a|)', {
-          a: fittingMockPreviewFile
-        })
-      )
-      mockGetDatasetPreviewFromId.withArgs({ datasetId: 'foo', filename: 'bar' }).and.returnValue(
-        hot('(a|)', {
-          a: mockPreviewFile
-        })
-      )
-      mockGetDatasetPreviewFromId.withArgs(mockPreviewFileIds3).and.returnValue(
-        hot('(a|)', {
-          a: null
-        })
-      )
-      mockGetDatasetPreviewFromId.withArgs(mockPreviewFileIds4).and.returnValue(
-        hot('(a|)', {
-          a: previewFileNoRefSpace
-        })
-      )
-    })
-
-    afterEach(() => {
-      mockGetDatasetPreviewFromId.calls.reset()
-    })
-
-    describe('> regionTemplateParcChange$', () => {
-
-      const copiedState0 = JSON.parse(JSON.stringify(defaultState))
-      copiedState0.viewerState.regionsSelected = [{ name: 'coffee' }]
-      copiedState0.viewerState.parcellationSelected = { name: 'chicken' }
-      copiedState0.viewerState.templateSelected = { name: 'spinach' }
-
-      const generateTest = (m1, m2) => {
-
-        const mockStore = TestBed.inject(MockStore)
-        mockStore.setState(copiedState0)
-        const glueEffects = TestBed.inject(GlueEffects)
-        /**
-         * couldn't get jasmine-marble to coopoerate
-         * TODO test proper with jasmine marble (?)
-         */
-        let numOfEmit = 0
-        const sub = glueEffects.regionTemplateParcChange$.subscribe(() => {
-          numOfEmit += 1
-        })
-
-        const copiedState1 = JSON.parse(JSON.stringify(copiedState0))
-        m1(copiedState1)
-        mockStore.setState(copiedState1)
-        expect(numOfEmit).toEqual(1)
-
-        const copiedState2 = JSON.parse(JSON.stringify(copiedState0))
-        m2(copiedState2)
-        mockStore.setState(copiedState2)
-        expect(numOfEmit).toEqual(2)
-
-        sub.unsubscribe()
-      }
-      
-      it('> on change of region, should emit', () => {
-        generateTest(
-          copiedState1 => copiedState1.viewerState.regionsSelected = [{ name: 'cake' }],
-          copiedState2 => copiedState2.viewerState.regionsSelected = [{ name: 't bone' }]
-        )
-      })
-
-      it('> on change of parcellation, should emit', () => {
-        generateTest(
-          copiedState1 => copiedState1.viewerState.parcellationSelected = { name: 'pizza' },
-          copiedState2 => copiedState2.viewerState.parcellationSelected = { name: 'pizza on pineapple' }
-        )
-      })
-
-      it('> on change of template, should emit', () => {
-        generateTest(
-          copiedState1 => copiedState1.viewerState.templateSelected = { name: 'calzone' },
-          copiedState2 => copiedState2.viewerState.templateSelected = { name: 'calzone on pineapple' }
-        )
-      })
-    })
-    
-  
-    describe('> unsuitablePreviews$', () => {
-
-      it('> calls injected getDatasetPreviewFromId', () => {
-        const mockStore = TestBed.inject(MockStore)
-        mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-        mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds2])
-
-        const glueEffects = TestBed.inject(GlueEffects)
-        expect(glueEffects.unsuitablePreviews$).toBeObservable(
-          hot('')
-        )
-        /**
-         * calling twice, once to check if the dataset preview can be retrieved, the other to check the referenceSpace
-         */
-        expect(mockGetDatasetPreviewFromId).toHaveBeenCalledTimes(2)
-        expect(mockGetDatasetPreviewFromId).toHaveBeenCalledWith(mockPreviewFileIds2)
-      })
-
-      it('> if getDatasetPreviewFromId throws in event stream, handles gracefully', () => {
-        const mockStore = TestBed.inject(MockStore)
-        mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-        mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds3])
-
-        const glueEffects = TestBed.inject(GlueEffects)
-        
-        expect(glueEffects.unsuitablePreviews$).toBeObservable(
-          hot('a', {
-            a: [ mockPreviewFileIds3 ]
-          })
-        )
-      })
-
-      describe('> filtering out dataset previews that do not satisfy reference space requirements', () => {
-        it('> if reference spaces does not match the selected reference template, will emit', () => {
-          const mockStore = TestBed.inject(MockStore)
-
-          mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-          mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds])
-          const glueEffects = TestBed.inject(GlueEffects)
-          expect(glueEffects.unsuitablePreviews$).toBeObservable(
-            hot('a', {
-              a: [ mockPreviewFile ]
-            })
-          )
-        })
-      })
-
-      describe('> keeping dataset previews that satisfy reference space criteria', () => {
-        it('> if ref space is undefined, keep preview', () => {
-
-          const mockStore = TestBed.inject(MockStore)
-          mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-          mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds4])
-          const glueEffects = TestBed.inject(GlueEffects)
-          expect(glueEffects.unsuitablePreviews$).toBeObservable(
-            hot('')
-          )
-        })
-
-        it('> if ref space is defined, and matches, keep preview', () => {
-
-          const mockStore = TestBed.inject(MockStore)
-          mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-          mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds2])
-          const glueEffects = TestBed.inject(GlueEffects)
-          expect(glueEffects.unsuitablePreviews$).toBeObservable(
-            hot('')
-          )
-        })
-      })  
-    
-    })
-
-    describe('> uiRemoveUnsuitablePreviews$', () => {
-      it('> emits whenever unsuitablePreviews$ emits', () => {
-        const mockStore = TestBed.inject(MockStore)
-        mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-        mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds])
-        const glueEffects = TestBed.inject(GlueEffects)
-        expect(glueEffects.uiRemoveUnsuitablePreviews$).toBeObservable(
-          hot('a', {
-            a: generalActionError({
-              message: `Dataset previews ${mockPreviewFile.name} cannot be displayed.`
-            })
-          })
-        )
-      })
-    })
-    
-    describe('> filterDatasetPreviewByTemplateSelected$', () => {
-
-      it('> remove 1 preview datasetfile depending on unsuitablepreview$', () => {
-        const mockStore = TestBed.inject(MockStore)
-
-        mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-        mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds])
-        const glueEffects = TestBed.inject(GlueEffects)
-        expect(glueEffects.filterDatasetPreviewByTemplateSelected$).toBeObservable(
-          hot('a', {
-            a: uiActionSetPreviewingDatasetFiles({
-              previewingDatasetFiles: [  ]
-            })
-          })
-        )
-
-      })
-      it('> remove 1 preview datasetfile (get preview info fail) depending on unsuitablepreview$', () => {
-        const mockStore = TestBed.inject(MockStore)
-
-        mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-        mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds3])
-        const glueEffects = TestBed.inject(GlueEffects)
-        expect(glueEffects.filterDatasetPreviewByTemplateSelected$).toBeObservable(
-          hot('a', {
-            a: uiActionSetPreviewingDatasetFiles({
-              previewingDatasetFiles: [  ]
-            })
-          })
-        )
-
-      })
-      it('> remove 2 preview datasetfile depending on unsuitablepreview$', () => {
-        const mockStore = TestBed.inject(MockStore)
-
-        mockStore.overrideSelector(viewerStateSelectedTemplateSelector, mockTemplate)
-        mockStore.overrideSelector(uiStatePreviewingDatasetFilesSelector, [mockPreviewFileIds, mockPreviewFileIds2, mockPreviewFileIds4])
-        const glueEffects = TestBed.inject(GlueEffects)
-        expect(glueEffects.filterDatasetPreviewByTemplateSelected$).toBeObservable(
-          hot('a', {
-            a: uiActionSetPreviewingDatasetFiles({
-              previewingDatasetFiles: [ mockPreviewFileIds2, mockPreviewFileIds4 ]
-            })
-          })
-        )
-
-      })
-      
-    })
-
-  })
 
   describe('> ClickInterceptorService', () => {
     /**
diff --git a/src/glue.ts b/src/glue.ts
index 027858745e6ac5223431e586aa6bd016e1ff3611..89b97a7f5647a8ff7e99a7bcf1dfa52837ab9c85 100644
--- a/src/glue.ts
+++ b/src/glue.ts
@@ -1,447 +1,6 @@
-import { uiActionSetPreviewingDatasetFiles, IDatasetPreviewData, uiStatePreviewingDatasetFilesSelector } from "./services/state/uiState.store.helper"
-import { OnDestroy, Injectable, Inject, InjectionToken } from "@angular/core"
-import { DatasetPreview, determinePreviewFileType, EnumPreviewFileTypes, IKgDataEntry, getKgSchemaIdFromFullId, GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME } from "./databrowser.fallback"
-import { Subscription, Observable, forkJoin, of, merge, combineLatest } from "rxjs"
-import { select, Store, ActionReducer, createAction, props, createSelector, Action } from "@ngrx/store"
-import { startWith, map, shareReplay, pairwise, debounceTime, distinctUntilChanged, tap, switchMap, withLatestFrom, mapTo, switchMapTo, filter, skip, catchError } from "rxjs/operators"
-import { getIdObj } from 'common/util'
-import { MatDialogRef } from "@angular/material/dialog"
-import { HttpClient } from "@angular/common/http"
-import { DS_PREVIEW_URL } from 'src/util/constants'
-import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer } from "./services/state/ngViewerState.store.helper"
-import { ARIA_LABELS } from 'common/constants'
-import { Effect } from "@ngrx/effects"
-import { viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector, viewerStateSelectedParcellationSelector } from "./services/state/viewerState/selectors"
-import { ngViewerActionClearView } from './services/state/ngViewerState/actions'
-import { generalActionError } from "./services/stateStore.helper"
+import { Injectable } from "@angular/core"
 import { RegDeregController } from "./util/regDereg.base"
 
-const prvFilterNull = ({ prvToDismiss, prvToShow }) => ({
-  prvToDismiss: prvToDismiss.filter(v => !!v),
-  prvToShow: prvToShow.filter(v => !!v),
-})
-
-export const glueActionToggleDatasetPreview = createAction(
-  '[glue] toggleDatasetPreview',
-  props<{ datasetPreviewFile: IDatasetPreviewData }>()
-)
-
-export const glueActionAddDatasetPreview = createAction(
-  '[glue] addDatasetPreview',
-  props<{ datasetPreviewFile: IDatasetPreviewData }>()
-)
-
-export const glueActionRemoveDatasetPreview = createAction(
-  '[glue] removeDatasetPreview',
-  props<{ datasetPreviewFile: IDatasetPreviewData }>()
-)
-
-export const glueSelectorGetUiStatePreviewingFiles = createSelector(
-  (state: any) => state.uiState,
-  uiState => uiState.previewingDatasetFiles
-)
-
-export interface IDatasetPreviewGlue{
-  datasetPreviewDisplayed(file: DatasetPreview, dataset: IKgDataEntry): Observable<boolean>
-  displayDatasetPreview(previewFile: DatasetPreview, dataset: IKgDataEntry): void
-}
-
-@Injectable({
-  providedIn: 'root'
-})
-
-export class GlueEffects {
-  
-  public regionTemplateParcChange$ = merge(
-    this.store$.pipe(
-      select(viewerStateSelectedRegionsSelector),
-      map(rs => (rs || []).map(r => r['name']).sort().join(',')),
-      distinctUntilChanged(),
-      skip(1),
-    ),
-    this.store$.pipe(
-      select(viewerStateSelectedTemplateSelector),
-      map(tmpl => tmpl
-        ? tmpl['@id'] || tmpl['name']
-        : null),
-      distinctUntilChanged(),
-      skip(1)
-    ),
-    this.store$.pipe(
-      select(viewerStateSelectedParcellationSelector),
-      map(parc => parc
-        ? parc['@id'] || parc['name']
-        : null),
-      distinctUntilChanged(),
-      skip(1)
-    )
-  ).pipe(
-    mapTo(true)
-  )
-
-  @Effect()
-  resetDatasetPreview$: Observable<any> = this.store$.pipe(
-    select(uiStatePreviewingDatasetFilesSelector),
-    distinctUntilChanged(),
-    filter(previews => previews?.length > 0),
-    switchMapTo(this.regionTemplateParcChange$)
-  ).pipe(
-    mapTo(uiActionSetPreviewingDatasetFiles({
-      previewingDatasetFiles: []
-    }))
-  )
-
-  unsuitablePreviews$: Observable<any> = merge(
-    /**
-     * filter out the dataset previews, whose details cannot be fetchd from getdatasetPreviewFromId method
-     */
-
-    this.store$.pipe(
-      select(uiStatePreviewingDatasetFilesSelector),
-      switchMap(previews => 
-        forkJoin(
-          previews.map(prev => this.getDatasetPreviewFromId(prev).pipe(
-            // filter out the null's 
-            filter(val => !val),
-            mapTo(prev)
-          ))
-        ).pipe(
-          filter(previewFiles => previewFiles.length > 0)
-        )
-      )
-    ),
-    /**
-     * filter out the dataset previews, whose details can be fetched from getDatasetPreviewFromId method
-     */
-    combineLatest([
-      this.store$.pipe(
-        select(viewerStateSelectedTemplateSelector)
-      ),
-      this.store$.pipe(
-        select(uiStatePreviewingDatasetFilesSelector),
-        switchMap(previews => 
-          forkJoin(
-            previews.map(prev => this.getDatasetPreviewFromId(prev).pipe(
-              filter(val => !!val)
-            ))
-          ).pipe(
-            // filter out the null's 
-            filter(previewFiles => previewFiles.length > 0)
-          )
-        ),
-      )
-    ]).pipe(
-      map(([ templateSelected, previewFiles ]) => 
-        previewFiles.filter(({ referenceSpaces }) => 
-          // if referenceSpaces of the dataset preview is undefined, assume it is suitable for all reference spaces
-          (!referenceSpaces)
-            ? false
-            : !referenceSpaces.some(({ fullId }) => fullId === '*' || fullId === templateSelected.fullId)
-        )
-      ),
-    ) 
-  ).pipe(
-    filter(arr => arr.length > 0),
-    shareReplay(1),
-  )
-
-  @Effect()
-  uiRemoveUnsuitablePreviews$: Observable<any> = this.unsuitablePreviews$.pipe(
-    map(previews => generalActionError({
-      message: `Dataset previews ${previews.map(v => v.name)} cannot be displayed.`
-    }))
-  )
-
-  @Effect()
-  filterDatasetPreviewByTemplateSelected$: Observable<any> = this.unsuitablePreviews$.pipe(
-    withLatestFrom(
-      this.store$.pipe(
-        select(uiStatePreviewingDatasetFilesSelector),
-      )
-    ),
-    map(([ unsuitablePreviews, previewFiles ]) => uiActionSetPreviewingDatasetFiles({
-      previewingDatasetFiles: previewFiles.filter(
-        ({ datasetId: dsId, filename: fName }) => !unsuitablePreviews.some(
-          ({ datasetId, filename }) => datasetId === dsId && fName === filename
-        )
-      )
-    }))
-  )
-
-  @Effect()
-  resetConnectivityMode: Observable<any> = this.store$.pipe(
-    select(viewerStateSelectedRegionsSelector),
-    pairwise(),
-    filter(([o, n]) => o.length > 0 && n.length === 0),
-    mapTo(
-      ngViewerActionClearView({
-        payload: {
-          'Connectivity': false
-        }
-      })
-    )
-  )
-
-  constructor(
-    private store$: Store<any>,
-    @Inject(GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME) private getDatasetPreviewFromId: (arg) => Observable<any|null>
-  ){
-  }
-}
-
-@Injectable({
-  providedIn: 'root'
-})
-
-export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{
-  
-  static readonly DEFAULT_DIALOG_OPTION = {
-    ariaLabel: ARIA_LABELS.DATASET_FILE_PREVIEW,
-    hasBackdrop: false,
-    disableClose: true,
-    autoFocus: false,
-    panelClass: 'mat-card-sm',
-    height: '50vh',
-    width: '350px',
-    position: {
-      left: '5px'
-    },
-  }
-
-  static GetDatasetPreviewId(data: IDatasetPreviewData ){
-    const { datasetSchema = 'minds/core/dataset/v1.0.0', datasetId, filename } = data
-    return `${datasetSchema}/${datasetId}:${filename}`
-  }
-
-  static GetDatasetPreviewFromId(id: string): IDatasetPreviewData{
-    const re = /([a-f0-9-]+):(.+)$/.exec(id)
-    if (!re) throw new Error(`id cannot be decoded: ${id}`)
-    return { datasetId: re[1], filename: re[2] }
-  }
-
-  static PreviewFileIsInCorrectSpace(previewFile, templateSelected): boolean{
-
-    const re = getKgSchemaIdFromFullId(
-      (templateSelected && templateSelected.fullId) || ''
-    )
-    const templateId = re && re[0] && `${re[0]}/${re[1]}`
-    const { referenceSpaces } = previewFile
-    return referenceSpaces.findIndex(({ fullId }) => fullId === '*' || fullId === templateId) >= 0
-  }
-
-  private subscriptions: Subscription[] = []
-  private openedPreviewMap = new Map<string, {id: string, matDialogRef: MatDialogRef<any>}>()
-
-  private previewingDatasetFiles$: Observable<IDatasetPreviewData[]> = this.store$.pipe(
-    select(glueSelectorGetUiStatePreviewingFiles),
-    startWith([]),
-    shareReplay(1),
-  )
-
-  public _volumePreview$ = this.previewingDatasetFiles$.pipe(
-    switchMap(arr => arr.length > 0
-      ? forkJoin(arr.map(v => this.getDatasetPreviewFromId(v)))
-      : of([])),
-    map(arr => arr.filter(v => determinePreviewFileType(v) === EnumPreviewFileTypes.VOLUMES))
-  )
-
-  private diffPreviewingDatasetFiles$= this.previewingDatasetFiles$.pipe(
-    debounceTime(100),
-    startWith([] as IDatasetPreviewData[]),
-    pairwise(),
-    map(([ oldPreviewWidgets, newPreviewWidgets ]) => {
-      const oldPrvWgtIdSet = new Set(oldPreviewWidgets.map(DatasetPreviewGlue.GetDatasetPreviewId))
-      const newPrvWgtIdSet = new Set(newPreviewWidgets.map(DatasetPreviewGlue.GetDatasetPreviewId))
-      
-      const prvToShow = newPreviewWidgets.filter(obj => !oldPrvWgtIdSet.has(DatasetPreviewGlue.GetDatasetPreviewId(obj)))
-      const prvToDismiss = oldPreviewWidgets.filter(obj => !newPrvWgtIdSet.has(DatasetPreviewGlue.GetDatasetPreviewId(obj)))
-
-      return { prvToShow, prvToDismiss }
-    }),
-  )
-
-  ngOnDestroy(){
-    while(this.subscriptions.length > 0){
-      this.subscriptions.pop().unsubscribe()
-    }
-  }
-
-  private sharedDiffObs$ = this.diffPreviewingDatasetFiles$.pipe(
-    switchMap(({ prvToShow, prvToDismiss }) => {
-      return forkJoin({
-        prvToShow: prvToShow.length > 0 
-          ? forkJoin(prvToShow.map(val => this.getDatasetPreviewFromId(val)))
-          : of([]),
-        prvToDismiss: prvToDismiss.length > 0 
-          ? forkJoin(prvToDismiss.map(val => this.getDatasetPreviewFromId(val)))
-          : of([])
-      })
-    }),
-    map(prvFilterNull),
-    shareReplay(1)
-  )
-
-  private getDiffDatasetFilesPreviews(filterFn: (prv: any) => boolean = () => true): Observable<{prvToShow: any[], prvToDismiss: any[]}>{
-    return this.sharedDiffObs$.pipe(
-      map(({ prvToDismiss, prvToShow }) => {
-        return {
-          prvToShow: prvToShow.filter(filterFn),
-          prvToDismiss: prvToDismiss.filter(filterFn),
-        }
-      })
-    )
-  }
-
-  private fetchedDatasetPreviewCache: Map<string, Observable<any>> = new Map()
-  public getDatasetPreviewFromId({ datasetSchema = 'minds/core/dataset/v1.0.0', datasetId, filename }: IDatasetPreviewData){
-    const dsPrvId = DatasetPreviewGlue.GetDatasetPreviewId({ datasetSchema, datasetId, filename })
-    const cachedPrv$ = this.fetchedDatasetPreviewCache.get(dsPrvId)
-    const filteredDsId = /[a-f0-9-]+$/.exec(datasetId)
-    if (cachedPrv$) return cachedPrv$
-    const url = `${DS_PREVIEW_URL}/${encodeURIComponent(datasetSchema)}/${filteredDsId}/${encodeURIComponent(filename)}`
-    const filedetail$ = this.http.get(url, { responseType: 'json' }).pipe(
-      map(json => {
-        return {
-          ...json,
-          filename,
-          datasetId,
-          datasetSchema
-        }
-      }),
-      catchError((_err, _obs) => of(null))
-    )
-    this.fetchedDatasetPreviewCache.set(dsPrvId, filedetail$)
-    return filedetail$.pipe(
-      tap(val => this.fetchedDatasetPreviewCache.set(dsPrvId, of(val)))
-    )
-  }
-
-  constructor(
-    private store$: Store<any>,
-    private http: HttpClient,
-  ){
-
-    // managing dataset previews without UI
-
-    // managing registeredVolumes
-    this.subscriptions.push(
-      this.getDiffDatasetFilesPreviews(
-        dsPrv => determinePreviewFileType(dsPrv) === EnumPreviewFileTypes.VOLUMES
-      ).pipe(
-        withLatestFrom(this.store$.pipe(
-          select(state => state?.viewerState?.templateSelected || null),
-          distinctUntilChanged(),
-        ))
-      ).subscribe(([ { prvToShow, prvToDismiss }, templateSelected ]) => {
-        const filterdPrvs = prvToShow.filter(prv => DatasetPreviewGlue.PreviewFileIsInCorrectSpace(prv, templateSelected))
-        for (const prv of filterdPrvs) {
-          const { volumes } = prv['data']['iav-registered-volumes']
-          this.store$.dispatch(ngViewerActionAddNgLayer({
-            layer: volumes
-          }))
-        }
-
-        for (const prv of prvToDismiss) {
-          const { volumes } = prv['data']['iav-registered-volumes']
-          this.store$.dispatch(ngViewerActionRemoveNgLayer({
-            layer: volumes
-          }))
-        }
-      })
-    )
-  }
-  
-  public datasetPreviewDisplayed(file: DatasetPreview, dataset?: IKgDataEntry){
-    if (!file) return of(false)
-    return this.previewingDatasetFiles$.pipe(
-      map(datasetPreviews => {
-        const { filename, datasetId } = file
-        const { fullId } = dataset || {}
-        const { kgId } = getIdObj(fullId) || {}
-
-        return datasetPreviews.findIndex(({ datasetId: dsId, filename: fName }) => {
-          return (datasetId || kgId) === dsId && fName === filename
-        }) >= 0
-      })
-    )
-  }
-
-  public displayDatasetPreview(previewFile: DatasetPreview, dataset: IKgDataEntry){
-    const { filename, datasetId } = previewFile
-    const { fullId } = dataset
-    const { kgId, kgSchema } = getIdObj(fullId)
-
-    const datasetPreviewFile = {
-      datasetSchema: kgSchema,
-      datasetId: datasetId || kgId,
-      filename
-    }
-
-    this.store$.dispatch(glueActionToggleDatasetPreview({ datasetPreviewFile }))
-  }
-}
-
-export function datasetPreviewMetaReducer(reducer: ActionReducer<any>): ActionReducer<any>{
-  return function (state, action) {
-    switch(action.type) {
-    case glueActionToggleDatasetPreview.type: {
-
-      const previewingDatasetFiles = (state?.uiState?.previewingDatasetFiles || []) as IDatasetPreviewData[]
-      const ids = new Set(previewingDatasetFiles.map(DatasetPreviewGlue.GetDatasetPreviewId))
-      const { datasetPreviewFile } = action as Action & { datasetPreviewFile: IDatasetPreviewData }
-      const newId = DatasetPreviewGlue.GetDatasetPreviewId(datasetPreviewFile)
-      if (ids.has(newId)) {
-        const removeId = DatasetPreviewGlue.GetDatasetPreviewId(datasetPreviewFile)
-        const filteredOpenedWidgets = previewingDatasetFiles.filter(obj => {
-          const id = DatasetPreviewGlue.GetDatasetPreviewId(obj)
-          return id !== removeId
-        })
-        return reducer(state, uiActionSetPreviewingDatasetFiles({ previewingDatasetFiles: filteredOpenedWidgets }))
-      } else {
-        return reducer(state, uiActionSetPreviewingDatasetFiles({ previewingDatasetFiles: [ ...previewingDatasetFiles, datasetPreviewFile ] }))
-      }
-    }
-    case glueActionAddDatasetPreview.type: {
-      const previewingDatasetFiles = (state?.uiState?.previewingDatasetFiles || []) as IDatasetPreviewData[]
-      const { datasetPreviewFile } = action as Action & { datasetPreviewFile: IDatasetPreviewData }
-      return reducer(state, uiActionSetPreviewingDatasetFiles({ previewingDatasetFiles: [ ...previewingDatasetFiles, datasetPreviewFile] }))
-    }
-    case glueActionRemoveDatasetPreview.type: {
-      const previewingDatasetFiles = (state?.uiState?.previewingDatasetFiles || []) as IDatasetPreviewData[]
-      const { datasetPreviewFile } = action as any
-
-      const removeId = DatasetPreviewGlue.GetDatasetPreviewId(datasetPreviewFile)
-      const filteredOpenedWidgets = previewingDatasetFiles.filter(obj => {
-        const id = DatasetPreviewGlue.GetDatasetPreviewId(obj)
-        return id !== removeId
-      })
-      return reducer(state, uiActionSetPreviewingDatasetFiles({ previewingDatasetFiles: filteredOpenedWidgets }))
-    }
-    default: return reducer(state, action)
-    }
-  }
-}
-
-export const SAVE_USER_DATA = new InjectionToken<TypeSaveUserData>('SAVE_USER_DATA')
-
-type TypeSaveUserData = (key: string, value: string) => void
-
-export const gluActionFavDataset = createAction(
-  '[glue] favDataset',
-  props<{dataentry: Partial<IKgDataEntry>}>()
-)
-export const gluActionUnfavDataset = createAction(
-  '[glue] favDataset',
-  props<{dataentry: Partial<IKgDataEntry>}>()
-)
-export const gluActionToggleDataset = createAction(
-  '[glue] favDataset',
-  props<{dataentry: Partial<IKgDataEntry>}>()
-)
-export const gluActionSetFavDataset = createAction(
-  '[glue] favDataset',
-  props<{dataentries: Partial<IKgDataEntry>[]}>()
-)
 
 @Injectable({
   providedIn: 'root'
@@ -467,28 +26,3 @@ export class ClickInterceptorService extends RegDeregController<any, boolean>{
     // called when the call has not been intercepted
   }
 }
-
-export type _TPLIVal = {
-  name: string
-  filename: string
-  datasetSchema: string
-  datasetId: string
-  data: {
-    'iav-registered-volumes': {
-      volumes: {
-        name: string
-        source: string
-        shader: string
-        transform: any
-        opacity: string
-      }[]
-    }
-  }
-  referenceSpaces: {
-    name: string
-    fullId: string
-  }[]
-  mimetype: 'application/json'
-}
-
-export const _PLI_VOLUME_INJ_TOKEN = new InjectionToken<Observable<_TPLIVal[]>>('_PLI_VOLUME_INJ_TOKEN')
diff --git a/src/keyframesModule/service.ts b/src/keyframesModule/service.ts
index b807aa15ba8414c823bf48ab132fb01c29c19590..98575c6b3fc1f6de5439791eaf01d0609c580d92 100644
--- a/src/keyframesModule/service.ts
+++ b/src/keyframesModule/service.ts
@@ -1,11 +1,8 @@
 import { Injectable, OnDestroy } from "@angular/core";
-import { MatDialog } from "@angular/material/dialog";
 import { Store } from "@ngrx/store";
 import { BehaviorSubject, Subscription } from "rxjs";
 import { distinctUntilChanged } from "rxjs/operators";
-import { viewerStateSetViewerMode } from "src/services/state/viewerState.store.helper";
-import { KEYFRAME_VIEWMODE } from "./constants";
-import { KeyFrameCtrlCmp } from "./keyframeCtrl/keyframeCtrl.component";
+import { actions } from "src/state/atlasSelection";
 
 @Injectable()
 export class KeyFrameService implements OnDestroy {
@@ -42,8 +39,10 @@ export class KeyFrameService implements OnDestroy {
 
       // TODO enable side bar when ready
       this.store.dispatch(
-        viewerStateSetViewerMode({
-          payload: flag && KEYFRAME_VIEWMODE
+        actions.setViewerMode({
+          viewerMode: flag
+            ? "key frame"
+            : null
         })
       )
     })
diff --git a/src/main.module.ts b/src/main.module.ts
index ea82fa7eb23dbd27e2037f7f52ad1f3e7bdd43e1..5ed5774ef07f50825dc22e721129e76e524f0c94 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -7,7 +7,7 @@ import { AngularMaterialModule } from 'src/sharedModules'
 import { AtlasViewer } from "./atlasViewer/atlasViewer.component";
 import { ComponentsModule } from "./components/components.module";
 import { LayoutModule } from "./layouts/layout.module";
-import { ngViewerState, pluginState, uiState, userConfigState, UserConfigStateUseEffect, viewerConfigState, viewerState } from "./services/stateStore.service";
+import { ngViewerState, uiState, userConfigState, UserConfigStateUseEffect, viewerConfigState } from "./services/stateStore.service";
 import { UIModule } from "./ui/ui.module";
 
 import { HttpClientModule } from "@angular/common/http";
@@ -18,29 +18,22 @@ import { WINDOW_MESSAGING_HANDLER_TOKEN } from 'src/messaging/types'
 import { ConfirmDialogComponent } from "./components/confirmDialog/confirmDialog.component";
 import { DialogComponent } from "./components/dialog/dialog.component";
 import { DialogService } from "./services/dialogService.service";
-import { UseEffects } from "./services/effect/effect";
-import { LocalFileService } from "./services/localFile.service";
 import { NgViewerUseEffect } from "./services/state/ngViewerState.store";
-import { ViewerStateUseEffect } from "./services/state/viewerState.store";
 import { UIService } from "./services/uiService.service";
-import { ViewerStateControllerUseEffect } from "src/state";
 import { FloatingContainerDirective } from "./util/directives/floatingContainer.directive";
 import { FloatingMouseContextualContainerDirective } from "./util/directives/floatingMouseContextualContainer.directive";
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR, PureContantService, UtilModule } from "src/util";
 import { SpotLightModule } from 'src/spotlight/spot-light.module'
 import { TryMeComponent } from "./ui/tryme/tryme.component";
 import { UiStateUseEffect } from "src/services/state/uiState.store";
-import { PluginServiceUseEffect } from './services/effect/pluginUseEffect';
 import { TemplateCoordinatesTransformation } from "src/services/templateCoordinatesTransformation.service";
-import { NewTemplateUseEffect } from './services/effect/newTemplate.effect';
 import { WidgetModule } from 'src/widget';
 import { PluginModule } from './plugin/plugin.module';
 import { LoggingModule } from './logging/logging.module';
 import { AuthService } from './auth'
 
 import 'src/theme.scss'
-import { DatasetPreviewGlue, datasetPreviewMetaReducer, IDatasetPreviewGlue, GlueEffects, ClickInterceptorService, _PLI_VOLUME_INJ_TOKEN } from './glue';
-import { viewerStateHelperReducer, viewerStateMetaReducers, ViewerStateHelperEffect } from './services/state/viewerState.store.helper';
+import { ClickInterceptorService } from './glue';
 import { TOS_OBS_INJECTION_TOKEN } from './ui/kgtos';
 import { UiEffects } from './services/state/uiState/ui.effects';
 import { MesssagingModule } from './messaging/module';
@@ -54,11 +47,19 @@ import { MessagingGlue } from './messagingGlue';
 import { BS_ENDPOINT } from './util/constants';
 import { QuickTourModule } from './ui/quickTour';
 import { of } from 'rxjs';
-import { GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME, OVERRIDE_IAV_DATASET_PREVIEW_DATASET_FN, kgTos, IAV_DATASET_PREVIEW_ACTIVE } from './databrowser.fallback'
+import { kgTos } from './databrowser.fallback'
 import { CANCELLABLE_DIALOG } from './util/interfaces';
 import { environment } from 'src/environments/environment' 
 import { NotSupportedCmp } from './notSupportedCmp/notSupported.component';
 
+import {
+  atlasSelection,
+  annotation,
+  userInterface,
+  userInteraction,
+  plugins,
+} from "./state"
+
 export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
   return function(state, action) {
     console.log('state', state);
@@ -93,31 +94,26 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
     QuickTourModule,
     
     EffectsModule.forRoot([
-      UseEffects,
       UserConfigStateUseEffect,
-      ViewerStateControllerUseEffect,
-      ViewerStateUseEffect,
       NgViewerUseEffect,
-      PluginServiceUseEffect,
+      plugins.Effects,
       UiStateUseEffect,
-      NewTemplateUseEffect,
-      ViewerStateHelperEffect,
-      GlueEffects,
       UiEffects,
+      atlasSelection.Effect,
     ]),
     StoreModule.forRoot({
-      pluginState,
       viewerConfigState,
       ngViewerState,
-      viewerState,
-      viewerStateHelper: viewerStateHelperReducer,
       uiState,
       userConfigState,
+      [atlasSelection.nameSpace]: atlasSelection.reducer,
+      [userInterface.nameSpace]: userInterface.reducer,
+      [userInteraction.nameSpace]: userInteraction.reducer,
+      [annotation.nameSpace]: annotation.reducer,
+      [plugins.nameSpace]: plugins.reducer,
     },{
       metaReducers: [ 
         // debug,
-        ...viewerStateMetaReducers,
-        datasetPreviewMetaReducer,
       ]
     }),
     HttpClientModule,
@@ -139,16 +135,10 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
   providers : [
     AtlasWorkerService,
     AuthService,
-    LocalFileService,
     DialogService,
     UIService,
     TemplateCoordinatesTransformation,
     ClickInterceptorService,
-    {
-      provide: OVERRIDE_IAV_DATASET_PREVIEW_DATASET_FN,
-      useFactory: (glue: IDatasetPreviewGlue) => glue.displayDatasetPreview.bind(glue),
-      deps: [ DatasetPreviewGlue ]
-    },
     {
       provide: CANCELLABLE_DIALOG,
       useFactory: (uiService: UIService) => {
@@ -187,23 +177,6 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
       },
       deps: [ UIService ]
     },
-    {
-      provide: _PLI_VOLUME_INJ_TOKEN,
-      useFactory: (glue: DatasetPreviewGlue) => glue._volumePreview$,
-      deps: [ DatasetPreviewGlue ]
-    },
-    {
-      provide: IAV_DATASET_PREVIEW_ACTIVE,
-      useFactory: (glue: DatasetPreviewGlue) => glue.datasetPreviewDisplayed.bind(glue),
-      deps: [ DatasetPreviewGlue ]
-    },
-    {
-      provide: GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME,
-      useFactory: (glue: DatasetPreviewGlue) => glue.getDatasetPreviewFromId.bind(glue),
-      deps: [ DatasetPreviewGlue ]
-    },
-    DatasetPreviewGlue,
-    
     {
       provide: TOS_OBS_INJECTION_TOKEN,
       useValue: of(kgTos)
@@ -252,9 +225,6 @@ export class MainModule {
 
   constructor(
     authServce: AuthService,
-    // bandaid fix: required to init glueService on startup
-    // TODO figure out why, then init service without this hack
-    glueService: DatasetPreviewGlue
   ) {
     authServce.authReloadState()
   }
diff --git a/src/messaging/types.ts b/src/messaging/types.ts
index eda7bc06a35931dd508ead545b9bb7f6df38c174..0e7cc13eba6bba6817222122592a29a0707eaf9d 100644
--- a/src/messaging/types.ts
+++ b/src/messaging/types.ts
@@ -8,10 +8,10 @@ interface IResourceType {
   swc: string
 }
 
-export type TVec4 = [number, number, number, number]
-export type TVec3 = [number, number, number]
-export type TMat3 = [TVec3, TVec3, TVec3]
-export type TMat4 = [TVec4, TVec4, TVec4, TVec4]
+export type TVec4 = number[]
+export type TVec3 = number[]
+export type TMat3 = TVec3[]
+export type TMat4 = TVec4[]
 
 interface ICommonResParam {
   transform: TMat4
diff --git a/src/messagingGlue.ts b/src/messagingGlue.ts
index 80e459157a717ec90b21f426596e531acbb48843..96bce9f87b0a723b592abc5b8f78a03ffde7ee9d 100644
--- a/src/messagingGlue.ts
+++ b/src/messagingGlue.ts
@@ -2,9 +2,9 @@ import { Injectable, OnDestroy } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { IMessagingActionTmpl, IWindowMessaging } from "./messaging/types";
 import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer } from "./services/state/ngViewerState/actions";
-import { viewerStateSelectAtlas } from "./services/state/viewerState/actions";
-import { viewerStateFetchedAtlasesSelector } from "./services/state/viewerState/selectors";
 import { generalActionError } from "./services/stateStore.helper";
+import { atlasSelection } from "src/state"
+import { SAPI } from "./atlasComponents/sapi";
 
 @Injectable()
 export class MessagingGlue implements IWindowMessaging, OnDestroy {
@@ -17,14 +17,15 @@ export class MessagingGlue implements IWindowMessaging, OnDestroy {
     while(this.onDestroyCb.length > 0) this.onDestroyCb.pop()()
   }
 
-  constructor(private store: Store<any>){
+  constructor(
+    private store: Store<any>,
+    sapi: SAPI,
+  ){
 
-    const sub = this.store.pipe(
-      select(viewerStateFetchedAtlasesSelector)
-    ).subscribe((atlases: any[]) => {
+    const sub = sapi.atlases$.subscribe(atlases => {
       for (const atlas of atlases) {
-        const { ['@id']: atlasId, templateSpaces } = atlas
-        for (const tmpl of templateSpaces) {
+        const { ['@id']: atlasId, spaces } = atlas
+        for (const tmpl of spaces) {
           const { ['@id']: tmplId } = tmpl
           this.tmplSpIdToAtlasId.set(tmplId, atlasId)
         }
@@ -48,13 +49,9 @@ export class MessagingGlue implements IWindowMessaging, OnDestroy {
       )
     }
     this.store.dispatch(
-      viewerStateSelectAtlas({
-        atlas: {
-          ['@id']: atlasId,
-          template: {
-            ['@id']: payload['@id']
-          }
-        }
+      atlasSelection.actions.selectATPById({
+        atlasId,
+        templateId: payload["@id"]
       })
     )
   }
diff --git a/src/mouseoverModule/mouseOverCvt.pipe.ts b/src/mouseoverModule/mouseOverCvt.pipe.ts
index b0a86234237ad87ab895e70575e8dd1964ba5d51..f325feacc32b30c67e39451bac74cff846782185 100644
--- a/src/mouseoverModule/mouseOverCvt.pipe.ts
+++ b/src/mouseoverModule/mouseOverCvt.pipe.ts
@@ -4,16 +4,14 @@ import { TOnHoverObj } from "./util";
 function render<T extends keyof TOnHoverObj>(key: T, value: TOnHoverObj[T]){
   if (!value) return []
   switch (key) {
-  case 'segments': {
-    return (value as TOnHoverObj['segments']).map(seg => {
+  case 'regions': {
+    return (value as TOnHoverObj['regions']).map(seg => {
       return {
         icon: {
           fontSet: 'fas',
           fontIcon: 'fa-brain'
         },
-        text: typeof seg.segment === 'string'
-          ? seg.segment
-          : seg.segment.name
+        text: seg.name
       }
     })
   }
diff --git a/src/mouseoverModule/mouseover.directive.ts b/src/mouseoverModule/mouseover.directive.ts
index cc4ae00872d32f4463aeb4d6a9ce7fbdee37ebe3..b05625a943fea38ccf10203ec518138b9b2cdd29 100644
--- a/src/mouseoverModule/mouseover.directive.ts
+++ b/src/mouseoverModule/mouseover.directive.ts
@@ -3,9 +3,10 @@ import { select, Store } from "@ngrx/store"
 import { merge, Observable } from "rxjs"
 import { distinctUntilChanged, map, scan, shareReplay } from "rxjs/operators"
 import { LoggingService } from "src/logging"
-import { uiStateMouseOverLandmarkSelector, uiStateMouseOverSegmentsSelector, uiStateMouseoverUserLandmark } from "src/services/state/uiState/selectors"
+import { uiStateMouseOverLandmarkSelector, uiStateMouseoverUserLandmark } from "src/services/state/uiState/selectors"
 import { TOnHoverObj, temporalPositveScanFn } from "./util"
 import { ModularUserAnnotationToolService } from "src/atlasComponents/userAnnotations/tools/service";
+import { userInteraction } from "src/state"
 
 @Directive({
   selector: '[iav-mouse-hover]',
@@ -45,7 +46,7 @@ export class MouseHoverDirective {
     )
 
     const onHoverSegments$ = this.store$.pipe(
-      select(uiStateMouseOverSegmentsSelector),
+      select(userInteraction.selectors.mousingOverRegions),
 
       // TODO fix aux mesh filtering
 
@@ -59,7 +60,7 @@ export class MouseHoverDirective {
       //   ? arr.filter(({ segment }) => {
       //     // if segment is not a string (i.e., not labelIndexId) return true
       //     if (typeof segment !== 'string') { return true }
-      //     const { labelIndex } = deserialiseParcRegionId(segment)
+      //     const { label: labelIndex } = deserializeSegment(segment)
       //     return parcellationSelected.auxillaryMeshIndices.indexOf(labelIndex) < 0
       //   })
       //   : arr),
@@ -70,8 +71,8 @@ export class MouseHoverDirective {
     const mergeObs = merge(
       onHoverSegments$.pipe(
         distinctUntilChanged(),
-        map(segments => {
-          return { segments }
+        map(regions => {
+          return { regions }
         }),
       ),
       onHoverAnnotation$.pipe(
@@ -101,7 +102,7 @@ export class MouseHoverDirective {
       map(arr => {
 
         let returnObj = {
-          segments: null,
+          regions: null,
           annotation: null,
           landmark: null,
           userLandmark: null,
diff --git a/src/mouseoverModule/type.ts b/src/mouseoverModule/type.ts
index 07c4312fa7896c53a7f4a8ca58b842e3cd88dc59..38033f903e9047b4164c90137564a19d0f75ae86 100644
--- a/src/mouseoverModule/type.ts
+++ b/src/mouseoverModule/type.ts
@@ -1,13 +1,5 @@
 import { TRegionSummary } from "src/util/siibraApiConstants/types";
 
-export type TMouseOverSegment = {
-  layer: {
-    name: string
-  }
-  segmentId: number
-  segment: TRegionSummary | string // if cannot decode, then segment will be {ngId}#{labelIndex}
-}
-
 export type TMouseOverVtkLandmark = {
   landmarkName: string
 }
\ No newline at end of file
diff --git a/src/mouseoverModule/util.ts b/src/mouseoverModule/util.ts
index ed4fbe50f42c9580f554e19b6e98678438c1b038..0811db26a592492f396f27f1d61cae1b4c7e2cb6 100644
--- a/src/mouseoverModule/util.ts
+++ b/src/mouseoverModule/util.ts
@@ -1,8 +1,8 @@
+import { SapiRegionModel } from "src/atlasComponents/sapi"
 import { IAnnotationGeometry } from "src/atlasComponents/userAnnotations/tools/type"
-import { TMouseOverSegment } from "./type"
 
 export type TOnHoverObj = {
-  segments: TMouseOverSegment[]
+  regions: SapiRegionModel[]
   annotation: IAnnotationGeometry
   landmark: {
     landmarkName: number
diff --git a/src/plugin/atlasViewer.pluginService.service.ts b/src/plugin/atlasViewer.pluginService.service.ts
index 668027764cf639fe3be327119a12fb4140352f08..3707c087d376b589ff673fe0482bf4a59b300046 100644
--- a/src/plugin/atlasViewer.pluginService.service.ts
+++ b/src/plugin/atlasViewer.pluginService.service.ts
@@ -1,6 +1,5 @@
 import { HttpClient } from '@angular/common/http'
 import { ComponentFactory, ComponentFactoryResolver, Injectable, ViewContainerRef, Inject, SecurityContext } from "@angular/core";
-import { PLUGINSTORE_ACTION_TYPES } from "src/services/state/pluginState.helper";
 import { PluginUnit } from "./pluginUnit/pluginUnit.component";
 import { select, Store } from "@ngrx/store";
 import { BehaviorSubject, from, merge, Observable, of } from "rxjs";
@@ -14,6 +13,7 @@ import { DialogService } from 'src/services/dialogService.service';
 import { DomSanitizer } from '@angular/platform-browser';
 import { MatSnackBar } from '@angular/material/snack-bar';
 import { PureContantService } from 'src/util';
+import { actions } from "src/state/plugins"
 
 const requiresReloadMd = `\n\n***\n\n**warning**: interactive atlas viewer **will** be reloaded in order for the change to take effect.`
 
@@ -306,13 +306,12 @@ export class PluginServices {
       ? plugin.initStateUrl
       : null
 
-    handler.setInitManifestUrl = (url) => this.store.dispatch({
-      type : PLUGINSTORE_ACTION_TYPES.SET_INIT_PLUGIN,
-      manifest : {
-        name : plugin.name,
-        initManifestUrl : url,
-      },
-    })
+    handler.setInitManifestUrl = url => this.store.dispatch(
+      actions.setInitMan({
+        nameSpace: plugin.name,
+        url
+      })
+    )
 
     const shutdownCB = [
       () => {
diff --git a/src/routerModule/parseRouteToTmplParcReg.ts b/src/routerModule/parseRouteToTmplParcReg.ts
index a1ed2a7c47003fbaae169cc49bdd0b7e8be0e3bb..ee4d505a1fa390d55c9aed507998897f896cf203 100644
--- a/src/routerModule/parseRouteToTmplParcReg.ts
+++ b/src/routerModule/parseRouteToTmplParcReg.ts
@@ -1,5 +1,3 @@
-import { getGetRegionFromLabelIndexId } from 'src/util/fn'
-import { serialiseParcellationRegion } from "common/util"
 import { decodeToNumber, separator } from './cipher'
 
 import {
@@ -7,6 +5,7 @@ import {
   TUrlPathObj,
 } from './type'
 import { UrlTree } from '@angular/router'
+import { serializeSegment } from "src/viewerModule/nehuba/util"
 
 
 export const PARSE_ERROR = {
@@ -55,7 +54,7 @@ export function parseSearchParamForTemplateParcellationRegion(obj: TUrlPathObj<s
     // TODO deprecate. Fallback (defaultNgId) (should) already exist
     // if (!viewerState.parcellationSelected.updated) throw new Error(PARCELLATION_NOT_UPDATED)
 
-    const getRegionFromlabelIndexId = getGetRegionFromLabelIndexId({ parcellation: parcellationSelected })
+    
     /**
      * either or both parcellationToLoad and .regions maybe empty
      */
@@ -80,18 +79,19 @@ export function parseSearchParamForTemplateParcellationRegion(obj: TUrlPathObj<s
           }
         }).filter(v => !!v)
         for (const labelIndex of labelIndicies) {
-          selectRegionIds.push( serialiseParcellationRegion({ ngId, labelIndex }) )
+          selectRegionIds.push( serializeSegment(ngId, labelIndex) )
         }
       }
-      return selectRegionIds
-        .map(labelIndexId => {
-          const region = getRegionFromlabelIndexId({ labelIndexId })
-          if (!region) {
-            // cb && cb({ type: ID_ERROR, message: `region with id ${labelIndexId} not found, and will be ignored.` })
-          }
-          return region
-        })
-        .filter(r => !!r)
+      return [] 
+      // selectRegionIds
+      //   .map(labelIndexId => {
+      //     const region = getRegionFromlabelIndexId({ labelIndexId })
+      //     if (!region) {
+      //       // cb && cb({ type: ID_ERROR, message: `region with id ${labelIndexId} not found, and will be ignored.` })
+      //     }
+      //     return region
+      //   })
+      //   .filter(r => !!r)
 
     } catch (e) {
       /**
diff --git a/src/routerModule/router.service.ts b/src/routerModule/router.service.ts
index a17b554adcc8d430c279d7c241f8f96438ca018d..2837af008e31978422ba494aabdc8223f9d188ba 100644
--- a/src/routerModule/router.service.ts
+++ b/src/routerModule/router.service.ts
@@ -7,7 +7,7 @@ import { debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith
 import { generalApplyState } from "src/services/stateStore.helper";
 import { PureContantService } from "src/util";
 import { cvtStateToHashedRoutes, cvtFullRouteToState, encodeCustomState, decodeCustomState, verifyCustomState } from "./util";
-import { BehaviorSubject, combineLatest, merge, Observable, of } from 'rxjs'
+import { BehaviorSubject, combineLatest, merge, NEVER, Observable, of } from 'rxjs'
 import { scan } from 'rxjs/operators'
 
 @Injectable({
@@ -51,7 +51,8 @@ export class RouterService {
 
     navEnd$.subscribe()
 
-    const ready$ = pureConstantService.allFetchingReady$.pipe(
+    // TODO fix
+    const ready$ = NEVER.pipe(
       filter(flag => !!flag),
       take(1),
       shareReplay(1),
diff --git a/src/routerModule/util.ts b/src/routerModule/util.ts
index 39ec477aebc60ba1bd201971923bc5c3a6f539c5..127c593470102dcab030df1ca508c22f22e82e30 100644
--- a/src/routerModule/util.ts
+++ b/src/routerModule/util.ts
@@ -1,12 +1,10 @@
-import { viewerStateGetSelectedAtlas, viewerStateSelectedParcellationSelector, viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector, viewerStateSelectorNavigation, viewerStateSelectorStandaloneVolumes } from "src/services/state/viewerState/selectors"
 import { encodeNumber, decodeToNumber, separator, encodeURIFull } from './cipher'
 import { UrlSegment, UrlTree } from "@angular/router"
 import { getShader, PMAP_DEFAULT_CONFIG } from "src/util/constants"
 import { mixNgLayers } from "src/services/state/ngViewerState.store"
-import { PLUGINSTORE_CONSTANTS } from 'src/services/state/pluginState.helper'
-import { viewerStateHelperStoreName } from "src/services/state/viewerState.store.helper"
 import { uiStatePreviewingDatasetFilesSelector } from "src/services/state/uiState/selectors"
 import { Component } from "@angular/core"
+import { atlasSelection, plugins } from "src/state"
 
 import {
   TUrlStandaloneVolume,
@@ -19,6 +17,7 @@ import {
   encodeId,
 } from './parseRouteToTmplParcReg'
 import { spaceMiscInfoMap } from "src/util/pureConstant.service"
+import { getRegionLabelIndex, getParcNgId } from "src/viewerModule/nehuba/config.service"
 
 const endcodePath = (key: string, val: string|string[]) =>
   key[0] === '?'
@@ -124,7 +123,7 @@ export const cvtFullRouteToState = (fullPath: UrlTree, state: any, _warnCb?: (ar
   if (pluginStates) {
     try {
       const arrPluginStates = JSON.parse(pluginStates)
-      pluginState.initManifests = arrPluginStates.map(url => [PLUGINSTORE_CONSTANTS.INIT_MANIFEST_SRC, url] as [string, string])
+      pluginState.initManifests = arrPluginStates.map(url => [plugins.INIT_MANIFEST_SRC, url] as [string, string])
     } catch (e) {
       /**
        * parsing plugin error
@@ -199,33 +198,21 @@ export const cvtFullRouteToState = (fullPath: UrlTree, state: any, _warnCb?: (ar
   /**
    * parsing template to get atlasId
    */
-  (() => {
-
-    const viewreHelperState = returnState[viewerStateHelperStoreName] || {}
-    const { templateSelected, parcellationSelected } = returnState['viewerState']
-    const { fetchedAtlases, ...rest } = viewreHelperState
-    
-    const selectedAtlas = (fetchedAtlases || []).find(a => a['templateSpaces'].find(t => t['@id'] === (templateSelected && templateSelected['@id'])))
-    
-    const overlayLayer = selectedAtlas && selectedAtlas['parcellations'].find(p => p['@id'] === (parcellationSelected && parcellationSelected['@id']))
-
-    viewreHelperState['selectedAtlasId'] = selectedAtlas && selectedAtlas['@id']
-    viewreHelperState['overlayingAdditionalParcellations'] = (overlayLayer && !overlayLayer['baseLayer'])
-      ? [ overlayLayer ]
-      : []
-  })()
-
+  // TODO
   return returnState
 }
 
 export const cvtStateToHashedRoutes = (state): string => {
   // TODO check if this causes memleak
-  const selectedAtlas = viewerStateGetSelectedAtlas(state)
-  const selectedTemplate = viewerStateSelectedTemplateSelector(state)
-  const selectedParcellation = viewerStateSelectedParcellationSelector(state)
-  const selectedRegions = viewerStateSelectedRegionsSelector(state)
-  const standaloneVolumes = viewerStateSelectorStandaloneVolumes(state)
-  const navigation = viewerStateSelectorNavigation(state)
+  const {
+    atlas: selectedAtlas,
+    parcellation: selectedParcellation,
+    template: selectedTemplate,
+  } = atlasSelection.selectors.selectedATP(state)
+  
+  const selectedRegions = atlasSelection.selectors.selectedRegions(state)
+  const standaloneVolumes = atlasSelection.selectors.standaloneVolumes(state)
+  const navigation = atlasSelection.selectors.navigation(state)
 
   const previewingDatasetFiles = uiStatePreviewingDatasetFilesSelector(state)
   let dsPrvString: string
@@ -258,10 +245,12 @@ export const cvtStateToHashedRoutes = (state): string => {
   }
 
   // encoding selected regions
-  let selectedRegionsString
+  let selectedRegionsString: string
   if (selectedRegions.length === 1) {
     const region = selectedRegions[0]
-    const { ngId, labelIndex } = region
+    const labelIndex = getRegionLabelIndex(selectedAtlas, selectedTemplate, selectedParcellation, region)
+    
+    const ngId = getParcNgId(selectedAtlas, selectedTemplate, selectedParcellation, region)
     selectedRegionsString = `${ngId}::${encodeNumber(labelIndex, { float: false })}`
   }
   let routes: any
diff --git a/src/services/effect/effect.spec.ts b/src/services/effect/effect.spec.ts
deleted file mode 100644
index 906e23daf3f5d76b601306fa10fff91e6c912611..0000000000000000000000000000000000000000
--- a/src/services/effect/effect.spec.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import {} from 'jasmine'
-import { UseEffects } from './effect'
-import { TestBed } from '@angular/core/testing'
-import { Observable } from 'rxjs'
-import { SELECT_PARCELLATION, SELECT_REGIONS } from '../state/viewerState.store'
-import { provideMockActions } from '@ngrx/effects/testing'
-import { hot } from 'jasmine-marbles'
-import { provideMockStore } from '@ngrx/store/testing'
-import { defaultRootState } from '../stateStore.service'
-import { viewerStateNewViewer } from '../state/viewerState/actions'
-
-describe('effect.ts', () => {
-
-  describe('UseEffects', () => {
-    let actions$:Observable<any>
-
-    beforeEach(() => {  
-      TestBed.configureTestingModule({
-        providers: [
-          UseEffects,
-          provideMockActions(() => actions$),
-          provideMockStore({ initialState: defaultRootState })
-        ]
-      })
-    })
-
-    it('both SELECT_PARCELLATION and viewerStateNewViewer.type actions should trigger onParcellationSelected$', () => {
-      const useEffectsInstance: UseEffects = TestBed.inject(UseEffects)
-      actions$ = hot(
-        'ab',
-        {
-          a: { type: SELECT_PARCELLATION },
-          b: { type: viewerStateNewViewer.type }
-        }
-      )
-      expect(
-        useEffectsInstance.onParcChange$
-      ).toBeObservable(
-        hot(
-          'aa',
-          {
-            a: { type: SELECT_REGIONS, selectRegions: [] }
-          }  
-        )
-      )
-    })
-  })
-})
diff --git a/src/services/effect/effect.ts b/src/services/effect/effect.ts
deleted file mode 100644
index 10e5506143f0963ddaea23b81bd3e09509c8623b..0000000000000000000000000000000000000000
--- a/src/services/effect/effect.ts
+++ /dev/null
@@ -1,243 +0,0 @@
-import { Injectable, OnDestroy } from "@angular/core";
-import { Actions, Effect, ofType } from "@ngrx/effects";
-import { select, Store } from "@ngrx/store";
-import { merge, Observable, Subscription, combineLatest } from "rxjs";
-import { filter, map, shareReplay, switchMap, take, withLatestFrom, mapTo, distinctUntilChanged } from "rxjs/operators";
-import { LoggingService } from "src/logging";
-import { IavRootStoreInterface, recursiveFindRegionWithLabelIndexId } from '../stateStore.service';
-import { viewerStateNewViewer, viewerStateSelectAtlas, viewerStateSetSelectedRegionsWithIds, viewerStateToggleLayer } from "../state/viewerState.store.helper";
-import { deserialiseParcRegionId, serialiseParcellationRegion } from "common/util"
-import { getGetRegionFromLabelIndexId } from 'src/util/fn'
-import { actionAddToRegionsSelectionWithIds, actionSelectLandmarks, viewerStateSelectParcellation, viewerStateSelectRegionWithIdDeprecated, viewerStateSetSelectedRegions } from "../state/viewerState/actions";
-
-@Injectable({
-  providedIn: 'root',
-})
-export class UseEffects implements OnDestroy {
-
-  @Effect()
-  setRegionsSelected$: Observable<any> 
-
-  constructor(
-    private actions$: Actions,
-    private store$: Store<IavRootStoreInterface>,
-    private log: LoggingService,
-  ) {
-
-    this.regionsSelected$ = this.store$.pipe(
-      select('viewerState'),
-      select('regionsSelected'),
-      shareReplay(1),
-    )
-
-    this.setRegionsSelected$ = combineLatest(
-      this.actions$.pipe(
-        ofType(viewerStateSetSelectedRegionsWithIds),
-        map(action => {
-          const { selectRegionIds } = action
-          return selectRegionIds
-        })
-      ),
-      this.store$.pipe(
-        select('viewerState'),
-        select('parcellationSelected'),
-        filter(v => !!v),
-        distinctUntilChanged()
-      ),
-    ).pipe(
-      map(([ids, parcellation]) => {
-        const getRegionFromlabelIndexId = getGetRegionFromLabelIndexId({ parcellation })
-        const selectRegions = !!ids && Array.isArray(ids)
-          ? ids.map(id => getRegionFromlabelIndexId({ labelIndexId: id })).filter(v => !!v)
-          : []
-          /**
-           * only allow 1 selection at a time
-           */
-        return viewerStateSetSelectedRegions({
-          selectRegions: selectRegions.slice(0,1)
-        })
-      })
-    )
-
-    this.onDeselectRegionsWithId$ = this.actions$.pipe(
-      ofType(ACTION_TYPES.DESELECT_REGIONS_WITH_ID),
-      map(action => {
-        const { deselecRegionIds } = action as any
-        return deselecRegionIds
-      }),
-      withLatestFrom(this.regionsSelected$),
-      map(([ deselecRegionIds, alreadySelectedRegions ]) => {
-        const deselectSet = new Set(deselecRegionIds)
-        return viewerStateSetSelectedRegions({
-          selectRegions: alreadySelectedRegions
-            .filter(({ ngId, labelIndex }) => !deselectSet.has(serialiseParcellationRegion({ ngId, labelIndex }))),
-        })
-      }),
-    )
-
-    this.addToSelectedRegions$ = this.actions$.pipe(
-      ofType(actionAddToRegionsSelectionWithIds.type),
-      map(action => {
-        const { selectRegionIds } = action
-        return selectRegionIds
-      }),
-      switchMap(selectRegionIds => this.updatedParcellation$.pipe(
-        filter(p => !!p),
-        take(1),
-        map(p => [selectRegionIds, p]),
-      )),
-      map(this.convertRegionIdsToRegion),
-      withLatestFrom(this.regionsSelected$),
-      map(([ selectedRegions, alreadySelectedRegions ]) => {
-        return viewerStateSetSelectedRegions({
-          selectRegions: this.removeDuplicatedRegions(selectedRegions, alreadySelectedRegions),
-        })
-      }),
-    )
-  }
-
-  private regionsSelected$: Observable<any[]>
-
-  public ngOnDestroy() {
-    while (this.subscriptions.length > 0) {
-      this.subscriptions.pop().unsubscribe()
-    }
-  }
-
-  private subscriptions: Subscription[] = []
-
-  private parcellationSelected$ = this.actions$.pipe(
-    ofType(viewerStateSelectParcellation.type),
-  )
-
-
-  private updatedParcellation$ = this.store$.pipe(
-    select('viewerState'),
-    select('parcellationSelected'),
-    map(p => p.updated ? p : null),
-    shareReplay(1),
-  )
-
-  @Effect()
-  public onDeselectRegionsWithId$: Observable<any>
-
-  private convertRegionIdsToRegion = ([selectRegionIds, parcellation]) => {
-    const { ngId: defaultNgId } = parcellation
-    return (selectRegionIds as any[])
-      .map(labelIndexId => deserialiseParcRegionId(labelIndexId))
-      .map(({ ngId, labelIndex }) => {
-        return {
-          labelIndexId: serialiseParcellationRegion({
-            ngId: ngId || defaultNgId,
-            labelIndex,
-          }),
-        }
-      })
-      .map(({ labelIndexId }) => {
-        return recursiveFindRegionWithLabelIndexId({
-          regions: parcellation.regions,
-          labelIndexId,
-          inheritedNgId: defaultNgId,
-        })
-      })
-      .filter(v => {
-        if (!v) {
-          this.log.log(`SELECT_REGIONS_WITH_ID, some ids cannot be parsed intto label index`)
-        }
-        return !!v
-      })
-  }
-
-  private removeDuplicatedRegions = (...args) => {
-    const set = new Set()
-    const returnArr = []
-    for (const regions of args) {
-      for (const region of regions) {
-        if (!set.has(region.name)) {
-          returnArr.push(region)
-          set.add(region.name)
-        }
-      }
-    }
-    return returnArr
-  }
-
-  @Effect()
-  public addToSelectedRegions$: Observable<any>
-
-  /**
-   * for backwards compatibility.
-   * older versions of atlas viewer may only have labelIndex as region identifier
-   */
-  @Effect()
-  public onSelectRegionWithId = this.actions$.pipe(
-    ofType(viewerStateSelectRegionWithIdDeprecated.type),
-    map(action => {
-      const { selectRegionIds } = action
-      return selectRegionIds
-    }),
-    switchMap(selectRegionIds => this.updatedParcellation$.pipe(
-      filter(p => !!p),
-      take(1),
-      map(parcellation => [selectRegionIds, parcellation]),
-    )),
-    map(this.convertRegionIdsToRegion),
-    map(selectRegions => {
-      return viewerStateSetSelectedRegions({
-        selectRegions
-      })
-    }),
-  )
-
-  /**
-   * side effect of selecting a parcellation means deselecting all regions
-   */
-  @Effect()
-  public onParcChange$ = merge(
-    this.actions$.pipe(
-      ofType(viewerStateToggleLayer.type)
-    ),
-    this.parcellationSelected$,
-    this.actions$.pipe(
-      ofType(viewerStateNewViewer.type)
-    ),
-    this.actions$.pipe(
-      ofType(viewerStateSelectAtlas.type)
-    )
-  ).pipe(
-    mapTo(
-      viewerStateSetSelectedRegions({
-        selectRegions: []
-      })
-    )
-  )
-
-  /**
-   * side effects of loading a new template space
-   * Landmarks will no longer be accurate (differente template space)
-   */
-
-  @Effect()
-  public onNewViewerResetLandmarkSelected$ = this.actions$.pipe(
-    ofType(viewerStateNewViewer.type),
-    mapTo(
-      actionSelectLandmarks({
-        landmarks: []
-      })
-    )
-  )
-}
-
-export const compareRegions: (r1: any, r2: any) => boolean = (r1, r2) => {
-  if (!r1) { return !r2 }
-  if (!r2) { return !r1 }
-  return r1.ngId === r2.ngId
-    && r1.labelIndex === r2.labelIndex
-    && r1.name === r2.name
-}
-
-const ACTION_TYPES = {
-  DESELECT_REGIONS_WITH_ID: 'DESELECT_REGIONS_WITH_ID',
-}
-
-export const VIEWER_STATE_ACTION_TYPES = ACTION_TYPES
diff --git a/src/services/effect/newTemplate.effect.ts b/src/services/effect/newTemplate.effect.ts
deleted file mode 100644
index f2c2541fe6fee218be482ad7f67b0b84443a8928..0000000000000000000000000000000000000000
--- a/src/services/effect/newTemplate.effect.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Injectable } from "@angular/core";
-import { Actions, Effect, ofType } from "@ngrx/effects";
-import { Observable } from "rxjs";
-import { mapTo } from "rxjs/operators";
-import { DATASETS_ACTIONS_TYPES } from "../state/dataStore.store";
-import { viewerStateNewViewer } from "../state/viewerState/actions";
-
-@Injectable({
-  providedIn: 'root'
-})
-
-export class NewTemplateUseEffect{
-
-  @Effect()
-  public onNewTemplateShouldClearPreviewDataset$: Observable<any>
-
-  constructor(
-    private actions$: Actions
-  ){
-    this.onNewTemplateShouldClearPreviewDataset$ = this.actions$.pipe(
-      ofType(viewerStateNewViewer.type),
-      mapTo({
-        type: DATASETS_ACTIONS_TYPES.CLEAR_PREVIEW_DATASETS
-      })
-    )
-  }
-}
diff --git a/src/services/effect/pluginUseEffect.ts b/src/services/effect/pluginUseEffect.ts
deleted file mode 100644
index bd0a74772c60d75cceda439cb5402df584c4e2af..0000000000000000000000000000000000000000
--- a/src/services/effect/pluginUseEffect.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Injectable } from "@angular/core"
-import { Effect } from "@ngrx/effects"
-import { select, Store } from "@ngrx/store"
-import { Observable, forkJoin } from "rxjs"
-import { filter, map, startWith, switchMap } from "rxjs/operators"
-import { PluginServices } from "src/plugin/atlasViewer.pluginService.service"
-import { PLUGINSTORE_CONSTANTS, PLUGINSTORE_ACTION_TYPES, pluginStateSelectorInitManifests } from 'src/services/state/pluginState.helper'
-import { HttpClient } from "@angular/common/http"
-import { getHttpHeader } from "src/util/constants"
-
-@Injectable({
-  providedIn: 'root',
-})
-
-export class PluginServiceUseEffect {
-
-  @Effect()
-  public initManifests$: Observable<any>
-
-  constructor(
-    store$: Store<any>,
-    pluginService: PluginServices,
-    http: HttpClient
-  ) {
-    this.initManifests$ = store$.pipe(
-      select(pluginStateSelectorInitManifests),
-      startWith([]),
-      map(arr => {
-        // only launch plugins that has init manifest src label on it
-        return arr.filter(([ source ]) => source === PLUGINSTORE_CONSTANTS.INIT_MANIFEST_SRC)
-      }),
-      filter(arr => arr.length > 0),
-      switchMap(arr => forkJoin(
-        arr.map(([_source, url]) => 
-          http.get(url, {
-            headers: getHttpHeader(),
-            responseType: 'json'
-          })
-        )
-      )),
-      map((jsons: any[]) => {
-        for (const json of jsons){
-          pluginService.launchNewWidget(json)
-        }
-
-        // clear init manifest
-        return {
-          type: PLUGINSTORE_ACTION_TYPES.CLEAR_INIT_PLUGIN,
-        }
-      }),
-    )
-  }
-}
diff --git a/src/services/localFile.service.ts b/src/services/localFile.service.ts
deleted file mode 100644
index 045ac686b54f7b65e2985f7d75c2bce85ce705c6..0000000000000000000000000000000000000000
--- a/src/services/localFile.service.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { Injectable } from "@angular/core";
-import { Store } from "@ngrx/store";
-import { SNACKBAR_MESSAGE } from "./state/uiState.store";
-import { IavRootStoreInterface } from "./stateStore.service";
-import { DATASETS_ACTIONS_TYPES } from "./state/dataStore.store";
-
-/**
- * experimental service handling local user files such as nifti and gifti
- */
-
-@Injectable({
-  providedIn: 'root',
-})
-
-export class LocalFileService {
-  public SUPPORTED_EXT = SUPPORTED_EXT
-  private supportedExtSet = new Set(SUPPORTED_EXT)
-
-  constructor(
-    private store: Store<IavRootStoreInterface>,
-  ) {
-
-  }
-
-  private niiUrl: string
-
-  public handleFileDrop(files: File[]) {
-    try {
-      this.validateDrop(files)
-      for (const file of files) {
-        const ext = this.getExtension(file.name)
-        switch (ext) {
-        case NII: {
-          this.handleNiiFile(file)
-          break;
-        }
-        default:
-          throw new Error(`File ${file.name} does not have a file handler`)
-        }
-      }
-    } catch (e) {
-      this.store.dispatch({
-        type: SNACKBAR_MESSAGE,
-        snackbarMessage: `Opening local NIFTI error: ${e.toString()}`,
-      })
-    }
-  }
-
-  private getExtension(filename: string) {
-    const match = /(\.\w*?)$/i.exec(filename)
-    return (match && match[1]) || ''
-  }
-
-  private validateDrop(files: File[]) {
-    if (files.length !== 1) {
-      throw new Error('Interactive atlas viewer currently only supports drag and drop of one file at a time')
-    }
-    for (const file of files) {
-      const ext = this.getExtension(file.name)
-      if (!this.supportedExtSet.has(ext)) {
-        throw new Error(`File ${file.name}${ext === '' ? ' ' : (' with extension ' + ext)} cannot be loaded. The supported extensions are: ${this.SUPPORTED_EXT.join(', ')}`)
-      }
-    }
-  }
-
-  private handleNiiFile(file: File) {
-
-    if (this.niiUrl) {
-      URL.revokeObjectURL(this.niiUrl)
-    }
-    this.niiUrl = URL.createObjectURL(file)
-    
-    this.store.dispatch({
-      type: DATASETS_ACTIONS_TYPES.PREVIEW_DATASET,
-      payload: {
-        file: {
-          mimetype: 'application/json',
-          url: this.niiUrl
-        }
-      }
-    })
-
-    this.showLocalWarning()
-  }
-
-  private showLocalWarning() {
-    this.store.dispatch({
-      type: SNACKBAR_MESSAGE,
-      snackbarMessage: `Warning: sharing URL will not share the loaded local file`,
-    })
-  }
-}
-
-const NII = `.nii`
-const GII = '.gii'
-
-const SUPPORTED_EXT = [
-  NII,
-  GII,
-]
diff --git a/src/services/state/dataState/actions.ts b/src/services/state/dataState/actions.ts
deleted file mode 100644
index 34af72ff7364bb0c575eb3cbf21aae9a739a9890..0000000000000000000000000000000000000000
--- a/src/services/state/dataState/actions.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { createAction, props } from "@ngrx/store";
-import { IKgDataEntry } from "src/databrowser.fallback";
-
-export const datastateActionToggleFav = createAction(
-  `[datastate] toggleFav`,
-  props<{payload: { fullId: string }}>()
-)
-
-export const datastateActionUpdateFavDataset = createAction(
-  `[datastate] updateFav`,
-  props<{ favDataEntries: any[] }>()
-)
-
-export const datastateActionUnfavDataset = createAction(
-  `[datastate] unFav`,
-  props<{ payload: { fullId: string } }>()
-)
-
-export const datastateActionFavDataset = createAction(
-  `[datastate] fav`,
-  props<{ payload: { fullId: string } }>()
-)
-
-export const datastateActionFetchedDataentries = createAction(
-  `[datastate] fetchedDatastate`,
-  props<{ fetchedDataEntries: IKgDataEntry[] }>()
-)
\ No newline at end of file
diff --git a/src/services/state/dataStore.store.ts b/src/services/state/dataStore.store.ts
deleted file mode 100644
index 962168dd111b4219e69c6f595f5ccf596df2fc95..0000000000000000000000000000000000000000
--- a/src/services/state/dataStore.store.ts
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * TODO move to databrowser module
- */
-
-import { Action } from '@ngrx/store'
-import { LOCAL_STORAGE_CONST } from 'src/util/constants'
-import { datastateActionFetchedDataentries, datastateActionUpdateFavDataset } from './dataState/actions'
-import { IHasId } from 'src/util/interfaces'
-import { generalApplyState } from '../stateStore.helper'
-
-/**
- * TODO merge with databrowser.usereffect.ts
- */
-
-export interface DatasetPreview {
-  datasetId: string
-  filename: string
-}
-
-export interface IStateInterface {
-  fetchedDataEntries: IDataEntry[]
-  favDataEntries: Partial<IDataEntry>[]
-  fetchedSpatialData: IDataEntry[]
-}
-
-// TODO deprecate
-export const defaultState = {
-  fetchedDataEntries: [],
-  favDataEntries: (() => {
-    try {
-      const saved = localStorage.getItem(LOCAL_STORAGE_CONST.FAV_DATASET)
-      const arr = JSON.parse(saved) as any[]
-      return arr.every(item => item && !!item.fullId)
-        ? arr
-        : []
-    } catch (e) {
-      // TODO propagate error
-      return []
-    }
-  })(),
-  fetchedSpatialData: [],
-}
-
-export const getStateStore = ({ state: state = defaultState } = {}) => (prevState: IStateInterface = state, action: Partial<IActionInterface>) => {
-
-  switch (action.type) {
-  case datastateActionFetchedDataentries.type:
-  case FETCHED_DATAENTRIES: {
-    return {
-      ...prevState,
-      fetchedDataEntries : action.fetchedDataEntries,
-    }
-  }
-  case FETCHED_SPATIAL_DATA: {
-    return {
-      ...prevState,
-      fetchedSpatialData : action.fetchedDataEntries,
-    }
-  }
-  case datastateActionUpdateFavDataset.type: {
-    const { favDataEntries = [] } = action
-    return {
-      ...prevState,
-      favDataEntries,
-    }
-  }
-  case generalApplyState.type: {
-    const { dataStore } = (action as any).state
-    return dataStore
-  }
-  default: return prevState
-  }
-}
-
-// must export a named function for aot compilation
-// see https://github.com/angular/angular/issues/15587
-// https://github.com/amcdnl/ngrx-actions/issues/23
-// or just google for:
-//
-// angular function expressions are not supported in decorators
-
-const defaultStateStore = getStateStore()
-
-export function stateStore(state, action) {
-  return defaultStateStore(state, action)
-}
-
-export interface IActionInterface extends Action {
-  favDataEntries: IDataEntry[]
-  fetchedDataEntries: IDataEntry[]
-  fetchedSpatialData: IDataEntry[]
-  payload?: any
-}
-
-export const FETCHED_DATAENTRIES = 'FETCHED_DATAENTRIES'
-export const FETCHED_SPATIAL_DATA = `FETCHED_SPATIAL_DATA`
-
-// TODO deprecate in favour of src/ui/datamodule/constants.ts
-
-export interface IActivity {
-  methods: string[]
-  preparation: string[]
-  protocols: string[]
-}
-
-export interface IDataEntry {
-  activity: IActivity[]
-  name: string
-  description: string
-  license: string[]
-  licenseInfo: string[]
-  parcellationRegion: IParcellationRegion[]
-  formats: string[]
-  custodians: string[]
-  contributors: string[]
-  referenceSpaces: IReferenceSpace[]
-  files: File[]
-  publications: IPublication[]
-  embargoStatus: IHasId[]
-
-  methods: string[]
-  protocols: string[]
-
-  preview?: boolean
-
-  /**
-   * TODO typo, should be kgReferences
-   */
-  kgReference: string[]
-
-  id: string
-  fullId: string
-}
-
-export interface IParcellationRegion {
-  id?: string
-  name: string
-}
-
-export interface IReferenceSpace {
-  name: string
-}
-
-export interface IPublication {
-  name: string
-  doi: string
-  cite: string
-}
-
-export interface IProperty {
-  description: string
-  publications: IPublication[]
-}
-
-export interface ILandmark {
-  type: string // e.g. sEEG recording site, etc
-  name: string
-  templateSpace: string // possibily inherited from LandmarkBundle (?)
-  geometry: IPointLandmarkGeometry | IPlaneLandmarkGeometry | IOtherLandmarkGeometry
-  properties: IProperty
-  files: File[]
-}
-
-export interface IDataStateInterface {
-  fetchedDataEntries: IDataEntry[]
-
-  /**
-   * Map that maps parcellation name to a Map, which maps datasetname to Property Object
-   */
-  fetchedMetadataMap: Map<string, Map<string, {properties: IProperty}>>
-}
-
-export interface IPointLandmarkGeometry extends ILandmarkGeometry {
-  position: [number, number, number]
-}
-
-export interface IPlaneLandmarkGeometry extends ILandmarkGeometry {
-  // corners have to be CW or CCW (no zigzag)
-  corners: [[number, number, number], [number, number, number], [number, number, number], [number, number, number]]
-}
-
-export interface IOtherLandmarkGeometry extends ILandmarkGeometry {
-  vertices: Array<[number, number, number]>
-  meshIdx: Array<[number, number, number]>
-}
-
-interface ILandmarkGeometry {
-  type: 'point' | 'plane'
-  space?: 'voxel' | 'real'
-}
-
-export interface IFile {
-  name: string
-  absolutePath: string
-  byteSize: number
-  contentType: string
-}
-
-export interface ViewerPreviewFile {
-  name: string
-  filename: string
-  mimetype: string
-  referenceSpaces: { 
-    name: string 
-    fullId: string
-  }[]
-  url?: string
-  data?: any
-  position?: any
-}
-
-export interface IFileSupplementData {
-  data: any
-}
-
-const ACTION_TYPES = {
-  PREVIEW_DATASET: 'PREVIEW_DATASET',
-  CLEAR_PREVIEW_DATASET: 'CLEAR_PREVIEW_DATASET',
-  CLEAR_PREVIEW_DATASETS: 'CLEAR_PREVIEW_DATASETS'
-}
-
-export const DATASETS_ACTIONS_TYPES = ACTION_TYPES
diff --git a/src/services/state/ngViewerState.store.ts b/src/services/state/ngViewerState.store.ts
index 5b1758d60906076840930cafbf878ab834e7e88d..a27495313235764aceeabb3b8b43bb526b4f0726 100644
--- a/src/services/state/ngViewerState.store.ts
+++ b/src/services/state/ngViewerState.store.ts
@@ -14,7 +14,6 @@ import { generalApplyState } from '../stateStore.helper';
 import { ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from './ngViewerState/selectors';
 import { uiActionSnackbarMessage } from './uiState/actions';
 import { TUserRouteError } from 'src/auth/auth.service';
-import { viewerStateSelectedTemplateSelector } from './viewerState.store.helper';
 
 export function mixNgLayers(oldLayers: INgLayerInterface[], newLayers: INgLayerInterface|INgLayerInterface[]): INgLayerInterface[] {
   if (newLayers instanceof Array) {
@@ -173,9 +172,6 @@ export class NgViewerUseEffect implements OnDestroy {
   @Effect()
   public cycleViews$: Observable<any>
 
-  @Effect()
-  public removeAllNonBaseLayers$: Observable<any>
-
   private panelOrder$: Observable<string>
   private panelMode$: Observable<string>
 
@@ -325,62 +321,6 @@ export class NgViewerUseEffect implements OnDestroy {
         snackbarMessage: CYCLE_PANEL_MESSAGE
       })),
     )
-
-    /**
-     * simplify with layer browser
-     */
-    const baseNgLayerName$ = this.store$.pipe(
-      select(viewerStateSelectedTemplateSelector),
-      
-      map(templateSelected => {
-        if (!templateSelected) { return [] }
-
-        const { ngId , otherNgIds = []} = templateSelected
-
-        return [
-          ngId,
-          ...otherNgIds,
-          ...templateSelected.parcellations.reduce((acc, curr) => {
-            return acc.concat([
-              curr.ngId,
-              ...getNgIds(curr.regions),
-            ])
-          }, []),
-        ]
-      }),
-      /**
-       * get unique array
-       */
-      map(nonUniqueArray => Array.from(new Set(nonUniqueArray))),
-      /**
-       * remove falsy values
-       */
-      map(arr => arr.filter(v => !!v)),
-    )
-
-    const allLoadedNgLayers$ = this.store$.pipe(
-      select('viewerState'),
-      select('loadedNgLayers'),
-    )
-
-    this.removeAllNonBaseLayers$ = this.actions.pipe(
-      ofType(ACTION_TYPES.REMOVE_ALL_NONBASE_LAYERS),
-      withLatestFrom(
-        combineLatest(
-          baseNgLayerName$,
-          allLoadedNgLayers$,
-        ),
-      ),
-      map(([_, [baseNgLayerNames, loadedNgLayers] ]) => {
-        const baseNameSet = new Set(baseNgLayerNames)
-        return loadedNgLayers.filter(l => !baseNameSet.has(l.name))
-      }),
-      map(layer => {
-        return ngViewerActionRemoveNgLayer({
-          layer
-        })
-      }),
-    )
   }
 
   public ngOnDestroy() {
@@ -392,11 +332,6 @@ export class NgViewerUseEffect implements OnDestroy {
 
 export { INgLayerInterface } 
 
-const ACTION_TYPES = {
-
-  REMOVE_ALL_NONBASE_LAYERS: `REMOVE_ALL_NONBASE_LAYERS`,
-}
-
 export const SUPPORTED_PANEL_MODES = [
   PANELS.FOUR_PANEL,
   PANELS.H_ONE_THREE,
@@ -404,4 +339,3 @@ export const SUPPORTED_PANEL_MODES = [
   PANELS.SINGLE_PANEL,
 ]
 
-export const NG_VIEWER_ACTION_TYPES = ACTION_TYPES
diff --git a/src/services/state/pluginState.helper.ts b/src/services/state/pluginState.helper.ts
deleted file mode 100644
index e1c48c1941ab716f1bacc6c8980f62c2367a933a..0000000000000000000000000000000000000000
--- a/src/services/state/pluginState.helper.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { createSelector } from "@ngrx/store"
-
-export const PLUGINSTORE_ACTION_TYPES = {
-  SET_INIT_PLUGIN: `SET_INIT_PLUGIN`,
-  CLEAR_INIT_PLUGIN: 'CLEAR_INIT_PLUGIN',
-}
-
-export const pluginStateSelectorInitManifests = createSelector(
-  state => state['pluginState'],
-  pluginState => pluginState.initManifests
-)
-
-export const PLUGINSTORE_CONSTANTS = {
-  INIT_MANIFEST_SRC: 'INIT_MANIFEST_SRC',
-}
diff --git a/src/services/state/pluginState.store.ts b/src/services/state/pluginState.store.ts
deleted file mode 100644
index 85bfa20a915ec8ab2e11497321cd66d95edabb91..0000000000000000000000000000000000000000
--- a/src/services/state/pluginState.store.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Action } from '@ngrx/store'
-import { generalApplyState } from '../stateStore.helper'
-import { PLUGINSTORE_ACTION_TYPES, PLUGINSTORE_CONSTANTS } from './pluginState.helper'
-export const defaultState: StateInterface = {
-  initManifests: []
-}
-
-export interface StateInterface {
-  initManifests: Array<[ string, string|null ]>
-}
-
-export interface ActionInterface extends Action {
-  manifest: {
-    name: string
-    initManifestUrl?: string
-  }
-}
-
-
-export const getStateStore = ({ state = defaultState } = {}) => (prevState: StateInterface = state, action: ActionInterface): StateInterface => {
-  switch (action.type) {
-  case PLUGINSTORE_ACTION_TYPES.SET_INIT_PLUGIN: {
-    const newMap = new Map(prevState.initManifests )
-
-    // reserved source label for init manifest
-    if (action.manifest.name !== PLUGINSTORE_CONSTANTS.INIT_MANIFEST_SRC) { newMap.set(action.manifest.name, action.manifest.initManifestUrl) }
-    return {
-      ...prevState,
-      initManifests: Array.from(newMap),
-    }
-  }
-  case PLUGINSTORE_ACTION_TYPES.CLEAR_INIT_PLUGIN: {
-    const { initManifests } = prevState
-    const newManifests = initManifests.filter(([source]) => source !== PLUGINSTORE_CONSTANTS.INIT_MANIFEST_SRC)
-    return {
-      ...prevState,
-      initManifests: newManifests,
-    }
-  }
-  case generalApplyState.type: {
-    const { pluginState } = (action as any).state
-    return pluginState
-  }
-  default: return prevState
-  }
-}
-
-// must export a named function for aot compilation
-// see https://github.com/angular/angular/issues/15587
-// https://github.com/amcdnl/ngrx-actions/issues/23
-// or just google for:
-//
-// angular function expressions are not supported in decorators
-
-const defaultStateStore = getStateStore()
-
-export function stateStore(state, action) {
-  return defaultStateStore(state, action)
-}
diff --git a/src/services/state/uiState.store.helper.ts b/src/services/state/uiState.store.helper.ts
index 6f1c187c15b94170fcdc5db6b5ba3d0664d6da75..2a89567a3896ec1cf986f2e070837b970eebed41 100644
--- a/src/services/state/uiState.store.helper.ts
+++ b/src/services/state/uiState.store.helper.ts
@@ -15,7 +15,6 @@ export {
 
 export {
   uiStatePreviewingDatasetFilesSelector,
-  uiStateMouseOverSegmentsSelector,
   uiStateMouseoverUserLandmark,
 } from './uiState/selectors'
 
diff --git a/src/services/state/uiState.store.ts b/src/services/state/uiState.store.ts
index cab51af1edb88fdbcf360fb5e5a3628e9809dc51..1df46f1de6ef7a7ee6bc223b2b8b488ec31de727 100644
--- a/src/services/state/uiState.store.ts
+++ b/src/services/state/uiState.store.ts
@@ -88,6 +88,7 @@ export const getStateStore = ({ state = defaultState } = {}) => (prevState: IUiS
       ...prevState,
       sidePanelIsOpen: true,
     }
+  // src/state/userInteraction/actions.closeSidePanel
   case uiStateCloseSidePanel.type:
   case CLOSE_SIDE_PANEL:
     return {
@@ -174,14 +175,6 @@ export class UiStateUseEffect implements OnDestroy{
 
   private subscriptions: Subscription[] = []
 
-  private numRegionSelectedWithHistory$: Observable<any[]>
-
-  @Effect()
-  public sidePanelOpen$: Observable<any>
-
-  @Effect()
-  public viewCurrentOpen$: Observable<any>
-
   private bottomSheetRef: MatBottomSheetRef
 
   constructor(
@@ -189,27 +182,6 @@ export class UiStateUseEffect implements OnDestroy{
     actions$: Actions,
     bottomSheet: MatBottomSheet
   ) {
-    this.numRegionSelectedWithHistory$ = store$.pipe(
-      select('viewerState'),
-      select('regionsSelected'),
-      map(arr => arr.length),
-      startWith(0),
-      scan((acc, curr) => [curr, ...acc], []),
-    )
-
-    this.sidePanelOpen$ = this.numRegionSelectedWithHistory$.pipe(
-      filter(([curr, prev]) => prev === 0 && curr > 0),
-      mapTo({
-        type: OPEN_SIDE_PANEL,
-      }),
-    )
-
-    this.viewCurrentOpen$ = this.numRegionSelectedWithHistory$.pipe(
-      filter(([curr, prev]) => prev === 0 && curr > 0),
-      mapTo({
-        type: EXPAND_SIDE_PANEL_CURRENT_VIEW,
-      }),
-    )
     
     this.subscriptions.push(
       actions$.pipe(
diff --git a/src/services/state/uiState/selectors.spec.ts b/src/services/state/uiState/selectors.spec.ts
index 2464c9c8a1a4770a1e1c14afd28cb7c3dd4a3833..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/src/services/state/uiState/selectors.spec.ts
+++ b/src/services/state/uiState/selectors.spec.ts
@@ -1,7 +0,0 @@
-import { uiStateMouseOverSegmentsSelector } from './selectors'
-
-describe('> uiState/selectors.ts', () => {
-  describe('> mouseOverSegments', () => {
-
-  })
-})
diff --git a/src/services/state/uiState/selectors.ts b/src/services/state/uiState/selectors.ts
index 483539b2d784f567564bc2963233b8dd91dabcb1..9d48fadedf36d09e6292a08bfce5d13cee787f8c 100644
--- a/src/services/state/uiState/selectors.ts
+++ b/src/services/state/uiState/selectors.ts
@@ -1,5 +1,4 @@
 import { createSelector } from "@ngrx/store";
-import { TMouseOverSegment } from "src/mouseoverModule/type";
 import { IUiState } from './common'
 
 export const uiStatePreviewingDatasetFilesSelector = createSelector(
@@ -7,11 +6,6 @@ export const uiStatePreviewingDatasetFilesSelector = createSelector(
   (uiState: IUiState) => uiState['previewingDatasetFiles']
 )
 
-export const uiStateMouseOverSegmentsSelector = createSelector(
-  state => state['uiState'],
-  uiState => uiState['mouseOverSegments'] as TMouseOverSegment[]
-)
-
 export const uiStateMouseOverLandmarkSelector = createSelector(
   state => state['uiState'],
   uiState => uiState['mouseOverLandmark'] as string
diff --git a/src/services/state/userConfigState.store.ts b/src/services/state/userConfigState.store.ts
index 81fef3205c4020651d6169012d43c19da67ec0f9..4c869cd8f9ee3a752e5572752f910882b1bad319 100644
--- a/src/services/state/userConfigState.store.ts
+++ b/src/services/state/userConfigState.store.ts
@@ -1,17 +1,13 @@
 import { Injectable, OnDestroy } from "@angular/core";
 import { Actions, Effect, ofType } from "@ngrx/effects";
 import { Action, createAction, createReducer, props, select, Store, on, createSelector } from "@ngrx/store";
-import { combineLatest, from, Observable, of, Subscription } from "rxjs";
-import { catchError, distinctUntilChanged, filter, map, mapTo, share, shareReplay, switchMap, take, withLatestFrom } from "rxjs/operators";
-import { BACKENDURL, LOCAL_STORAGE_CONST } from "src/util//constants";
-import { DialogService } from "../dialogService.service";
-import { recursiveFindRegionWithLabelIndexId } from "src/util/fn";
-import { serialiseParcellationRegion } from 'common/util'
+import { of, Subscription } from "rxjs";
+import { catchError, filter, map } from "rxjs/operators";
+import { LOCAL_STORAGE_CONST } from "src/util//constants";
 // Get around the problem of importing duplicated string (ACTION_TYPES), even using ES6 alias seems to trip up the compiler
 // TODO file bug and reverse
 import { HttpClient } from "@angular/common/http";
-import { actionSetMobileUi, viewerStateNewViewer, viewerStateSelectParcellation, viewerStateSetSelectedRegions } from "./viewerState/actions";
-import { viewerStateSelectedParcellationSelector, viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector } from "./viewerState/selectors";
+import { actionSetMobileUi } from "./viewerState/actions";
 import { PureContantService } from "src/util";
 
 interface ICsp{
@@ -62,11 +58,6 @@ export const defaultState: StateInterface = {
   pluginCsp: {}
 }
 
-export const actionUpdateRegionSelections = createAction(
-  `[userConfig] updateRegionSelections`,
-  props<{ config: { savedRegionsSelection: RegionSelection[]} }>()
-)
-
 export const selectorAllPluginsCspPermission = createSelector(
   (state: any) => state.userConfigState,
   userConfigState => userConfigState.pluginCsp
@@ -82,24 +73,12 @@ export const actionUpdatePluginCsp = createAction(
 )
 
 export const ACTION_TYPES = {
-  UPDATE_REGIONS_SELECTIONS: actionUpdateRegionSelections.type,
   UPDATE_REGIONS_SELECTION: 'UPDATE_REGIONS_SELECTION',
-  SAVE_REGIONS_SELECTION: `SAVE_REGIONS_SELECTIONN`,
-  DELETE_REGIONS_SELECTION: 'DELETE_REGIONS_SELECTION',
-
-  LOAD_REGIONS_SELECTION: 'LOAD_REGIONS_SELECTION',
 }
 
 
 export const userConfigReducer = createReducer(
   defaultState,
-  on(actionUpdateRegionSelections, (state, { config }) => {
-    const { savedRegionsSelection } = config
-    return {
-      ...state,
-      savedRegionsSelection
-    }
-  }),
   on(actionUpdatePluginCsp, (state, { payload }) => {
     return {
       ...state,
@@ -118,187 +97,9 @@ export class UserConfigStateUseEffect implements OnDestroy {
   constructor(
     private actions$: Actions,
     private store$: Store<any>,
-    private dialogService: DialogService,
     private http: HttpClient,
     private constantSvc: PureContantService,
   ) {
-    const viewerState$ = this.store$.pipe(
-      select('viewerState'),
-      shareReplay(1),
-    )
-
-    this.parcellationSelected$ = this.store$.pipe(
-      select(viewerStateSelectedParcellationSelector),
-      distinctUntilChanged(),
-    )
-
-    this.tprSelected$ = combineLatest(
-      this.store$.pipe(
-        select(viewerStateSelectedTemplateSelector),
-        distinctUntilChanged(),
-      ),
-      this.parcellationSelected$,
-      this.store$.pipe(
-        select(viewerStateSelectedRegionsSelector)
-        /**
-         * TODO
-         * distinct selectedRegions
-         */
-      ),
-    ).pipe(
-      map(([ templateSelected, parcellationSelected, regionsSelected ]) => {
-        return {
-          templateSelected, parcellationSelected, regionsSelected,
-        }
-      }),
-    )
-
-    this.savedRegionsSelections$ = this.store$.pipe(
-      select('userConfigState'),
-      select('savedRegionsSelection'),
-      shareReplay(1),
-    )
-
-    this.onSaveRegionsSelection$ = this.actions$.pipe(
-      ofType(ACTION_TYPES.SAVE_REGIONS_SELECTION),
-      withLatestFrom(this.tprSelected$),
-      withLatestFrom(this.savedRegionsSelections$),
-
-      map(([[action, tprSelected], savedRegionsSelection]) => {
-        const { payload = {} } = action as UserConfigAction
-        const { name = 'Untitled' } = payload
-
-        const { templateSelected, parcellationSelected, regionsSelected } = tprSelected
-        const newSavedRegionSelection: RegionSelection = {
-          id: Date.now().toString(),
-          name,
-          templateSelected,
-          parcellationSelected,
-          regionsSelected,
-        }
-        return {
-          type: ACTION_TYPES.UPDATE_REGIONS_SELECTIONS,
-          config: {
-            savedRegionsSelection: savedRegionsSelection.concat([newSavedRegionSelection]),
-          },
-        } as UserConfigAction
-      }),
-    )
-
-    this.onDeleteRegionsSelection$ = this.actions$.pipe(
-      ofType(ACTION_TYPES.DELETE_REGIONS_SELECTION),
-      withLatestFrom(this.savedRegionsSelections$),
-      map(([ action, savedRegionsSelection ]) => {
-        const { payload = {} } = action as UserConfigAction
-        const { id } = payload
-        return {
-          type: ACTION_TYPES.UPDATE_REGIONS_SELECTIONS,
-          config: {
-            savedRegionsSelection: savedRegionsSelection.filter(srs => srs.id !== id),
-          },
-        }
-      }),
-    )
-
-    this.onUpdateRegionsSelection$ = this.actions$.pipe(
-      ofType(ACTION_TYPES.UPDATE_REGIONS_SELECTION),
-      withLatestFrom(this.savedRegionsSelections$),
-      map(([ action, savedRegionsSelection]) => {
-        const { payload = {} } = action as UserConfigAction
-        const { id, ...rest } = payload
-        return {
-          type: ACTION_TYPES.UPDATE_REGIONS_SELECTIONS,
-          config: {
-            savedRegionsSelection: savedRegionsSelection
-              .map(srs => srs.id === id
-                ? { ...srs, ...rest }
-                : { ...srs }),
-          },
-        }
-      }),
-    )
-
-    this.subscriptions.push(
-      this.actions$.pipe(
-        ofType(ACTION_TYPES.LOAD_REGIONS_SELECTION),
-        map(action => {
-          const { payload = {}} = action as UserConfigAction
-          const { savedRegionsSelection }: {savedRegionsSelection: RegionSelection} = payload
-          return savedRegionsSelection
-        }),
-        filter(val => !!val),
-        withLatestFrom(this.tprSelected$),
-        switchMap(([savedRegionsSelection, { parcellationSelected, templateSelected, regionsSelected }]) =>
-          from(this.dialogService.getUserConfirm({
-            title: `Load region selection: ${savedRegionsSelection.name}`,
-            message: `This action would cause the viewer to navigate away from the current view. Proceed?`,
-          })).pipe(
-            catchError((e, obs) => of(null)),
-            map(() => {
-              return {
-                savedRegionsSelection,
-                parcellationSelected,
-                templateSelected,
-                regionsSelected,
-              }
-            }),
-            filter(val => !!val),
-          ),
-        ),
-        switchMap(({ savedRegionsSelection, parcellationSelected, templateSelected, regionsSelected }) => {
-          if (templateSelected.name !== savedRegionsSelection.templateSelected.name ) {
-            /**
-             * template different, dispatch viewerStateNewViewer.type
-             */
-            this.store$.dispatch(
-              viewerStateNewViewer({
-                selectParcellation: savedRegionsSelection.parcellationSelected,
-                selectTemplate: savedRegionsSelection.templateSelected,
-              })
-            )
-            return this.parcellationSelected$.pipe(
-              filter(p => p.updated),
-              take(1),
-              map(() => {
-                return {
-                  regionsSelected: savedRegionsSelection.regionsSelected,
-                }
-              }),
-            )
-          }
-
-          if (parcellationSelected.name !== savedRegionsSelection.parcellationSelected.name) {
-            /**
-             * parcellation different, dispatch SELECT_PARCELLATION
-             */
-            this.store$.dispatch(
-              viewerStateSelectParcellation({
-                selectParcellation: savedRegionsSelection.parcellationSelected,
-              })
-            )
-            return this.parcellationSelected$.pipe(
-              filter(p => p.updated),
-              take(1),
-              map(() => {
-                return {
-                  regionsSelected: savedRegionsSelection.regionsSelected,
-                }
-              }),
-            )
-          }
-
-          return of({
-            regionsSelected: savedRegionsSelection.regionsSelected,
-          })
-        }),
-      ).subscribe(({ regionsSelected }) => {
-        this.store$.dispatch(
-          viewerStateSetSelectedRegions({
-            selectRegions: regionsSelected,
-          })
-        )
-      }),
-    )
 
     this.subscriptions.push(
       this.store$.pipe(
@@ -328,61 +129,6 @@ export class UserConfigStateUseEffect implements OnDestroy {
       }),
     )
 
-    this.subscriptions.push(
-      this.actions$.pipe(
-        ofType(ACTION_TYPES.UPDATE_REGIONS_SELECTIONS),
-      ).subscribe(action => {
-        const { config = {} } = action as UserConfigAction
-        const { savedRegionsSelection } = config
-        const simpleSRSs = savedRegionsSelection.map(({ id, name, templateSelected, parcellationSelected, regionsSelected }) => {
-          return {
-            id,
-            name,
-            tName: templateSelected.name,
-            pName: parcellationSelected.name,
-            rSelected: regionsSelected.map(({ ngId, labelIndex }) => serialiseParcellationRegion({ ngId, labelIndex })),
-          } as SimpleRegionSelection
-        })
-
-        /**
-         * TODO save server side on per user basis
-         */
-        window.localStorage.setItem(LOCAL_STORAGE_CONST.SAVED_REGION_SELECTIONS, JSON.stringify(simpleSRSs))
-      }),
-    )
-
-    const savedSRSsString = window.localStorage.getItem(LOCAL_STORAGE_CONST.SAVED_REGION_SELECTIONS)
-    const savedSRSs: SimpleRegionSelection[] = savedSRSsString && JSON.parse(savedSRSsString)
-
-    this.restoreSRSsFromStorage$ = viewerState$.pipe(
-      filter(() => !!savedSRSs),
-      select('fetchedTemplates'),
-      distinctUntilChanged(),
-      map(fetchedTemplates => savedSRSs.map(({ id, name, tName, pName, rSelected }) => {
-        const templateSelected = fetchedTemplates.find(t => t.name === tName)
-        const parcellationSelected = templateSelected && templateSelected.parcellations.find(p => p.name === pName)
-        const regionsSelected = parcellationSelected && rSelected.map(labelIndexId => recursiveFindRegionWithLabelIndexId({
-          regions: parcellationSelected.regions,
-          labelIndexId,
-          inheritedNgId: parcellationSelected.ngId
-        }))
-        return {
-          templateSelected,
-          parcellationSelected,
-          id,
-          name,
-          regionsSelected,
-        } as RegionSelection
-      })),
-      filter(restoredSavedRegions => restoredSavedRegions.every(rs => rs.regionsSelected && rs.regionsSelected.every(r => !!r))),
-      take(1),
-      map(savedRegionsSelection => {
-        return {
-          type: ACTION_TYPES.UPDATE_REGIONS_SELECTIONS,
-          config: { savedRegionsSelection },
-        }
-      }),
-    )
   }
 
   public ngOnDestroy() {
@@ -391,24 +137,6 @@ export class UserConfigStateUseEffect implements OnDestroy {
     }
   }
 
-  /**
-   * Temmplate Parcellation Regions selected
-   */
-  private tprSelected$: Observable<{templateSelected: any, parcellationSelected: any, regionsSelected: any[]}>
-  private savedRegionsSelections$: Observable<any[]>
-  private parcellationSelected$: Observable<any>
-
-  @Effect()
-  public onSaveRegionsSelection$: Observable<any>
-
-  @Effect()
-  public onDeleteRegionsSelection$: Observable<any>
-
-  @Effect()
-  public onUpdateRegionsSelection$: Observable<any>
-
-  @Effect()
-  public restoreSRSsFromStorage$: Observable<any>
 
   @Effect()
   public setInitPluginPermission$ = this.http.get(`${this.constantSvc.backendUrl}user/pluginPermissions`, {
diff --git a/src/services/state/viewerState.store.helper.spec.ts b/src/services/state/viewerState.store.helper.spec.ts
deleted file mode 100644
index fa0845554d221ea0051658ba8d096145913be883..0000000000000000000000000000000000000000
--- a/src/services/state/viewerState.store.helper.spec.ts
+++ /dev/null
@@ -1,346 +0,0 @@
-import { TestBed } from "@angular/core/testing"
-import { Action } from "@ngrx/store"
-import { provideMockActions } from "@ngrx/effects/testing"
-import { MockStore, provideMockStore } from "@ngrx/store/testing"
-import { Observable, of } from "rxjs"
-import { isNewerThan, ViewerStateHelperEffect } from "./viewerState.store.helper"
-import { viewerStateGetSelectedAtlas, viewerStateSelectedTemplateSelector } from "./viewerState/selectors"
-import { viewerStateHelperSelectParcellationWithId, viewerStateRemoveAdditionalLayer } from "./viewerState/actions"
-import { generalActionError } from "../stateStore.helper"
-import { hot } from "jasmine-marbles"
-
-describe('> viewerState.store.helper.ts', () => {
-  const tmplId = 'test-tmpl-id'
-  const tmplId0 = 'test-tmpl-id-0'
-  describe('> ViewerStateHelperEffect', () => {
-    let effect: ViewerStateHelperEffect
-    let mockStore: MockStore
-    let actions$: Observable<Action>
-    beforeEach(() => {
-      TestBed.configureTestingModule({
-        providers: [
-          ViewerStateHelperEffect,
-          provideMockStore(),
-          provideMockActions(() => actions$)
-        ]
-      })
-
-      mockStore = TestBed.inject(MockStore)
-      mockStore.overrideSelector(viewerStateSelectedTemplateSelector, {
-        ['@id']: tmplId
-      })
-
-      actions$ = of(
-        viewerStateRemoveAdditionalLayer({
-          payload: {
-            ['@id']: 'bla'
-          }
-        })
-      )
-    })
-
-    describe('> if selected atlas has no matching tmpl space', () => {
-      beforeEach(() => {
-        mockStore.overrideSelector(viewerStateGetSelectedAtlas, {
-          templateSpaces: [{
-            ['@id']: tmplId0
-          }]
-        })
-      })
-      it('> should emit gernal error', () => {
-        effect = TestBed.inject(ViewerStateHelperEffect)
-        effect.onRemoveAdditionalLayer$.subscribe(val => {
-          expect(val.type === generalActionError.type)
-        })
-      })
-    })
-
-    describe('> if selected atlas has matching tmpl', () => {
-
-      const parcId0 = 'test-parc-id-0'
-      const parcId1 = 'test-parc-id-1'
-      const tmpSp = {
-        ['@id']: tmplId,
-        availableIn: [{
-          ['@id']: parcId0
-        }],
-      }
-      beforeEach(() => {
-        mockStore.overrideSelector(viewerStateGetSelectedAtlas, {
-          templateSpaces: [
-            tmpSp
-          ],
-          parcellations: [],
-        })
-      })
-
-      describe('> if parc is empty array', () => {
-        it('> should emit with falsy as payload', () => {
-          effect = TestBed.inject(ViewerStateHelperEffect)
-          expect(
-            effect.onRemoveAdditionalLayer$
-          ).toBeObservable(
-            hot('(a|)', {
-              a: viewerStateHelperSelectParcellationWithId({
-                payload: undefined
-              })
-            })
-          )
-        })
-      })
-      describe('> if no parc has eligible @id', () => {
-        beforeEach(() => {
-          mockStore.overrideSelector(viewerStateGetSelectedAtlas, {
-            templateSpaces: [
-              tmpSp
-            ],
-            parcellations: [{
-              ['@id']: parcId1
-            }]
-          })
-        })
-        it('> should emit with falsy as payload', () => {
-          effect = TestBed.inject(ViewerStateHelperEffect)
-          expect(
-            effect.onRemoveAdditionalLayer$
-          ).toBeObservable(
-            hot('(a|)', {
-              a: viewerStateHelperSelectParcellationWithId({
-                payload: undefined
-              })
-            })
-          )
-        })
-      })
-
-      describe('> if some parc has eligible @id', () => {
-        describe('> if no @version is available', () => {
-          const parc1 = {
-            ['@id']: parcId0,
-            name: 'p0-0',
-            baseLayer: true
-          }
-          const parc2 = {
-            ['@id']: parcId0,
-            name: 'p0-1',
-            baseLayer: true
-          }
-          beforeEach(() => {
-
-            mockStore.overrideSelector(viewerStateGetSelectedAtlas, {
-              templateSpaces: [
-                tmpSp
-              ],
-              parcellations: [
-                parc1,
-                parc2
-              ]
-            })
-          })
-          it('> selects the first parc', () => {
-
-            effect = TestBed.inject(ViewerStateHelperEffect)
-            expect(
-              effect.onRemoveAdditionalLayer$
-            ).toBeObservable(
-              hot('(a|)', {
-                a: viewerStateHelperSelectParcellationWithId({
-                  payload: parc1
-                })
-              })
-            )
-          })
-        })
-
-        describe('> if @version is available', () => {
-          
-          describe('> if there exist an entry without @next attribute', () => {
-            
-            const parc1 = {
-              ['@id']: parcId0,
-              name: 'p0-0',
-              baseLayer: true,
-              ['@version']: {
-                ['@next']: 'random-value'
-              }
-            }
-            const parc2 = {
-              ['@id']: parcId0,
-              name: 'p0-1',
-              baseLayer: true,
-              ['@version']: {
-                ['@next']: null
-              }
-            }
-            beforeEach(() => {
-
-              mockStore.overrideSelector(viewerStateGetSelectedAtlas, {
-                templateSpaces: [
-                  tmpSp
-                ],
-                parcellations: [
-                  parc1,
-                  parc2
-                ]
-              })
-            })
-            it('> selects the first one without @next attribute', () => {
-
-              effect = TestBed.inject(ViewerStateHelperEffect)
-              expect(
-                effect.onRemoveAdditionalLayer$
-              ).toBeObservable(
-                hot('(a|)', {
-                  a: viewerStateHelperSelectParcellationWithId({
-                    payload: parc2
-                  })
-                })
-              )
-            })
-          })
-          describe('> if there exist no entry without @next attribute', () => {
-            
-            const parc1 = {
-              ['@id']: parcId0,
-              name: 'p0-0',
-              baseLayer: true,
-              ['@version']: {
-                ['@next']: 'random-value'
-              }
-            }
-            const parc2 = {
-              ['@id']: parcId0,
-              name: 'p0-1',
-              baseLayer: true,
-              ['@version']: {
-                ['@next']: 'another-random-value'
-              }
-            }
-            beforeEach(() => {
-
-              mockStore.overrideSelector(viewerStateGetSelectedAtlas, {
-                templateSpaces: [
-                  tmpSp
-                ],
-                parcellations: [
-                  parc1,
-                  parc2
-                ]
-              })
-            })
-            it('> selects the first one without @next attribute', () => {
-
-              effect = TestBed.inject(ViewerStateHelperEffect)
-              expect(
-                effect.onRemoveAdditionalLayer$
-              ).toBeObservable(
-                hot('(a|)', {
-                  a: viewerStateHelperSelectParcellationWithId({
-                    payload: parc1
-                  })
-                })
-              )
-            })
-          })
-        })
-      })
-    })
-  })
-
-  describe('> isNewerThan', () => {
-    describe('> ill formed versions', () => {
-      it('> in circular references, throws', () => {
-
-        const parc0Circular = {
-
-          "@version": {
-            "@next": "aaa-bbb",
-            "@this": "ccc-ddd",
-            "name": "",
-            "@previous": null,
-          }
-        }
-        const parc1Circular = {
-  
-          "@version": {
-            "@next": "ccc-ddd",
-            "@this": "aaa-bbb",
-            "name": "",
-            "@previous": null,
-          }
-        }
-        const p2 = {
-          ["@id"]: "foo-bar"
-        }
-        const p3 = {
-          ["@id"]: "baz"
-        }
-        expect(() => {
-          isNewerThan([parc0Circular, parc1Circular], p2, p3)
-        }).toThrow()
-      })
-
-      it('> if not found, will throw', () => {
-
-        const parc0Circular = {
-
-          "@version": {
-            "@next": "aaa-bbb",
-            "@this": "ccc-ddd",
-            "name": "",
-            "@previous": null,
-          }
-        }
-        const parc1Circular = {
-  
-          "@version": {
-            "@next": null,
-            "@this": "aaa-bbb",
-            "name": "",
-            "@previous": null,
-          }
-        }
-        const p2 = {
-          ["@id"]: "foo-bar"
-        }
-        const p3 = {
-          ["@id"]: "baz"
-        }
-        expect(() => {
-          isNewerThan([parc0Circular, parc1Circular], p2, p3)
-        }).toThrow()
-      })
-    })
-
-    it('> works on well formed versions', () => {
-
-      const parc0 = {
-        "@version": {
-          "@next": null,
-          "@this": "aaa-bbb",
-          "name": "",
-          "@previous": "ccc-ddd",
-        }
-      }
-      const parc1 = {
-        "@version": {
-          "@next": "aaa-bbb",
-          "@this": "ccc-ddd",
-          "name": "",
-          "@previous": null,
-        }
-      }
-
-      const p0 = {
-        ['@id']: 'aaa-bbb'
-      }
-      const p1 = {
-        ['@id']: 'ccc-ddd'
-      }
-      expect(
-        isNewerThan([parc0, parc1], p0, p1)
-      ).toBeTrue()
-    })
-
-  })
-})
\ No newline at end of file
diff --git a/src/services/state/viewerState.store.helper.ts b/src/services/state/viewerState.store.helper.ts
deleted file mode 100644
index bf5f69fb89b4e9dbed57fd4066927a0254758944..0000000000000000000000000000000000000000
--- a/src/services/state/viewerState.store.helper.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-// TODO merge with viewerstate.store.ts when refactor is done
-import { createReducer, on, ActionReducer, Store, select } from "@ngrx/store";
-import { generalActionError, generalApplyState } from "../stateStore.helper";
-import { Effect, Actions, ofType } from "@ngrx/effects";
-import { Observable } from "rxjs";
-import { withLatestFrom, map } from "rxjs/operators";
-import { Injectable } from "@angular/core";
-
-import {
-  viewerStateNewViewer,
-  viewerStateHelperSelectParcellationWithId,
-  viewerStateNavigateToRegion,
-  viewerStateRemoveAdditionalLayer,
-  viewerStateSelectAtlas,
-  viewerStateSelectParcellation,
-  viewerStateSelectTemplateWithId,
-  viewerStateSetConnectivityRegion,
-  viewerStateNehubaLayerchanged,
-  viewerStateSetFetchedAtlases,
-  viewerStateSetSelectedRegions,
-  viewerStateSetSelectedRegionsWithIds,
-  viewerStateToggleLayer,
-  viewerStateToggleRegionSelect,
-  viewerStateSelectRegionWithIdDeprecated,
-  viewerStateSetViewerMode,
-  viewerStateDblClickOnViewer,
-  viewerStateAddUserLandmarks,
-  viewreStateRemoveUserLandmarks,
-  viewerStateMouseOverCustomLandmark,
-  viewerStateMouseOverCustomLandmarkInPerspectiveView,
-  viewerStateSelectTemplateWithName,
-} from './viewerState/actions'
-
-export {
-  viewerStateNewViewer,
-  viewerStateHelperSelectParcellationWithId,
-  viewerStateNavigateToRegion,
-  viewerStateRemoveAdditionalLayer,
-  viewerStateSelectAtlas,
-  viewerStateSelectParcellation,
-  viewerStateSelectTemplateWithId,
-  viewerStateSetConnectivityRegion,
-  viewerStateNehubaLayerchanged,
-  viewerStateSetFetchedAtlases,
-  viewerStateSetSelectedRegions,
-  viewerStateSetSelectedRegionsWithIds,
-  viewerStateToggleLayer,
-  viewerStateToggleRegionSelect,
-  viewerStateSelectRegionWithIdDeprecated,
-  viewerStateSetViewerMode,
-  viewerStateDblClickOnViewer,
-  viewerStateAddUserLandmarks,
-  viewreStateRemoveUserLandmarks,
-  viewerStateMouseOverCustomLandmark,
-  viewerStateMouseOverCustomLandmarkInPerspectiveView,
-  viewerStateSelectTemplateWithName,
-}
-
-import {
-  viewerStateSelectedRegionsSelector,
-  viewerStateSelectedTemplateSelector,
-  viewerStateSelectedParcellationSelector,
-  viewerStateGetSelectedAtlas,
-  viewerStateCustomLandmarkSelector,
-  viewerStateFetchedTemplatesSelector,
-  viewerStateNavigationStateSelector,
-} from './viewerState/selectors'
-import { IHasId } from "src/util/interfaces";
-
-export {
-  viewerStateSelectedRegionsSelector,
-  viewerStateSelectedTemplateSelector,
-  viewerStateSelectedParcellationSelector,
-  viewerStateCustomLandmarkSelector,
-  viewerStateFetchedTemplatesSelector,
-  viewerStateNavigationStateSelector,
-}
-
-interface IViewerStateHelperStore{
-  fetchedAtlases: any[]
-  selectedAtlasId: string
-  overlayingAdditionalParcellations: any[]
-}
-
-const initialState: IViewerStateHelperStore = {
-  fetchedAtlases: [],
-  selectedAtlasId: null,
-  overlayingAdditionalParcellations: []
-}
-
-function handleToggleLayerAction(reducer: ActionReducer<any>): ActionReducer<any>{
-  return function(state, action) {
-    switch(action.type){
-    case viewerStateToggleLayer.type: {
-      const { payload } = action as any
-      const { templateSelected } = (state && state['viewerState']) || {}
-
-      const selectParcellation = templateSelected?.parcellations.find(p => p['@id'] === payload['@id'])
-      return reducer(state, viewerStateSelectParcellation({ selectParcellation }))
-    }
-    default: reducer(state, action)
-    }
-    return reducer(state, action)
-  }
-}
-
-export const viewerStateMetaReducers = [
-  handleToggleLayerAction
-]
-
-@Injectable({
-  providedIn: 'root'
-})
-
-export class ViewerStateHelperEffect{
-  @Effect()
-  onRemoveAdditionalLayer$: Observable<any> = this.actions$.pipe(
-    ofType(viewerStateRemoveAdditionalLayer.type),
-    withLatestFrom(
-      this.store$.pipe(
-        select(viewerStateGetSelectedAtlas)
-      ),
-      this.store$.pipe(
-        select(viewerStateSelectedTemplateSelector)
-      )
-    ),
-    map(([ { payload }, selectedAtlas, selectedTemplate ]) => {
-      const tmpl = selectedAtlas['templateSpaces'].find(t => t['@id'] === selectedTemplate['@id'])
-      if (!tmpl) {
-        return generalActionError({
-          message: `templateSpace with id ${selectedTemplate['@id']} cannot be found in atlas with id ${selectedAtlas['@id']}`
-        })
-      }
-
-      const eligibleParcIdSet = new Set(
-        tmpl.availableIn.map(p => p['@id'])
-      )
-      const baseLayers = selectedAtlas['parcellations'].filter(fullP => fullP['baseLayer'] && eligibleParcIdSet.has(fullP['@id']))
-      const baseLayer = baseLayers.find(layer => !!layer['@version'] && !layer['@version']['@next']) || baseLayers[0]
-      return viewerStateHelperSelectParcellationWithId({ payload: baseLayer })
-    })
-  )
-
-  constructor(
-    private store$: Store<any>,
-    private actions$: Actions
-  ){
-
-  }
-}
-
-export const viewerStateHelperReducer = createReducer(
-  initialState,
-  on(viewerStateSetFetchedAtlases, (state, { fetchedAtlases }) => ({ ...state, fetchedAtlases })),
-  on(viewerStateSelectAtlas, (state, { atlas }) => ({ ...state, selectedAtlasId: atlas['@id'] })),
-  on(generalApplyState, (_prevState, { state }) => ({ ...state[viewerStateHelperStoreName] })),
-)
-
-export const viewerStateHelperStoreName = 'viewerStateHelper'
-
-export const defaultState = initialState
-
-interface IVersion{
-  "@next": string
-  "@this": string
-  "name": string
-  "@previous": string
-}
-
-interface IHasVersion{
-  ['@version']: IVersion
-}
-
-export function isNewerThan(arr: IHasVersion[], srcObj: IHasId, compObj: IHasId): boolean {
-
-  function* GenNewerVersions(flag){
-    let it = 0
-    const newest =  arr.find((v => v['@version'] && v['@version']['@this'] === srcObj['@id']))
-    if (!newest) throw new Error(`GenNewerVersions error newest element isn't found`)
-    yield newest
-    let currPreviousId = newest['@version'][ flag ? '@next' : '@previous' ]
-    while (currPreviousId) {
-      it += 1
-      if (it>100) throw new Error(`iteration excced 100, did you include a loop?`)
-
-      const curr = arr.find(v => v['@version']['@this'] === currPreviousId)
-      if (!curr) throw new Error(`GenNewerVersions error, version id ${currPreviousId} not found`)
-      currPreviousId = curr['@version'][ flag ? '@next' : '@previous' ]
-      yield curr
-    }
-  }
-  for (const obj of GenNewerVersions(true)) {
-    if (obj['@version']['@this'] === compObj['@id']) {
-      return false
-    }
-  }
-
-  for (const obj of GenNewerVersions(false)) {
-    if (obj['@version']['@this'] === compObj['@id']) {
-      return true
-    }
-  }
-
-  throw new Error(`isNewerThan error, neither srcObj nor compObj exist in array`)
-}
diff --git a/src/services/state/viewerState.store.ts b/src/services/state/viewerState.store.ts
deleted file mode 100644
index d4433a0db42c514a3d3ea64191cf7ee8404742bb..0000000000000000000000000000000000000000
--- a/src/services/state/viewerState.store.ts
+++ /dev/null
@@ -1,417 +0,0 @@
-import { Injectable } from '@angular/core';
-import { Actions, Effect, ofType } from '@ngrx/effects';
-import { Action, select, Store } from '@ngrx/store'
-import { Observable } from 'rxjs';
-import { distinctUntilChanged, filter, map, shareReplay, startWith, withLatestFrom, mapTo } from 'rxjs/operators';
-import { IUserLandmark } from 'src/atlasViewer/atlasViewer.apiService.service';
-import { INgLayerInterface } from 'src/atlasViewer/atlasViewer.component';
-import { getViewer } from 'src/util/fn';
-import { LoggingService } from 'src/logging';
-import { IavRootStoreInterface } from '../stateStore.service';
-import { GENERAL_ACTION_TYPES } from '../stateStore.service'
-import { CLOSE_SIDE_PANEL } from './uiState.store';
-import {
-  viewerStateSetSelectedRegions,
-  viewerStateSetConnectivityRegion,
-  viewerStateSelectParcellation,
-  viewerStateSelectRegionWithIdDeprecated,
-  viewerStateCustomLandmarkSelector,
-  viewerStateDblClickOnViewer,
-  viewerStateAddUserLandmarks,
-  viewreStateRemoveUserLandmarks,
-  viewerStateMouseOverCustomLandmark,
-  viewerStateMouseOverCustomLandmarkInPerspectiveView,
-  viewerStateNewViewer
-} from './viewerState.store.helper';
-import { cvtNehubaConfigToNavigationObj } from 'src/state';
-import {
-  viewerStateChangeNavigation,
-  viewerStateNehubaLayerchanged,
-  viewerStateSetViewerMode,
-  actionSelectLandmarks,
-  actionViewerStateSelectFeature
-} from './viewerState/actions';
-import { serialiseParcellationRegion } from "common/util"
-import { IViewerState, defaultViewerState } from "./viewerState/type"
-
-export { IViewerState, defaultViewerState }
-
-export interface ActionInterface extends Action {
-  fetchedTemplate?: any[]
-
-  selectTemplate?: any
-  selectParcellation?: any
-  selectRegions?: any[]
-  selectRegionIds: string[]
-  deselectRegions?: any[]
-
-  updatedParcellation?: any
-
-  landmarks: IUserLandmark[]
-  deselectLandmarks: IUserLandmark[]
-
-  navigation?: any
-
-  payload: any
-
-  connectivityRegion?: string
-}
-
-
-export const getStateStore = ({ state = defaultViewerState } = {}) => (prevState: Partial<IViewerState> = state, action: ActionInterface) => {
-  switch (action.type) {
-  case CLEAR_STANDALONE_VOLUMES:
-    return {
-      ...prevState,
-      standaloneVolumes: []
-    }
-  case viewerStateNewViewer.type: {
-
-    const {
-      selectParcellation: parcellation,
-      navigation,
-      selectTemplate,
-    } = action
-    const navigationFromTemplateSelected = cvtNehubaConfigToNavigationObj(selectTemplate?.nehubaConfig?.dataset?.initialNgState)
-    return {
-      ...prevState,
-      templateSelected : selectTemplate,
-      parcellationSelected : parcellation,
-      // taken care of by effect.ts
-      // regionsSelected : [],
-
-      // taken care of by effect.ts
-      // landmarksSelected : [],
-      navigation : navigation || navigationFromTemplateSelected,
-    }
-  }
-  case FETCHED_TEMPLATE : {
-    return {
-      ...prevState,
-      fetchedTemplates: prevState.fetchedTemplates.concat(action.fetchedTemplate),
-    }
-  }
-  case viewerStateChangeNavigation.type:
-  case CHANGE_NAVIGATION : {
-    return {
-      ...prevState,
-      navigation : action.navigation,
-    }
-  }
-  case viewerStateSelectParcellation.type:
-  case SELECT_PARCELLATION : {
-    const { selectParcellation } = action
-    return {
-      ...prevState,
-      parcellationSelected: selectParcellation,
-      // taken care of by effect.ts
-      // regionsSelected: []
-    }
-  }
-  case viewerStateSetSelectedRegions.type:
-  case SELECT_REGIONS: {
-    const { selectRegions } = action
-    return {
-      ...prevState,
-      regionsSelected: selectRegions,
-    }
-  }
-  case viewerStateSetViewerMode.type: {
-    return {
-      ...prevState,
-      viewerMode: action.payload
-    }
-  }
-  case DESELECT_LANDMARKS : {
-    return {
-      ...prevState,
-      landmarksSelected : prevState.landmarksSelected.filter(lm => action.deselectLandmarks.findIndex(dLm => dLm.name === lm.name) < 0),
-    }
-  }
-  case actionSelectLandmarks.type: {
-    return {
-      ...prevState,
-      landmarksSelected : action.landmarks,
-    }
-  }
-  case USER_LANDMARKS : {
-    return {
-      ...prevState,
-      userLandmarks: action.landmarks,
-    }
-  }
-  /**
-     * TODO
-     * duplicated with ngViewerState.layers ?
-     */
-  case viewerStateNehubaLayerchanged.type: {
-    const viewer = getViewer()
-    if (!viewer) {
-      return {
-        ...prevState,
-        loadedNgLayers: [],
-      }
-    } else {
-      return {
-        ...prevState,
-        loadedNgLayers: (viewer.layerManager.managedLayers as any[]).map(obj => ({
-          name : obj.name,
-          type : obj.initialSpecification.type,
-          source : obj.sourceUrl,
-          visible : obj.visible,
-        }) as INgLayerInterface),
-      }
-    }
-  }
-  case GENERAL_ACTION_TYPES.APPLY_STATE: {
-    const { viewerState } = (action as any).state
-    return viewerState
-  }
-  case viewerStateSetConnectivityRegion.type:
-  case SET_CONNECTIVITY_REGION:
-    return {
-      ...prevState,
-      connectivityRegion: action.connectivityRegion,
-    }
-  case CLEAR_CONNECTIVITY_REGION:
-    return {
-      ...prevState,
-      connectivityRegion: '',
-    }
-  case SET_OVERWRITTEN_COLOR_MAP:
-    return {
-      ...prevState,
-      overwrittenColorMap: action.payload || '',
-    }
-  case actionViewerStateSelectFeature.type:
-    return {
-      ...prevState,
-      featureSelected: (action as any).feature
-    }
-  default :
-    return prevState
-  }
-}
-
-// must export a named function for aot compilation
-// see https://github.com/angular/angular/issues/15587
-// https://github.com/amcdnl/ngrx-actions/issues/23
-// or just google for:
-//
-// angular function expressions are not supported in decorators
-
-const defaultStateStore = getStateStore()
-
-export function stateStore(state, action) {
-  return defaultStateStore(state, action)
-}
-
-export const FETCHED_TEMPLATE = 'FETCHED_TEMPLATE'
-export const CHANGE_NAVIGATION = viewerStateChangeNavigation.type
-
-export const SELECT_PARCELLATION = viewerStateSelectParcellation.type
-
-export const DESELECT_REGIONS = `DESELECT_REGIONS`
-export const SELECT_REGIONS_WITH_ID = viewerStateSelectRegionWithIdDeprecated.type
-// export const SET_VIEWER_MODE = viewerStateSetViewerMode.type
-export const SELECT_LANDMARKS = `SELECT_LANDMARKS`
-export const SELECT_REGIONS = viewerStateSetSelectedRegions.type
-export const DESELECT_LANDMARKS = `DESELECT_LANDMARKS`
-export const USER_LANDMARKS = `USER_LANDMARKS`
-
-export const SET_CONNECTIVITY_REGION = `SET_CONNECTIVITY_REGION`
-export const CLEAR_CONNECTIVITY_REGION = `CLEAR_CONNECTIVITY_REGION`
-export const SET_OVERWRITTEN_COLOR_MAP = `SET_OVERWRITTEN_COLOR_MAP`
-export const CLEAR_STANDALONE_VOLUMES = `CLEAR_STANDALONE_VOLUMES`
-
-@Injectable({
-  providedIn: 'root',
-})
-
-export class ViewerStateUseEffect {
-  constructor(
-    private actions$: Actions,
-    private store$: Store<IavRootStoreInterface>,
-    private log: LoggingService,
-  ) {
-
-    const viewerState$ = this.store$.pipe(
-      select('viewerState'),
-      shareReplay(1)
-    )
-    this.currentLandmarks$ = this.store$.pipe(
-      select(viewerStateCustomLandmarkSelector),
-      shareReplay(1),
-    )
-
-    this.removeUserLandmarks = this.actions$.pipe(
-      ofType(ACTION_TYPES.REMOVE_USER_LANDMARKS),
-      withLatestFrom(this.currentLandmarks$),
-      map(([action, currentLandmarks]) => {
-        const { landmarkIds } = (action as ActionInterface).payload
-        for ( const rmId of landmarkIds ) {
-          const idx = currentLandmarks.findIndex(({ id }) => id === rmId)
-          if (idx < 0) { this.log.warn(`remove userlandmark with id ${rmId} does not exist`) }
-        }
-        const removeSet = new Set(landmarkIds)
-        return {
-          type: USER_LANDMARKS,
-          landmarks: currentLandmarks.filter(({ id }) => !removeSet.has(id)),
-        }
-      }),
-    )
-
-    this.addUserLandmarks$ = this.actions$.pipe(
-      ofType(viewerStateAddUserLandmarks.type),
-      withLatestFrom(this.currentLandmarks$),
-      map(([action, currentLandmarks]) => {
-        const { landmarks } = action as ActionInterface
-        const landmarkMap = new Map()
-        for (const landmark of currentLandmarks) {
-          const { id } = landmark
-          landmarkMap.set(id, landmark)
-        }
-        for (const landmark of landmarks) {
-          const { id } = landmark
-          if (landmarkMap.has(id)) {
-            this.log.warn(`Attempting to add a landmark that already exists, id: ${id}`)
-          } else {
-            landmarkMap.set(id, landmark)
-          }
-        }
-        const userLandmarks = Array.from(landmarkMap).map(([_id, landmark]) => landmark)
-        return {
-          type: USER_LANDMARKS,
-          landmarks: userLandmarks,
-        }
-      }),
-    )
-
-    this.mouseoverUserLandmarks = this.actions$.pipe(
-      ofType(viewerStateMouseOverCustomLandmarkInPerspectiveView.type),
-      withLatestFrom(this.currentLandmarks$),
-      map(([ action, currentLandmarks ]) => {
-        const { payload } = action as any
-        const { label } = payload
-        if (!label) {
-          return viewerStateMouseOverCustomLandmark({
-            payload: {
-              userLandmark: null
-            }
-          })
-        }
-
-        const idx = Number(label.replace('label=', ''))
-        if (isNaN(idx)) {
-          this.log.warn(`Landmark index could not be parsed as a number: ${idx}`)
-          return viewerStateMouseOverCustomLandmark({
-            payload: { userLandmark: null }
-          })
-        }
-        return viewerStateMouseOverCustomLandmark({
-          payload: {
-            userLandmark: currentLandmarks[idx]
-          }
-        })
-      }),
-
-    )
-
-    const doubleClickOnViewer$ = this.actions$.pipe(
-      ofType(ACTION_TYPES.DOUBLE_CLICK_ON_VIEWER),
-      map(action => {
-        const { payload } = action as any
-        const { segments, landmark, userLandmark } = payload
-        return { segments, landmark, userLandmark }
-      }),
-      shareReplay(1),
-    )
-
-    this.doubleClickOnViewerToggleRegions$ = doubleClickOnViewer$.pipe(
-      filter(({ segments }) => segments && segments.length > 0),
-      withLatestFrom(viewerState$.pipe(
-        select('regionsSelected'),
-        distinctUntilChanged(),
-        startWith([]),
-      )),
-      map(([{ segments }, regionsSelected]) => {
-        const selectedSet = new Set<string>(regionsSelected.map(serialiseParcellationRegion))
-        const toggleArr = segments.map(({ segment, layer }) => serialiseParcellationRegion({ ngId: layer.name, ...segment }))
-
-        const deleteFlag = toggleArr.some(id => selectedSet.has(id))
-
-        for (const id of toggleArr) {
-          if (deleteFlag) { selectedSet.delete(id) } else { selectedSet.add(id) }
-        }
-
-        return viewerStateSelectRegionWithIdDeprecated({
-          selectRegionIds: [...selectedSet],
-        })
-      }),
-    )
-
-    this.doubleClickOnViewerToggleLandmark$ = doubleClickOnViewer$.pipe(
-      filter(({ landmark }) => !!landmark),
-      withLatestFrom(viewerState$.pipe(
-        select('landmarksSelected'),
-        startWith([]),
-      )),
-      map(([{ landmark }, selectedSpatialDatas]) => {
-
-        const selectedIdx = selectedSpatialDatas.findIndex(data => data.name === landmark.name)
-
-        const newSelectedSpatialDatas = selectedIdx >= 0
-          ? selectedSpatialDatas.filter((_, idx) => idx !== selectedIdx)
-          : selectedSpatialDatas.concat(landmark)
-
-        return actionSelectLandmarks({
-          landmarks: newSelectedSpatialDatas,
-        })
-      }),
-    )
-
-    this.doubleClickOnViewerToogleUserLandmark$ = doubleClickOnViewer$.pipe(
-      filter(({ userLandmark }) => userLandmark),
-    )
-
-    this.onStandAloneVolumesExistCloseMatDrawer$ = viewerState$.pipe(
-      select('standaloneVolumes'),
-      filter(v => v && Array.isArray(v) && v.length > 0),
-      mapTo({
-        type: CLOSE_SIDE_PANEL
-      })
-    )
-  }
-
-  private currentLandmarks$: Observable<any[]>
-
-  @Effect()
-  public onStandAloneVolumesExistCloseMatDrawer$: Observable<any>
-
-  @Effect()
-  public mouseoverUserLandmarks: Observable<any>
-
-  @Effect()
-  public removeUserLandmarks: Observable<any>
-
-  @Effect()
-  public addUserLandmarks$: Observable<any>
-
-  @Effect()
-  public doubleClickOnViewerToggleRegions$: Observable<any>
-
-  @Effect()
-  public doubleClickOnViewerToggleLandmark$: Observable<any>
-
-  // @Effect()
-  public doubleClickOnViewerToogleUserLandmark$: Observable<any>
-}
-
-const ACTION_TYPES = {
-  REMOVE_USER_LANDMARKS: viewreStateRemoveUserLandmarks.type,
-
-  SINGLE_CLICK_ON_VIEWER: 'SINGLE_CLICK_ON_VIEWER',
-  DOUBLE_CLICK_ON_VIEWER: viewerStateDblClickOnViewer.type
-}
-
-export const VIEWERSTATE_ACTION_TYPES = ACTION_TYPES
diff --git a/src/services/state/viewerState/actions.ts b/src/services/state/viewerState/actions.ts
index 46f6c1e47c0af113ffe5f6c6f61cb1fe02416e8e..0157c15f83ad1cb8a1fcf84302db772d883a98f0 100644
--- a/src/services/state/viewerState/actions.ts
+++ b/src/services/state/viewerState/actions.ts
@@ -1,117 +1,20 @@
 import { createAction, props } from "@ngrx/store"
-import { IRegion } from './constants'
-import { FeatureResponse } from "src/atlasComponents/sapi"
-
-export const viewerStateNewViewer = createAction(
-  `[viewerState] newViewer`,
-  props<{
-    selectTemplate: any
-    selectParcellation: any
-    navigation?: any
-  }>()
-)
-
-export const viewerStateSetSelectedRegionsWithIds = createAction(
-  `[viewerState] setSelectedRegionsWithIds`,
-  props<{ selectRegionIds: string[] }>()
-)
-
-export const viewerStateSetSelectedRegions = createAction(
-  '[viewerState] setSelectedRegions',
-  props<{ selectRegions: IRegion[] }>()
-)
-
-export const viewerStateSetConnectivityRegion = createAction(
-  `[viewerState] setConnectivityRegion`,
-  props<{ connectivityRegion: any }>()
-)
-
-export const viewerStateNehubaLayerchanged = createAction(
-  `[viewerState] nehubaLayerChanged`,
-)
 
 export const viewerStateNavigateToRegion = createAction(
   `[viewerState] navigateToRegion`,
   props<{ payload: { region: any } }>()
 )
 
-export const viewerStateToggleRegionSelect = createAction(
-  `[viewerState] toggleRegionSelect`,
-  props<{ payload: { region: any } }>()
-)
-
-export const viewerStateSetFetchedAtlases = createAction(
-  '[viewerState] setFetchedatlases',
-  props<{ fetchedAtlases: any[] }>()
-)
-
-export const viewerStateSelectAtlas = createAction(
-  `[viewerState] selectAtlas`,
-  props<{
-    atlas: {
-      ['@id']: string
-      template?: {
-        ['@id']: string
-      }
-    }
-  }>()
-)
-
-export const viewerStateHelperSelectParcellationWithId = createAction(
-  `[viewerStateHelper] selectParcellationWithId`,
-  props<{ payload: { ['@id']: string } }>()
-)
-
-export const viewerStateSelectParcellation = createAction(
-  `[viewerState] selectParcellation`,
-  props<{ selectParcellation: any }>()
-)
-
-export const viewerStateSelectTemplateWithName = createAction(
-  `[viewerState] selectTemplateWithName`,
-  props<{ payload: { name: string } }>()
-)
-
 export const viewerStateSelectTemplateWithId = createAction(
   `[viewerState] selectTemplateWithId`,
   props<{ payload: { ['@id']: string }, config?: { selectParcellation: { ['@id']: string } } }>()
 )
 
-export const viewerStateToggleLayer = createAction(
-  `[viewerState] toggleLayer`,
-  props<{ payload: { ['@id']: string }  }>()
-)
-
-export const viewerStateRemoveAdditionalLayer = createAction(
-  `[viewerState] removeAdditionalLayer`,
-  props<{ payload?: { ['@id']: string } }>()
-)
-
-export const viewerStateSelectRegionWithIdDeprecated = createAction(
-  `[viewerState] [deprecated] selectRegionsWithId`,
-  props<{ selectRegionIds: string[] }>()
-)
-
-export const viewerStateSetViewerMode = createAction(
-  `[viewerState] setViewerMode`,
-  props<{payload: string}>()
-)
-
-export const viewerStateDblClickOnViewer = createAction(
-  `[viewerState] dblClickOnViewer`,
-  props<{ payload: { annotation: any, segments: any, landmark: any, userLandmark: any } }>()
-)
-
 export const viewerStateAddUserLandmarks = createAction(
   `[viewerState] addUserlandmark,`,
   props<{ landmarks: any[] }>()
 )
 
-export const viewreStateRemoveUserLandmarks = createAction(
-  `[viewerState] removeUserLandmarks`,
-  props<{ payload: { landmarkIds: string[] } }>()
-)
-
 export const viewerStateMouseOverCustomLandmark = createAction(
   '[viewerState] mouseOverCustomLandmark',
   props<{ payload: { userLandmark: any } }>()
@@ -122,34 +25,7 @@ export const viewerStateMouseOverCustomLandmarkInPerspectiveView = createAction(
   props<{ payload: { label: string } }>()
 )
 
-export const viewerStateChangeNavigation = createAction(
-  `[viewerState] changeNavigation`,
-  props<{ navigation: any }>()
-)
-
 export const actionSetMobileUi = createAction(
   `[viewerState] setMobileUi`,
   props<{ payload: { useMobileUI: boolean } }>()
 )
-
-export const actionAddToRegionsSelectionWithIds = createAction(
-  `[viewerState] addToRegionSelectionWithIds`,
-  props<{
-    selectRegionIds: string[]
-  }>()
-)
-
-export const actionSelectLandmarks = createAction(
-  `[viewerState] selectLandmarks`,
-  props<{
-    landmarks: any[]
-  }>()
-)
-
-
-export const actionViewerStateSelectFeature = createAction(
-  `[viewerState] selectFeature`,
-  props<{
-    feature: FeatureResponse
-  }>()
-)
diff --git a/src/services/state/viewerState/selectors.spec.ts b/src/services/state/viewerState/selectors.spec.ts
index 6f13c133919aa50774b6e72eb15f2f872e1dfcc8..e5916b75e671cdb281508c796106e9de484ff7f3 100644
--- a/src/services/state/viewerState/selectors.spec.ts
+++ b/src/services/state/viewerState/selectors.spec.ts
@@ -3,6 +3,10 @@ import {
   viewerStateAtlasParcellationSelector,
   viewerStateAtlasLatestParcellationSelector,
   viewerStateParcVersionSelector,
+  selectorSelectedATP,
+  viewerStateGetSelectedAtlas,
+  viewerStateSelectedTemplateSelector,
+  viewerStateSelectedParcellationSelector,
 } from './selectors'
 
 
@@ -153,95 +157,133 @@ const fetchedTemplates = [
 ]
 
 describe('viewerState/selector.ts', () => {
-  describe('> viewerStateGetOverlayingAdditionalParcellations', () => {
-    describe('> if atlas has no basic layer', () => {
-      it('> should return empty array', () => {
-
-        const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
-          fetchedAtlases,
-          selectedAtlasId: atlas2['@id']
-        }, {
-          parcellationSelected: tmpl2.parcellations[0]
-        })
+  // describe('> viewerStateGetOverlayingAdditionalParcellations', () => {
+  //   describe('> if atlas has no basic layer', () => {
+  //     it('> should return empty array', () => {
+
+  //       const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
+  //         fetchedAtlases,
+  //         selectedAtlasId: atlas2['@id']
+  //       }, {
+  //         parcellationSelected: tmpl2.parcellations[0]
+  //       })
         
-        expect(parcs).toEqual([])
-      })
-    })
+  //       expect(parcs).toEqual([])
+  //     })
+  //   })
 
-    describe('> if atlas has basic layer', () => {
-      describe('> if non basiclayer is selected', () => {
-        it('> should return non empty array', () => {
-          const parc = atlas1.parcellations.find(p => !p['baseLayer'])
-          const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
-            fetchedAtlases,
-            selectedAtlasId: atlas1['@id']
-          }, {
-            parcellationSelected: parc
-          })
-          expect(parcs.length).toEqual(1)
-          expect(parcs[0]['@id']).toEqual(parc['@id'])
-        })
-      })
+  //   describe('> if atlas has basic layer', () => {
+  //     describe('> if non basiclayer is selected', () => {
+  //       it('> should return non empty array', () => {
+  //         const parc = atlas1.parcellations.find(p => !p['baseLayer'])
+  //         const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
+  //           fetchedAtlases,
+  //           selectedAtlasId: atlas1['@id']
+  //         }, {
+  //           parcellationSelected: parc
+  //         })
+  //         expect(parcs.length).toEqual(1)
+  //         expect(parcs[0]['@id']).toEqual(parc['@id'])
+  //       })
+  //     })
 
-      describe('> if basic layer is selected', () => {
-        it('> should return empty array', () => {
-          const parc = atlas1.parcellations.find(p => !!p['baseLayer'])
-          const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
-            fetchedAtlases,
-            selectedAtlasId: atlas1['@id']
-          }, {
-            parcellationSelected: parc
-          })
-          expect(parcs.length).toEqual(0)
-        })
-      })
-    })
-  })
+  //     describe('> if basic layer is selected', () => {
+  //       it('> should return empty array', () => {
+  //         const parc = atlas1.parcellations.find(p => !!p['baseLayer'])
+  //         const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
+  //           fetchedAtlases,
+  //           selectedAtlasId: atlas1['@id']
+  //         }, {
+  //           parcellationSelected: parc
+  //         })
+  //         expect(parcs.length).toEqual(0)
+  //       })
+  //     })
+  //   })
+  // })
 
-  describe('> viewerStateAtlasParcellationSelector', () => {
-    const check = (atlasJson, templates) => {
+  // describe('> viewerStateAtlasParcellationSelector', () => {
+  //   const check = (atlasJson, templates) => {
 
-      const parcs = viewerStateAtlasParcellationSelector.projector({
-        fetchedAtlases,
-        selectedAtlasId: atlasJson['@id']
-      }, {
-        fetchedTemplates
-      })
-      const templateParcs = []
-      for (const tmpl of templates) {
-        templateParcs.push(...tmpl.parcellations)
-      }
-      for (const parc of parcs) {
-        const firstHalf = templateParcs.find(p => p['@id'] === parc['@id'])
-        const secondHalf = atlasJson.parcellations.find(p => p['@id'] === parc['@id'])
-        expect(firstHalf).toBeTruthy()
-        expect(secondHalf).toBeTruthy()
-        //TODO compare strict equality of firsthalf+secondhalf with parc
-      }
-    }
+  //     const parcs = viewerStateAtlasParcellationSelector.projector({
+  //       fetchedAtlases,
+  //       selectedAtlasId: atlasJson['@id']
+  //     }, {
+  //       fetchedTemplates
+  //     })
+  //     const templateParcs = []
+  //     for (const tmpl of templates) {
+  //       templateParcs.push(...tmpl.parcellations)
+  //     }
+  //     for (const parc of parcs) {
+  //       const firstHalf = templateParcs.find(p => p['@id'] === parc['@id'])
+  //       const secondHalf = atlasJson.parcellations.find(p => p['@id'] === parc['@id'])
+  //       expect(firstHalf).toBeTruthy()
+  //       expect(secondHalf).toBeTruthy()
+  //       //TODO compare strict equality of firsthalf+secondhalf with parc
+  //     }
+  //   }
 
-    it('> should work', () => {
-      check(atlas1, [tmpl1, tmpl2, tmpl2_2])
-      check(atlas2, [tmpl1, tmpl2, tmpl2_2])
-    })
-  })
+  //   it('> should work', () => {
+  //     check(atlas1, [tmpl1, tmpl2, tmpl2_2])
+  //     check(atlas2, [tmpl1, tmpl2, tmpl2_2])
+  //   })
+  // })
+
+  // describe('> viewerStateAtlasLatestParcellationSelector', () => {
+  //   it('> should only show 1 parc', () => {
+  //     const parcs = viewerStateAtlasLatestParcellationSelector.projector(atlas2.parcellations)
+  //     expect(parcs.length).toEqual(1)
+  //   })
+  // })
+
+  // describe('> viewerStateParcVersionSelector', () => {
+  //   it('> should work', () => {
+  //     const parcs = viewerStateParcVersionSelector.projector(atlas2.parcellations, {
+  //       parcellationSelected: atlas2.parcellations[0]
+  //     })
+  //     expect(parcs.length).toEqual(2)
+
+  //     expect(parcs[0]['@version']['@next']).toBeFalsy()
+  //     expect(parcs[parcs.length-1]['@version']['@previous']).toBeFalsy()
+  //   })
+  // })
 
-  describe('> viewerStateAtlasLatestParcellationSelector', () => {
-    it('> should only show 1 parc', () => {
-      const parcs = viewerStateAtlasLatestParcellationSelector.projector(atlas2.parcellations)
-      expect(parcs.length).toEqual(1)
+  describe("> viewerStateGetSelectedAtlas", () => {
+    it("> projects properly", () => {
+      const atlas1 = {
+        "@id": "atlas1"
+      }
+      const atlas2 = {
+        "@id": "atlas2"
+      }
+      const atlas3 = {
+        "@id": "atlas3"
+      }
+      const allAtlases = [ atlas1, atlas2, atlas3 ]
+      const result = viewerStateGetSelectedAtlas.projector({
+        fetchedAtlases: allAtlases,
+        overlayingAdditionalParcellations: [],
+        selectedAtlasId: atlas1["@id"]
+      })
+      expect(result).toEqual(atlas1 as any)
     })
   })
 
-  describe('> viewerStateParcVersionSelector', () => {
-    it('> should work', () => {
-      const parcs = viewerStateParcVersionSelector.projector(atlas2.parcellations, {
-        parcellationSelected: atlas2.parcellations[0]
-      })
-      expect(parcs.length).toEqual(2)
+  describe("> selectorSelectedATP", () => {
+    const mockAtlas = {
+      "@id": "mock atlas"
+    } as any
+    const mockTmpl = {
+      "@id": "mock Tmpl"
+    } as any
+    const mockParc = {
+      "@id": "mock Parc"
+    } as any
 
-      expect(parcs[0]['@version']['@next']).toBeFalsy()
-      expect(parcs[parcs.length-1]['@version']['@previous']).toBeFalsy()
+    it("> transforms the selectors properly", () => {
+      const result = selectorSelectedATP.projector(mockAtlas,mockTmpl,mockParc)
+      expect(result).toEqual({ atlas: mockAtlas, template: mockTmpl, parcellation: mockParc })
     })
   })
 })
\ No newline at end of file
diff --git a/src/services/state/viewerState/selectors.ts b/src/services/state/viewerState/selectors.ts
index bef013ae8bdb5dc70f05f01d39ce34c0c39b8463..c752e8aeae91104be3fd789cf7829894361ff9e3 100644
--- a/src/services/state/viewerState/selectors.ts
+++ b/src/services/state/viewerState/selectors.ts
@@ -1,237 +1,188 @@
-import { createSelector } from "@ngrx/store"
-import { viewerStateHelperStoreName } from "../viewerState.store.helper"
-import { IViewerState } from "./type"
-
-export const viewerStateSelectedRegionsSelector = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['regionsSelected']
-)
-
-export const viewerStateCustomLandmarkSelector = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['userLandmarks']
-)
-
-const flattenFetchedTemplatesIntoParcellationsReducer = (acc, curr) => {
-  const parcelations = (curr['parcellations'] || []).map(p => {
-    return {
-      ...p,
-      useTheme: curr['useTheme']
-    }
-  })
-
-  return acc.concat( parcelations )
-}
-
-export const viewerStateFetchedTemplatesSelector = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['fetchedTemplates']
-)
-
-export const viewerStateSelectedTemplateSelector = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState?.['templateSelected']
-)
-
-export const viewerStateSelectorStandaloneVolumes = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['standaloneVolumes']
-)
-
-export const viewerStateSelectorFeatureSelector = createSelector(
-  (state: any) => state.viewerState as IViewerState,
-  viewerState => viewerState.featureSelected
-)
-
-/**
- * viewerStateSelectedTemplateSelector may have it navigation mutated to allow for initiliasation of viewer at the correct navigation
- * in some circumstances, it may be required to get the original navigation object
- */
-export const viewerStateSelectedTemplatePureSelector = createSelector(
-  viewerStateFetchedTemplatesSelector,
-  viewerStateSelectedTemplateSelector,
-  (fetchedTemplates, selectedTemplate) => {
-    if (!selectedTemplate) return null
-    return fetchedTemplates.find(t => t['@id'] === selectedTemplate['@id'])
-  }
-)
-
-export const viewerStateSelectedParcellationSelector = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['parcellationSelected']
-)
-
-export const viewerStateNavigationStateSelector = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['navigation']
-)
-
-export const viewerStateAllRegionsFlattenedRegionSelector = createSelector(
-  viewerStateSelectedParcellationSelector,
-  parc => {
-    const returnArr = []
-    const processRegion = region => {
-      const { children, ...rest } = region
-      returnArr.push({ ...rest })
-      region.children && Array.isArray(region.children) && region.children.forEach(processRegion)
-    }
-    if (parc && parc.regions && Array.isArray(parc.regions)) {
-      parc.regions.forEach(processRegion)
-    }
-    return returnArr
-  }
-)
-
-export const viewerStateOverwrittenColorMapSelector = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['overwrittenColorMap']
-)
-
-export const viewerStateStandAloneVolumes = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['standaloneVolumes']
-)
-
-export const viewerStateSelectorNavigation = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['navigation']
-)
-
-export const viewerStateViewerModeSelector = createSelector(
-  state => state['viewerState'],
-  viewerState => viewerState['viewerMode']
-)
-
-export const viewerStateGetOverlayingAdditionalParcellations = createSelector(
-  state => state[viewerStateHelperStoreName],
-  state => state['viewerState'],
-  (viewerHelperState, viewerState ) => {
-    const { selectedAtlasId, fetchedAtlases } = viewerHelperState
-    const { parcellationSelected } = viewerState
-    const selectedAtlas = selectedAtlasId && fetchedAtlases.find(a => a['@id'] === selectedAtlasId)
-    const hasBaseLayer = selectedAtlas?.parcellations.find(p => p.baseLayer)
-    if (!hasBaseLayer) return []
-    const atlasLayer =  selectedAtlas?.parcellations.find(p => p['@id'] === (parcellationSelected && parcellationSelected['@id']))
-    const isBaseLayer = atlasLayer && atlasLayer.baseLayer
-    return (!!atlasLayer && !isBaseLayer) ? [{
-      ...(parcellationSelected || {} ),
-      ...atlasLayer
-    }] : []
-  }
-)
-
-export const viewerStateFetchedAtlasesSelector = createSelector(
-  state => state[viewerStateHelperStoreName],
-  helperState => helperState['fetchedAtlases']
-)
-
-export const viewerStateGetSelectedAtlas = createSelector(
-  state => state[viewerStateHelperStoreName],
-  helperState => {
-    if (!helperState) return null
-    const { selectedAtlasId, fetchedAtlases } = helperState
-    if (!selectedAtlasId) return null
-    return selectedAtlasId && fetchedAtlases.find(a => a['@id'] === selectedAtlasId)
-  }
-)
-
-export const viewerStateAtlasParcellationSelector = createSelector(
-  state => state[viewerStateHelperStoreName],
-  state => state['viewerState'],
-  (viewerHelperState, viewerState) => {
-    const { selectedAtlasId, fetchedAtlases } = viewerHelperState
-    const { fetchedTemplates } = viewerState
-
-    const allParcellations = fetchedTemplates.reduce(flattenFetchedTemplatesIntoParcellationsReducer, [])
-
-    const selectedAtlas = selectedAtlasId && fetchedAtlases.find(a => a['@id'] === selectedAtlasId)
-    const atlasLayers = selectedAtlas?.parcellations
-      .map(p => {
-        const otherHalfOfParc = allParcellations.find(parc => parc['@id'] === p['@id']) || {}
-        return {
-          ...p,
-          ...otherHalfOfParc,
-        }
-      })
-    return atlasLayers
-  }
-)
-
-export const viewerStateAtlasLatestParcellationSelector = createSelector(
-  viewerStateAtlasParcellationSelector,
-  parcs => (parcs && parcs.filter( p => !p['@version'] || !p['@version']['@next']) || [])
-)
-
-export const viewerStateParcVersionSelector = createSelector(
-  viewerStateAtlasParcellationSelector,
-  state => state['viewerState'],
-  (allAtlasParcellations, viewerState) => {
-    if (!viewerState || !viewerState.parcellationSelected) return []
-    const returnParc = []
-    const foundParc = allAtlasParcellations.find(p => p['@id'] === viewerState.parcellationSelected['@id'])
-    if (!foundParc) return []
-    returnParc.push(foundParc)
-    const traverseParc = parc => {
-      if (!parc) return []
-      if (!parc['@version']) return []
-      if (parc['@version']['@next']) {
-        const nextParc = allAtlasParcellations.find(p => p['@id'] === parc['@version']['@next'])
-        if (nextParc) {
-          const nextParcAlreadyIncluded = returnParc.find(p => p['@id'] === nextParc['@id'])
-          if (!nextParcAlreadyIncluded) {
-            returnParc.unshift(nextParc)
-            traverseParc(nextParc)
-          }
-        }
-      }
-
-      if (parc['@version']['@previous']) {
-        const previousParc = allAtlasParcellations.find(p => p['@id'] === parc['@version']['@previous'])
-        if (previousParc) {
-          const previousParcAlreadyIncluded = returnParc.find(p => p['@id'] === previousParc['@id'])
-          if (!previousParcAlreadyIncluded) {
-            returnParc.push(previousParc)
-            traverseParc(previousParc)
-          }
-        }
-      }
-    }
-    traverseParc(foundParc)
-    return returnParc
-  }
-)
-
-
-export const viewerStateSelectedTemplateFullInfoSelector = createSelector(
-  viewerStateGetSelectedAtlas,
-  viewerStateFetchedTemplatesSelector,
-  (selectedAtlas, fetchedTemplates) => {
-    if (!selectedAtlas) return null
-    const { templateSpaces } = selectedAtlas
-    return templateSpaces.map(templateSpace => {
-      const fullTemplateInfo = fetchedTemplates.find(t => t['@id'] === templateSpace['@id'])
-      return {
-        ...templateSpace,
-        ...(fullTemplateInfo || {}),
-        darktheme: (fullTemplateInfo || {}).useTheme === 'dark'
-      }
-    })
-  }
-)
-
-export const viewerStateContextedSelectedRegionsSelector = createSelector(
-  viewerStateSelectedRegionsSelector,
-  viewerStateGetSelectedAtlas,
-  viewerStateSelectedTemplatePureSelector,
-  viewerStateSelectedParcellationSelector,
-  (regions, atlas, template, parcellation) => regions.map(r => {
-    return {
-      ...r,
-      context: {
-        atlas,
-        template,
-        parcellation
-      }
-    }
-  })
-)
+// import { createSelector } from "@ngrx/store"
+// import { SapiAtlasModel, SapiParcellationModel, SapiSpaceModel } from "src/atlasComponents/sapi"
+// import { SapiRegionModel } from "src/atlasComponents/sapi/type"
+// import { viewerStateHelperStoreName, IViewerStateHelperStore } from "../viewerState.store.helper"
+// import { IViewerState } from "./type"
+
+// import {
+//   selectors as atlasSelectionSelectors
+// } from "src/state/atlasSelection"
+
+// const {
+//   selectedATP: selectorSelectedATP,
+//   selectedAtlas: viewerStateGetSelectedAtlas,
+//   selectedParcellation: viewerStateSelectedParcellationSelector,
+//   selectedTemplate: viewerStateSelectedTemplateSelector,
+// } = atlasSelectionSelectors
+
+
+// const viewerStateSelectedRegionsSelector = createSelector<any, any, SapiRegionModel[]>(
+//   state => state['viewerState'],
+//   viewerState => viewerState['regionsSelected']
+// )
+
+// const viewerStateCustomLandmarkSelector = createSelector(
+//   state => state['viewerState'],
+//   viewerState => viewerState['userLandmarks']
+// )
+
+// const flattenFetchedTemplatesIntoParcellationsReducer = (acc, curr) => {
+//   const parcelations = (curr['parcellations'] || []).map(p => {
+//     return {
+//       ...p,
+//       useTheme: curr['useTheme']
+//     }
+//   })
+
+//   return acc.concat( parcelations )
+// }
+
+// const viewerStateFetchedTemplatesSelector = createSelector(
+//   state => state['viewerState'],
+//   viewerState => viewerState['fetchedTemplates']
+// )
+
+// const viewerStateSelectorFeatureSelector = createSelector(
+//   (state: any) => state.viewerState as IViewerState,
+//   viewerState => viewerState.featureSelected
+// )
+
+// /**
+//  * viewerStateSelectedTemplateSelector may have it navigation mutated to allow for initiliasation of viewer at the correct navigation
+//  * in some circumstances, it may be required to get the original navigation object
+//  */
+// const viewerStateSelectedTemplatePureSelector = createSelector(
+//   viewerStateFetchedTemplatesSelector,
+//   viewerStateSelectedTemplateSelector,
+//   (fetchedTemplates, selectedTemplate) => {
+//     if (!selectedTemplate) return null
+//     return fetchedTemplates.find(t => t['@id'] === selectedTemplate['@id'])
+//   }
+// )
+
+// const viewerStateNavigationStateSelector = createSelector(
+//   state => state['viewerState'],
+//   viewerState => viewerState['navigation']
+// )
+
+// const viewerStateOverwrittenColorMapSelector = createSelector(
+//   state => state['viewerState'],
+//   viewerState => viewerState['overwrittenColorMap']
+// )
+
+// const viewerStateSelectorNavigation = createSelector(
+//   state => state['viewerState'],
+//   viewerState => viewerState['navigation']
+// )
+
+// const viewerStateViewerModeSelector = createSelector(
+//   state => state['viewerState'],
+//   viewerState => viewerState['viewerMode']
+// )
+
+// const viewerStateGetOverlayingAdditionalParcellations = createSelector(
+//   state => state[viewerStateHelperStoreName],
+//   state => state['viewerState'],
+//   (viewerHelperState, viewerState ) => {
+//     const { selectedAtlasId, fetchedAtlases } = viewerHelperState
+//     const { parcellationSelected } = viewerState
+//     const selectedAtlas = selectedAtlasId && fetchedAtlases.find(a => a['@id'] === selectedAtlasId)
+//     const hasBaseLayer = selectedAtlas?.parcellations.find(p => p.baseLayer)
+//     if (!hasBaseLayer) return []
+//     const atlasLayer =  selectedAtlas?.parcellations.find(p => p['@id'] === (parcellationSelected && parcellationSelected['@id']))
+//     const isBaseLayer = atlasLayer && atlasLayer.baseLayer
+//     return (!!atlasLayer && !isBaseLayer) ? [{
+//       ...(parcellationSelected || {} ),
+//       ...atlasLayer
+//     }] : []
+//   }
+// )
+
+// const viewerStateFetchedAtlasesSelector = createSelector<any, any, SapiAtlasModel[]>(
+//   state => state[viewerStateHelperStoreName],
+//   helperState => helperState['fetchedAtlases']
+// )
+
+
+// const viewerStateAtlasParcellationSelector = createSelector(
+//   state => state[viewerStateHelperStoreName],
+//   state => state['viewerState'],
+//   (viewerHelperState, viewerState) => {
+//     const { selectedAtlasId, fetchedAtlases } = viewerHelperState
+//     const { fetchedTemplates } = viewerState
+
+//     const allParcellations = fetchedTemplates.reduce(flattenFetchedTemplatesIntoParcellationsReducer, [])
+
+//     const selectedAtlas = selectedAtlasId && fetchedAtlases.find(a => a['@id'] === selectedAtlasId)
+//     const atlasLayers = selectedAtlas?.parcellations
+//       .map(p => {
+//         const otherHalfOfParc = allParcellations.find(parc => parc['@id'] === p['@id']) || {}
+//         return {
+//           ...p,
+//           ...otherHalfOfParc,
+//         }
+//       })
+//     return atlasLayers
+//   }
+// )
+
+// const viewerStateAtlasLatestParcellationSelector = createSelector(
+//   viewerStateAtlasParcellationSelector,
+//   parcs => (parcs && parcs.filter( p => !p['@version'] || !p['@version']['@next']) || [])
+// )
+
+// const viewerStateParcVersionSelector = createSelector(
+//   viewerStateAtlasParcellationSelector,
+//   state => state['viewerState'],
+//   (allAtlasParcellations, viewerState) => {
+//     if (!viewerState || !viewerState.parcellationSelected) return []
+//     const returnParc = []
+//     const foundParc = allAtlasParcellations.find(p => p['@id'] === viewerState.parcellationSelected['@id'])
+//     if (!foundParc) return []
+//     returnParc.push(foundParc)
+//     const traverseParc = parc => {
+//       if (!parc) return []
+//       if (!parc['@version']) return []
+//       if (parc['@version']['@next']) {
+//         const nextParc = allAtlasParcellations.find(p => p['@id'] === parc['@version']['@next'])
+//         if (nextParc) {
+//           const nextParcAlreadyIncluded = returnParc.find(p => p['@id'] === nextParc['@id'])
+//           if (!nextParcAlreadyIncluded) {
+//             returnParc.unshift(nextParc)
+//             traverseParc(nextParc)
+//           }
+//         }
+//       }
+
+//       if (parc['@version']['@previous']) {
+//         const previousParc = allAtlasParcellations.find(p => p['@id'] === parc['@version']['@previous'])
+//         if (previousParc) {
+//           const previousParcAlreadyIncluded = returnParc.find(p => p['@id'] === previousParc['@id'])
+//           if (!previousParcAlreadyIncluded) {
+//             returnParc.push(previousParc)
+//             traverseParc(previousParc)
+//           }
+//         }
+//       }
+//     }
+//     traverseParc(foundParc)
+//     return returnParc
+//   }
+// )
+
+// const viewerStateContextedSelectedRegionsSelector = createSelector(
+//   viewerStateSelectedRegionsSelector,
+//   viewerStateGetSelectedAtlas,
+//   viewerStateSelectedTemplatePureSelector,
+//   viewerStateSelectedParcellationSelector,
+//   (regions, atlas, template, parcellation) => regions.map(r => {
+//     return {
+//       ...r,
+//       context: {
+//         atlas,
+//         template,
+//         parcellation
+//       }
+//     }
+//   })
+// )
diff --git a/src/services/stateStore.service.ts b/src/services/stateStore.service.ts
index 9169175790cd539fe2ffe400da0f772216df064c..558823d1ba54dced97da93a2a6c251833999bfda 100644
--- a/src/services/stateStore.service.ts
+++ b/src/services/stateStore.service.ts
@@ -1,9 +1,5 @@
 import { filter } from 'rxjs/operators';
 
-export {
-  recursiveFindRegionWithLabelIndexId
-} from 'src/util/fn'
-
 export { getNgIds } from 'src/util/fn'
 
 import {
@@ -12,11 +8,6 @@ import {
   StateInterface as NgViewerStateInterface,
   stateStore as ngViewerState,
 } from './state/ngViewerState.store'
-import {
-  defaultState as pluginDefaultState,
-  StateInterface as PluginStateInterface,
-  stateStore as pluginState,
-} from './state/pluginState.store'
 import {
   ActionInterface as UIActionInterface,
   defaultState as uiDefaultState,
@@ -34,28 +25,14 @@ import {
   StateInterface as ViewerConfigStateInterface,
   stateStore as viewerConfigState,
 } from './state/viewerConfig.store'
-import {
-  ActionInterface as ViewerActionInterface,
-  defaultViewerState,
-  IViewerState,
-  stateStore as viewerState,
-} from './state/viewerState.store'
-
-import { 
-  defaultState as defaultViewerHelperState,
-  viewerStateHelperStoreName
-} from './state/viewerState.store.helper'
-
-export { pluginState }
+
+
 export { viewerConfigState }
 export { NgViewerStateInterface, NgViewerActionInterface, ngViewerState }
-export { IViewerState, ViewerActionInterface, viewerState }
 export { IUiState, UIActionInterface, uiState }
 export { userConfigState,  USER_CONFIG_ACTION_TYPES}
 
-export { CHANGE_NAVIGATION, DESELECT_LANDMARKS, FETCHED_TEMPLATE, SELECT_PARCELLATION, SELECT_REGIONS, USER_LANDMARKS } from './state/viewerState.store'
-export { IDataEntry, IParcellationRegion, FETCHED_DATAENTRIES, FETCHED_SPATIAL_DATA, ILandmark, IOtherLandmarkGeometry, IPlaneLandmarkGeometry, IPointLandmarkGeometry, IProperty, IPublication, IReferenceSpace, IFile, IFileSupplementData } from './state/dataStore.store'
-export { CLOSE_SIDE_PANEL, MOUSE_OVER_SEGMENT, OPEN_SIDE_PANEL, COLLAPSE_SIDE_PANEL_CURRENT_VIEW, EXPAND_SIDE_PANEL_CURRENT_VIEW } from './state/uiState.store'
+export { MOUSE_OVER_SEGMENT, OPEN_SIDE_PANEL, COLLAPSE_SIDE_PANEL_CURRENT_VIEW, EXPAND_SIDE_PANEL_CURRENT_VIEW } from './state/uiState.store'
 export { UserConfigStateUseEffect } from './state/userConfigState.store'
 
 export { GENERAL_ACTION_TYPES, generalActionError } from './stateStore.helper'
@@ -140,22 +117,17 @@ export function isDefined(obj) {
 }
 
 export interface IavRootStoreInterface {
-  pluginState: PluginStateInterface
   viewerConfigState: ViewerConfigStateInterface
   ngViewerState: NgViewerStateInterface
-  viewerState: IViewerState
   dataStore: any
   uiState: IUiState
   userConfigState: UserConfigStateInterface
 }
 
 export const defaultRootState: any = {
-  pluginState: pluginDefaultState,
   dataStore: {},
   ngViewerState: ngViewerDefaultState,
   uiState: uiDefaultState,
   userConfigState: userConfigDefaultState,
   viewerConfigState: viewerConfigDefaultState,
-  viewerState: defaultViewerState,
-  [viewerStateHelperStoreName]: defaultViewerHelperState
 }
diff --git a/src/state/actions.ts b/src/state/actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2465c644ab5cd842e2e9f9f9537b10c1a51f155b
--- /dev/null
+++ b/src/state/actions.ts
@@ -0,0 +1,13 @@
+import { createAction, props } from "@ngrx/store";
+import { nameSpace } from "./const"
+
+const generalActionError = createAction(
+  `${nameSpace} generalActionError`,
+  props<{
+    message: string
+  }>()
+)
+
+export const actions = {
+  generalActionError
+}
diff --git a/src/state/annotations/actions.ts b/src/state/annotations/actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..da4ad8edeb6f86d3f80a5d8d3a310d56dc353428
--- /dev/null
+++ b/src/state/annotations/actions.ts
@@ -0,0 +1,19 @@
+import { createAction, props } from "@ngrx/store"
+import { nameSpace } from "./const"
+import { Annotation } from "./store"
+
+const clearAllAnnotations = createAction(
+  `${nameSpace} clearAllAnnotations`
+)
+
+const rmAnnotations = createAction(
+  `${nameSpace} rmAnnotation`,
+  props<{
+    annotations: Annotation[]
+  }>()
+)
+
+export const actions = {
+  clearAllAnnotations,
+  rmAnnotations,
+}
diff --git a/src/state/annotations/const.ts b/src/state/annotations/const.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0ca3a95036366f410633ade16db8d2a4e1665064
--- /dev/null
+++ b/src/state/annotations/const.ts
@@ -0,0 +1 @@
+export const nameSpace = `[state.annotations]`
\ No newline at end of file
diff --git a/src/state/annotations/index.ts b/src/state/annotations/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e044bea3dee02127fed851a564f49d95d3be6f26
--- /dev/null
+++ b/src/state/annotations/index.ts
@@ -0,0 +1,4 @@
+export { actions } from "./actions"
+export { Annotation, AnnotationState, reducer } from "./store"
+export { nameSpace } from "./const"
+export * as selectors from "./selectors"
\ No newline at end of file
diff --git a/src/state/annotations/selectors.ts b/src/state/annotations/selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..abbb3444f4f659714226c63ed2e60f4d796a5489
--- /dev/null
+++ b/src/state/annotations/selectors.ts
@@ -0,0 +1,10 @@
+import { createSelector } from "@ngrx/store"
+import { nameSpace } from "./const"
+import { Annotation, AnnotationState } from "./store"
+
+const selectStore = state => state[nameSpace] as AnnotationState
+
+export const annotations = createSelector(
+  selectStore,
+  state => state.annotations
+)
diff --git a/src/state/annotations/store.ts b/src/state/annotations/store.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6278ac4e6520ca06fc0ce4daf55c019685e22ed6
--- /dev/null
+++ b/src/state/annotations/store.ts
@@ -0,0 +1,21 @@
+import { createReducer } from "@ngrx/store"
+
+export type Annotation = {
+  "@id": string
+}
+
+export type AnnotationState = {
+  annotations: Annotation[]
+}
+
+const defaultState: AnnotationState = {
+  annotations: []
+}
+
+const reducer = createReducer(
+  defaultState
+)
+
+export {
+  reducer
+}
diff --git a/src/state/atlasAppearance/action.ts b/src/state/atlasAppearance/action.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d9065e07c2871b118ceb9a2bfd7d4d11eb488d87
--- /dev/null
+++ b/src/state/atlasAppearance/action.ts
@@ -0,0 +1,9 @@
+import { createAction, props } from "@ngrx/store";
+import { nameSpace } from "./const"
+
+export const overwriteColorMap = createAction(
+  `${nameSpace} overwriteColorMap`,
+  props<{
+    colormap: Record<string, number[]>
+  }>()
+)
diff --git a/src/state/atlasAppearance/const.ts b/src/state/atlasAppearance/const.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ee9d2e45f3c36217015b6c2a18e7e6cd4721ea9e
--- /dev/null
+++ b/src/state/atlasAppearance/const.ts
@@ -0,0 +1 @@
+export const nameSpace = `[state.atlasAppearance]`
\ No newline at end of file
diff --git a/src/state/atlasAppearance/index.ts b/src/state/atlasAppearance/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cf777e1fef5bcd30e900b26d381d0f0851cb441c
--- /dev/null
+++ b/src/state/atlasAppearance/index.ts
@@ -0,0 +1,3 @@
+export * as actions from "./action"
+export * as selectors from "./selector"
+export { reducer } from "./store"
\ No newline at end of file
diff --git a/src/state/atlasAppearance/selector.ts b/src/state/atlasAppearance/selector.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c43c619782f4d9e68eef4312269f0774e008c642
--- /dev/null
+++ b/src/state/atlasAppearance/selector.ts
@@ -0,0 +1,10 @@
+import { createSelector } from "@ngrx/store"
+import { nameSpace } from "./const"
+import { AtlasAppearanceStore } from "./store"
+
+const selectStore = state => state[nameSpace] as AtlasAppearanceStore
+
+export const getOverwrittenColormap = createSelector(
+  selectStore,
+  state => state.overwrittenColormap
+)
\ No newline at end of file
diff --git a/src/state/atlasAppearance/store.ts b/src/state/atlasAppearance/store.ts
new file mode 100644
index 0000000000000000000000000000000000000000..817603c934596095de985e912183360f9427efca
--- /dev/null
+++ b/src/state/atlasAppearance/store.ts
@@ -0,0 +1,23 @@
+import { createReducer, on } from "@ngrx/store"
+import * as actions from "./action"
+
+export type AtlasAppearanceStore = {
+  overwrittenColormap: Record<string, number[]>
+}
+
+const defaultState: AtlasAppearanceStore = {
+  overwrittenColormap: null
+}
+
+export const reducer = createReducer(
+  defaultState,
+  on(
+    actions.overwriteColorMap,
+    (state, { colormap }) => {
+      return {
+        ...state,
+        overwrittenColormap: colormap
+      }
+    }
+  )
+)
diff --git a/src/state/atlasSelection/actions.ts b/src/state/atlasSelection/actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7d114fa5cd3a2acb7811f3d8d08c594e9c0d5164
--- /dev/null
+++ b/src/state/atlasSelection/actions.ts
@@ -0,0 +1,127 @@
+import { createAction, props } from "@ngrx/store";
+import { SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
+import { nameSpace, ViewerMode } from "./const"
+
+export const selectAtlas = createAction(
+  `${nameSpace} selectAtlas`,
+  props<{
+    atlas: SapiAtlasModel
+  }>()
+)
+
+export const selectTemplate = createAction(
+  `${nameSpace} selectTemplate`,
+  props<{
+    template: SapiSpaceModel
+  }>()
+)
+
+export const selectParcellation = createAction(
+  `${nameSpace} selectParcellation`,
+  props<{
+    parcellation: SapiParcellationModel
+  }>()
+)
+
+export const selectRegions = createAction(
+  `${nameSpace} selectRegions`,
+  props<{
+    regions: SapiRegionModel[]
+  }>()
+)
+
+export const setStandAloneVolumes = createAction(
+  `${nameSpace} setStandAloneVolumes`,
+  props<{
+    standAloneVolumes: string[]
+  }>()
+)
+
+export const setNavigation = createAction(
+  `${nameSpace} setNavigation`,
+  props<{
+    navigation: {
+      position: number[]
+      orientation: number[]
+      zoom: number
+      perspectiveOrientation: number[]
+      perspectiveZoom: number
+    }
+  }>()
+)
+
+export const setViewerMode = createAction(
+  `${nameSpace} setViewerMode`,
+  props<{
+    viewerMode: ViewerMode
+  }>()
+)
+
+export const clearSelectedRegions = createAction(
+  `${nameSpace} clearSelectedRegions`
+)
+
+export const selectATPById = createAction(
+  `${nameSpace} selectATPById`,
+  props<{
+    atlasId?: string,
+    templateId?: string
+    parcellationId?: string
+  }>()
+)
+
+export const clearNonBaseParcLayer = createAction(
+  `${nameSpace} clearNonBaseParcLayer`
+)
+
+export const clearStandAloneVolumes = createAction(
+  `${nameSpace} clearStandAloneVolumes`
+)
+
+export const navigateTo = createAction(
+  `${nameSpace} navigateTo`,
+  props<{
+    navigation: Partial<{
+      position: number[]
+      orientation: number[]
+      zoom: number
+      perspectiveOrientation: number[]
+      perspectiveZoom: number
+    }>
+    physical?: boolean
+    animation?: boolean
+  }>()
+)
+
+export const navigateToRegion = createAction(
+  `${nameSpace} navigateToRegion`,
+  props<{
+    region: SapiRegionModel
+  }>()
+)
+
+export const clearViewerMode = createAction(
+  `${nameSpace} clearViewerMode`,
+)
+
+export const toggleRegionSelect = createAction(
+  `${nameSpace} toggleRegionSelect`,
+  props<{
+    region: SapiRegionModel
+  }>()
+)
+
+export const toggleRegionSelectById = createAction(
+  `${nameSpace} toggleRegionSelectById`,
+  props<{
+    id: string
+  }>()
+)
+
+export const viewSelRegionInNewSpace = createAction(
+  `${nameSpace} viewSelRegionInNewSpace`,
+  props<{
+    region: SapiRegionModel
+    template: SapiSpaceModel
+  }>()
+)
\ No newline at end of file
diff --git a/src/state/atlasSelection/const.ts b/src/state/atlasSelection/const.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7e26794f3173ebf6b97ce8ab614c963e32685548
--- /dev/null
+++ b/src/state/atlasSelection/const.ts
@@ -0,0 +1,2 @@
+export const nameSpace = `[state.atlasSelection]`
+export type ViewerMode = 'annotating' | 'key frame'
\ No newline at end of file
diff --git a/src/state/atlasSelection/effects.spec.ts b/src/state/atlasSelection/effects.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..511cf1b532b84590b26bae80e43a470fc7d60377
--- /dev/null
+++ b/src/state/atlasSelection/effects.spec.ts
@@ -0,0 +1,141 @@
+describe("> effects.ts", () => {
+  describe("> Effect", () => {
+
+    describe('> selectTemplate$', () => {
+
+      describe('> when transiting from template A to template B', () => {
+        describe('> if the current navigation is correctly formed', () => {
+          it('> uses current navigation param', () => {
+
+          })
+        })
+
+        describe('> if current navigation is malformed', () => {
+          it('> if current navigation is undefined, use nehubaConfig of last template', () => {
+          })
+  
+          it('> if current navigation is empty object, use nehubaConfig of last template', () => {
+          })
+        })
+  
+      })
+
+      it('> if coordXform returns error', () => {
+
+      })
+
+      it('> if coordXform complete', () => {
+
+      })
+
+    })
+  
+    describe('> if selected atlas has no matching tmpl space', () => {
+
+      it('> should emit gernal error', () => {
+
+      })
+    })
+
+    describe('> if selected atlas has matching tmpl', () => {
+
+      describe('> if parc is empty array', () => {
+        it('> should emit with falsy as payload', () => {
+
+        })
+      })
+      describe('> if no parc has eligible @id', () => {
+
+        it('> should emit with falsy as payload', () => {
+
+        })
+      })
+
+      describe('> if some parc has eligible @id', () => {
+        describe('> if no @version is available', () => {
+
+          it('> selects the first parc', () => {
+
+          })
+        })
+
+        describe('> if @version is available', () => {
+          
+          describe('> if there exist an entry without @next attribute', () => {
+            
+            it('> selects the first one without @next attribute', () => {
+            })
+          })
+          describe('> if there exist no entry without @next attribute', () => {
+            
+            it('> selects the first one without @next attribute', () => {
+
+            })
+          })
+        })
+      })
+    })
+
+    describe('> onNavigateToRegion', () => {
+
+      describe('> if atlas, template, parc is not set', () => {
+
+        describe('> if atlas is unset', () => {
+          it('> returns general error', () => {
+          })
+        })
+        describe('> if template is unset', () => {
+          it('> returns general error', () => {
+          })
+        })
+        describe('> if parc is unset', () => {
+          it('> returns general error', () => {
+          })
+        })
+      })
+      describe('> if atlas, template, parc is set, but region unset', () => {
+        it('> returns general error', () => {
+        })
+      })
+
+      describe('> if inputs are fine', () => {
+        it('> getRegionDetailSpy is called', () => {
+        })
+
+        describe('> mal formed return', () => {
+          describe('> returns null', () => {
+            it('> generalactionerror', () => {
+            })
+          })
+          describe('> general throw', () => {
+
+            it('> generalactionerror', () => {
+            })
+
+          })
+          describe('> does not contain props attr', () => {
+            it('> generalactionerror', () => {
+            })
+          })
+
+          describe('> does not contain props.length === 0', () => {
+            it('> generalactionerror', () => {
+            })
+          })
+        })
+
+        describe('> wellformed response', () => {
+          beforeEach(() => {
+
+            beforeEach(() => {
+            })
+
+            it('> emits navigateTo', () => {
+
+            })
+          })
+        })
+      })
+    })
+  })
+})
\ No newline at end of file
diff --git a/src/state/atlasSelection/effects.ts b/src/state/atlasSelection/effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f8be02508d3355868350ea07cd4991983f78f7c5
--- /dev/null
+++ b/src/state/atlasSelection/effects.ts
@@ -0,0 +1,169 @@
+import { Injectable } from "@angular/core";
+import { Actions, createEffect, ofType } from "@ngrx/effects";
+import { forkJoin, merge, of } from "rxjs";
+import { filter, map, mapTo, switchMap, withLatestFrom } from "rxjs/operators";
+import { SAPI } from "src/atlasComponents/sapi";
+import * as actions from "./actions"
+import { actions as generalAction } from "../actions"
+import { select, Store } from "@ngrx/store";
+import { selectors } from '.'
+
+@Injectable()
+export class Effect {
+
+  onAtlasSelectionSelectTmplParc = createEffect(() => this.action.pipe(
+    ofType(actions.selectAtlas),
+    filter(action => !!action.atlas),
+    switchMap(action => 
+      this.sapiSvc.getParcDetail(action.atlas["@id"], action.atlas.parcellations[0]["@id"], 100).then(
+        parcellation => ({
+          parcellation,
+          atlas: action.atlas
+        })
+      )
+    ),
+    switchMap(({ atlas, parcellation }) => {
+      const spacdIds = parcellation.brainAtlasVersions.map(bas => bas.coordinateSpace) as { "@id": string }[]
+      return forkJoin(
+        spacdIds.filter(
+          spaceId => atlas.spaces.map(spc => spc["@id"]).indexOf(spaceId["@id"]) >= 0
+        ).map(spaceId =>
+          this.sapiSvc.getSpaceDetail(atlas["@id"], spaceId["@id"])
+        )
+      ).pipe(
+        switchMap(spaces => {
+          const selectSpaceId = spaces[2]["@id"]
+          const selectedSpace = spaces.find(s => s["@id"] === selectSpaceId)
+          if (!selectedSpace) {
+            return of(
+              generalAction.generalActionError({
+                message: `space with id ${selectSpaceId} not found!`
+              })
+            )
+          }
+          
+          return of(
+            actions.selectTemplate({
+              template: selectedSpace
+            }),
+            actions.selectParcellation({
+              parcellation
+            })
+          )
+        })
+      )
+    }),
+  ))
+
+  onAtlasSelClearStandAloneVolumes = createEffect(() => this.action.pipe(
+    ofType(actions.selectAtlas),
+    mapTo(actions.setStandAloneVolumes({
+      standAloneVolumes: []
+    }))
+  ))
+
+  onClearRegion = createEffect(() => this.action.pipe(
+    ofType(actions.clearSelectedRegions),
+    mapTo(actions.selectRegions({
+      regions: []
+    }))
+  ))
+
+  onNonBaseLayerRemoval = createEffect(() => this.action.pipe(
+    ofType(actions.clearNonBaseParcLayer),
+    mapTo(generalAction.generalActionError({
+      message: `NYI`
+    }))
+  ))
+
+  onClearStandAloneVolumes = createEffect(() => this.action.pipe(
+    ofType(actions.clearStandAloneVolumes),
+    mapTo(actions.setStandAloneVolumes({
+      standAloneVolumes: []
+    }))
+  ))
+
+  /**
+   * nb for template selection
+   * navigation should be transformed
+   * see selectTemplate$ in spec.ts
+   */
+  onSelectATPById = createEffect(() => this.action.pipe(
+    ofType(actions.selectATPById),
+    mapTo(generalAction.generalActionError({
+      message: `NYI`
+    }))
+  ))
+
+  /**
+   * consider what happens if it was nehuba viewer?
+   * what happens if it was three surfer viewer?
+   */
+  onNavigateTo = createEffect(() => this.action.pipe(
+    ofType(actions.navigateTo),
+    mapTo(generalAction.generalActionError({
+      message: `NYI`
+    }))
+  ))
+
+  onClearViewerMode = createEffect(() => this.action.pipe(
+    ofType(actions.clearViewerMode),
+    mapTo(actions.setViewerMode({ viewerMode: null }))
+  ))
+
+  onToggleRegionSelectById = createEffect(() => this.action.pipe(
+    ofType(actions.toggleRegionSelectById),
+    mapTo(generalAction.generalActionError({
+      message: `NYI`
+    }))
+  ))
+
+  onNavigateToRegion = createEffect(() => this.action.pipe(
+    ofType(actions.navigateToRegion),
+    mapTo(generalAction.generalActionError({
+      message: `NYI`
+    }))
+  ))
+
+  onSelAtlasTmplParcClearRegion = createEffect(() => merge(
+    this.action.pipe(
+      ofType(actions.selectAtlas)
+    ),
+    this.action.pipe(
+      ofType(actions.selectTemplate)
+    ),
+    this.action.pipe(
+      ofType(actions.selectParcellation)
+    )
+  ).pipe(
+    mapTo(actions.selectRegions({
+      regions: []
+    }))
+  ))
+
+  onRegionToggleSelect = createEffect(() => this.action.pipe(
+    ofType(actions.toggleRegionSelect),
+    withLatestFrom(
+      this.store.pipe(
+        select(selectors.selectedRegions)
+      )
+    ),
+    map(([ { region }, regions ]) => {
+      const selectedRegionsIndicies = regions.map(r => r["@id"])
+      const roiIndex = selectedRegionsIndicies.indexOf(region["@id"])
+      return actions.selectRegions({
+        regions: roiIndex >= 0
+          ? [...regions.slice(0, roiIndex), ...regions.slice(roiIndex + 1)]
+          : [...regions, region]
+      })
+    })
+  ))
+
+  constructor(
+    private action: Actions,
+    private sapiSvc: SAPI,
+    private store: Store,
+  ){
+
+  }
+}
\ No newline at end of file
diff --git a/src/state/atlasSelection/index.ts b/src/state/atlasSelection/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..603220cde6013640c42cb4f86d9fdeac342b7140
--- /dev/null
+++ b/src/state/atlasSelection/index.ts
@@ -0,0 +1,6 @@
+export * as selectors from "./selectors"
+export { fromRootStore } from "./util"
+export { nameSpace } from "./const"
+export { reducer } from "./store"
+export * as actions from "./actions"
+export { Effect } from "./effects"
\ No newline at end of file
diff --git a/src/state/atlasSelection/selectors.ts b/src/state/atlasSelection/selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a60c20225d382e20691a955a7f3010c4bb1a0dc0
--- /dev/null
+++ b/src/state/atlasSelection/selectors.ts
@@ -0,0 +1,49 @@
+import { createSelector } from "@ngrx/store"
+import { nameSpace } from "./const"
+import { AtlasSelectionState } from "./store"
+
+export const viewerStateHelperStoreName = 'viewerStateHelper'
+
+const selectStore = (state: any) => state[nameSpace] as AtlasSelectionState
+
+export const selectedAtlas = createSelector(
+  selectStore,
+  state => state.selectedAtlas
+)
+
+export const selectedTemplate = createSelector(
+  selectStore,
+  state => state.selectedTemplate
+)
+
+export const selectedParcellation = createSelector(
+  selectStore,
+  state => state.selectedParcellation
+)
+
+export const selectedRegions = createSelector(
+  selectStore,
+  state => state.selectedRegions
+)
+
+export const selectedATP = createSelector(
+  selectedAtlas,
+  selectedTemplate,
+  selectedParcellation,
+  (atlas, template, parcellation) => ({ atlas, template, parcellation })
+)
+
+export const standaloneVolumes = createSelector(
+  selectStore,
+  state => state.standAloneVolumes
+)
+
+export const navigation = createSelector(
+  selectStore,
+  state => state.navigation
+)
+
+export const viewerMode = createSelector(
+  selectStore,
+  state => state.viewerMode
+)
diff --git a/src/state/atlasSelection/store.ts b/src/state/atlasSelection/store.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2f1caaf5419913b6991055248a485a316336ec90
--- /dev/null
+++ b/src/state/atlasSelection/store.ts
@@ -0,0 +1,107 @@
+import { createReducer, on } from "@ngrx/store";
+import { SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
+import * as actions from "./actions"
+import { ViewerMode } from "./const"
+
+export type AtlasSelectionState = {
+  selectedAtlas: SapiAtlasModel
+  selectedTemplate: SapiSpaceModel
+  selectedParcellation: SapiParcellationModel
+  selectedRegions: SapiRegionModel[]
+  standAloneVolumes: string[]
+
+  /**
+   * the navigation may mean something very different
+   * depending on if the user is using threesurfer/nehuba view
+   */
+  navigation: {
+    position: number[]
+    orientation: number[]
+    zoom: number
+    perspectiveOrientation: number[]
+    perspectiveZoom: number
+  }
+
+  viewerMode: ViewerMode
+}
+
+const defaultState: AtlasSelectionState = {
+  selectedAtlas: null,
+  selectedParcellation: null,
+  selectedRegions: [],
+  selectedTemplate: null,
+  standAloneVolumes: [],
+  navigation: null,
+  viewerMode: null
+}
+
+const reducer = createReducer(
+  defaultState,
+  on(
+    actions.selectAtlas,
+    (state, { atlas }) => {
+      return {
+        ...state,
+        selectedAtlas: atlas
+      }
+    }
+  ),
+  on(
+    actions.selectTemplate,
+    (state, { template }) => {
+      return {
+        ...state,
+        selectedTemplate: template
+      }
+    }
+  ),
+  on(
+    actions.selectParcellation,
+    (state, { parcellation }) => {
+      return {
+        ...state,
+        selectedParcellation: parcellation
+      }
+    }
+  ),
+  on(
+    actions.selectRegions,
+    (state, { regions }) => {
+      return {
+        ...state,
+        selectedRegions: regions
+      }
+    }
+  ),
+  on(
+    actions.setStandAloneVolumes,
+    (state, { standAloneVolumes }) => {
+      return {
+        ...state,
+        standAloneVolumes
+      }
+    }
+  ),
+  on(
+    actions.setNavigation,
+    (state, { navigation }) => {
+      return {
+        ...state,
+        navigation
+      }
+    }
+  ),
+  on(
+    actions.setViewerMode,
+    (state, { viewerMode }) => {
+      return {
+        ...state,
+        viewerMode
+      }
+    }
+  )
+)
+
+export {
+  reducer
+}
diff --git a/src/state/atlasSelection/util.ts b/src/state/atlasSelection/util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..241a4a1a211ba1a9bfaccb3ac030ce249c1b79df
--- /dev/null
+++ b/src/state/atlasSelection/util.ts
@@ -0,0 +1,36 @@
+import { select } from "@ngrx/store";
+import { forkJoin, pipe } from "rxjs";
+import { switchMap } from "rxjs/operators";
+import { SAPI } from "src/atlasComponents/sapi";
+import * as selectors from "./selectors"
+
+const allAvailSpaces = (sapi: SAPI) => pipe(
+  select(selectors.selectedAtlas),
+  switchMap(atlas => forkJoin(
+    atlas.spaces.map(spcWId => sapi.getSpaceDetail(atlas["@id"], spcWId["@id"])))
+  )
+)
+
+const allAvailParcs = (sapi: SAPI) => pipe(
+  select(selectors.selectedAtlas),
+  switchMap(atlas =>
+    forkJoin(
+      atlas.parcellations.map(parcWId => sapi.getParcDetail(atlas["@id"], parcWId["@id"]))
+    )
+  )
+)
+const allAvailSpacesParcs = (sapi: SAPI) => pipe(
+  select(selectors.selectedAtlas),
+  switchMap(atlas =>
+    forkJoin({
+      spaces: atlas.spaces.map(spcWId => sapi.getSpaceDetail(atlas["@id"], spcWId["@id"])),
+      parcellation: atlas.parcellations.map(parcWId => sapi.getParcDetail(atlas["@id"], parcWId["@id"])),
+    })
+  )
+)
+
+export const fromRootStore = {
+  allAvailSpaces,
+  allAvailParcs,
+  allAvailSpacesParcs,
+}
diff --git a/src/state/const.ts b/src/state/const.ts
new file mode 100644
index 0000000000000000000000000000000000000000..60f4c38b8b2f0d9f9dd4f8db61c0bc42e37a6ac4
--- /dev/null
+++ b/src/state/const.ts
@@ -0,0 +1 @@
+export const nameSpace = `[state]`
\ No newline at end of file
diff --git a/src/state/effects/viewerState.useEffect.spec.ts b/src/state/effects/viewerState.useEffect.spec.ts
index 37c7b0ee9f18297b0268a6459b74863e6f07d2b9..180223fc10dd36bd9e9cdffdfcc04d3850f4b5b8 100644
--- a/src/state/effects/viewerState.useEffect.spec.ts
+++ b/src/state/effects/viewerState.useEffect.spec.ts
@@ -3,22 +3,18 @@ import { Observable, of, throwError } from 'rxjs'
 import { TestBed } from '@angular/core/testing'
 import { provideMockActions } from '@ngrx/effects/testing'
 import { MockStore, provideMockStore } from '@ngrx/store/testing'
-import { defaultRootState, generalActionError } from 'src/services/stateStore.service'
+import { defaultRootState } from 'src/services/stateStore.service'
 import { Injectable } from '@angular/core'
 import { TemplateCoordinatesTransformation, ITemplateCoordXformResp } from 'src/services/templateCoordinatesTransformation.service'
-import { hot } from 'jasmine-marbles'
 import { AngularMaterialModule } from 'src/sharedModules'
 import { HttpClientModule } from '@angular/common/http'
-import { viewerStateFetchedTemplatesSelector, viewerStateNavigateToRegion, viewerStateNavigationStateSelector, viewerStateNewViewer, viewerStateSelectAtlas, viewerStateSelectTemplateWithName } from 'src/services/state/viewerState.store.helper'
-import { viewerStateFetchedAtlasesSelector, viewerStateGetSelectedAtlas, viewerStateSelectedParcellationSelector, viewerStateSelectedTemplateSelector } from 'src/services/state/viewerState/selectors'
-import { CONST } from 'common/constants'
 import { PureContantService } from 'src/util'
-import { viewerStateChangeNavigation } from 'src/services/state/viewerState/actions'
+
 
 let returnPosition = null
 const dummyParc1 = {
   name: 'dummyParc1'
-}
+} as any
 const dummyTmpl1 = {
   '@id': 'dummyTmpl1-id',
   name: 'dummyTmpl1',
@@ -30,7 +26,7 @@ const dummyTmpl1 = {
       }
     }
   }
-}
+} as any
 
 const dummyParc2 = {
   name: 'dummyParc2'
@@ -117,392 +113,6 @@ describe('> viewerState.useEffect.ts', () => {
       mockStore = TestBed.inject(MockStore)
     })
 
-    describe('> selectTemplate$', () => {
-      beforeEach(() => {
-        mockStore.overrideSelector(viewerStateFetchedTemplatesSelector, mockFetchedTemplates)
-        mockStore.overrideSelector(viewerStateSelectedParcellationSelector, dummyParc1)
-        actions$ = hot(
-          'a',
-          {
-            a: viewerStateSelectTemplateWithName({
-                payload: {
-                  name: dummyTmpl1.name
-                }
-              })
-          }
-        )
-      })
-      describe('> when transiting from template A to template B', () => {
-        describe('> if the current navigation is correctly formed', () => {
-          it('> uses current navigation param', () => {
-
-            const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-            expect(
-              viewerStateCtrlEffect.selectTemplate$
-            ).toBeObservable(
-              hot(
-                'a',
-                {
-                  a: viewerStateNewViewer({
-                      selectTemplate: dummyTmpl1,
-                      selectParcellation: dummyTmpl1.parcellations[0],
-                    })
-                }
-              )
-            )
-            expect(spy).toHaveBeenCalledWith(
-              dummyTmpl2.name,
-              dummyTmpl1.name,
-              initialState.viewerState.navigation.position
-            )
-          })
-        })
-
-        describe('> if current navigation is malformed', () => {
-          it('> if current navigation is undefined, use nehubaConfig of last template', () => {
-
-            const mockStore = TestBed.inject(MockStore)
-            mockStore.overrideSelector(viewerStateNavigationStateSelector, null)
-            const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-
-            expect(
-              viewerStateCtrlEffect.selectTemplate$
-            ).toBeObservable(
-              hot(
-                'a',
-                {
-                  a: viewerStateNewViewer({
-                      selectTemplate: dummyTmpl1,
-                      selectParcellation: dummyTmpl1.parcellations[0],
-                    })
-                }
-              )
-            )
-            const { position } = cvtNehubaConfigToNavigationObj(dummyTmpl2.nehubaConfig.dataset.initialNgState)
-
-            expect(spy).toHaveBeenCalledWith(
-              dummyTmpl2.name,
-              dummyTmpl1.name,
-              position
-            )
-          })
-  
-          it('> if current navigation is empty object, use nehubaConfig of last template', () => {
-
-            const mockStore = TestBed.inject(MockStore)
-            mockStore.overrideSelector(viewerStateNavigationStateSelector, {})
-            const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-
-            expect(
-              viewerStateCtrlEffect.selectTemplate$
-            ).toBeObservable(
-              hot(
-                'a',
-                {
-                  a: viewerStateNewViewer({
-                      selectTemplate: dummyTmpl1,
-                      selectParcellation: dummyTmpl1.parcellations[0],
-                    })
-                }
-              )
-            )
-            const { position } = cvtNehubaConfigToNavigationObj(dummyTmpl2.nehubaConfig.dataset.initialNgState)
-
-            expect(spy).toHaveBeenCalledWith(
-              dummyTmpl2.name,
-              dummyTmpl1.name,
-              position
-            )
-          })
-        })
-  
-      })
-
-      it('> if coordXform returns error', () => {
-        const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-        expect(
-          viewerStateCtrlEffect.selectTemplate$
-        ).toBeObservable(
-          hot(
-            'a',
-            {
-              a: viewerStateNewViewer({
-                  selectTemplate: dummyTmpl1,
-                  selectParcellation: dummyTmpl1.parcellations[0],
-                })
-            }
-          )
-        )
-      })
-
-      it('> if coordXform complete', () => {
-        returnPosition = [ 1.11e6, 2.22e6, 3.33e6 ]
-
-        const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-        const updatedColin = JSON.parse( JSON.stringify( dummyTmpl1 ) )
-        const initialNgState = updatedColin.nehubaConfig.dataset.initialNgState
-        const updatedColinNavigation = updatedColin.nehubaConfig.dataset.initialNgState.navigation
-
-        const { zoom, orientation, perspectiveOrientation, position, perspectiveZoom } = currentNavigation
-
-        for (const idx of [0, 1, 2]) {
-          updatedColinNavigation.pose.position.voxelCoordinates[idx] = returnPosition[idx] / updatedColinNavigation.pose.position.voxelSize[idx]
-        }
-        updatedColinNavigation.zoomFactor = zoom
-        updatedColinNavigation.pose.orientation = orientation
-        initialNgState.perspectiveOrientation = perspectiveOrientation
-        initialNgState.perspectiveZoom = perspectiveZoom
-        
-        expect(
-          viewerStateCtrlEffect.selectTemplate$
-        ).toBeObservable(
-          hot(
-            'a',
-            {
-              a: viewerStateNewViewer({
-                  selectTemplate: updatedColin,
-                  selectParcellation: updatedColin.parcellations[0],
-                })
-            }
-          )
-        )
-      })
-
-    })
-  
-    describe('> navigateToRegion$', () => {
-      const setAction = region => {
-        actions$ = hot(
-          'a',
-          {
-            a: viewerStateNavigateToRegion({
-              payload: { region }
-            })
-          }
-        )
-      }
-      let mockStore: MockStore
-      beforeEach(() => {
-
-        mockStore = TestBed.inject(MockStore)
-          
-        mockStore.overrideSelector(viewerStateGetSelectedAtlas, { '@id': 'foo-bar-atlas'})
-        mockStore.overrideSelector(viewerStateSelectedTemplateSelector, { '@id': 'foo-bar-template'})
-        mockStore.overrideSelector(viewerStateSelectedParcellationSelector, { '@id': 'foo-bar-parcellation'})
-      })
-      describe('> if atlas, template, parc is not set', () => {
-        beforeEach(() => {
-          const region = {
-            name: 'foo bar'
-          }
-          setAction(region)
-        })
-        describe('> if atlas is unset', () => {
-          beforeEach(() => {
-            mockStore.overrideSelector(viewerStateGetSelectedAtlas, null)
-          })
-          it('> returns general error', () => {
-            const effect = TestBed.inject(ViewerStateControllerUseEffect)
-            expect(effect.navigateToRegion$).toBeObservable(
-              hot('a', {
-                a: generalActionError({
-                  message: 'Go to region: region / atlas / template / parcellation not defined.'
-                })
-              })
-            )
-          })
-        })
-        describe('> if template is unset', () => {
-          beforeEach(() => {
-            mockStore.overrideSelector(viewerStateSelectedTemplateSelector, null)
-          })
-          it('> returns general error', () => {
-            const effect = TestBed.inject(ViewerStateControllerUseEffect)
-            expect(effect.navigateToRegion$).toBeObservable(
-              hot('a', {
-                a: generalActionError({
-                  message: 'Go to region: region / atlas / template / parcellation not defined.'
-                })
-              })
-            )
-          })
-        })
-        describe('> if parc is unset', () => {
-          beforeEach(() => {
-            mockStore.overrideSelector(viewerStateSelectedParcellationSelector, null)
-          })
-          it('> returns general error', () => {
-            const effect = TestBed.inject(ViewerStateControllerUseEffect)
-            expect(effect.navigateToRegion$).toBeObservable(
-              hot('a', {
-                a: generalActionError({
-                  message: 'Go to region: region / atlas / template / parcellation not defined.'
-                })
-              })
-            )
-          })
-        })
-      })
-      describe('> if atlas, template, parc is set, but region unset', () => {
-        beforeEach(() => {
-          setAction(null)
-        })
-        it('> returns general error', () => {
-          const effect = TestBed.inject(ViewerStateControllerUseEffect)
-          expect(effect.navigateToRegion$).toBeObservable(
-            hot('a', {
-              a: generalActionError({
-                message: 'Go to region: region / atlas / template / parcellation not defined.'
-              })
-            })
-          )
-        })
-      })
-
-      describe('> if inputs are fine', () => {
-        let getRegionDetailSpy: jasmine.Spy
-        const region = {
-          name: 'foo bar'
-        }
-        beforeEach(() => {
-          getRegionDetailSpy = spyOn(mockPureConstantService, 'getRegionDetail').and.callThrough()
-          setAction(region)
-        })
-        afterEach(() => {
-          getRegionDetailSpy.calls.reset()
-        })
-
-        it('> getRegionDetailSpy is called', () => {
-          const ctrl = TestBed.inject(ViewerStateControllerUseEffect)
-
-          // necessary to trigger the emit
-          expect(
-            ctrl.navigateToRegion$
-          ).toBeObservable(
-            hot('a', {
-              a: generalActionError({
-                message: 'Fetching region detail error: Error: region does not have props defined!'
-              })
-            })
-          )
-
-          expect(getRegionDetailSpy).toHaveBeenCalled()
-        })
-
-        describe('> mal formed return', () => {
-          describe('> returns null', () => {
-            it('> generalactionerror', () => {
-              const ctrl = TestBed.inject(ViewerStateControllerUseEffect)
-              expect(
-                ctrl.navigateToRegion$
-              ).toBeObservable(
-                hot('a', {
-                  a: generalActionError({
-                    message: 'Fetching region detail error: Error: region does not have props defined!'
-                  })
-                })
-              )
-            })
-          })
-          describe('> general throw', () => {
-            const msg = 'oh no!'
-            beforeEach(() => {
-              getRegionDetailSpy.and.callFake(() => throwError(msg))
-            })
-
-            it('> generalactionerror', () => {
-              const ctrl = TestBed.inject(ViewerStateControllerUseEffect)
-              expect(
-                ctrl.navigateToRegion$
-              ).toBeObservable(
-                hot('a', {
-                  a: generalActionError({
-                    message: `Fetching region detail error: ${msg}`
-                  })
-                })
-              )
-            })
-
-          })
-          describe('> does not contain props attr', () => {
-
-            beforeEach(() => {
-              getRegionDetailSpy.and.callFake(() => of({
-                name: 'foo-bar'
-              }))
-            })
-
-            it('> generalactionerror', () => {
-              const ctrl = TestBed.inject(ViewerStateControllerUseEffect)
-              expect(
-                ctrl.navigateToRegion$
-              ).toBeObservable(
-                hot('a', {
-                  a: generalActionError({
-                    message: `Fetching region detail error: Error: region does not have props defined!`
-                  })
-                })
-              )
-            })
-          })
-
-          describe('> does not contain props.length === 0', () => {
-
-            beforeEach(() => {
-              getRegionDetailSpy.and.callFake(() => of({
-                name: 'foo-bar',
-                props: {}
-              }))
-            })
-
-            it('> generalactionerror', () => {
-              const ctrl = TestBed.inject(ViewerStateControllerUseEffect)
-              expect(
-                ctrl.navigateToRegion$
-              ).toBeObservable(
-                hot('a', {
-                  a: generalActionError({
-                    message: `Fetching region detail error: Error: region does not have props defined!`
-                  })
-                })
-              )
-            })
-          })
-        })
-
-        describe('> wellformed response', () => {
-          beforeEach(() => {
-
-            beforeEach(() => {
-              getRegionDetailSpy.and.callFake(() => of({
-                name: 'foo-bar',
-                props: {
-                  components: {
-                    centroid: [1,2,3]
-                  }
-                }
-              }))
-            })
-
-            it('> emits viewerStateChangeNavigation', () => {
-              const ctrl = TestBed.inject(ViewerStateControllerUseEffect)
-              expect(
-                ctrl.navigateToRegion$
-              ).toBeObservable(
-                hot('a', {
-                  a: viewerStateChangeNavigation({
-                    navigation: {
-                      position: [1e6,2e6,3e6],
-                      animation: {}
-                    }
-                  })
-                })
-              )
-            })
-          })
-        })
-      })
-    })
   
     describe('> onSelectAtlasSelectTmplParc$', () => {
       let mockStore: MockStore
@@ -511,26 +121,7 @@ describe('> viewerState.useEffect.ts', () => {
       })
 
       it('> if atlas not found, return general error', () => {
-        mockStore.overrideSelector(viewerStateFetchedTemplatesSelector, [])
-        mockStore.overrideSelector(viewerStateFetchedAtlasesSelector, [])
-        actions$ = hot('a', {
-          a: viewerStateSelectAtlas({
-            atlas: {
-              ['@id']: 'foo-bar',
-            }
-          })
-        })
-        
-        const viewerSTateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-        expect(
-          viewerSTateCtrlEffect.onSelectAtlasSelectTmplParc$
-        ).toBeObservable(
-          hot('a', {
-            a: generalActionError({
-              message: CONST.ATLAS_NOT_FOUND
-            })
-          })
-        )
+
       })
     
       describe('> if atlas found', () => {
@@ -560,66 +151,10 @@ describe('> viewerState.useEffect.ts', () => {
 
             it('> if fails, will return general error', () => {
 
-              mockStore.overrideSelector(viewerStateFetchedTemplatesSelector, [
-                mockTmplSpc1
-              ])
-              mockStore.overrideSelector(viewerStateFetchedAtlasesSelector, [{
-                ['@id']: 'foo-bar',
-                templateSpaces: [ mockTmplSpc ],
-                parcellations: [ mockParc0 ]
-              }])
-              actions$ = hot('a', {
-                a: viewerStateSelectAtlas({
-                  atlas: {
-                    ['@id']: 'foo-bar',
-                  }
-                })
-              })
-              
-              const viewerSTateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-              expect(
-                viewerSTateCtrlEffect.onSelectAtlasSelectTmplParc$
-              ).toBeObservable(
-                hot('a', {
-                  a: generalActionError({
-                    message: CONST.TEMPLATE_NOT_FOUND
-                  })
-                })
-              )
             })
           
             it('> if succeeds, will dispatch new viewer', () => {
-              const completeMocktmpl = {
-                ...mockTmplSpc1,
-                parcellations: [ mockParc1 ]
-              }
-              mockStore.overrideSelector(viewerStateFetchedTemplatesSelector, [
-                completeMocktmpl
-              ])
-              mockStore.overrideSelector(viewerStateFetchedAtlasesSelector, [{
-                ['@id']: 'foo-bar',
-                templateSpaces: [ mockTmplSpc1 ],
-                parcellations: [ mockParc1 ]
-              }])
-              actions$ = hot('a', {
-                a: viewerStateSelectAtlas({
-                  atlas: {
-                    ['@id']: 'foo-bar',
-                  }
-                })
-              })
-              
-              const viewerSTateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-              expect(
-                viewerSTateCtrlEffect.onSelectAtlasSelectTmplParc$
-              ).toBeObservable(
-                hot('a', {
-                  a: viewerStateNewViewer({
-                    selectTemplate: completeMocktmpl,
-                    selectParcellation: mockParc1
-                  })
-                })
-              )
+
             })
       
           })
@@ -637,68 +172,13 @@ describe('> viewerState.useEffect.ts', () => {
           }
           beforeEach(() => {
 
-            mockStore.overrideSelector(viewerStateFetchedTemplatesSelector, [
-              completeMockTmpl,
-              completeMocktmpl1,
-            ])
-            mockStore.overrideSelector(viewerStateFetchedAtlasesSelector, [{
-              ['@id']: 'foo-bar',
-              templateSpaces: [ mockTmplSpc, mockTmplSpc1 ],
-              parcellations: [ mockParc0, mockParc1 ]
-            }])
           })
           it('> will select template.@id', () => {
 
-            actions$ = hot('a', {
-              a: viewerStateSelectAtlas({
-                atlas: {
-                  ['@id']: 'foo-bar',
-                  template: {
-                    ['@id']: mockTmplSpc1['@id']
-                  }
-                }
-              })
-            })
-            
-            const viewerSTateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-            expect(
-              viewerSTateCtrlEffect.onSelectAtlasSelectTmplParc$
-            ).toBeObservable(
-              hot('a', {
-                a: viewerStateNewViewer({
-                  selectTemplate: completeMocktmpl1,
-                  selectParcellation: mockParc1
-                })
-              })
-            )
-
           })
           
           it('> if template.@id is not defined, will fallback to first template', () => {
 
-            actions$ = hot('a', {
-              a: viewerStateSelectAtlas({
-                atlas: {
-                  ['@id']: 'foo-bar',
-                  template: {
-                    
-                  } as any
-                }
-              })
-            })
-
-            const viewerSTateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-            expect(
-              viewerSTateCtrlEffect.onSelectAtlasSelectTmplParc$
-            ).toBeObservable(
-              hot('a', {
-                a: viewerStateNewViewer({
-                  selectTemplate: completeMockTmpl,
-                  selectParcellation: mockParc0
-                })
-              })
-            )
-
           })
         })
       })
diff --git a/src/state/effects/viewerState.useEffect.ts b/src/state/effects/viewerState.useEffect.ts
deleted file mode 100644
index 7c590f0c46922146b5c1b8471d219b24e5a335e5..0000000000000000000000000000000000000000
--- a/src/state/effects/viewerState.useEffect.ts
+++ /dev/null
@@ -1,466 +0,0 @@
-import { Injectable, OnDestroy } from "@angular/core";
-import { Actions, Effect, ofType } from "@ngrx/effects";
-import { Action, select, Store } from "@ngrx/store";
-import { Observable, Subscription, of, merge } from "rxjs";
-import { distinctUntilChanged, filter, map, shareReplay, withLatestFrom, switchMap, mapTo, startWith, catchError } from "rxjs/operators";
-import { FETCHED_TEMPLATE, IavRootStoreInterface, SELECT_PARCELLATION, SELECT_REGIONS, generalActionError } from "src/services/stateStore.service";
-import { TemplateCoordinatesTransformation } from "src/services/templateCoordinatesTransformation.service";
-import { CLEAR_STANDALONE_VOLUMES } from "src/services/state/viewerState.store";
-import { viewerStateToggleRegionSelect, viewerStateHelperSelectParcellationWithId, viewerStateSelectTemplateWithId, viewerStateNavigateToRegion, viewerStateSelectedTemplateSelector, viewerStateFetchedTemplatesSelector, viewerStateNewViewer, viewerStateSelectedParcellationSelector, viewerStateNavigationStateSelector, viewerStateSelectTemplateWithName, viewerStateSelectedRegionsSelector, viewerStateSelectAtlas } from "src/services/state/viewerState.store.helper";
-import { ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState/selectors";
-import { ngViewerActionClearView } from "src/services/state/ngViewerState/actions";
-import { PureContantService } from "src/util";
-import { CONST } from 'common/constants'
-import { viewerStateFetchedAtlasesSelector, viewerStateGetSelectedAtlas } from "src/services/state/viewerState/selectors";
-import { viewerStateChangeNavigation } from "src/services/state/viewerState/actions";
-import { cvtNavigationObjToNehubaConfig } from 'src/viewerModule/nehuba/util'
-import { getPosFromRegion } from "src/util/siibraApiConstants/fn";
-
-const defaultPerspectiveZoom = 1e6
-const defaultZoom = 1e6
-
-export const defaultNavigationObject = {
-  orientation: [0, 0, 0, 1],
-  perspectiveOrientation: [0.5, -0.5, -0.5, 0.5],
-  perspectiveZoom: defaultPerspectiveZoom,
-  zoom: defaultZoom,
-  position: [0, 0, 0],
-  positionReal: true
-}
-
-export const defaultNehubaConfigObject = {
-  perspectiveOrientation: [0.5, -0.5, -0.5, 0.5],
-  perspectiveZoom: 1e6,
-  navigation: {
-    pose: {
-      position: {
-        voxelCoordinates: [0, 0, 0],
-        voxelSize: [1,1,1]
-      },
-      orientation: [0, 0, 0, 1],
-    },
-    zoomFactor: defaultZoom
-  }
-}
-
-export function cvtNehubaConfigToNavigationObj(nehubaConfig?){
-  const {
-    navigation,
-    perspectiveOrientation = defaultNavigationObject.perspectiveOrientation,
-    perspectiveZoom = defaultNavigationObject.perspectiveZoom
-  } = nehubaConfig || {}
-  const { pose, zoomFactor = 1e6 } = navigation || {}
-  const { position, orientation = [0, 0, 0, 1] } = pose || {}
-  const { voxelSize = [1, 1, 1], voxelCoordinates = [0, 0, 0] } = position || {}
-
-  return {
-    orientation,
-    perspectiveOrientation: perspectiveOrientation,
-    perspectiveZoom: perspectiveZoom,
-    zoom: zoomFactor,
-    position: [0, 1, 2].map(idx => voxelSize[idx] * voxelCoordinates[idx]),
-    positionReal: true
-  }
-}
-
-@Injectable({
-  providedIn: 'root',
-})
-
-export class ViewerStateControllerUseEffect implements OnDestroy {
-
-  private subscriptions: Subscription[] = []
-
-  private selectedRegions$: Observable<any[]>
-
-  @Effect()
-  public init$ = this.pureService.initFetchTemplate$.pipe(
-    map(fetchedTemplate => {
-      return {
-        type: FETCHED_TEMPLATE,
-        fetchedTemplate,
-      }
-    }),
-  )
-
-  @Effect()
-  public onSelectAtlasSelectTmplParc$ = this.actions$.pipe(
-    ofType(viewerStateSelectAtlas.type),
-    switchMap(action => this.pureService.allFetchingReady$.pipe(
-      filter(v => !!v),
-      mapTo(action)
-    )),
-    withLatestFrom(
-      this.store$.pipe(
-        select(viewerStateFetchedTemplatesSelector),
-        startWith([])
-      ),
-      this.store$.pipe(
-        select(viewerStateFetchedAtlasesSelector),
-        startWith([])
-      )
-    ),
-    map(([action, fetchedTemplates, fetchedAtlases ])=> {
-
-      const { atlas: atlasObj } = action as any
-      const atlas = fetchedAtlases.find(a => a['@id'] === atlasObj['@id'])
-      if (!atlas) {
-        return generalActionError({
-          message: CONST.ATLAS_NOT_FOUND
-        })
-      }
-      /**
-       * selecting atlas means selecting the first available templateSpace
-       */
-      const targetTmplSpcId = atlasObj['template']?.['@id']
-      const templateTobeSelected = (
-        targetTmplSpcId
-        && atlas.templateSpaces.find(t => t['@id'] === targetTmplSpcId)
-      ) || atlas.templateSpaces[0]
-      
-      const templateSpaceId = templateTobeSelected['@id']
-      const atlasTmpl = atlas.templateSpaces.find(t => t['@id'] === templateSpaceId)
-
-      const templateSelected = fetchedTemplates.find(t => templateSpaceId === t['@id'])
-      if (!templateSelected) {
-        return generalActionError({
-          message: CONST.TEMPLATE_NOT_FOUND
-        })
-      }
-
-      const atlasParcs = atlasTmpl.availableIn
-        .map(availP => atlas.parcellations.find(p => availP['@id'] === p['@id']))
-        .filter(fullP => !!fullP)
-      const atlasParc = atlasParcs.find(p => {
-        if (!p.baseLayer) return false
-        if (p['@version']) {
-          return !p['@version']['@next']
-        }
-        return true
-      }) || templateSelected.parcellations[0]
-      const parcellationId = atlasParc && atlasParc['@id']
-      const parcellationSelected = parcellationId && templateSelected.parcellations.find(p => p['@id'] === parcellationId)
-      return viewerStateNewViewer({
-        selectTemplate: templateSelected,
-        selectParcellation: parcellationSelected
-      })
-    })
-  )
-
-
-  @Effect()
-  public selectParcellation$: Observable<any>
-
-  private selectTemplateIntent$: Observable<any> = merge(
-    this.actions$.pipe(
-      ofType(viewerStateSelectTemplateWithId.type),
-      map(({ payload, config }) => {
-        return {
-          templateId: payload['@id'],
-          parcellationId: config && config['selectParcellation'] && config['selectParcellation']['@id']
-        }
-      })
-    ),
-    this.actions$.pipe(
-      ofType(viewerStateSelectTemplateWithName),
-      withLatestFrom(this.store$.pipe(
-        select(viewerStateFetchedTemplatesSelector)
-      )),
-      map(([ action, fetchedTemplates ]) => {
-        const templateName = (action as any).payload.name
-        const foundTemplate = fetchedTemplates.find(t => t.name === templateName)
-        return foundTemplate && foundTemplate['@id']
-      }),
-      filter(v => !!v),
-      map(templateId => {
-        return { templateId, parcellationId: null }
-      })
-    )
-  )
-
-  @Effect()
-  public selectTemplate$: Observable<any> = this.selectTemplateIntent$.pipe(
-    withLatestFrom(
-      this.store$.pipe(
-        select(viewerStateFetchedTemplatesSelector)
-      ),
-      this.store$.pipe(
-        select(viewerStateSelectedParcellationSelector)
-      )
-    ),
-    map(([ { templateId, parcellationId }, fetchedTemplates, parcellationSelected ]) => {
-      /**
-       * find the correct template & parcellation from their IDs
-       */
-
-      /**
-       * for template, just look for the new id in fetched templates
-       */
-      const newTemplateTobeSelected = fetchedTemplates.find(t => t['@id'] === templateId)
-      if (!newTemplateTobeSelected) {
-        return {
-          selectTemplate: null,
-          selectParcellation: null,
-          errorMessage: `Selected templateId ${templateId} not found.`
-        }
-      }
-
-      /**
-       * for parcellation,
-       * if new parc id is defined, try to find the corresponding parcellation in the new template
-       * if above fails, try to find the corresponding parcellation of the currently selected parcellation
-       * if the above fails, select the first parcellation in the new template
-       */
-      const selectParcellationWithTemplate = (parcellationId && newTemplateTobeSelected['parcellations'].find(p => p['@id'] === parcellationId))
-        || (parcellationSelected && parcellationSelected['@id'] && newTemplateTobeSelected['parcellations'].find(p => p['@id'] === parcellationSelected['@id']))
-        || newTemplateTobeSelected.parcellations[0]
-
-      return {
-        selectTemplate: newTemplateTobeSelected,
-        selectParcellation: selectParcellationWithTemplate
-      }
-    }),
-    withLatestFrom(
-      this.store$.pipe(
-        select(viewerStateSelectedTemplateSelector),
-        startWith(null as any),
-      ),
-      this.store$.pipe(
-        select(viewerStateNavigationStateSelector),
-        startWith(null as any),
-      )
-    ),
-    switchMap(([{ selectTemplate, selectParcellation, errorMessage }, lastSelectedTemplate, navigation]) => {
-      /**
-       * if selectTemplate is undefined (cannot find template with id)
-       */
-      if (errorMessage) {
-        return of(generalActionError({
-          message: errorMessage || 'Switching template error.',
-        }))
-      }
-      /**
-       * if there were no template selected last
-       * simply return selectTemplate object
-       */
-      if (!lastSelectedTemplate) {
-        return of(viewerStateNewViewer({
-          selectParcellation,
-          selectTemplate,
-        }))
-      }
-
-      /**
-       * if there were template selected last, extract navigation info
-       */
-      const previousNavigation = (navigation && Object.keys(navigation).length > 0 && navigation) || cvtNehubaConfigToNavigationObj(lastSelectedTemplate.nehubaConfig?.dataset?.initialNgState)
-      return this.coordinatesTransformation.getPointCoordinatesForTemplate(lastSelectedTemplate.name, selectTemplate.name, previousNavigation.position).pipe(
-        map(({ status, result }) => {
-
-          /**
-           * if getPointCoordinatesForTemplate returns error, simply load the temp/parc
-           */
-          if (status === 'error') {
-            return viewerStateNewViewer({
-              selectParcellation,
-              selectTemplate,
-            })
-          }
-
-          /**
-           * otherwise, copy the nav state to templateSelected
-           * deepclone of json object is required, or it will mutate the fetchedTemplate
-           * setting navigation sometimes creates a race con, as creating nehubaViewer is not sync
-           */
-          const deepCopiedState = JSON.parse(JSON.stringify(selectTemplate))
-          const initialNgState = deepCopiedState.nehubaConfig.dataset.initialNgState
-
-          const newInitialNgState = cvtNavigationObjToNehubaConfig({
-            ...previousNavigation,
-            position: result
-          }, initialNgState)
-
-          /**
-           * mutation of initialNgState is expected here
-           */
-          deepCopiedState.nehubaConfig.dataset.initialNgState = {
-            ...initialNgState,
-            ...newInitialNgState
-          }
-
-          return viewerStateNewViewer({
-            selectTemplate: deepCopiedState,
-            selectParcellation,
-          })
-        })
-      )
-    })
-  )
-
-  @Effect()
-  public toggleRegionSelection$: Observable<any>
-
-  @Effect()
-  public navigateToRegion$: Observable<any>
-
-  @Effect()
-  public onTemplateSelectClearStandAloneVolumes$: Observable<any>
-
-  @Effect()
-  public onTemplateSelectUnsetAllClearQueues$: Observable<any> = this.store$.pipe(
-    select(viewerStateSelectedTemplateSelector),
-    withLatestFrom(this.store$.pipe(
-      select(ngViewerSelectorClearViewEntries)
-    )),
-    map(([_, clearViewQueue]) => {
-      const newVal = {}
-      for (const key of clearViewQueue) {
-        newVal[key] = false
-      }
-      return ngViewerActionClearView({
-        payload: newVal
-      })
-    })
-  )
-
-  constructor(
-    private actions$: Actions,
-    private store$: Store<IavRootStoreInterface>,
-    private pureService: PureContantService,
-    private coordinatesTransformation: TemplateCoordinatesTransformation
-  ) {
-    const viewerState$ = this.store$.pipe(
-      select('viewerState'),
-      shareReplay(1),
-    )
-
-    this.selectedRegions$ = viewerState$.pipe(
-      select('regionsSelected'),
-      distinctUntilChanged(),
-    )
-
-    this.onTemplateSelectClearStandAloneVolumes$ = this.store$.pipe(
-      select(viewerStateSelectedTemplateSelector),
-      distinctUntilChanged(),
-      mapTo({ type: CLEAR_STANDALONE_VOLUMES })
-    )
-
-    /**
-     * merge all sources of selecting parcellation into parcellation id
-     */
-    this.selectParcellation$ = merge(
-
-      /**
-       * listening on action
-       */
-
-      this.actions$.pipe(
-        ofType(viewerStateHelperSelectParcellationWithId.type),
-        map(({ payload }) => payload['@id'])
-      ),
-
-    ).pipe(
-      withLatestFrom(viewerState$.pipe(
-        select('templateSelected'),
-      )),
-      map(([id, templateSelected]) => {
-        const { parcellations: availableParcellations } = templateSelected
-        const newParcellation = availableParcellations.find(t => t['@id'] === id)
-        if (!newParcellation) {
-          return generalActionError({
-            message: 'Selected parcellation not found.'
-          })
-        }
-        return {
-          type: SELECT_PARCELLATION,
-          selectParcellation: newParcellation,
-        }
-      })
-    )
-
-    this.navigateToRegion$ = this.actions$.pipe(
-      ofType(viewerStateNavigateToRegion),
-      map(action => action.payload?.region),
-      withLatestFrom(
-        this.store$.pipe(
-          select(viewerStateGetSelectedAtlas)
-        ),
-        this.store$.pipe(
-          select(viewerStateSelectedTemplateSelector)
-        ),
-        this.store$.pipe(
-          select(viewerStateSelectedParcellationSelector)
-        )
-      ),
-      switchMap(([ region,  selectedAtlas, selectedTemplate, selectedParcellation ]) => {
-        if (!region || !selectedAtlas || !selectedTemplate || !selectedParcellation) {
-          return of(
-            generalActionError({
-              message: `Go to region: region / atlas / template / parcellation not defined.`
-            })
-          )
-        }
-        return this.pureService.getRegionDetail(selectedAtlas['@id'], selectedParcellation['@id'], selectedTemplate['@id'], region).pipe(
-          map(regDetail => {
-            const position = getPosFromRegion(regDetail)
-            if (!position) throw new Error(`region does not have props defined!`)
-            
-            return viewerStateChangeNavigation({
-              navigation: {
-                position,
-                animation: {},
-              }
-            })
-          }),
-          catchError((err) => of(
-            generalActionError({
-              message: `Fetching region detail error: ${err}`
-            })
-          ))
-        )
-      }),
-    )
-
-    this.toggleRegionSelection$ = this.actions$.pipe(
-      ofType(viewerStateToggleRegionSelect.type),
-      withLatestFrom(this.selectedRegions$),
-      map(([action, regionsSelected]) => {
-
-        const { payload = {} } = action as ViewerStateAction
-        const { region } = payload
-
-        /**
-         * if region does not have labelIndex (not tree leaf), for now, return error
-         */
-        if (!region.labelIndex) {
-          return generalActionError({
-            message: 'Currently, only regions at the lowest hierarchy can be selected.'
-          })
-        }
-
-        /**
-         * if the region is already selected, deselect it
-         * if the region is not yet selected, deselect any existing region, and select this region
-         */
-        const roiIsSelected = !!regionsSelected.find(r => r.name === region.name)
-        return {
-          type: SELECT_REGIONS,
-          selectRegions: roiIsSelected
-            ? []
-            : [ region ]
-        }
-      }),
-    )
-  }
-
-  public ngOnDestroy() {
-    while (this.subscriptions.length > 0) {
-      this.subscriptions.pop().unsubscribe()
-    }
-  }
-}
-
-interface ViewerStateAction extends Action {
-  payload: any
-  config: any
-}
diff --git a/src/state/index.ts b/src/state/index.ts
index 778709a1c7cdd5a85c71824a18b8c2f1aff1df07..8567985487ab7f6278d38d5d4253b7edc985b2e7 100644
--- a/src/state/index.ts
+++ b/src/state/index.ts
@@ -1,5 +1,8 @@
 export { StateModule } from "./state.module"
-export {
-  ViewerStateControllerUseEffect,
-  cvtNehubaConfigToNavigationObj,
-} from "./effects/viewerState.useEffect"
\ No newline at end of file
+
+export * as atlasSelection from "./atlasSelection"
+export * as annotation from "./annotations"
+export * as userInterface from "./userInterface"
+export * as atlasAppearance from "./atlasAppearance"
+export * as plugins from "./plugins"
+export * as userInteraction from "./userInteraction"
diff --git a/src/state/plugins/actions.ts b/src/state/plugins/actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5fe4fcd15b162f4bf26f5947d124e925dca43552
--- /dev/null
+++ b/src/state/plugins/actions.ts
@@ -0,0 +1,18 @@
+import { createAction, props } from "@ngrx/store";
+import { nameSpace } from "./const"
+
+export const clearInitManifests = createAction(
+  `${nameSpace} clearInitManifests`,
+  props<{
+    nameSpace: string
+  }>()
+)
+
+export const setInitMan = createAction(
+  `${nameSpace} setInitMan`,
+  props<{
+    nameSpace: string
+    url: string
+    internal?: boolean
+  }>()
+)
diff --git a/src/state/plugins/const.ts b/src/state/plugins/const.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7b004e658ddc8e803a00c892e32a82a6a57499be
--- /dev/null
+++ b/src/state/plugins/const.ts
@@ -0,0 +1,2 @@
+export const nameSpace = `[state.plugins]`
+export const INIT_MANIFEST_SRC = `__INIT_MANFEST_SRC__`
diff --git a/src/services/effect/pluginUseEffect.spec.ts b/src/state/plugins/effects.spec.ts
similarity index 80%
rename from src/services/effect/pluginUseEffect.spec.ts
rename to src/state/plugins/effects.spec.ts
index 978b28ad0485761025ad70b263e0440e26929326..0acf2f75a00630c5797aab39d59c2c957484fd67 100644
--- a/src/services/effect/pluginUseEffect.spec.ts
+++ b/src/state/plugins/effects.spec.ts
@@ -1,18 +1,18 @@
 import { TestBed } from "@angular/core/testing";
 import { HttpClientModule, HTTP_INTERCEPTORS, HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse, HttpHeaders } from "@angular/common/http";
-import { PluginServiceUseEffect } from "./pluginUseEffect";
+import { Effects } from "./effects";
 import { Observable, of } from "rxjs";
 import { Action } from "@ngrx/store";
 import { provideMockActions } from "@ngrx/effects/testing";
 import { provideMockStore } from "@ngrx/store/testing";
-import { defaultRootState } from "../stateStore.service";
-import { PLUGINSTORE_CONSTANTS, PLUGINSTORE_ACTION_TYPES } from '../state/pluginState.helper'
 import { Injectable } from "@angular/core";
 import { getRandomHex } from 'common/util'
 import { PluginServices } from "src/plugin";
 import { AngularMaterialModule } from "src/sharedModules";
 import { hot } from "jasmine-marbles";
 import { BS_ENDPOINT } from "src/util/constants";
+import * as actions from "./actions"
+import { INIT_MANIFEST_SRC } from "./const"
 
 const actions$: Observable<Action> = of({type: 'TEST'})
 
@@ -83,18 +83,9 @@ describe('pluginUseEffect.ts', () => {
         AngularMaterialModule
       ],
       providers: [
-        PluginServiceUseEffect,
+        Effects,
         provideMockActions(() => actions$),
-        provideMockStore({
-          initialState: {
-            ...defaultRootState,
-            pluginState:{
-              initManifests: [
-                [ PLUGINSTORE_CONSTANTS.INIT_MANIFEST_SRC, 'http://localhost:12345/manifest.json' ]
-              ]
-            }
-          }
-        }),
+        provideMockStore(),
         {
           provide: HTTP_INTERCEPTORS,
           useClass: HTTPInterceptorClass,
@@ -115,13 +106,13 @@ describe('pluginUseEffect.ts', () => {
   })
 
   it('initManifests should fetch manifest.json', () => {
-    const effect = TestBed.get(PluginServiceUseEffect) as PluginServiceUseEffect
+    const effect = TestBed.inject(Effects)
     expect(
-      effect.initManifests$
+      effect.initManClear
     ).toBeObservable(
-      hot('a', {
-        a: {type: PLUGINSTORE_ACTION_TYPES.CLEAR_INIT_PLUGIN}
-      })
+      hot('a', actions.clearInitManifests({
+        nameSpace: INIT_MANIFEST_SRC
+      }))
     )
     expect(spy).toHaveBeenCalledWith(manifest)
   })
diff --git a/src/state/plugins/effects.ts b/src/state/plugins/effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1d810950bedd003ef237e8fee4c38da08de360e3
--- /dev/null
+++ b/src/state/plugins/effects.ts
@@ -0,0 +1,67 @@
+import { Injectable } from "@angular/core";
+import { createEffect } from "@ngrx/effects";
+import { select, Store } from "@ngrx/store";
+import { catchError, filter, map, mapTo, switchMap } from "rxjs/operators";
+import { PluginServices } from "src/plugin";
+import { WidgetServices } from "src/widget";
+import { atlasSelection } from ".."
+import * as constants from "./const"
+import * as selectors from "./selectors"
+import * as actions from "./actions"
+import { DialogService } from "src/services/dialogService.service";
+import { of } from "rxjs";
+import { HttpClient } from "@angular/common/http";
+import { getHttpHeader } from "src/util/constants"
+
+@Injectable()
+export class Effects{
+  onATPUpdateClearWidgets = createEffect(() => this.store.pipe(
+    select(atlasSelection.selectors.selectedATP),
+    map(() => {
+      this.widgetSvc.clearAllWidgets()
+    })
+  ), { dispatch: false })
+
+  initMan = this.store.pipe(
+    select(selectors.initManfests),
+    map(initMan => initMan[constants.INIT_MANIFEST_SRC]),
+    filter(val => !!val),
+  )
+
+  initManLaunch = createEffect(() => this.initMan.pipe(
+    switchMap(val => 
+      this.dialogSvc
+        .getUserConfirm({
+          message: `This URL is trying to open a plugin from ${val}. Proceed?`
+        })
+        .then(() => 
+          this.http.get(val, {
+            headers: getHttpHeader(),
+            responseType: 'json'
+          }).toPromise()
+        )
+        .then(json => 
+          this.pluginSvc.launchNewWidget(json)
+        )
+    ),
+    catchError(() => of(null))
+  ), { dispatch: false })
+
+  initManClear = createEffect(() => this.initMan.pipe(
+    mapTo(
+      actions.clearInitManifests({
+        nameSpace: constants.INIT_MANIFEST_SRC
+      })
+    )
+  ))
+
+  constructor(
+    private store: Store,
+    private widgetSvc: WidgetServices,
+    private pluginSvc: PluginServices,
+    private dialogSvc: DialogService,
+    private http: HttpClient,
+  ){
+    
+  }
+}
\ No newline at end of file
diff --git a/src/state/plugins/index.ts b/src/state/plugins/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bdca8a18cd994e4c61ac6588fe2052efd79e4634
--- /dev/null
+++ b/src/state/plugins/index.ts
@@ -0,0 +1,5 @@
+export * as selectors from "./selectors"
+export * as actions from "./actions"
+export { reducer } from "./store"
+export { Effects } from "./effects"
+export { nameSpace, INIT_MANIFEST_SRC } from "./const"
\ No newline at end of file
diff --git a/src/state/plugins/selectors.ts b/src/state/plugins/selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6b70d2e7d5dcc500739a02e53abcf938f2ccc094
--- /dev/null
+++ b/src/state/plugins/selectors.ts
@@ -0,0 +1,10 @@
+import { createSelector } from "@ngrx/store";
+import { PluginStore } from "./store"
+import { nameSpace } from "./const"
+
+const storeSelector = state => state[nameSpace] as PluginStore
+
+export const initManfests = createSelector(
+  storeSelector,
+  state => state.initManifests
+)
diff --git a/src/state/plugins/store.ts b/src/state/plugins/store.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0648d1fa68c2dd6e631ef975984c8f005966f810
--- /dev/null
+++ b/src/state/plugins/store.ts
@@ -0,0 +1,47 @@
+import { createReducer, on } from "@ngrx/store";
+import * as actions from "./actions"
+import { INIT_MANIFEST_SRC } from "./const"
+
+export type PluginStore = {
+  initManifests: Record<string, string>
+}
+
+const defaultState: PluginStore = {
+  initManifests: {}
+}
+
+export const reducer = createReducer(
+  defaultState,
+  on(
+    actions.clearInitManifests,
+    (state, { nameSpace }) => {
+      if (!state[nameSpace]) return state
+      const newMan: Record<string, string> = {}
+      const { initManifests } = state
+      for (const key in initManifests) {
+        if (key === nameSpace) continue
+        newMan[key] = initManifests[key]
+      }
+      return {
+        ...state,
+        initManifests: newMan
+      }
+    }
+  ),
+  on(
+    actions.setInitMan,
+    (state, { nameSpace, url, internal }) => {
+      if (!internal) {
+        if (nameSpace === INIT_MANIFEST_SRC) return state
+      }
+      const { initManifests } = state
+      return {
+        ...state,
+        initManifests: {
+          ...initManifests,
+          [nameSpace]: url
+        }
+      }
+    }
+  )
+)
diff --git a/src/state/userInteraction/actions.ts b/src/state/userInteraction/actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b7d30d2de689972864d6fede14753ee376525600
--- /dev/null
+++ b/src/state/userInteraction/actions.ts
@@ -0,0 +1,33 @@
+import { createAction, props } from "@ngrx/store"
+import { nameSpace } from "./const"
+import * as atlasSelection from "../atlasSelection"
+import { SapiRegionModel } from "src/atlasComponents/sapi"
+import * as userInterface from "../userInterface"
+
+export const {
+  clearSelectedRegions,
+  clearStandAloneVolumes,
+  clearNonBaseParcLayer,
+} = atlasSelection.actions
+
+export const {
+  openSidePanel,
+  closeSidePanel,
+  expandSidePanelDetailView,
+} = userInterface.actions
+
+export const mouseOverAnnotations = createAction(
+  `${nameSpace} mouseOverAnnotations`,
+  props<{
+    annotations: {
+      "@id": string
+    }[]
+  }>()
+)
+
+export const mouseoverRegions = createAction(
+  `${nameSpace} mouseoverRegions`,
+  props<{
+    regions: SapiRegionModel[]
+  }>()
+)
diff --git a/src/state/userInteraction/const.ts b/src/state/userInteraction/const.ts
new file mode 100644
index 0000000000000000000000000000000000000000..322454b4575be2ad44f6f7a251a46fc087db1e0c
--- /dev/null
+++ b/src/state/userInteraction/const.ts
@@ -0,0 +1 @@
+export const nameSpace = `[state.userInteraction]`
\ No newline at end of file
diff --git a/src/state/userInteraction/effects.ts b/src/state/userInteraction/effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ee8baa706e67df5746b163fa59f11cb01855bc33
--- /dev/null
+++ b/src/state/userInteraction/effects.ts
@@ -0,0 +1,17 @@
+import { Injectable } from "@angular/core";
+import { Actions, createEffect, ofType } from "@ngrx/effects";
+import * as actions from "./actions"
+import * as atlasSelectionActions from "../atlasSelection/actions"
+import { mapTo } from "rxjs/operators";
+
+@Injectable()
+export class Effect {
+  onStandAloneVolumesExistCloseMatDrawer = createEffect(() => this.action.pipe(
+    ofType(atlasSelectionActions.clearStandAloneVolumes),
+    mapTo(actions.closeSidePanel())
+  ))
+
+  constructor(private action: Actions){
+
+  }
+}
\ No newline at end of file
diff --git a/src/state/userInteraction/index.ts b/src/state/userInteraction/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2bad8f6b313c2a4a4f8c7afff8f5def60db6d43c
--- /dev/null
+++ b/src/state/userInteraction/index.ts
@@ -0,0 +1,5 @@
+export { Effect } from "./effects"
+export { nameSpace } from "./const"
+export * as actions from "./actions"
+export * as selectors from "./selectors"
+export { reducer } from "./store"
\ No newline at end of file
diff --git a/src/state/userInteraction/selectors.ts b/src/state/userInteraction/selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5b9b0bd79c821d3d21e31b6482894340775974b4
--- /dev/null
+++ b/src/state/userInteraction/selectors.ts
@@ -0,0 +1,11 @@
+import { createAction, createSelector, props } from "@ngrx/store";
+import { SapiRegionModel } from "src/atlasComponents/sapi";
+import { nameSpace } from "./const"
+import { UserInteraction } from "./store";
+
+const selectStore = state => state[nameSpace] as UserInteraction
+
+export const mousingOverRegions = createSelector(
+  selectStore,
+  state => state.mouseoverRegions
+)
diff --git a/src/state/userInteraction/store.ts b/src/state/userInteraction/store.ts
new file mode 100644
index 0000000000000000000000000000000000000000..83bf75863f3c1c76733851f74a0930dea37afc5a
--- /dev/null
+++ b/src/state/userInteraction/store.ts
@@ -0,0 +1,24 @@
+import { createReducer, on } from "@ngrx/store";
+import { SapiRegionModel } from "src/atlasComponents/sapi";
+import * as actions from "./actions"
+
+export type UserInteraction = {
+  mouseoverRegions: SapiRegionModel[]
+}
+
+const defaultState: UserInteraction = {
+  mouseoverRegions: []
+}
+
+export const reducer = createReducer(
+  defaultState,
+  on(
+    actions.mouseoverRegions,
+    (state, { regions }) => {
+      return {
+        ...state,
+        mouseoverRegions: regions
+      }
+    }
+  )
+)
\ No newline at end of file
diff --git a/src/state/userInterface/actions.ts b/src/state/userInterface/actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f229006bc473dc280521befb7e4cf1ae8fa78c6a
--- /dev/null
+++ b/src/state/userInterface/actions.ts
@@ -0,0 +1,46 @@
+import { TemplateRef } from "@angular/core";
+import { MatBottomSheetConfig } from "@angular/material/bottom-sheet";
+import { MatSnackBarConfig } from "@angular/material/snack-bar";
+import { createAction, props } from "@ngrx/store";
+import { nameSpace } from "./const"
+
+export const showFeature = createAction(
+  `${nameSpace} showFeature`,
+  props<{
+    feature: {
+      "@id": string
+    }
+  }>()
+)
+
+export const clearShownFeature = createAction(
+  `${nameSpace} clearShownFeature`,
+)
+
+export const openSidePanel = createAction(
+  `${nameSpace} openSidePanel`
+)
+
+export const closeSidePanel = createAction(
+  `${nameSpace} closeSidePanel`
+)
+
+export const expandSidePanelDetailView = createAction(
+  `${nameSpace} expandDetailView`
+)
+
+export const showBottomSheet = createAction(
+  `${nameSpace} showBottomSheet`,
+  props<{
+    template: TemplateRef<any>
+    config?: MatBottomSheetConfig
+  }>()
+)
+
+export const snackBarMessage = createAction(
+  `${nameSpace} snackBarMessage`,
+  props<{
+    message: string
+    config?: MatSnackBarConfig
+  }>()
+)
diff --git a/src/state/userInterface/const.ts b/src/state/userInterface/const.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1033ee3687f1571cc6f6125f949cb7660d0673b2
--- /dev/null
+++ b/src/state/userInterface/const.ts
@@ -0,0 +1 @@
+export const nameSpace = `[state.ui]`
\ No newline at end of file
diff --git a/src/state/userInterface/effects.ts b/src/state/userInterface/effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..254cf22a40b32c9cd910e624175c85bb6f64622f
--- /dev/null
+++ b/src/state/userInterface/effects.ts
@@ -0,0 +1,56 @@
+import { Injectable } from "@angular/core";
+import { MatBottomSheet, MatBottomSheetRef } from "@angular/material/bottom-sheet";
+import { MatSnackBar } from "@angular/material/snack-bar";
+import { Actions, createEffect, ofType } from "@ngrx/effects";
+import { select, Store } from "@ngrx/store";
+import { filter, map, mapTo, pairwise, startWith } from "rxjs/operators";
+import { selectors } from "../atlasSelection"
+import * as actions from "./actions"
+
+@Injectable()
+export class Effects{
+
+  freshRegionSelect = this.store.pipe(
+    select(selectors.selectedRegions),
+    map(selReg => selReg.length),
+    startWith(0),
+    pairwise(),
+    filter(([prev, curr]) => prev === 0 && curr > 0),
+  )
+
+  onFreshRegionSelectSidePanelOpen = createEffect(() => this.freshRegionSelect.pipe(
+    mapTo(actions.openSidePanel()),
+  ))
+
+  onFreshRegionSelectSidePanelDetailExpand = createEffect(() => this.freshRegionSelect.pipe(
+    mapTo(actions.expandSidePanelDetailView())
+  ))
+
+  private bottomSheetRef: MatBottomSheetRef
+  constructor(
+    private store: Store,
+    private action: Actions,
+    bottomsheet: MatBottomSheet,
+    snackbar: MatSnackBar,
+  ){
+    this.action.pipe(
+      ofType(actions.showBottomSheet)
+    ).subscribe(({ template, config }) => {
+      if (this.bottomSheetRef) {
+        this.bottomSheetRef.dismiss()
+      }
+      this.bottomSheetRef = bottomsheet.open(
+        template,
+        config
+      )
+      this.bottomSheetRef.afterDismissed().subscribe(() => this.bottomSheetRef = null)
+    })
+
+    this.action.pipe(
+      ofType(actions.snackBarMessage)
+    ).subscribe(({ message, config }) => {
+      const _config = config || { duration: 5000 }
+      snackbar.open(message, "Dismiss", _config)
+    })
+  }
+}
diff --git a/src/state/userInterface/index.ts b/src/state/userInterface/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f0b98013604df6b9bb5923a4a3a84f80d39c7b52
--- /dev/null
+++ b/src/state/userInterface/index.ts
@@ -0,0 +1,4 @@
+export * as actions from "./actions"
+export * as selectors from "./selectors"
+export { nameSpace } from "./const"
+export { reducer } from "./store"
\ No newline at end of file
diff --git a/src/state/userInterface/selectors.ts b/src/state/userInterface/selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fd36b44ec95d78fb394e3c17ad785661e02d7fa8
--- /dev/null
+++ b/src/state/userInterface/selectors.ts
@@ -0,0 +1,10 @@
+import { createSelector } from "@ngrx/store";
+import { nameSpace } from "./const"
+import { UiStore } from "./store"
+
+const selectStore = state => state[nameSpace] as UiStore
+
+export const selectedFeature = createSelector(
+  selectStore,
+  state => state.selectedFeature
+)
diff --git a/src/state/userInterface/store.ts b/src/state/userInterface/store.ts
new file mode 100644
index 0000000000000000000000000000000000000000..400e7983b59269a4c47983d42797d3b63e2ea788
--- /dev/null
+++ b/src/state/userInterface/store.ts
@@ -0,0 +1,33 @@
+import { createReducer, on } from "@ngrx/store";
+import { SapiVolumeModel } from "src/atlasComponents/sapi";
+import * as actions from "./actions"
+
+export type UiStore = {
+  selectedFeature: SapiVolumeModel
+}
+
+const defaultStore: UiStore = {
+  selectedFeature: null
+}
+
+export const reducer = createReducer(
+  defaultStore,
+  on(
+    actions.showFeature,
+    (state, { feature }) => {
+      return {
+        ...state,
+        feature
+      }
+    }
+  ),
+  on(
+    actions.clearShownFeature,
+    state => {
+      return {
+        ...state,
+        feature: null
+      }
+    }
+  )
+)
diff --git a/src/state/userInterface/ui.ts b/src/state/userInterface/ui.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/ui/config/configCmp/config.component.ts b/src/ui/config/configCmp/config.component.ts
index 15f92277c707e22aeeb25cb64dec3e562f907030..f34ca0eec31149a10ab3b96a425b2cf8ebfd5bee 100644
--- a/src/ui/config/configCmp/config.component.ts
+++ b/src/ui/config/configCmp/config.component.ts
@@ -12,7 +12,7 @@ import {MatSliderChange} from "@angular/material/slider";
 import { PureContantService } from 'src/util';
 import { ngViewerActionSwitchPanelMode } from 'src/services/state/ngViewerState/actions';
 import { ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from 'src/services/state/ngViewerState/selectors';
-import { viewerStateSelectorNavigation } from 'src/services/state/viewerState/selectors';
+import { atlasSelection } from 'src/state';
 
 const GPU_TOOLTIP = `Higher GPU usage can cause crashes on lower end machines`
 const ANIMATION_TOOLTIP = `Animation can cause slowdowns in lower end machines`
@@ -84,7 +84,7 @@ export class ConfigComponent implements OnInit, OnDestroy {
     )
 
     this.viewerObliqueRotated$ = this.store.pipe(
-      select(viewerStateSelectorNavigation),
+      select(atlasSelection.selectors.navigation),
       map(navigation => (navigation && navigation.orientation) || [0, 0, 0, 1]),
       debounceTime(100),
       map(isIdentityQuat),
diff --git a/src/ui/dialogInfo/const.ts b/src/ui/dialogInfo/const.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c787856708abba3e57f01fe1779cac6da3fa4c2b
--- /dev/null
+++ b/src/ui/dialogInfo/const.ts
@@ -0,0 +1,3 @@
+import { InjectionToken } from "@angular/core";
+
+export const IAV_DATASET_SHOW_DATASET_DIALOG_CMP = new InjectionToken('IAV_DATASET_SHOW_DATASET_DIALOG_CMP')
\ No newline at end of file
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.ts b/src/ui/dialogInfo/dialog.directive.ts
similarity index 73%
rename from src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.ts
rename to src/ui/dialogInfo/dialog.directive.ts
index d4b02e120d85776b02b0db606da5aa059cd46113..e05ef5fdec865b152600285cee13675ba1467f18 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.ts
+++ b/src/ui/dialogInfo/dialog.directive.ts
@@ -2,17 +2,14 @@ import { Directive, HostListener, Inject, Input, Optional } from "@angular/core"
 import { MatDialog, MatDialogConfig } from "@angular/material/dialog";
 import { MatSnackBar } from "@angular/material/snack-bar";
 import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN, TOverwriteShowDatasetDialog } from "src/util/interfaces";
-import { TRegionDetail as TSiibraRegion } from "src/util/siibraApiConstants/types";
-import { TRegion as TContextRegion } from 'src/atlasComponents/regionalFeatures/bsFeatures/type'
-
-export const IAV_DATASET_SHOW_DATASET_DIALOG_CMP = 'IAV_DATASET_SHOW_DATASET_DIALOG_CMP'
-export const IAV_DATASET_SHOW_DATASET_DIALOG_CONFIG = `IAV_DATASET_SHOW_DATASET_DIALOG_CONFIG`
+import { IAV_DATASET_SHOW_DATASET_DIALOG_CMP } from "./const";
 
 @Directive({
-  selector: '[iav-dataset-show-dataset-dialog]',
-  exportAs: 'iavDatasetShowDatasetDialog'
+  selector: `[iav-dataset-show-dataset-dialog]`,
+  exportAs: 'iavDatasetShowDatasetDialog',
 })
-export class ShowDatasetDialogDirective{
+
+export class DialogDirective{
 
   static defaultDialogConfig: MatDialogConfig = {
     autoFocus: false
@@ -25,13 +22,20 @@ export class ShowDatasetDialogDirective{
   description: string
 
   @Input('iav-dataset-show-dataset-dialog-kgschema')
-  kgSchema: string = 'minds/core/dataset/v1.0.0'
+  set kgSchema(val) {
+    throw new Error(`setting kgschema & kgid has been deprecated`)
+  }
 
   @Input('iav-dataset-show-dataset-dialog-kgid')
-  kgId: string
+  set kgId(val) {
+    throw new Error(`setting kgschema & kgid has been deprecated`)
+  }
 
   @Input('iav-dataset-show-dataset-dialog-fullid')
-  fullId: string
+  set fullId(val) {
+    throw new Error(`setting fullid has been deprecated`)
+  }
+
 
   @Input('iav-dataset-show-dataset-dialog-urls')
   urls: {
@@ -42,8 +46,6 @@ export class ShowDatasetDialogDirective{
   @Input('iav-dataset-show-dataset-dialog-ignore-overwrite')
   ignoreOverwrite = false
 
-  @Input('iav-dataset-show-dataset-dialog-contexted-region')
-  region: TSiibraRegion & TContextRegion
 
   constructor(
     private matDialog: MatDialog,
@@ -77,9 +79,9 @@ export class ShowDatasetDialogDirective{
     if (!this.dialogCmp) throw new Error(`IAV_DATASET_SHOW_DATASET_DIALOG_CMP not provided!`)
     const { useClassicUi } = data
     this.matDialog.open(this.dialogCmp, {
-      ...ShowDatasetDialogDirective.defaultDialogConfig,
+      ...DialogDirective.defaultDialogConfig,
       data,
       ...(useClassicUi ? {} : { panelClass: ['no-padding-dialog'] })
     })
   }
-}
+}
\ No newline at end of file
diff --git a/src/ui/dialogInfo/dialog/dialog.component.ts b/src/ui/dialogInfo/dialog/dialog.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e478f1cc88ad9e4b9798dd6d8bc5e8ea4bfe2f42
--- /dev/null
+++ b/src/ui/dialogInfo/dialog/dialog.component.ts
@@ -0,0 +1,22 @@
+import { Component, Inject, Optional } from "@angular/core"
+import { MAT_DIALOG_DATA } from "@angular/material/dialog"
+import { CONST, ARIA_LABELS } from "common/constants"
+
+@Component({
+  templateUrl: './dialog.template.html',
+  styleUrls: [
+    './dialog.style.css'
+  ]
+})
+
+export class DialogCmp{
+  public useClassicUi = false
+  public CONST = CONST
+  public ARIA_LABELS = ARIA_LABELS
+  constructor(
+    @Optional() @Inject(MAT_DIALOG_DATA) public data: any
+  ){
+    const { dataType, description, name, urls, useClassicUi, view, region, summary, isGdprProtected } = data
+    this.useClassicUi = data.useClassicUi
+  }
+}
\ No newline at end of file
diff --git a/src/ui/dialogInfo/dialog/dialog.style.css b/src/ui/dialogInfo/dialog/dialog.style.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.template.html b/src/ui/dialogInfo/dialog/dialog.template.html
similarity index 83%
rename from src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.template.html
rename to src/ui/dialogInfo/dialog/dialog.template.html
index 2bce44e578033cd6aa517f3dae798aafb6944bc4..324616d965dc23ea9950d71718ab393696669c93 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.template.html
+++ b/src/ui/dialogInfo/dialog/dialog.template.html
@@ -1,6 +1,6 @@
 
 <!-- classic UI -->
-<ng-template [ngIf]="useClassicUi" [ngIfElse]="modernUi">
+<ng-template [ngIf]="data.useClassicUi" [ngIfElse]="modernUi">
   <mat-card-subtitle>
     <ng-container *ngTemplateOutlet="nameTmpl">
     </ng-container>
@@ -27,7 +27,7 @@
     <!-- explore -->
     <ng-container>
 
-      <a *ngFor="let kgRef of (doiUrls || [])"
+      <a *ngFor="let kgRef of (data.urls || [])"
         [href]="kgRef.doi | doiParserPipe"
         class="color-inherit"
         [matTooltip]="ARIA_LABELS.EXPLORE_DATASET_IN_KG"
@@ -61,10 +61,10 @@
       <mat-card-subtitle class="d-inline-flex align-items-center">
         <mat-icon fontSet="fas" fontIcon="fa-database"></mat-icon>
         <span>
-          {{ dataType }}
+          {{ data?.dataType || 'Dataset' }}
         </span>
 
-        <button *ngIf="isGdprProtected"
+        <button *ngIf="data?.isGdprProtected"
           [matTooltip]="CONST.GDPR_TEXT"
           mat-icon-button color="warn">
           <i class="fas fa-exclamation-triangle"></i>
@@ -73,7 +73,7 @@
         <mat-divider [vertical]="true" class="ml-2 h-2rem"></mat-divider>
 
         <!-- explore btn -->
-        <a *ngFor="let kgRef of (urls || [])"
+        <a *ngFor="let kgRef of (data.urls || [])"
           [href]="kgRef.doi | doiParserPipe"
           class="color-inherit"
           mat-icon-button
@@ -88,8 +88,7 @@
   </mat-card>
 
   <!-- description -->
-  <div class="text-muted d-block mat-body m-4"
-    *ngIf="!loadingFlag">
+  <div class="text-muted d-block mat-body m-4">
     <ng-container *ngTemplateOutlet="descTmpl">
     </ng-container>
   </div>
@@ -101,15 +100,13 @@
 </ng-template>
 
 <ng-template #nameTmpl>
-  <span *ngIf="!loadingFlag; else isLoadingTmpl">
-    {{ name || nameFallback }}
-  </span>
+  {{ data?.name || 'Unknown Name' }}
 </ng-template>
 
 <!-- desc -->
 <ng-template #descTmpl>
   <markdown-dom 
-    [markdown]="description || descriptionFallback">
+    [markdown]="data?.description || 'Unknown Desc'">
   </markdown-dom>
 </ng-template>
 
@@ -119,8 +116,3 @@
 
   </ng-template>
 </ng-template>
-
-<!-- is loading tmpl -->
-<ng-template #isLoadingTmpl>
-  <spinner-cmp></spinner-cmp>
-</ng-template>
diff --git a/src/ui/dialogInfo/index.ts b/src/ui/dialogInfo/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e78523f63c467b78ed512627163806b9e46ca510
--- /dev/null
+++ b/src/ui/dialogInfo/index.ts
@@ -0,0 +1,5 @@
+export {
+  DialogInfoModule,
+  DialogDirective,
+  DialogCmp,
+} from "./module"
diff --git a/src/ui/dialogInfo/module.ts b/src/ui/dialogInfo/module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fa02156c5245ab5bdc44c7d79b9279b637d699e4
--- /dev/null
+++ b/src/ui/dialogInfo/module.ts
@@ -0,0 +1,38 @@
+import { CommonModule } from "@angular/common";
+import { NgModule } from "@angular/core";
+import { ComponentsModule } from "src/components";
+import { AngularMaterialModule } from "src/sharedModules";
+import { UtilModule } from "src/util";
+import { IAV_DATASET_SHOW_DATASET_DIALOG_CMP } from "./const";
+import { DialogDirective } from "./dialog.directive"
+import { DialogCmp } from "./dialog/dialog.component"
+
+@NgModule({
+  imports: [
+    CommonModule,
+    AngularMaterialModule,
+    UtilModule,
+    ComponentsModule,
+  ],
+  declarations: [
+    DialogDirective,
+    DialogCmp,
+  ],
+  exports: [
+    DialogDirective,
+    DialogCmp,
+  ],
+  providers: [
+    {
+      provide: IAV_DATASET_SHOW_DATASET_DIALOG_CMP,
+      useValue: DialogCmp
+    }
+  ]
+})
+
+export class DialogInfoModule{}
+
+export {
+  DialogDirective,
+  DialogCmp,
+}
\ No newline at end of file
diff --git a/src/ui/ui.module.ts b/src/ui/ui.module.ts
index c33043639f957bbe8640db5e3c5104d682c14958..92ecdd79f20feb0060cc996e7329549eb2de5a33 100644
--- a/src/ui/ui.module.ts
+++ b/src/ui/ui.module.ts
@@ -26,11 +26,11 @@ import { ActionDialog } from "./actionDialog/actionDialog.component";
 import { APPEND_SCRIPT_TOKEN, appendScriptFactory } from "src/util/constants";
 import { DOCUMENT } from "@angular/common";
 import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
-import { RegionalFeaturesModule } from "../atlasComponents/regionalFeatures";
 import { Landmark2DModule } from "./nehubaContainer/2dLandmarks/module";
 import { HANDLE_SCREENSHOT_PROMISE, TypeHandleScrnShotPromise } from "../screenshot";
 import { ParcellationRegionModule } from "src/atlasComponents/parcellationRegion";
 import { AtlasCmpParcellationModule } from "src/atlasComponents/parcellation";
+import { DialogInfoModule } from "./dialogInfo"
 
 @NgModule({
   imports : [
@@ -45,10 +45,10 @@ import { AtlasCmpParcellationModule } from "src/atlasComponents/parcellation";
     AngularMaterialModule,
     ShareModule,
     AuthModule,
-    RegionalFeaturesModule,
     Landmark2DModule,
     ParcellationRegionModule,
     AtlasCmpParcellationModule,
+    DialogInfoModule,
   ],
   declarations : [
     
diff --git a/src/util/constants.ts b/src/util/constants.ts
index 84ee596993c519223fc8f28487af1a0cb8372f4d..ee179b2d40b4eeb7bb1bc533000034f6ba6b77e9 100644
--- a/src/util/constants.ts
+++ b/src/util/constants.ts
@@ -4,7 +4,6 @@ import { environment } from 'src/environments/environment'
 export const LOCAL_STORAGE_CONST = {
   GPU_LIMIT: 'fzj.xg.iv.GPU_LIMIT',
   ANIMATION: 'fzj.xg.iv.ANIMATION_FLAG',
-  SAVED_REGION_SELECTIONS: 'fzj.xg.iv.SAVED_REGION_SELECTIONS',
   MOBILE_UI: 'fzj.xg.iv.MOBILE_UI',
   AGREE_COOKIE: 'fzj.xg.iv.AGREE_COOKIE',
   AGREE_KG_TOS: 'fzj.xg.iv.AGREE_KG_TOS',
diff --git a/src/util/fn.spec.ts b/src/util/fn.spec.ts
index 61bb2fd8cb23665bc85aacb76b298f026d2f89aa..efd5e418d29f6d46df2442bb8d02cb1a63b14840 100644
--- a/src/util/fn.spec.ts
+++ b/src/util/fn.spec.ts
@@ -3,78 +3,10 @@ import {} from 'jasmine'
 import { hot } from 'jasmine-marbles'
 import { Observable, of } from 'rxjs'
 import { switchMap } from 'rxjs/operators'
-import { isSame, getGetRegionFromLabelIndexId, switchMapWaitFor, bufferUntil } from './fn'
+import { switchMapWaitFor, bufferUntil } from './fn'
 
 describe(`> util/fn.ts`, () => {
 
-  describe('> #getGetRegionFromLabelIndexId', () => {
-    
-    const COLIN_JULICHBRAIN_LAYER_NAME = `COLIN_V25_LEFT_NG_SPLIT_HEMISPHERE`
-    const LABEL_INDEX = 12
-    const dummyParc = {
-      regions: [
-        {
-          name: 'foo-bar',
-          children: [
-            {
-              name: 'foo-bar-region-ba',
-              ngId: `${COLIN_JULICHBRAIN_LAYER_NAME}-ba`,
-              labelIndex: LABEL_INDEX
-            },
-            {
-              name: 'foo-bar-region+1',
-              ngId: COLIN_JULICHBRAIN_LAYER_NAME,
-              labelIndex: LABEL_INDEX + 1
-            },
-            {
-              name: 'foo-bar-region',
-              ngId: COLIN_JULICHBRAIN_LAYER_NAME,
-              labelIndex: LABEL_INDEX
-            }
-          ]
-        }
-      ]
-    }
-    it('translateds hoc1 from labelIndex to region', () => {
-
-      const getRegionFromlabelIndexId = getGetRegionFromLabelIndexId({
-        parcellation: {
-          ...dummyParc,
-          updated: true,
-        },
-      })
-      const fetchedRegion = getRegionFromlabelIndexId({ labelIndexId: `${COLIN_JULICHBRAIN_LAYER_NAME}#${LABEL_INDEX}` })
-      expect(fetchedRegion).toBeTruthy()
-      expect(fetchedRegion.name).toEqual('foo-bar-region')
-      
-    })
-  })
-  describe(`> #isSame`, () => {
-    it('should return true with null, null', () => {
-      expect(isSame(null, null)).toBe(true)
-    })
-
-    it('should return true with string', () => {
-      expect(isSame('test', 'test')).toBe(true)
-    })
-
-    it(`should return true with numbers`, () => {
-      expect(isSame(12, 12)).toBe(true)
-    })
-
-    it('should return true with obj with name attribute', () => {
-
-      const obj = {
-        name: 'hello',
-      }
-      const obj2 = {
-        name: 'hello',
-        world: 'world',
-      }
-      expect(isSame(obj, obj2)).toBe(true)
-      expect(obj).not.toEqual(obj2)
-    })
-  })
 
   describe('> #switchMapWaitFor', () => {
     const val = 'hello world'
diff --git a/src/util/fn.ts b/src/util/fn.ts
index 479958c477576d2e34b7cc8f1be6243048024992..e5ef8ac6bde4b72b67c2fb76f7b94edde8123476 100644
--- a/src/util/fn.ts
+++ b/src/util/fn.ts
@@ -1,12 +1,6 @@
-import { deserialiseParcRegionId } from 'common/util'
 import { interval, Observable, of } from 'rxjs'
 import { filter, mapTo, take } from 'rxjs/operators'
 
-export function isSame(o, n) {
-  if (!o) { return !n }
-  return o === n || (o && n && o.name === n.name)
-}
-
 export function getViewer() {
   return (window as any).viewer
 }
@@ -45,26 +39,10 @@ const recursiveFlatten = (region, {ngId}) => {
   )
 }
 
-export function recursiveFindRegionWithLabelIndexId({ regions, labelIndexId, inheritedNgId = 'root' }: {regions: any[], labelIndexId: string, inheritedNgId: string}) {
-  const { ngId, labelIndex } = deserialiseParcRegionId( labelIndexId )
-  const fr1 = regions.map(r => recursiveFlatten(r, { ngId: inheritedNgId }))
-  const fr2 = fr1.reduce((acc, curr) => acc.concat(...curr), [])
-  const found = fr2.find(r => r.ngId === ngId && Number(r.labelIndex) === Number(labelIndex))
-  if (found) { return found }
-  return null
-}
-
 export function getUuid(){
   return crypto.getRandomValues(new Uint32Array(1))[0].toString(16)
 }
 
-export const getGetRegionFromLabelIndexId = ({ parcellation }) => {
-  const { ngId: defaultNgId, regions } = parcellation
-  // if (!updated) throw new Error(`parcellation not yet updated`)
-  return ({ labelIndexId }) =>
-    recursiveFindRegionWithLabelIndexId({ regions, labelIndexId, inheritedNgId: defaultNgId })
-}
-
 type TPrimitive = string | number
 
 const include = <T extends TPrimitive>(el: T, arr: T[]) => arr.indexOf(el) >= 0
@@ -131,8 +109,7 @@ export class QuickHash {
     if (opts?.length) this.length = opts.length
   }
 
-  @CachedFunction()
-  getHash(str: string){
+  static GetHash(str: string) {
     let hash = 0
     for (const char of str) {
       const charCode = char.charCodeAt(0)
@@ -141,6 +118,11 @@ export class QuickHash {
     }
     return hash.toString(16).slice(1)
   }
+
+  @CachedFunction()
+  getHash(str: string){
+    return QuickHash.GetHash(str)
+  }
 }
 
 // fsaverage uses threesurfer, which, whilst do not use ngId, uses 'left' and 'right' as keys 
diff --git a/src/util/interfaces.ts b/src/util/interfaces.ts
index e5c2fbd9686a3f1036a5e34959c2e697e9f8d1a4..21de2b34d51872fb0ead9e8c2f6f2299a3f278f2 100644
--- a/src/util/interfaces.ts
+++ b/src/util/interfaces.ts
@@ -20,7 +20,6 @@ export const OVERWRITE_SHOW_DATASET_DIALOG_TOKEN = new InjectionToken<TOverwrite
 
 export type TRegionOfInterest = { ['fullId']: string }
 
-export const REGION_OF_INTEREST = new InjectionToken<Observable<TRegionOfInterest>>('RegionOfInterest')
 export const CANCELLABLE_DIALOG = new InjectionToken('CANCELLABLE_DIALOG')
 
 export type TTemplateImage = {
diff --git a/src/util/priority.ts b/src/util/priority.ts
new file mode 100644
index 0000000000000000000000000000000000000000..441ed5e0a5270854eeada43ea220ab80054392ef
--- /dev/null
+++ b/src/util/priority.ts
@@ -0,0 +1,92 @@
+import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http"
+import { Injectable } from "@angular/core"
+import { interval, merge, Observable, Subject, timer } from "rxjs"
+import { filter, finalize, switchMap, switchMapTo, take } from "rxjs/operators"
+
+export const PRIORITY_HEADER = 'x-sxplr-http-priority'
+
+type PriorityReq = {
+  urlWithParams: string
+  priority: number
+  req: HttpRequest<any>
+  next: HttpHandler
+}
+
+@Injectable()
+export class PriorityHttpInterceptor implements HttpInterceptor{
+
+  private priorityQueue: PriorityReq[] = []
+
+  private priority$: Subject<PriorityReq> = new Subject()
+
+  private forceCheck$ = new Subject()
+
+  private counter = 0
+  private max = 6
+
+  private shouldRun(){
+    return this.counter <= this.max
+  }
+
+  constructor(){
+    this.forceCheck$.pipe(
+      switchMapTo(
+        merge(
+          timer(0),
+          interval(16)
+        ).pipe(
+          filter(() => this.shouldRun())
+        )
+      )
+    ).subscribe(() => {
+      this.priority$.next(
+        this.priorityQueue.pop()
+      )
+    })
+  }
+
+  updatePriority(urlWithParams: string, newPriority: number) {
+    const foundIdx = this.priorityQueue.findIndex(v => v.urlWithParams === urlWithParams)
+    if (foundIdx < 0) return false
+    const [ item ] = this.priorityQueue.splice(foundIdx, 1)
+    item.priority = newPriority
+
+    this.insert(item)
+    this.forceCheck$.next(true)
+    return true
+  }
+
+  private insert(obj: PriorityReq) {
+    const { priority } = obj
+    const foundIdx = this.priorityQueue.findIndex(q => q.priority <= priority)
+    const useIndex = foundIdx >= 0 ? foundIdx : this.priorityQueue.length
+    this.priorityQueue.splice(useIndex, 0, obj)
+  }
+
+  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
+    const { urlWithParams } = req
+    
+    const priority = Number(req.headers.get(PRIORITY_HEADER) || 0)
+    const objToInsert: PriorityReq = {
+      priority,
+      req,
+      next,
+      urlWithParams
+    }
+
+    this.insert(objToInsert)
+    this.forceCheck$.next(true)
+
+    return this.priority$.pipe(
+      filter(v => v.urlWithParams === urlWithParams),
+      take(1),
+      switchMap(({ next, req }) => {
+        this.counter ++  
+        return next.handle(req)
+      }),
+      finalize(() => {
+        this.counter --
+      }),
+    )
+  }
+}
\ No newline at end of file
diff --git a/src/util/pureConstant.service.ts b/src/util/pureConstant.service.ts
index 98eff755d9e3ea11d4f03b6d3a89a098e4c2da94..9ffc4b9e992880421d931a88083f73bed093dee5 100644
--- a/src/util/pureConstant.service.ts
+++ b/src/util/pureConstant.service.ts
@@ -4,20 +4,14 @@ import { Observable, Subscription, of, forkJoin, combineLatest, from } from "rxj
 import { viewerConfigSelectorUseMobileUi } from "src/services/state/viewerConfig.store.helper";
 import { shareReplay, tap, scan, catchError, filter, switchMap, map, distinctUntilChanged, mapTo } from "rxjs/operators";
 import { HttpClient } from "@angular/common/http";
-import { viewerStateFetchedTemplatesSelector, viewerStateSetFetchedAtlases } from "src/services/state/viewerState.store.helper";
 import { LoggingService } from "src/logging";
-import { viewerStateFetchedAtlasesSelector, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState/selectors";
 import { BS_ENDPOINT, BACKENDURL } from "src/util/constants";
-import { flattenReducer } from 'common/util'
-import { IVolumeTypeDetail, TAtlas, TId, TParc, TRegionDetail, TRegionSummary, TSpaceFull, TSpaceSummary, TVolumeSrc } from "./siibraApiConstants/types";
+import { TAtlas, TId, TParc, TRegionDetail, TRegionSummary, TSpaceFull, TSpaceSummary, TVolumeSrc } from "./siibraApiConstants/types";
 import { MultiDimMap, recursiveMutate, mutateDeepMerge } from "./fn";
 import { patchRegions } from './patchPureConstants'
 import { environment } from "src/environments/environment";
 import { MatSnackBar } from "@angular/material/snack-bar";
-import { TTemplateImage } from "./interfaces";
-
-export const SIIBRA_API_VERSION_HEADER_KEY='x-siibra-api-version'
-export const SIIBRA_API_VERSION = '0.1.11'
+import { atlasSelection } from "src/state";
 
 const validVolumeType = new Set([
   'neuroglancer/precomputed',
@@ -93,93 +87,6 @@ export const spaceMiscInfoMap = new Map([
   }],
 ])
 
-function getNehubaConfig(space: TSpaceFull) {
-
-  const darkTheme = space.src_volume_type === 'mri'
-  const { scale } = spaceMiscInfoMap.get(space.id) || { scale: 1 }
-  const backgrd = darkTheme
-    ? [0,0,0,1]
-    : [1,1,1,1]
-
-  const rmPsp = darkTheme
-    ? {"mode":"<","color":[0.1,0.1,0.1,1]}
-    :{"color":[1,1,1,1],"mode":"=="}
-  const drawSubstrates = darkTheme
-    ? {"color":[0.5,0.5,1,0.2]}
-    : {"color":[0,0,0.5,0.15]}
-  const drawZoomLevels = darkTheme
-    ? {"cutOff":150000 * scale }
-    : {"cutOff":200000 * scale,"color":[0.5,0,0,0.15] }
-
-  // enable surface parcellation
-  // otherwise, on segmentation selection, the unselected meshes will also be invisible
-  const surfaceParcellation = space.id === 'minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992'
-  return {
-    "configName": "",
-    "globals": {
-      "hideNullImageValues": true,
-      "useNehubaLayout": {
-        "keepDefaultLayouts": false
-      },
-      "useNehubaMeshLayer": true,
-      "rightClickWithCtrlGlobal": false,
-      "zoomWithoutCtrlGlobal": false,
-      "useCustomSegmentColors": true
-    },
-    "zoomWithoutCtrl": true,
-    "hideNeuroglancerUI": true,
-    "rightClickWithCtrl": true,
-    "rotateAtViewCentre": true,
-    "enableMeshLoadingControl": true,
-    "zoomAtViewCentre": true,
-    // "restrictUserNavigation": true,
-    "dataset": {
-      "imageBackground": backgrd,
-      "initialNgState": {
-        "showDefaultAnnotations": false,
-        "layers": {},
-        "navigation": {
-          "zoomFactor": 350000 * scale,
-        },
-        "perspectiveOrientation": [
-          0.3140767216682434,
-          -0.7418519854545593,
-          0.4988985061645508,
-          -0.3195493221282959
-        ],
-        "perspectiveZoom": 1922235.5293810747 * scale
-      }
-    },
-    "layout": {
-      "useNehubaPerspective": {
-        "perspectiveSlicesBackground": backgrd,
-        "removePerspectiveSlicesBackground": rmPsp,
-        "perspectiveBackground": backgrd,
-        "fixedZoomPerspectiveSlices": {
-          "sliceViewportWidth": 300,
-          "sliceViewportHeight": 300,
-          "sliceZoom": 563818.3562426177 * scale,
-          "sliceViewportSizeMultiplier": 2
-        },
-        "mesh": {
-          "backFaceColor": backgrd,
-          "removeBasedOnNavigation": true,
-          "flipRemovedOctant": true,
-          surfaceParcellation
-        },
-        "centerToOrigin": true,
-        "drawSubstrates": drawSubstrates,
-        "drawZoomLevels": drawZoomLevels,
-        "restrictZoomLevel": {
-          "minZoom": 1200000 * scale,
-          "maxZoom": 3500000 * scale
-        }
-      }
-    }
-  }
-  
-}
-
 @Injectable({
   providedIn: 'root'
 })
@@ -202,10 +109,6 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
 
   public totalAtlasesLength: number
 
-  public allFetchingReady$: Observable<boolean>
-
-  private atlasParcSpcRegionMap = new MultiDimMap()
-
   private _backendUrl = (BACKENDURL && `${BACKENDURL}/`.replace(/\/\/$/, '/')) || `${window.location.origin}${window.location.pathname}`
   get backendUrl() {
     console.warn(`something is using backendUrl`)
@@ -396,9 +299,11 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
     private snackbar: MatSnackBar,
     @Inject(BS_ENDPOINT) private bsEndpoint: string,
   ){
+
+    // TODO how do we find out which theme to use now?
     this.darktheme$ = this.store.pipe(
-      select(viewerStateSelectedTemplateSelector),
-      map(tmpl => tmpl?.useTheme === 'dark')
+      select(atlasSelection.selectors.selectedTemplate),
+      map(tmpl => !!(tmpl && tmpl["@id"] !== 'minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588'))
     )
 
     this.useTouchUI$ = this.store.pipe(
@@ -406,127 +311,95 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
       shareReplay(1)
     )
 
-    this.subscriptions.push(
-      this.fetchedAtlases$.subscribe(fetchedAtlases => 
-        this.store.dispatch(
-          viewerStateSetFetchedAtlases({ fetchedAtlases })
-        )
-      )
-    )
-
-    this.allFetchingReady$ = combineLatest([
-      this.initFetchTemplate$.pipe(
-        filter(v => !!v),
-        map(arr => arr.length),
-      ),
-      this.store.pipe(
-        select(viewerStateFetchedTemplatesSelector),
-        map(arr => arr.length),
-      ),
-      this.store.pipe(
-        select(viewerStateFetchedAtlasesSelector),
-        map(arr => arr.length),
-      )
-    ]).pipe(
-      map(([ expNumTmpl, actNumTmpl, actNumAtlas ]) => {
-        return expNumTmpl === actNumTmpl && actNumAtlas === this.totalAtlasesLength
-      }),
-      distinctUntilChanged(),
-      shareReplay(1),
-    )
+    // this.allFetchingReady$ = combineLatest([
+    //   this.initFetchTemplate$.pipe(
+    //     filter(v => !!v),
+    //     map(arr => arr.length),
+    //   ),
+    //   this.store.pipe(
+    //     select(viewerStateFetchedTemplatesSelector),
+    //     map(arr => arr.length),
+    //   ),
+    //   this.store.pipe(
+    //     select(viewerStateFetchedAtlasesSelector),
+    //     map(arr => arr.length),
+    //   )
+    // ]).pipe(
+    //   map(([ expNumTmpl, actNumTmpl, actNumAtlas ]) => {
+    //     return expNumTmpl === actNumTmpl && actNumAtlas === this.totalAtlasesLength
+    //   }),
+    //   distinctUntilChanged(),
+    //   shareReplay(1),
+    // )
   }
 
-  private getAtlases$ = this.http.get<TAtlas[]>(
-    `${this.bsEndpoint}/atlases`,
-    {
-      observe: 'response'
-    }
-  ).pipe(
-    tap(resp => {
-      const respVersion = resp.headers.get(SIIBRA_API_VERSION_HEADER_KEY)
-      if (respVersion !== SIIBRA_API_VERSION) {
-        this.snackbar.open(`Expecting ${SIIBRA_API_VERSION}, got ${respVersion}. Some functionalities may not work as expected.`, 'Dismiss', {
-          duration: 5000
-        })
-      }
-      console.log(`siibra-api::version::${respVersion}, expecting::${SIIBRA_API_VERSION}`)
-    }),
-    map(resp => {
-      const arr = resp.body
-      const { EXPERIMENTAL_FEATURE_FLAG } = environment
-      if (EXPERIMENTAL_FEATURE_FLAG) return arr
-      return arr
-    }),
-    shareReplay(1),
-  )
-
-  public fetchedAtlases$: Observable<TIAVAtlas[]> = this.getAtlases$.pipe(
-    switchMap(atlases => {
-      return forkJoin(
-        atlases.map(
-          atlas => this.getSpacesAndParc(atlas.id).pipe(
-            map(({ templateSpaces, parcellations }) => {
-              return {
-                '@id': atlas.id,
-                name: atlas.name,
-                templateSpaces: templateSpaces.map(tmpl => {
-                  return {
-                    '@id': tmpl.id,
-                    name: tmpl.name,
-                    availableIn: tmpl.availableParcellations.map(parc => {
-                      return {
-                        '@id': parc.id,
-                        name: parc.name
-                      }
-                    }),
-                    originDatainfos: (tmpl._dataset_specs || []).filter(spec => spec["@type"] === 'fzj/tmp/simpleOriginInfo/v0.0.1')
-                  }
-                }),
-                parcellations: parcellations.filter(p => {
-                  if (p.version?.deprecated) return false
-                  return true
-                }).map(parc => {
-                  return {
-                    '@id': parseId(parc.id),
-                    name: parc.name,
-                    baseLayer: parc.modality === 'cytoarchitecture',
-                    '@version': {
-                      '@next': parc.version?.next,
-                      '@previous': parc.version?.prev,
-                      'name': parc.version?.name,
-                      '@this': parseId(parc.id)
-                    },
-                    groupName: parc.modality || null,
-                    availableIn: parc.availableSpaces.map(space => {
-                      return {
-                        '@id': space.id,
-                        name: space.name,
-                        /**
-                         * TODO need original data format
-                         */
-                        // originalDatasetFormats: [{
-                        //   name: "probability map"
-                        // }]
-                      }
-                    }),
-                    originDatainfos: [...(parc.infos || []), ...(parc._dataset_specs || []).filter(spec => spec["@type"] === 'fzj/tmp/simpleOriginInfo/v0.0.1')]
-                  }
-                })
-              }
-            }),
-            catchError((err, obs) => {
-              console.error(err)
-              return of(null)
-            })
-          )
-        )
-      )
-    }),
-    catchError((err, obs) => of([])),
-    tap((arr: any[]) => this.totalAtlasesLength = arr.length),
-    scan((acc, curr) => acc.concat(curr).sort((a, b) => (a.order || 0) - (b.order || 0)), []),
-    shareReplay(1)
-  )
+  // public fetchedAtlases$: Observable<TIAVAtlas[]> = this.getAtlases$.pipe(
+  //   switchMap(atlases => {
+  //     return forkJoin(
+  //       atlases.map(
+  //         atlas => this.getSpacesAndParc(atlas.id).pipe(
+  //           map(({ templateSpaces, parcellations }) => {
+  //             return {
+  //               '@id': atlas.id,
+  //               name: atlas.name,
+  //               templateSpaces: templateSpaces.map(tmpl => {
+  //                 return {
+  //                   '@id': tmpl.id,
+  //                   name: tmpl.name,
+  //                   availableIn: tmpl.availableParcellations.map(parc => {
+  //                     return {
+  //                       '@id': parc.id,
+  //                       name: parc.name
+  //                     }
+  //                   }),
+  //                   originDatainfos: (tmpl._dataset_specs || []).filter(spec => spec["@type"] === 'fzj/tmp/simpleOriginInfo/v0.0.1')
+  //                 }
+  //               }),
+  //               parcellations: parcellations.filter(p => {
+  //                 if (p.version?.deprecated) return false
+  //                 return true
+  //               }).map(parc => {
+  //                 return {
+  //                   '@id': parseId(parc.id),
+  //                   name: parc.name,
+  //                   baseLayer: parc.modality === 'cytoarchitecture',
+  //                   '@version': {
+  //                     '@next': parc.version?.next,
+  //                     '@previous': parc.version?.prev,
+  //                     'name': parc.version?.name,
+  //                     '@this': parseId(parc.id)
+  //                   },
+  //                   groupName: parc.modality || null,
+  //                   availableIn: parc.availableSpaces.map(space => {
+  //                     return {
+  //                       '@id': space.id,
+  //                       name: space.name,
+  //                       /**
+  //                        * TODO need original data format
+  //                        */
+  //                       // originalDatasetFormats: [{
+  //                       //   name: "probability map"
+  //                       // }]
+  //                     }
+  //                   }),
+  //                   originDatainfos: [...(parc.infos || []), ...(parc._dataset_specs || []).filter(spec => spec["@type"] === 'fzj/tmp/simpleOriginInfo/v0.0.1')]
+  //                 }
+  //               })
+  //             }
+  //           }),
+  //           catchError((err, obs) => {
+  //             console.error(err)
+  //             return of(null)
+  //           })
+  //         )
+  //       )
+  //     )
+  //   }),
+  //   catchError((err, obs) => of([])),
+  //   tap((arr: any[]) => this.totalAtlasesLength = arr.length),
+  //   scan((acc, curr) => acc.concat(curr).sort((a, b) => (a.order || 0) - (b.order || 0)), []),
+  //   shareReplay(1)
+  // )
 
   private atlasTmplConfig: TAtlasTmplViewerConfig = {}
 
@@ -536,316 +409,316 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
     return templateLayers || {}
   }
 
-  public initFetchTemplate$ = this.fetchedAtlases$.pipe(
-    switchMap(atlases => {
-      return forkJoin(
-        atlases.map(atlas => this.getSpacesAndParc(atlas['@id']).pipe(
-          switchMap(({ templateSpaces, parcellations }) => {
-            this.atlasTmplConfig[atlas["@id"]] = {}
-            return forkJoin(
-              templateSpaces.map(
-                tmpl => {
-                  // hardcode 
-                  // see https://github.com/FZJ-INM1-BDA/siibra-python/issues/98
-                  if (
-                    tmpl.id === 'minds/core/referencespace/v1.0.0/tmp-fsaverage'
-                    && !tmpl.availableParcellations.find(p => p.id === 'minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290')  
-                  ) {
-                    tmpl.availableParcellations.push({
-                      id: 'minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290',
-                      name: 'Julich-Brain Probabilistic Cytoarchitectonic Maps (v2.9)'
-                    })
-                  }
-                  this.atlasTmplConfig[atlas["@id"]][tmpl.id] = {}
-                  return tmpl.availableParcellations.map(
-                    parc => this.getRegions(atlas['@id'], parc.id, tmpl.id).pipe(
-                      tap(regions => {
-                        recursiveMutate(
-                          regions,
-                          region => region.children,
-                          region => {
-                            /**
-                             * individual map(s)
-                             * this should work for both fully mapped and interpolated
-                             * in the case of interpolated, it sucks that the ngLayerObj will be set multiple times
-                             */
-
-                            const dedicatedMap = region._dataset_specs.filter(
-                              spec => spec["@type"] === 'fzj/tmp/volume_type/v0.0.1'
-                              && spec.space_id === tmpl.id
-                              && spec['volume_type'] === 'neuroglancer/precomputed'
-                            ) as TVolumeSrc<'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
-                              this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngId] = {
-                                source: `precomputed://${dedicatedMap[0].url}`,
-                                type: "segmentation",
-                                transform: dedicatedMap[0].detail['neuroglancer/precomputed'].transform
-                              }
-                            }
+  // public initFetchTemplate$ = this.fetchedAtlases$.pipe(
+  //   switchMap(atlases => {
+  //     return forkJoin(
+  //       atlases.map(atlas => this.getSpacesAndParc(atlas['@id']).pipe(
+  //         switchMap(({ templateSpaces, parcellations }) => {
+  //           this.atlasTmplConfig[atlas["@id"]] = {}
+  //           return forkJoin(
+  //             templateSpaces.map(
+  //               tmpl => {
+  //                 // hardcode 
+  //                 // see https://github.com/FZJ-INM1-BDA/siibra-python/issues/98
+  //                 if (
+  //                   tmpl.id === 'minds/core/referencespace/v1.0.0/tmp-fsaverage'
+  //                   && !tmpl.availableParcellations.find(p => p.id === 'minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290')  
+  //                 ) {
+  //                   tmpl.availableParcellations.push({
+  //                     id: 'minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290',
+  //                     name: 'Julich-Brain Probabilistic Cytoarchitectonic Maps (v2.9)'
+  //                   })
+  //                 }
+  //                 this.atlasTmplConfig[atlas["@id"]][tmpl.id] = {}
+  //                 return tmpl.availableParcellations.map(
+  //                   parc => this.getRegions(atlas['@id'], parc.id, tmpl.id).pipe(
+  //                     tap(regions => {
+  //                       recursiveMutate(
+  //                         regions,
+  //                         region => region.children,
+  //                         region => {
+  //                           /**
+  //                            * individual map(s)
+  //                            * this should work for both fully mapped and interpolated
+  //                            * in the case of interpolated, it sucks that the ngLayerObj will be set multiple times
+  //                            */
+
+  //                           const dedicatedMap = region._dataset_specs.filter(
+  //                             spec => spec["@type"] === 'fzj/tmp/volume_type/v0.0.1'
+  //                             && spec.space_id === tmpl.id
+  //                             && spec['volume_type'] === 'neuroglancer/precomputed'
+  //                           ) as TVolumeSrc<'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
+  //                             this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngId] = {
+  //                               source: `precomputed://${dedicatedMap[0].url}`,
+  //                               type: "segmentation",
+  //                               transform: dedicatedMap[0].detail['neuroglancer/precomputed'].transform
+  //                             }
+  //                           }
   
-                            /**
-                             * if label index is defined
-                             */
-                            if (!!region.labelIndex) {
-                              const hemisphereKey = /left hemisphere|left/.test(region.name)
-                                // these two keys are, unfortunately, more or less hardcoded
-                                // which is less than ideal
-                                ? 'left hemisphere'
-                                : /right hemisphere|right/.test(region.name)
-                                  ? 'right hemisphere'
-                                  : 'whole brain'
-
-                              if (!region['ngId']) {
-                                const hemispheredNgId = getNgId(atlas['@id'], tmpl.id, parc.id, hemisphereKey)
-                                region['ngId'] = hemispheredNgId
-                              }
-                            }
-                          }  
-                        )
-                        this.atlasParcSpcRegionMap.set(
-                          atlas['@id'], tmpl.id, parc.id, regions
-                        )
+  //                           /**
+  //                            * if label index is defined
+  //                            */
+  //                           if (!!region.labelIndex) {
+  //                             const hemisphereKey = /left hemisphere|left/.test(region.name)
+  //                               // these two keys are, unfortunately, more or less hardcoded
+  //                               // which is less than ideal
+  //                               ? 'left hemisphere'
+  //                               : /right hemisphere|right/.test(region.name)
+  //                                 ? 'right hemisphere'
+  //                                 : 'whole brain'
+
+  //                             if (!region['ngId']) {
+  //                               const hemispheredNgId = getNgId(atlas['@id'], tmpl.id, parc.id, hemisphereKey)
+  //                               region['ngId'] = hemispheredNgId
+  //                             }
+  //                           }
+  //                         }  
+  //                       )
+  //                       this.atlasParcSpcRegionMap.set(
+  //                         atlas['@id'], tmpl.id, parc.id, regions
+  //                       )
   
-                        /**
-                         * populate maps for parc
-                         */
-                        for (const parc of parcellations) {
-                          const precomputedVols = parc._dataset_specs.filter(
-                            spec => spec["@type"] === 'fzj/tmp/volume_type/v0.0.1'
-                              && spec.volume_type === 'neuroglancer/precomputed'
-                              && spec.space_id === tmpl.id
-                          ) as TVolumeSrc<'neuroglancer/precomputed'>[]
-
-                          if (precomputedVols.length === 1) {
-                            const vol = precomputedVols[0]
-                            const key = 'whole brain'
-
-                            const ngIdKey = getNgId(atlas['@id'], tmpl.id, parseId(parc.id), key)
-                            this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngIdKey] = {
-                              source: `precomputed://${vol.url}`,
-                              type: "segmentation",
-                              transform: vol.detail['neuroglancer/precomputed'].transform
-                            }
-                          }
-
-                          if (precomputedVols.length === 2) {
-                            const mapIndexKey = [{
-                              mapIndex: 0,
-                              key: 'left hemisphere'
-                            }, {
-                              mapIndex: 1,
-                              key: 'right hemisphere'
-                            }]
-                            for (const { key, mapIndex } of mapIndexKey) {
-                              const ngIdKey = getNgId(atlas['@id'], tmpl.id, parseId(parc.id), key)
-                              this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngIdKey] = {
-                                source: `precomputed://${precomputedVols[mapIndex].url}`,
-                                type: "segmentation",
-                                transform: precomputedVols[mapIndex].detail['neuroglancer/precomputed'].transform
-                              }
-                            }
-                          }
-
-                          if (precomputedVols.length > 2) {
-                            console.error(`precomputedVols.length > 0, most likely an error`)
-                          }
-                        }
-                      }),
-                      catchError((err, obs) => {
-                        return of(null)
-                      })
-                    )
-                  )
-                }
-              ).reduce(flattenReducer, [])
-            ).pipe(
-              mapTo({ templateSpaces, parcellations, ngLayerObj: this.atlasTmplConfig })
-            )
-          }),
-          map(({ templateSpaces, parcellations, ngLayerObj }) => {
-            return templateSpaces.map(tmpl => {
-
-              // configuring three-surfer
-              let threeSurferConfig = {}
-              const volumes  = tmpl._dataset_specs.filter(v => v["@type"] === 'fzj/tmp/volume_type/v0.0.1') as TVolumeSrc<keyof IVolumeTypeDetail>[]
-              const threeSurferVolSrc = volumes.find(v => v.volume_type === 'threesurfer/gii')
-              if (threeSurferVolSrc) {
-                const foundP = parcellations.find(p => {
-                  return p._dataset_specs.some(spec => spec["@type"] === 'fzj/tmp/volume_type/v0.0.1' && spec.space_id === tmpl.id)
-                })
-                const url = threeSurferVolSrc.url
-                const { surfaces } = threeSurferVolSrc.detail['threesurfer/gii'] as { surfaces: {mode: string, hemisphere: 'left' | 'right', url: string}[] }
-                const modObj = {}
-                for (const surface of surfaces) {
+  //                       /**
+  //                        * populate maps for parc
+  //                        */
+  //                       for (const parc of parcellations) {
+  //                         const precomputedVols = parc._dataset_specs.filter(
+  //                           spec => spec["@type"] === 'fzj/tmp/volume_type/v0.0.1'
+  //                             && spec.volume_type === 'neuroglancer/precomputed'
+  //                             && spec.space_id === tmpl.id
+  //                         ) as TVolumeSrc<'neuroglancer/precomputed'>[]
+
+  //                         if (precomputedVols.length === 1) {
+  //                           const vol = precomputedVols[0]
+  //                           const key = 'whole brain'
+
+  //                           const ngIdKey = getNgId(atlas['@id'], tmpl.id, parseId(parc.id), key)
+  //                           this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngIdKey] = {
+  //                             source: `precomputed://${vol.url}`,
+  //                             type: "segmentation",
+  //                             transform: vol.detail['neuroglancer/precomputed'].transform
+  //                           }
+  //                         }
+
+  //                         if (precomputedVols.length === 2) {
+  //                           const mapIndexKey = [{
+  //                             mapIndex: 0,
+  //                             key: 'left hemisphere'
+  //                           }, {
+  //                             mapIndex: 1,
+  //                             key: 'right hemisphere'
+  //                           }]
+  //                           for (const { key, mapIndex } of mapIndexKey) {
+  //                             const ngIdKey = getNgId(atlas['@id'], tmpl.id, parseId(parc.id), key)
+  //                             this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngIdKey] = {
+  //                               source: `precomputed://${precomputedVols[mapIndex].url}`,
+  //                               type: "segmentation",
+  //                               transform: precomputedVols[mapIndex].detail['neuroglancer/precomputed'].transform
+  //                             }
+  //                           }
+  //                         }
+
+  //                         if (precomputedVols.length > 2) {
+  //                           console.error(`precomputedVols.length > 0, most likely an error`)
+  //                         }
+  //                       }
+  //                     }),
+  //                     catchError((err, obs) => {
+  //                       return of(null)
+  //                     })
+  //                   )
+  //                 )
+  //               }
+  //             ).reduce(flattenReducer, [])
+  //           ).pipe(
+  //             mapTo({ templateSpaces, parcellations, ngLayerObj: this.atlasTmplConfig })
+  //           )
+  //         }),
+  //         map(({ templateSpaces, parcellations, ngLayerObj }) => {
+  //           return templateSpaces.map(tmpl => {
+
+  //             // configuring three-surfer
+  //             let threeSurferConfig = {}
+  //             const volumes  = tmpl._dataset_specs.filter(v => v["@type"] === 'fzj/tmp/volume_type/v0.0.1') as TVolumeSrc<keyof IVolumeTypeDetail>[]
+  //             const threeSurferVolSrc = volumes.find(v => v.volume_type === 'threesurfer/gii')
+  //             if (threeSurferVolSrc) {
+  //               const foundP = parcellations.find(p => {
+  //                 return p._dataset_specs.some(spec => spec["@type"] === 'fzj/tmp/volume_type/v0.0.1' && spec.space_id === tmpl.id)
+  //               })
+  //               const url = threeSurferVolSrc.url
+  //               const { surfaces } = threeSurferVolSrc.detail['threesurfer/gii'] as { surfaces: {mode: string, hemisphere: 'left' | 'right', url: string}[] }
+  //               const modObj = {}
+  //               for (const surface of surfaces) {
                   
-                  const hemisphereKey = surface.hemisphere === 'left'
-                    ? 'left hemisphere'
-                    : 'right hemisphere'
-
-
-                  /**
-                   * concating all available gii maps
-                   */
-                  // const allFreesurferLabels = foundP.volumeSrc[tmpl.id][hemisphereKey].filter(v => v.volume_type === 'threesurfer/gii-label')
-                  // for (const lbl of allFreesurferLabels) {
-                  //   const modeToConcat = {
-                  //     mesh: surface.url,
-                  //     hemisphere: surface.hemisphere,
-                  //     colormap: lbl.url
-                  //   }
-
-                  //   const key = `${surface.mode} - ${lbl.name}`
-                  //   if (!modObj[key]) {
-                  //     modObj[key] = []
-                  //   }
-                  //   modObj[key].push(modeToConcat)
-                  // }
-
-                  /**
-                   * only concat first matching gii map
-                   */
-                  const mapIndex = hemisphereKey === 'left hemisphere'
-                    ? 0
-                    : 1
-                  const labelMaps = foundP._dataset_specs.filter(spec => spec["@type"] === 'fzj/tmp/volume_type/v0.0.1' && spec.volume_type === 'threesurfer/gii-label') as TVolumeSrc<'threesurfer/gii-label'>[]
-                  const key = surface.mode
-                  const modeToConcat = {
-                    mesh: surface.url,
-                    hemisphere: surface.hemisphere,
-                    colormap: (() => {
-                      const lbl = labelMaps[mapIndex]
-                      return lbl?.url
-                    })()
-                  }
-                  if (!modObj[key]) {
-                    modObj[key] = []
-                  }
-                  modObj[key].push(modeToConcat)
-
-                }
-                foundP[tmpl.id]
-                threeSurferConfig = {
-                  "three-surfer": {
-                    '@context': {
-                      root: url
-                    },
-                    modes: Object.keys(modObj).map(name => {
-                      return {
-                        name,
-                        meshes: modObj[name]
-                      }
-                    })
-                  },
-                  nehubaConfig: null,
-                  nehubaConfigURL: null,
-                  useTheme: 'dark'
-                }
-              }
-              const darkTheme = tmpl.src_volume_type === 'mri'
-              const nehubaConfig = getNehubaConfig(tmpl)
-              const initialLayers = nehubaConfig.dataset.initialNgState.layers
+  //                 const hemisphereKey = surface.hemisphere === 'left'
+  //                   ? 'left hemisphere'
+  //                   : 'right hemisphere'
+
+
+  //                 /**
+  //                  * concating all available gii maps
+  //                  */
+  //                 // const allFreesurferLabels = foundP.volumeSrc[tmpl.id][hemisphereKey].filter(v => v.volume_type === 'threesurfer/gii-label')
+  //                 // for (const lbl of allFreesurferLabels) {
+  //                 //   const modeToConcat = {
+  //                 //     mesh: surface.url,
+  //                 //     hemisphere: surface.hemisphere,
+  //                 //     colormap: lbl.url
+  //                 //   }
+
+  //                 //   const key = `${surface.mode} - ${lbl.name}`
+  //                 //   if (!modObj[key]) {
+  //                 //     modObj[key] = []
+  //                 //   }
+  //                 //   modObj[key].push(modeToConcat)
+  //                 // }
+
+  //                 /**
+  //                  * only concat first matching gii map
+  //                  */
+  //                 const mapIndex = hemisphereKey === 'left hemisphere'
+  //                   ? 0
+  //                   : 1
+  //                 const labelMaps = foundP._dataset_specs.filter(spec => spec["@type"] === 'fzj/tmp/volume_type/v0.0.1' && spec.volume_type === 'threesurfer/gii-label') as TVolumeSrc<'threesurfer/gii-label'>[]
+  //                 const key = surface.mode
+  //                 const modeToConcat = {
+  //                   mesh: surface.url,
+  //                   hemisphere: surface.hemisphere,
+  //                   colormap: (() => {
+  //                     const lbl = labelMaps[mapIndex]
+  //                     return lbl?.url
+  //                   })()
+  //                 }
+  //                 if (!modObj[key]) {
+  //                   modObj[key] = []
+  //                 }
+  //                 modObj[key].push(modeToConcat)
+
+  //               }
+  //               foundP[tmpl.id]
+  //               threeSurferConfig = {
+  //                 "three-surfer": {
+  //                   '@context': {
+  //                     root: url
+  //                   },
+  //                   modes: Object.keys(modObj).map(name => {
+  //                     return {
+  //                       name,
+  //                       meshes: modObj[name]
+  //                     }
+  //                   })
+  //                 },
+  //                 nehubaConfig: null,
+  //                 nehubaConfigURL: null,
+  //                 useTheme: 'dark'
+  //               }
+  //             }
+  //             const darkTheme = tmpl.src_volume_type === 'mri'
+  //             const nehubaConfig = getNehubaConfig(tmpl)
+  //             const initialLayers = nehubaConfig.dataset.initialNgState.layers
               
-              const tmplAuxMesh = `${tmpl.name} auxmesh`
-
-              const precomputedArr = tmpl._dataset_specs.filter(src => src['@type'] === 'fzj/tmp/volume_type/v0.0.1' && src.volume_type === 'neuroglancer/precomputed') as TVolumeSrc<'neuroglancer/precomputed'>[]
-              let visible = true
-              let tmplNgId: string
-              const templateImages: TTemplateImage[] = []
-              for (const precomputedItem of precomputedArr) {
-                const ngIdKey = MultiDimMap.GetKey(precomputedItem["@id"])
-                const precomputedUrl = 'https://neuroglancer.humanbrainproject.eu/precomputed/data-repo-ng-bot/20211001-mebrain/precomputed/images/MEBRAINS_T1.masked' === precomputedItem.url
-                  ? 'https://neuroglancer.humanbrainproject.eu/precomputed/data-repo-ng-bot/20211018-mebrains-masked-templates/precomputed/images/MEBRAINS_T1_masked'
-                  : precomputedItem.url
-                initialLayers[ngIdKey] = {
-                  type: "image",
-                  source: `precomputed://${precomputedUrl}`,
-                  transform: precomputedItem.detail['neuroglancer/precomputed'].transform,
-                  visible
-                }
-                templateImages.push({
-                  "@id": precomputedItem['@id'],
-                  name: precomputedItem.name,
-                  ngId: ngIdKey,
-                  visible
-                })
-                if (visible) {
-                  tmplNgId = ngIdKey
-                }
-                visible = false
-              }
-
-              // TODO
-              // siibra-python accidentally left out volume type of precompmesh
-              // https://github.com/FZJ-INM1-BDA/siibra-python/pull/55
-              // use url to determine for now
-              // const precompmesh = tmpl.volume_src.find(src => src.volume_type === 'neuroglancer/precompmesh')
-              const precompmesh = tmpl._dataset_specs.find(src => src["@type"] === 'fzj/tmp/volume_type/v0.0.1' && !!src.detail?.['neuroglancer/precompmesh']) as TVolumeSrc<'neuroglancer/precompmesh'>
-              const auxMeshes = []
-              if (precompmesh){
-                initialLayers[tmplAuxMesh] = {
-                  source: `precompmesh://${precompmesh.url}`,
-                  type: "segmentation",
-                  transform: precompmesh.detail['neuroglancer/precompmesh'].transform
-                }
-                for (const auxMesh of precompmesh.detail['neuroglancer/precompmesh'].auxMeshes) {
-
-                  auxMeshes.push({
-                    ...auxMesh,
-                    ngId: tmplAuxMesh,
-                    '@id': `${tmplAuxMesh} ${auxMesh.name}`,
-                    visible: true
-                  })
-                }
-              }
-
-              for (const key in (ngLayerObj[atlas["@id"]][tmpl.id] || {})) {
-                initialLayers[key] = ngLayerObj[atlas["@id"]][tmpl.id][key]
-              }
-
-              return {
-                name: tmpl.name,
-                '@id': tmpl.id,
-                fullId: tmpl.id,
-                useTheme: darkTheme ? 'dark' : 'light',
-                ngId: tmplNgId,
-                nehubaConfig,
-                templateImages,
-                auxMeshes,
-                /**
-                 * only populate the parcelltions made available
-                 */
-                parcellations: tmpl.availableParcellations.filter(
-                  p => parcellations.some(p2 => parseId(p2.id) === p.id)
-                ).map(parc => {
-                  const fullParcInfo = parcellations.find(p => parseId(p.id) === parc.id)
-                  const regions = this.atlasParcSpcRegionMap.get(atlas['@id'], tmpl.id, parc.id) || []
-                  return {
-                    fullId: parc.id,
-                    '@id': parc.id,
-                    name: parc.name,
-                    regions,
-                    originDatainfos: [...fullParcInfo.infos, ...(fullParcInfo?._dataset_specs || []).filter(spec => spec["@type"] === 'fzj/tmp/simpleOriginInfo/v0.0.1')]
-                  }
-                }),
-                ...threeSurferConfig
-              }
-            })
-          })
-        ))
-      )
-    }),
-    map(arr => {
-      return arr.reduce(flattenReducer, [])
-    }),
-    catchError((err) => {
-      this.log.warn(`fetching templates error`, err)
-      return of(null)
-    }),
-    shareReplay(1),
-  )
+  //             const tmplAuxMesh = `${tmpl.name} auxmesh`
+
+  //             const precomputedArr = tmpl._dataset_specs.filter(src => src['@type'] === 'fzj/tmp/volume_type/v0.0.1' && src.volume_type === 'neuroglancer/precomputed') as TVolumeSrc<'neuroglancer/precomputed'>[]
+  //             let visible = true
+  //             let tmplNgId: string
+  //             const templateImages: TTemplateImage[] = []
+  //             for (const precomputedItem of precomputedArr) {
+  //               const ngIdKey = MultiDimMap.GetKey(precomputedItem["@id"])
+  //               const precomputedUrl = 'https://neuroglancer.humanbrainproject.eu/precomputed/data-repo-ng-bot/20211001-mebrain/precomputed/images/MEBRAINS_T1.masked' === precomputedItem.url
+  //                 ? 'https://neuroglancer.humanbrainproject.eu/precomputed/data-repo-ng-bot/20211018-mebrains-masked-templates/precomputed/images/MEBRAINS_T1_masked'
+  //                 : precomputedItem.url
+  //               initialLayers[ngIdKey] = {
+  //                 type: "image",
+  //                 source: `precomputed://${precomputedUrl}`,
+  //                 transform: precomputedItem.detail['neuroglancer/precomputed'].transform,
+  //                 visible
+  //               }
+  //               templateImages.push({
+  //                 "@id": precomputedItem['@id'],
+  //                 name: precomputedItem.name,
+  //                 ngId: ngIdKey,
+  //                 visible
+  //               })
+  //               if (visible) {
+  //                 tmplNgId = ngIdKey
+  //               }
+  //               visible = false
+  //             }
+
+  //             // TODO
+  //             // siibra-python accidentally left out volume type of precompmesh
+  //             // https://github.com/FZJ-INM1-BDA/siibra-python/pull/55
+  //             // use url to determine for now
+  //             // const precompmesh = tmpl.volume_src.find(src => src.volume_type === 'neuroglancer/precompmesh')
+  //             const precompmesh = tmpl._dataset_specs.find(src => src["@type"] === 'fzj/tmp/volume_type/v0.0.1' && !!src.detail?.['neuroglancer/precompmesh']) as TVolumeSrc<'neuroglancer/precompmesh'>
+  //             const auxMeshes = []
+  //             if (precompmesh){
+  //               initialLayers[tmplAuxMesh] = {
+  //                 source: `precompmesh://${precompmesh.url}`,
+  //                 type: "segmentation",
+  //                 transform: precompmesh.detail['neuroglancer/precompmesh'].transform
+  //               }
+  //               for (const auxMesh of precompmesh.detail['neuroglancer/precompmesh'].auxMeshes) {
+
+  //                 auxMeshes.push({
+  //                   ...auxMesh,
+  //                   ngId: tmplAuxMesh,
+  //                   '@id': `${tmplAuxMesh} ${auxMesh.name}`,
+  //                   visible: true
+  //                 })
+  //               }
+  //             }
+
+  //             for (const key in (ngLayerObj[atlas["@id"]][tmpl.id] || {})) {
+  //               initialLayers[key] = ngLayerObj[atlas["@id"]][tmpl.id][key]
+  //             }
+
+  //             return {
+  //               name: tmpl.name,
+  //               '@id': tmpl.id,
+  //               fullId: tmpl.id,
+  //               useTheme: darkTheme ? 'dark' : 'light',
+  //               ngId: tmplNgId,
+  //               nehubaConfig,
+  //               templateImages,
+  //               auxMeshes,
+  //               /**
+  //                * only populate the parcelltions made available
+  //                */
+  //               parcellations: tmpl.availableParcellations.filter(
+  //                 p => parcellations.some(p2 => parseId(p2.id) === p.id)
+  //               ).map(parc => {
+  //                 const fullParcInfo = parcellations.find(p => parseId(p.id) === parc.id)
+  //                 const regions = this.atlasParcSpcRegionMap.get(atlas['@id'], tmpl.id, parc.id) || []
+  //                 return {
+  //                   fullId: parc.id,
+  //                   '@id': parc.id,
+  //                   name: parc.name,
+  //                   regions,
+  //                   originDatainfos: [...fullParcInfo.infos, ...(fullParcInfo?._dataset_specs || []).filter(spec => spec["@type"] === 'fzj/tmp/simpleOriginInfo/v0.0.1')]
+  //                 }
+  //               }),
+  //               ...threeSurferConfig
+  //             }
+  //           })
+  //         })
+  //       ))
+  //     )
+  //   }),
+  //   map(arr => {
+  //     return arr.reduce(flattenReducer, [])
+  //   }),
+  //   catchError((err) => {
+  //     this.log.warn(`fetching templates error`, err)
+  //     return of(null)
+  //   }),
+  //   shareReplay(1),
+  // )
 
   ngOnDestroy(){
     while(this.subscriptions.length > 0) this.subscriptions.pop().unsubscribe()
diff --git a/src/viewerModule/module.ts b/src/viewerModule/module.ts
index 8ec584071f6b3b2b2142e3d1be818f8a31f588e5..2f3d89f79a5999a2059a454b289c35da97e5d68d 100644
--- a/src/viewerModule/module.ts
+++ b/src/viewerModule/module.ts
@@ -3,7 +3,6 @@ import { NgModule } from "@angular/core";
 import { Observable } from "rxjs";
 import { AtlasCmpParcellationModule } from "src/atlasComponents/parcellation";
 import { ParcellationRegionModule } from "src/atlasComponents/parcellationRegion";
-import { BSFeatureModule, BS_DARKTHEME,  } from "src/atlasComponents/regionalFeatures/bsFeatures";
 import { SplashUiModule } from "src/atlasComponents/splashScreen";
 import { AtlasCmpUiSelectorsModule } from "src/atlasComponents/uiSelectors";
 import { ComponentsModule } from "src/components";
@@ -12,18 +11,16 @@ import { LayoutModule } from "src/layouts/layout.module";
 import { AngularMaterialModule } from "src/sharedModules";
 import { TopMenuModule } from "src/ui/topMenu/module";
 import { CONTEXT_MENU_ITEM_INJECTOR, TContextMenu, UtilModule } from "src/util";
-import { VIEWERMODULE_DARKTHEME } from "./constants";
 import { NehubaModule, NehubaViewerUnit } from "./nehuba";
 import { ThreeSurferModule } from "./threeSurfer";
 import { ViewerCmp } from "./viewerCmp/viewerCmp.component";
-import {UserAnnotationsModule} from "src/atlasComponents/userAnnotations";
-import {QuickTourModule} from "src/ui/quickTour/module";
+import { UserAnnotationsModule } from "src/atlasComponents/userAnnotations";
+import { QuickTourModule } from "src/ui/quickTour/module";
 import { INJ_ANNOT_TARGET } from "src/atlasComponents/userAnnotations/tools/type";
 import { NEHUBA_INSTANCE_INJTKN } from "./nehuba/util";
 import { map } from "rxjs/operators";
 import { TContextArg } from "./viewer.interface";
 import { ViewerStateBreadCrumbModule } from "./viewerStateBreadCrumb/module";
-import { KgRegionalFeatureModule } from "src/atlasComponents/regionalFeatures/bsFeatures/kgRegionalFeature";
 import { API_SERVICE_SET_VIEWER_HANDLE_TOKEN, AtlasViewerAPIServices, setViewerHandleFactory } from "src/atlasViewer/atlasViewer.apiService.service";
 import { ILoadMesh, LOAD_MESH_TOKEN } from "src/messaging/types";
 import { KeyFrameModule } from "src/keyframesModule/module";
@@ -46,12 +43,10 @@ import { NehubaVCtxToBbox } from "./pipes/nehubaVCtxToBbox.pipe";
     UtilModule,
     AtlasCmpParcellationModule,
     ComponentsModule,
-    BSFeatureModule,
     UserAnnotationsModule,
     QuickTourModule,
     ContextMenuModule,
     ViewerStateBreadCrumbModule,
-    KgRegionalFeatureModule,
     KeyFrameModule,
     LayerBrowserModule,
     SAPIModule,
@@ -61,13 +56,6 @@ import { NehubaVCtxToBbox } from "./pipes/nehubaVCtxToBbox.pipe";
     NehubaVCtxToBbox,
   ],
   providers: [
-    {
-      provide: BS_DARKTHEME,
-      useFactory: (obs$: Observable<boolean>) => obs$,
-      deps: [
-        VIEWERMODULE_DARKTHEME
-      ]
-    },
     {
       provide: INJ_ANNOT_TARGET,
       useFactory: (obs$: Observable<NehubaViewerUnit>) => {
diff --git a/src/viewerModule/nehuba/config.service/config.service.spec.ts b/src/viewerModule/nehuba/config.service/config.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/viewerModule/nehuba/config.service/index.ts b/src/viewerModule/nehuba/config.service/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8e92b3a002d5971a9616ed6899316506f7b615c0
--- /dev/null
+++ b/src/viewerModule/nehuba/config.service/index.ts
@@ -0,0 +1,19 @@
+export {
+  NehubaConfig,
+  NgConfig,
+  NgConfigViewerState,
+  NgLayerSpec,
+  NgPrecompMeshSpec,
+  NgSegLayerSpec,
+} from "./type"
+export {
+  getParcNgLayers,
+  getTmplAuxNgLayer,
+  getTmplNgLayer,
+  getNgLayersFromVolumesATP,
+  getParcNgId,
+  fromRootStore,
+  getRegionLabelIndex,
+  getNehubaConfig,
+  defaultNehubaConfig,
+} from "./util"
diff --git a/src/viewerModule/nehuba/config.service/type.ts b/src/viewerModule/nehuba/config.service/type.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fc79b98557e80a05e49ae1c5f526a5763520c18d
--- /dev/null
+++ b/src/viewerModule/nehuba/config.service/type.ts
@@ -0,0 +1,115 @@
+
+export type RecursivePartial<T> = {
+  [K in keyof T]?: RecursivePartial<T[K]>
+}
+
+type Vec4 = number[]
+type Vec3 = number[]
+
+export type NgConfigViewerState = {
+  perspectiveOrientation: Vec4
+  perspectiveZoom: number
+  navigation: {
+    pose: {
+      position: {
+        voxelSize: Vec3
+        voxelCoordinates: Vec3
+      }
+      orientation: Vec4
+    }
+    zoomFactor: number
+  }
+}
+
+export type NgConfig = {
+  showDefaultAnnotations: boolean
+  layers: Record<string, NgLayerSpec>
+  gpuMemoryLimit: number,
+} & NgConfigViewerState
+
+interface _NehubaConfig {
+  configName: string
+  globals: {
+    hideNullImageValues: boolean
+    useNehubaLayout: {
+      keepDefaultLayouts: boolean
+    }
+    useNehubaMeshLayer: boolean
+    rightClickWithCtrlGlobal: boolean
+    zoomWithoutCtrlGlobal: boolean
+    useCustomSegmentColors: boolean
+  }
+  zoomWithoutCtrl: boolean
+  hideNeuroglancerUI: boolean
+  rightClickWithCtrl: boolean
+  rotateAtViewCentre: boolean
+  enableMeshLoadingControl: boolean
+  zoomAtViewCentre: boolean
+  restrictUserNavigation: boolean
+  disableSegmentSelection: boolean
+  dataset: {
+    imageBackground: Vec4
+    initialNgState: NgConfig
+  },
+  layout: {
+    views: string,
+    planarSlicesBackground: Vec4
+    useNehubaPerspective: {
+      enableShiftDrag: boolean
+      doNotRestrictUserNavigation: boolean
+      removePerspectiveSlicesBackground: {
+        mode: string
+        color: Vec4
+      }
+      perspectiveSlicesBackground: Vec4
+      perspectiveBackground: Vec4
+      fixedZoomPerspectiveSlices: {
+        sliceViewportWidth: number
+        sliceViewportHeight: number
+        sliceZoom: number
+        sliceViewportSizeMultiplier: number
+      }
+      mesh: {
+        backFaceColor: Vec4
+        removeBasedOnNavigation: boolean
+        flipRemovedOctant: boolean
+        surfaceParcellation: boolean
+      },
+      centerToOrigin: boolean
+      drawSubstrates: {
+        color: Vec4
+      }
+      drawZoomLevels: {
+        cutOff: number
+        color: Vec4
+      }
+      restrictZoomLevel: {
+        minZoom: number
+        maxZoom: number
+      }
+      hideImages: boolean
+      waitForMesh: boolean
+    }
+  }
+}
+
+export type NehubaConfig = RecursivePartial<_NehubaConfig>
+
+export type NgLayerSpec = {
+  source: string
+  transform: number[][]
+  opacity?: number
+  visible?: boolean
+}
+
+export type NgPrecompMeshSpec = {
+  auxMeshes: {
+    name: string
+    labelIndicies: number[]
+  }[]
+} & NgLayerSpec
+
+export type NgSegLayerSpec = {
+  labelIndicies: number[]
+  laterality: 'left hemisphere' | 'right hemisphere' | 'whole brain'
+} & NgLayerSpec
diff --git a/src/viewerModule/nehuba/config.service/util.spec.ts b/src/viewerModule/nehuba/config.service/util.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b3e87a6c2ec5aa8ad9cde9d2eac4a9c9300194d2
--- /dev/null
+++ b/src/viewerModule/nehuba/config.service/util.spec.ts
@@ -0,0 +1,141 @@
+import { cvtNavigationObjToNehubaConfig } from './util'
+
+const currentNavigation = {
+  position: [4, 5, 6],
+  orientation: [0, 0, 0, 1],
+  perspectiveOrientation: [ 0, 0, 0, 1],
+  perspectiveZoom: 2e5,
+  zoom: 1e5
+}
+
+const defaultPerspectiveZoom = 1e6
+const defaultZoom = 1e6
+
+const defaultNavigationObject = {
+  orientation: [0, 0, 0, 1],
+  perspectiveOrientation: [0 , 0, 0, 1],
+  perspectiveZoom: defaultPerspectiveZoom,
+  zoom: defaultZoom,
+  position: [0, 0, 0],
+  positionReal: true
+}
+
+const defaultNehubaConfigObject = {
+  perspectiveOrientation: [0, 0, 0, 1],
+  perspectiveZoom: 1e6,
+  navigation: {
+    pose: {
+      position: {
+        voxelCoordinates: [0, 0, 0],
+        voxelSize: [1,1,1]
+      },
+      orientation: [0, 0, 0, 1],
+    },
+    zoomFactor: defaultZoom
+  }
+}
+
+const bigbrainNehubaConfig = {
+  "showDefaultAnnotations": false,
+  "layers": {
+  },
+  "navigation": {
+    "pose": {
+      "position": {
+        "voxelSize": [
+          21166.666015625,
+          20000,
+          21166.666015625
+        ],
+        "voxelCoordinates": [
+          -21.8844051361084,
+          16.288618087768555,
+          28.418994903564453
+        ]
+      }
+    },
+    "zoomFactor": 350000
+  },
+  "perspectiveOrientation": [
+    0.3140767216682434,
+    -0.7418519854545593,
+    0.4988985061645508,
+    -0.3195493221282959
+  ],
+  "perspectiveZoom": 1922235.5293810747
+}
+
+describe('> util.ts', () => {
+  
+  describe('> cvtNavigationObjToNehubaConfig', () => {
+    const validNavigationObj = currentNavigation
+    describe('> if inputs are malformed', () => {
+      describe('> if navigation object is malformed, uses navigation default object', () => {
+        it('> if navigation object is null', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(null, bigbrainNehubaConfig)
+          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, bigbrainNehubaConfig)
+          expect(v1).toEqual(v2)
+        })
+        it('> if navigation object is undefined', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(undefined, bigbrainNehubaConfig)
+          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, bigbrainNehubaConfig)
+          expect(v1).toEqual(v2)
+        })
+
+        it('> if navigation object is otherwise malformed', () => {
+          const v1 = cvtNavigationObjToNehubaConfig({foo: 'bar'}, bigbrainNehubaConfig)
+          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, bigbrainNehubaConfig)
+          expect(v1).toEqual(v2)
+
+          const v3 = cvtNavigationObjToNehubaConfig({}, bigbrainNehubaConfig)
+          const v4 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, bigbrainNehubaConfig)
+          expect(v3).toEqual(v4)
+        })
+      })
+
+      describe('> if nehubaConfig object is malformed, use default nehubaConfig obj', () => {
+        it('> if nehubaConfig is null', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, null)
+          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
+          expect(v1).toEqual(v2)
+        })
+
+        it('> if nehubaConfig is undefined', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, undefined)
+          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
+          expect(v1).toEqual(v2)
+        })
+
+        it('> if nehubaConfig is otherwise malformed', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, {})
+          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
+          expect(v1).toEqual(v2)
+
+          const v3 = cvtNavigationObjToNehubaConfig(validNavigationObj, {foo: 'bar'} as any)
+          const v4 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
+          expect(v3).toEqual(v4)
+        })
+      })
+    })
+    it('> converts navigation object and reference nehuba config object to navigation object', () => {
+      const convertedVal = cvtNavigationObjToNehubaConfig(validNavigationObj, bigbrainNehubaConfig)
+      const { perspectiveOrientation, orientation, zoom, perspectiveZoom, position } = validNavigationObj
+      
+      expect(convertedVal).toEqual({
+        navigation: {
+          pose: {
+            position: {
+              voxelSize: bigbrainNehubaConfig.navigation.pose.position.voxelSize,
+              voxelCoordinates: [0, 1, 2].map(idx => position[idx] / bigbrainNehubaConfig.navigation.pose.position.voxelSize[idx])
+            },
+            orientation
+          },
+          zoomFactor: zoom
+        },
+        perspectiveOrientation: perspectiveOrientation,
+        perspectiveZoom: perspectiveZoom
+      })
+    })
+  })
+
+})
diff --git a/src/viewerModule/nehuba/config.service/util.ts b/src/viewerModule/nehuba/config.service/util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b81660ed18b776d67be8eb629d42c8d201baafbf
--- /dev/null
+++ b/src/viewerModule/nehuba/config.service/util.ts
@@ -0,0 +1,484 @@
+import { select, Store } from '@ngrx/store'
+import { forkJoin, pipe } from 'rxjs'
+import { SapiParcellationModel, SapiSpaceModel, SapiAtlasModel, SapiRegionModel, SAPI } from 'src/atlasComponents/sapi'
+import { SapiVolumeModel } from 'src/atlasComponents/sapi/type'
+import { MultiDimMap } from 'src/util/fn'
+import { ParcVolumeSpec } from "../store/util"
+import { fromRootStore as nehubaStoreFromRootStore } from "../store"
+import { map, switchMap } from 'rxjs/operators'
+import {
+  NehubaConfig,
+  NgConfig,
+  RecursivePartial,
+  NgLayerSpec,
+  NgPrecompMeshSpec,
+  NgSegLayerSpec,
+} from "./type"
+import { atlasSelection } from 'src/state'
+
+// fsaverage uses threesurfer, which, whilst do not use ngId, uses 'left' and 'right' as keys 
+const fsAverageKeyVal = {
+  "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290": {
+    "left hemisphere": "left",
+    "right hemisphere": "right"
+  }
+}
+
+/**
+ * in order to maintain backwards compat with url encoding of selected regions
+ * TODO setup a sentry to catch if these are ever used. if not, retire the hard coding 
+ */
+ const BACKCOMAP_KEY_DICT = {
+
+  // human multi level
+  'juelich/iav/atlas/v1.0.0/1': {
+    // icbm152
+    'minds/core/referencespace/v1.0.0/dafcffc5-4826-4bf1-8ff6-46b8a31ff8e2': {
+      // julich brain v2.6
+      'minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-26': {
+        'left hemisphere': 'MNI152_V25_LEFT_NG_SPLIT_HEMISPHERE',
+        'right hemisphere': 'MNI152_V25_RIGHT_NG_SPLIT_HEMISPHERE'
+      },
+      // bundle hcp
+      // even though hcp, long/short bundle, and difumo has no hemisphere distinctions, the way siibra-python parses the region,
+      // and thus attributes left/right hemisphere, still results in some regions being parsed as left/right hemisphere
+      "juelich/iav/atlas/v1.0.0/79cbeaa4ee96d5d3dfe2876e9f74b3dc3d3ffb84304fb9b965b1776563a1069c": {
+        "whole brain": "superficial-white-bundle-HCP",
+        "left hemisphere": "superficial-white-bundle-HCP",
+        "right hemisphere": "superficial-white-bundle-HCP"
+      },
+      // julich brain v1.18
+      "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579": {
+        "left hemisphere": "jubrain mni152 v18 left",
+        "right hemisphere": "jubrain mni152 v18 right",
+      },
+      // long bundle
+      "juelich/iav/atlas/v1.0.0/5": {
+        "whole brain": "fibre bundle long",
+        "left hemisphere": "fibre bundle long",
+        "right hemisphere": "fibre bundle long",
+      },
+      // bundle short
+      "juelich/iav/atlas/v1.0.0/6": {
+        "whole brain": "fibre bundle short",
+        "left hemisphere": "fibre bundle short",
+        "right hemisphere": "fibre bundle short",
+      },
+      // difumo 64
+      "minds/core/parcellationatlas/v1.0.0/d80fbab2-ce7f-4901-a3a2-3c8ef8a3b721": {
+        "whole brain": "DiFuMo Atlas (64 dimensions)",
+        "left hemisphere": "DiFuMo Atlas (64 dimensions)",
+        "right hemisphere": "DiFuMo Atlas (64 dimensions)",
+      },
+      "minds/core/parcellationatlas/v1.0.0/73f41e04-b7ee-4301-a828-4b298ad05ab8": {
+        "whole brain": "DiFuMo Atlas (128 dimensions)",
+        "left hemisphere": "DiFuMo Atlas (128 dimensions)",
+        "right hemisphere": "DiFuMo Atlas (128 dimensions)",
+      },
+      "minds/core/parcellationatlas/v1.0.0/141d510f-0342-4f94-ace7-c97d5f160235": {
+        "whole brain": "DiFuMo Atlas (256 dimensions)",
+        "left hemisphere": "DiFuMo Atlas (256 dimensions)",
+        "right hemisphere": "DiFuMo Atlas (256 dimensions)",
+      },
+      "minds/core/parcellationatlas/v1.0.0/63b5794f-79a4-4464-8dc1-b32e170f3d16": {
+        "whole brain": "DiFuMo Atlas (512 dimensions)",
+        "left hemisphere": "DiFuMo Atlas (512 dimensions)",
+        "right hemisphere": "DiFuMo Atlas (512 dimensions)",
+      },
+      "minds/core/parcellationatlas/v1.0.0/12fca5c5-b02c-46ce-ab9f-f12babf4c7e1": {
+        "whole brain": "DiFuMo Atlas (1024 dimensions)",
+        "left hemisphere": "DiFuMo Atlas (1024 dimensions)",
+        "right hemisphere": "DiFuMo Atlas (1024 dimensions)",
+      },
+    },
+    // colin 27
+    "minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992": {
+      "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-26": {
+        "left hemisphere": "COLIN_V25_LEFT_NG_SPLIT_HEMISPHERE",
+        "right hemisphere": "COLIN_V25_RIGHT_NG_SPLIT_HEMISPHERE",
+      },
+      "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579": {
+        "left hemisphere": "jubrain colin v18 left",
+        "right hemisphere": "jubrain colin v18 right",
+      }
+    },
+    // big brain
+    "minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588": {
+      "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-26": {
+
+      },
+      // isocortex
+      "juelich/iav/atlas/v1.0.0/4": {
+        "whole brain": " tissue type: "
+      },
+      // cortical layers
+      "juelich/iav/atlas/v1.0.0/3": {
+        "whole brain": "cortical layers"
+      },
+    },
+
+    // fsaverage
+    "minds/core/referencespace/v1.0.0/tmp-fsaverage": fsAverageKeyVal,
+  },
+  // allen mouse
+  'juelich/iav/atlas/v1.0.0/2': {
+    // ccf v3
+    "minds/core/referencespace/v1.0.0/265d32a0-3d84-40a5-926f-bf89f68212b9": {
+      // ccf v3 2017
+      "minds/core/parcellationatlas/v1.0.0/05655b58-3b6f-49db-b285-64b5a0276f83": {
+        "whole brain": "v3_2017",
+        "left hemisphere": "v3_2017",
+        "right hemisphere": "v3_2017"
+      },
+      // ccf v3 2015,
+      "minds/core/parcellationatlas/v1.0.0/39a1384b-8413-4d27-af8d-22432225401f": {
+        "whole brain": "atlas",
+        "left hemisphere": "atlas",
+        "right hemisphere": "atlas"
+      }
+    }
+  },
+  // waxholm
+  "minds/core/parcellationatlas/v1.0.0/522b368e-49a3-49fa-88d3-0870a307974a": {
+    "minds/core/referencespace/v1.0.0/d5717c4a-0fa1-46e6-918c-b8003069ade8": {
+      // v1.01
+      "minds/core/parcellationatlas/v1.0.0/11017b35-7056-4593-baad-3934d211daba": {
+        "whole brain": "v1_01",
+        "left hemisphere": "v1_01",
+        "right hemisphere": "v1_01"
+      },
+      // v2
+      "minds/core/parcellationatlas/v1.0.0/2449a7f0-6dd0-4b5a-8f1e-aec0db03679d": {
+        "whole brain": "v2",
+        "left hemisphere": "v2",
+        "right hemisphere": "v2"
+      },
+      // v3
+      "minds/core/parcellationatlas/v1.0.0/ebb923ba-b4d5-4b82-8088-fa9215c2e1fe": {
+        "whole brain": "v3",
+        "left hemisphere": "v3",
+        "right hemisphere": "v3"
+      }
+    }
+  }
+}
+
+
+export function getTmplNgLayer(atlas: SapiAtlasModel, tmpl: SapiSpaceModel, spaceVolumes: SapiVolumeModel[]): Record<string, NgLayerSpec>{
+  const ngId = `_${MultiDimMap.GetKey(atlas["@id"], tmpl["@id"], "tmplImage")}`
+  const tmplImage = spaceVolumes.find(v => "neuroglancer/precomputed" in v.data.detail)
+  return {
+    [ngId]: {
+      source: `precomputed://${tmplImage.data.url.replace(/^precomputed:\/\//, '')}`,
+      ...tmplImage.data.detail["neuroglancer/precomputed"] as NgLayerSpec
+    }
+  }
+}
+
+export function getTmplAuxNgLayer(atlas: SapiAtlasModel, tmpl: SapiSpaceModel, spaceVolumes: SapiVolumeModel[]): Record<string, NgPrecompMeshSpec>{
+  const ngId = `_${MultiDimMap.GetKey(atlas["@id"], tmpl["@id"], "auxLayer")}`
+  const tmplImage = spaceVolumes.find(v => "neuroglancer/precompmesh" in v.data.detail)
+  if (!tmplImage) return {}
+  return {
+    [ngId]: {
+      source: `precompmesh://${tmplImage.data.url.replace(/^precompmesh:\/\//, '')}`,
+      ...tmplImage.data.detail["neuroglancer/precompmesh"] as NgPrecompMeshSpec
+    }
+  }
+}
+
+export function getParcNgId(atlas: SapiAtlasModel, tmpl: SapiSpaceModel, parc: SapiParcellationModel, _laterality: string | SapiRegionModel) {
+  let laterality: string
+  if (typeof _laterality === "string") {
+    laterality = _laterality
+  } else {
+    laterality = "whole brain"
+    if (_laterality.name.indexOf("left") >= 0) laterality = "left hemisphere"
+    if (_laterality.name.indexOf("right") >= 0) laterality = "right hemisphere"
+  }
+  let ngId = BACKCOMAP_KEY_DICT[atlas["@id"]]?.[tmpl["@id"]]?.[parc["@id"]]?.[laterality]
+  if (!ngId) {
+    ngId = `_${MultiDimMap.GetKey(atlas["@id"], tmpl["@id"], parc["@id"], laterality)}`
+  }
+  return ngId
+}
+
+export function getParcNgLayers(atlas: SapiAtlasModel, tmpl: SapiSpaceModel, parc: SapiParcellationModel, parcVolumes: { volume: SapiVolumeModel, volumeMetadata: ParcVolumeSpec }[]){
+  const returnVal: Record<string, NgSegLayerSpec> = {}
+  for (const parcVol of parcVolumes) {
+    const { volume, volumeMetadata } = parcVol
+    const { laterality, labelIndicies } = volumeMetadata
+    const ngId = getParcNgId(atlas, tmpl, parc, laterality)
+
+    returnVal[ngId] = {
+      source: `precomputed://${volume.data.url.replace(/^precomputed:\/\//, '')}`,
+      labelIndicies,
+      laterality,
+      transform: (volume.data.detail["neuroglancer/precomputed"] as any).transform
+    }
+  }
+  return returnVal
+}
+
+type CongregatedVolume = {
+  tmplVolumes: SapiVolumeModel[]
+  tmplAuxMeshVolumes: SapiVolumeModel[]
+  parcVolumes: { volume: SapiVolumeModel, volumeMetadata: ParcVolumeSpec}[]
+}
+
+export const getNgLayersFromVolumesATP = (volumes: CongregatedVolume, ATP: { atlas: SapiAtlasModel, template: SapiSpaceModel, parcellation: SapiParcellationModel }) => {
+  
+  const { tmplVolumes, tmplAuxMeshVolumes, parcVolumes } = volumes
+  const { atlas, template, parcellation } = ATP
+  return {
+    tmplNgLayers: getTmplNgLayer(atlas, template, tmplVolumes),
+    tmplAuxNgLayers: getTmplAuxNgLayer(atlas, template, tmplAuxMeshVolumes),
+    parcNgLayers: getParcNgLayers(atlas, template, parcellation, parcVolumes)
+  }
+}
+
+export const fromRootStore = {
+  getNgLayers: (store: Store, sapiSvc: SAPI) => pipe(
+    select(atlasSelection.selectors.selectedATP),
+    switchMap(ATP => 
+      forkJoin({
+        tmplVolumes: store.pipe(
+          nehubaStoreFromRootStore.getTmplVolumes(sapiSvc),
+        ),
+        tmplAuxMeshVolumes: store.pipe(
+          nehubaStoreFromRootStore.getAuxMeshVolumes(sapiSvc),
+        ),
+        parcVolumes: store.pipe(
+          nehubaStoreFromRootStore.getParcVolumes(sapiSvc),
+        )
+      }).pipe(
+        map(volumes => getNgLayersFromVolumesATP(volumes, ATP))
+      )
+    )
+  )
+}
+
+export function getRegionLabelIndex(atlas: SapiAtlasModel, tmpl: SapiSpaceModel, parc: SapiParcellationModel, region: SapiRegionModel) {
+  const lblIdx = Number(region?.hasAnnotation?.internalIdentifier)
+  if (lblIdx === NaN) return null
+  return lblIdx
+}
+
+export const defaultNehubaConfig: NehubaConfig = {
+  "configName": "",
+  "globals": {
+    "hideNullImageValues": true,
+    "useNehubaLayout": {
+      "keepDefaultLayouts": false
+    },
+    "useNehubaMeshLayer": true,
+    "rightClickWithCtrlGlobal": false,
+    "zoomWithoutCtrlGlobal": false,
+    "useCustomSegmentColors": true
+  },
+  "zoomWithoutCtrl": true,
+  "hideNeuroglancerUI": true,
+  "rightClickWithCtrl": true,
+  "rotateAtViewCentre": true,
+  "enableMeshLoadingControl": true,
+  "zoomAtViewCentre": true,
+  "restrictUserNavigation": true,
+  "disableSegmentSelection": false,
+  "dataset": {
+    "imageBackground": [
+      1,
+      1,
+      1,
+      1
+    ],
+    "initialNgState": {
+      "showDefaultAnnotations": false,
+      "layers": {},
+    }
+  },
+  "layout": {
+    "views": "hbp-neuro",
+    "planarSlicesBackground": [
+      1,
+      1,
+      1,
+      1
+    ],
+    "useNehubaPerspective": {
+      "enableShiftDrag": false,
+      "doNotRestrictUserNavigation": false,
+      "perspectiveSlicesBackground": [
+        1,
+        1,
+        1,
+        1
+      ],
+      "perspectiveBackground": [
+        1,
+        1,
+        1,
+        1
+      ],
+      "mesh": {
+        "backFaceColor": [
+          1,
+          1,
+          1,
+          1
+        ],
+        "removeBasedOnNavigation": true,
+        "flipRemovedOctant": true
+      },
+      "hideImages": false,
+      "waitForMesh": false,
+    }
+  }
+}
+
+export const spaceMiscInfoMap = new Map([
+  ['minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588', {
+    name: 'bigbrain',
+    scale: 1,
+  }],
+  ['minds/core/referencespace/v1.0.0/dafcffc5-4826-4bf1-8ff6-46b8a31ff8e2', {
+    name: 'icbm2009c',
+    scale: 1,
+  }],
+  ['minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992', {
+    name: 'colin27',
+    scale: 1,
+  }],
+  ['minds/core/referencespace/v1.0.0/265d32a0-3d84-40a5-926f-bf89f68212b9', {
+    name: 'allen-mouse',
+    scale: 0.1,
+  }],
+  ['minds/core/referencespace/v1.0.0/d5717c4a-0fa1-46e6-918c-b8003069ade8', {
+    name: 'waxholm',
+    scale: 0.1,
+  }],
+])
+
+export function getNehubaConfig(space: SapiSpaceModel): NehubaConfig {
+
+  const darkTheme = space["@id"] !== "minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588"
+  const { scale } = spaceMiscInfoMap.get(space["@id"]) || { scale: 1 }
+  const backgrd = darkTheme
+    ? [0,0,0,1]
+    : [1,1,1,1]
+
+  const rmPsp = darkTheme
+    ? {"mode":"<","color":[0.1,0.1,0.1,1]}
+    :{"color":[1,1,1,1],"mode":"=="}
+  const drawSubstrates = darkTheme
+    ? {"color":[0.5,0.5,1,0.2]}
+    : {"color":[0,0,0.5,0.15]}
+  const drawZoomLevels = darkTheme
+    ? {"cutOff":150000 * scale }
+    : {"cutOff":200000 * scale,"color":[0.5,0,0,0.15] }
+
+  // enable surface parcellation
+  // otherwise, on segmentation selection, the unselected meshes will also be invisible
+  const surfaceParcellation = space["@id"] === 'minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992'
+  return {
+    "configName": "",
+    "globals": {
+      "hideNullImageValues": true,
+      "useNehubaLayout": {
+        "keepDefaultLayouts": false
+      },
+      "useNehubaMeshLayer": true,
+      "rightClickWithCtrlGlobal": false,
+      "zoomWithoutCtrlGlobal": false,
+      "useCustomSegmentColors": true
+    },
+    "zoomWithoutCtrl": true,
+    "hideNeuroglancerUI": true,
+    "rightClickWithCtrl": true,
+    "rotateAtViewCentre": true,
+    "enableMeshLoadingControl": true,
+    "zoomAtViewCentre": true,
+    // "restrictUserNavigation": true,
+    "dataset": {
+      "imageBackground": backgrd,
+      "initialNgState": {
+        "showDefaultAnnotations": false,
+        "layers": {},
+        "navigation": {
+          "zoomFactor": 350000 * scale,
+        },
+        "perspectiveOrientation": [
+          0.3140767216682434,
+          -0.7418519854545593,
+          0.4988985061645508,
+          -0.3195493221282959
+        ],
+        "perspectiveZoom": 1922235.5293810747 * scale
+      }
+    },
+    "layout": {
+      "useNehubaPerspective": {
+        "perspectiveSlicesBackground": backgrd,
+        "removePerspectiveSlicesBackground": rmPsp,
+        "perspectiveBackground": backgrd,
+        "fixedZoomPerspectiveSlices": {
+          "sliceViewportWidth": 300,
+          "sliceViewportHeight": 300,
+          "sliceZoom": 563818.3562426177 * scale,
+          "sliceViewportSizeMultiplier": 2
+        },
+        "mesh": {
+          "backFaceColor": backgrd,
+          "removeBasedOnNavigation": true,
+          "flipRemovedOctant": true,
+          surfaceParcellation
+        },
+        "centerToOrigin": true,
+        "drawSubstrates": drawSubstrates,
+        "drawZoomLevels": drawZoomLevels,
+        "restrictZoomLevel": {
+          "minZoom": 1200000 * scale,
+          "maxZoom": 3500000 * scale
+        }
+      }
+    }
+  }
+}
+
+
+export function cvtNavigationObjToNehubaConfig(navigationObj, nehubaConfigObj: RecursivePartial<NgConfig>): RecursivePartial<NgConfig>{
+  const {
+    orientation = [0, 0, 0, 1],
+    perspectiveOrientation = [0, 0, 0, 1],
+    perspectiveZoom = 1e6,
+    zoom = 1e6,
+    position = [0, 0, 0],
+    positionReal = true,
+  } = navigationObj || {}
+
+  const voxelSize = (() => {
+    const {
+      navigation = {}
+    } = nehubaConfigObj || {}
+    const { pose = {} } = navigation
+    const { position = {} } = pose
+    const { voxelSize = [1, 1, 1] } = position
+    return voxelSize
+  })()
+
+  return {
+    perspectiveOrientation,
+    perspectiveZoom,
+    navigation: {
+      pose: {
+        position: {
+          voxelCoordinates: positionReal
+            ? [0, 1, 2].map(idx => position[idx] / voxelSize[idx])
+            : position,
+          voxelSize
+        },
+        orientation,
+      },
+      zoomFactor: zoom
+    }
+  }
+}
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
index d3232e3e098d260c3771b95858fb428ea7f1caf0..156410ee6a7c12efb549b6a72e6928700a315974 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
@@ -1,18 +1,18 @@
-import { Inject, Injectable, OnDestroy, Optional } from "@angular/core";
+import { Injectable, OnDestroy } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { BehaviorSubject, combineLatest, from, merge, NEVER, Observable, of, Subject, Subscription } from "rxjs";
-import { debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith, switchMap, withLatestFrom } from "rxjs/operators";
-import { viewerStateCustomLandmarkSelector, viewerStateSelectedParcellationSelector, viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState/selectors";
-import { getRgb, IColorMap, INgLayerCtrl, INgLayerInterface, TNgLayerCtrl } from "./layerCtrl.util";
-import { getMultiNgIdsRegionsLabelIndexMap } from "../constants";
+import { BehaviorSubject, combineLatest, from, merge, Observable, Subject, Subscription } from "rxjs";
+import { debounceTime, distinctUntilChanged, filter, map, shareReplay, switchMap, withLatestFrom } from "rxjs/operators";
+import { IColorMap, INgLayerCtrl, INgLayerInterface, TNgLayerCtrl } from "./layerCtrl.util";
 import { IAuxMesh } from '../store'
-import { REGION_OF_INTEREST } from "src/util/interfaces";
-import { TRegionDetail } from "src/util/siibraApiConstants/types";
-import { EnumColorMapName } from "src/util/colorMaps";
-import { getShader, PMAP_DEFAULT_CONFIG } from "src/util/constants";
+import { IVolumeTypeDetail } from "src/util/siibraApiConstants/types";
 import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer, ngViewerSelectorClearView, ngViewerSelectorLayers } from "src/services/state/ngViewerState.store.helper";
-import { serialiseParcellationRegion } from 'common/util'
-import { _PLI_VOLUME_INJ_TOKEN, _TPLIVal } from "src/glue";
+import { hexToRgb } from 'common/util'
+import { SAPI, SapiParcellationModel } from "src/atlasComponents/sapi";
+import { SAPISpace } from "src/atlasComponents/sapi/core";
+import { getParcNgId, fromRootStore as nehubaConfigSvcFromRootStore } from "../config.service"
+import { getRegionLabelIndex } from "../config.service/util";
+import { annotation, atlasSelection } from "src/state";
+import { serializeSegment } from "../util";
 
 export const BACKUP_COLOR = {
   red: 255,
@@ -20,6 +20,10 @@ export const BACKUP_COLOR = {
   blue: 255
 }
 
+export function getNgLayerName(parc: SapiParcellationModel){
+  return parc["@id"]
+}
+
 export function getAuxMeshesAndReturnIColor(auxMeshes: IAuxMesh[]): IColorMap{
   const returnVal: IColorMap = {}
   for (const auxMesh of auxMeshes as IAuxMesh[]) {
@@ -45,100 +49,103 @@ export class NehubaLayerControlService implements OnDestroy{
   static PMAP_LAYER_NAME = 'regional-pmap'
 
   private selectedRegion$ = this.store$.pipe(
-    select(viewerStateSelectedRegionsSelector),
+    select(atlasSelection.selectors.selectedRegions),
     shareReplay(1),
   )
 
-  private selectedParcellation$ = this.store$.pipe(
-    select(viewerStateSelectedParcellationSelector)
-  )
 
-  private selectedTemplateSelector$ = this.store$.pipe(
-    select(viewerStateSelectedTemplateSelector)
+  private defaultNgLayers$ = this.store$.pipe(
+    nehubaConfigSvcFromRootStore.getNgLayers(this.store$, this.sapiSvc)
   )
 
-  private selParcNgIdMap$ = this.selectedParcellation$.pipe(
-    map(parc => getMultiNgIdsRegionsLabelIndexMap(parc)),
+  private selectedATP$ = this.store$.pipe(
+    select(atlasSelection.selectors.selectedATP),
     shareReplay(1),
   )
-  
-  private activeColorMap$: Observable<IColorMap> = combineLatest([
-    this.selParcNgIdMap$.pipe(
-      map(map => {
+
+  public selectedATPR$ = this.selectedATP$.pipe(
+    switchMap(({ atlas, template, parcellation }) => 
+      from(this.sapiSvc.getParcRegions(atlas["@id"], parcellation["@id"], template["@id"])).pipe(
+        map(regions => ({
+          atlas, template, parcellation, regions
+        })),
+        shareReplay(1)
+      )
+    )
+  )
+
+  private activeColorMap$ = combineLatest([
+    this.selectedATPR$.pipe(
+      map(({ atlas, parcellation, regions, template }) => {
+
         const returnVal: IColorMap = {}
-        for (const [ key, val ] of map.entries()) {
-          returnVal[key] = {}
-          for (const [ lblIdx, region ] of val.entries()) {
-            const rgb = getRgb(lblIdx, region)
-            returnVal[key][lblIdx] = rgb
+        for (const r of regions) {
+          
+          if (!r.hasAnnotation) continue
+          if (!r.hasAnnotation.visualizedIn) continue
+
+          const ngId = getParcNgId(atlas, template, parcellation, r)
+          const [ red, green, blue ] = hexToRgb(r.hasAnnotation.displayColor) || Object.keys(BACKUP_COLOR).map(key => BACKUP_COLOR[key])
+          const labelIndex = getRegionLabelIndex(atlas, template, parcellation, r)
+          if (!labelIndex) continue
+
+          if (!returnVal[ngId]) {
+            returnVal[ngId] = {}
           }
+          returnVal[ngId][labelIndex] = { red, green, blue }
         }
         return returnVal
       })
     ),
-    this.selectedRegion$,
-    this.selectedTemplateSelector$.pipe(
-      map(template => {
-        const { auxMeshes = [] } = template || {}
-        return getAuxMeshesAndReturnIColor(auxMeshes)
-      })
-    ),
-    this.selectedParcellation$.pipe(
-      map(parc => {
-        const { auxMeshes = [] } = parc || {}
-        return getAuxMeshesAndReturnIColor(auxMeshes)
-      })
-    ),
-  ]).pipe(
-    map(([ regions, selReg, ...auxMeshesArr ]) => {
-      
-      const returnVal: IColorMap = {}
-      if (selReg.length === 0) {
-        for (const key in regions) {
-          returnVal[key] = regions[key]
-        }
-      } else {
-        /**
-         * if selected regions are non empty
-         * set the selected regions to show color,
-         * but the rest to show white 
-         */
-        for (const key in regions) {
-          const colorMap = {}
-          returnVal[key] = colorMap
-          for (const lblIdx in regions[key]) {
-            if (selReg.some(r => r.ngId === key && r.labelIndex === Number(lblIdx))) {
-              colorMap[lblIdx] = regions[key][lblIdx]
-            } else {
-              colorMap[lblIdx] = BACKUP_COLOR
+    this.defaultNgLayers$.pipe(
+      map(({ tmplAuxNgLayers }) => {
+        const returnVal: IColorMap = {}
+        for (const ngId in tmplAuxNgLayers) {
+          returnVal[ngId] = {}
+          const { auxMeshes } = tmplAuxNgLayers[ngId]
+          for (const auxMesh of auxMeshes) {
+            const { labelIndicies } = auxMesh
+            for (const lblIdx of labelIndicies) {
+              returnVal[ngId][lblIdx] = BACKUP_COLOR
             }
           }
         }
-      }
-
-      for (const auxMeshes of auxMeshesArr) {
-        for (const key in auxMeshes) {
-          const existingObj = returnVal[key] || {}
-          returnVal[key] = {
-            ...existingObj,
-            ...auxMeshes[key],
-          }
-        }
-      }
-      this.activeColorMap = returnVal
-      return returnVal
-    })
-  )
-
-  private auxMeshes$: Observable<IAuxMesh[]> = combineLatest([
-    this.selectedTemplateSelector$,
-    this.selectedParcellation$,
+        return returnVal
+      })
+    )
   ]).pipe(
-    map(([ tmpl, parc ]) => {
-      const { auxMeshes: tmplAuxMeshes = [] as IAuxMesh[] } = tmpl || {}
-      const { auxMeshes: parclAuxMeshes = [] as IAuxMesh[] } = parc || {}
-      return [...tmplAuxMeshes, ...parclAuxMeshes]
-    })
+    map(([cmParc, cmAux]) => ({
+      ...cmParc,
+      ...cmAux
+    }))
+  )
+  
+  private auxMeshes$: Observable<IAuxMesh[]> = this.selectedATP$.pipe(
+    map(({ template }) => template),
+    switchMap(tmpl => {
+      return this.sapiSvc.registry.get<SAPISpace>(tmpl["@id"])
+        .getVolumes()
+        .then(tmplVolumes => {
+          const auxMeshArr: IAuxMesh[] = []
+          for (const vol of tmplVolumes) {
+            if (vol.data.detail["neuroglancer/precompmesh"]) {
+              const detail = vol.data.detail as IVolumeTypeDetail["neuroglancer/precompmesh"]
+              for (const auxMesh of detail["neuroglancer/precompmesh"].auxMeshes) {
+                auxMeshArr.push({
+                  "@id": `auxmesh-${tmpl["@id"]}-${auxMesh.name}`,
+                  labelIndicies: auxMesh.labelIndicies,
+                  name: auxMesh.name,
+                  ngId: '',
+                  rgb: [255, 255, 255],
+                  visible: auxMesh.name !== "Sulci"
+                })
+              }
+            }
+          }
+          return auxMeshArr
+        })
+    }
+    )
   )
 
   private sub: Subscription[] = []
@@ -147,90 +154,92 @@ export class NehubaLayerControlService implements OnDestroy{
     while (this.sub.length > 0) this.sub.pop().unsubscribe()
   }
 
-  private pliVol$: Observable<string[]> = this._pliVol$
-    ? this._pliVol$.pipe(
-      map(arr => {
-        const output = []
-        for (const item of arr) {
-          for (const volume of item.data["iav-registered-volumes"].volumes) {
-            output.push(volume.name)
-          }
-        }
-        return output
-      })
-    )
-    : NEVER
   constructor(
     private store$: Store<any>,
-    @Optional() @Inject(_PLI_VOLUME_INJ_TOKEN) private _pliVol$: Observable<_TPLIVal[]>,
-    @Optional() @Inject(REGION_OF_INTEREST) roi$: Observable<TRegionDetail>
+    private sapiSvc: SAPI,
   ){
 
-    if (roi$) {
+    this.sub.push(
+      this.store$.pipe(
+        select(atlasSelection.selectors.selectedRegions)
+      ).subscribe(() => {
+        /**
+         * TODO
+         * below is the original code, but can be refactored.
+         * essentially, new workflow will be like the following:
+         * - get SapiRegion
+         * - getRegionalMap info (min/max)
+         * - dispatch new layer call
+         */
 
-      this.sub.push(
-        roi$.pipe(
-          switchMap(roi => {
-            if (!roi || !roi.hasRegionalMap) {
-              // clear pmap
-              return of(null)
-            }
-            
-            const { links } = roi
-            const { regional_map: regionalMapUrl, regional_map_info: regionalMapInfoUrl } = links
-            return from(fetch(regionalMapInfoUrl).then(res => res.json())).pipe(
-              map(regionalMapInfo => {
-                return {
-                  roi,
-                  regionalMapUrl,
-                  regionalMapInfo
-                }
-              })
-            )
-          })
-        ).subscribe(processedRoi => {
-          if (!processedRoi) {
-            this.store$.dispatch(
-              ngViewerActionRemoveNgLayer({
-                layer: {
-                  name: NehubaLayerControlService.PMAP_LAYER_NAME
-                }
-              })
-            )
-            return
-          }
-          const { 
-            roi,
-            regionalMapUrl,
-            regionalMapInfo
-          } = processedRoi
-          const { min, max, colormap = EnumColorMapName.VIRIDIS } = regionalMapInfo || {} as any
-
-          const shaderObj = {
-            ...PMAP_DEFAULT_CONFIG,
-            ...{ colormap },
-            ...( typeof min !== 'undefined' ? { lowThreshold: min } : {} ),
-            ...( max ? { highThreshold: max } : { highThreshold: 1 } )
-          }
+        // if (roi$) {
 
-          const layer = {
-            name: NehubaLayerControlService.PMAP_LAYER_NAME,
-            source : `nifti://${regionalMapUrl}`,
-            mixability : 'nonmixable',
-            shader : getShader(shaderObj),
-          }
+        //   this.sub.push(
+        //     roi$.pipe(
+        //       switchMap(roi => {
+        //         if (!roi || !roi.hasRegionalMap) {
+        //           // clear pmap
+        //           return of(null)
+        //         }
+                
+        //         const { links } = roi
+        //         const { regional_map: regionalMapUrl, regional_map_info: regionalMapInfoUrl } = links
+        //         return from(fetch(regionalMapInfoUrl).then(res => res.json())).pipe(
+        //           map(regionalMapInfo => {
+        //             return {
+        //               roi,
+        //               regionalMapUrl,
+        //               regionalMapInfo
+        //             }
+        //           })
+        //         )
+        //       })
+        //     ).subscribe(processedRoi => {
+        //       if (!processedRoi) {
+        //         this.store$.dispatch(
+        //           ngViewerActionRemoveNgLayer({
+        //             layer: {
+        //               name: NehubaLayerControlService.PMAP_LAYER_NAME
+        //             }
+        //           })
+        //         )
+        //         return
+        //       }
+        //       const { 
+        //         roi,
+        //         regionalMapUrl,
+        //         regionalMapInfo
+        //       } = processedRoi
+        //       const { min, max, colormap = EnumColorMapName.VIRIDIS } = regionalMapInfo || {} as any
 
-          this.store$.dispatch(
-            ngViewerActionAddNgLayer({ layer })
-          )
+        //       const shaderObj = {
+        //         ...PMAP_DEFAULT_CONFIG,
+        //         ...{ colormap },
+        //         ...( typeof min !== 'undefined' ? { lowThreshold: min } : {} ),
+        //         ...( max ? { highThreshold: max } : { highThreshold: 1 } )
+        //       }
 
-          // this.layersService.highThresholdMap.set(layerName, highThreshold)
-          // this.layersService.lowThresholdMap.set(layerName, lowThreshold)
-          // this.layersService.colorMapMap.set(layerName, cmap)
-          // this.layersService.removeBgMap.set(layerName, removeBg)
-        })
-      )
-    }
+        //       const layer = {
+        //         name: NehubaLayerControlService.PMAP_LAYER_NAME,
+        //         source : `nifti://${regionalMapUrl}`,
+        //         mixability : 'nonmixable',
+        //         shader : getShader(shaderObj),
+        //       }
+
+        //       this.store$.dispatch(
+        //         ngViewerActionAddNgLayer({ layer })
+        //       )
+
+        //       // this.layersService.highThresholdMap.set(layerName, highThreshold)
+        //       // this.layersService.lowThresholdMap.set(layerName, lowThreshold)
+        //       // this.layersService.colorMapMap.set(layerName, cmap)
+        //       // this.layersService.removeBgMap.set(layerName, removeBg)
+        //     })
+        //   )
+        // }
+
+      })
+    )
 
     this.sub.push(
       this.ngLayers$.subscribe(({ ngLayers }) => {
@@ -262,7 +271,7 @@ export class NehubaLayerControlService implements OnDestroy{
      */
     this.sub.push(
       this.store$.pipe(
-        select(viewerStateCustomLandmarkSelector),
+        select(annotation.selectors.annotations),
         withLatestFrom(this.auxMeshes$)
       ).subscribe(([landmarks, auxMeshes]) => {
         
@@ -303,34 +312,19 @@ export class NehubaLayerControlService implements OnDestroy{
     shareReplay(1)
   )
 
-  public expectedLayerNames$ = combineLatest([
-    this.selectedTemplateSelector$,
-    this.auxMeshes$,
-    this.selParcNgIdMap$,
-  ]).pipe(
-    map(([ tmpl, auxMeshes, parcNgIdMap ]) => {
-      const ngIdSet = new Set<string>()
-      const { ngId } = tmpl
-      ngIdSet.add(ngId)
-      for (const auxMesh of auxMeshes) {
-        const { ngId } = auxMesh
-        ngIdSet.add(ngId as string)
-      }
-      for (const ngId of parcNgIdMap.keys()) {
-        ngIdSet.add(ngId)
-      }
-      return Array.from(ngIdSet)
+  public expectedLayerNames$ = this.defaultNgLayers$.pipe(
+    map(({ parcNgLayers, tmplAuxNgLayers, tmplNgLayers }) => {
+      return [
+        ...Object.keys(parcNgLayers),
+        ...Object.keys(tmplAuxNgLayers),
+        ...Object.keys(tmplNgLayers),
+      ]
     })
   )
 
-  public visibleLayer$: Observable<string[]> = combineLatest([
-    this.expectedLayerNames$,
-    this.pliVol$.pipe(
-      startWith([])
-    ),
-  ]).pipe(
-    map(([ expectedLayerNames, layerNames ]) => {
-      const ngIdSet = new Set<string>([...layerNames, ...expectedLayerNames])
+  public visibleLayer$: Observable<string[]> = this.expectedLayerNames$.pipe(
+    map(expectedLayerNames => {
+      const ngIdSet = new Set<string>([...expectedLayerNames])
       return Array.from(ngIdSet)
     })
   )
@@ -338,6 +332,13 @@ export class NehubaLayerControlService implements OnDestroy{
   /**
    * define when shown segments should be updated
    */
+  public _segmentVis$: Observable<string[]> = combineLatest([
+    this.selectedATP$,
+    this.selectedRegion$
+  ]).pipe(
+    map(() => [''])
+  )
+
   public segmentVis$: Observable<string[]> = combineLatest([
     /**
      * selectedRegions
@@ -359,15 +360,20 @@ export class NehubaLayerControlService implements OnDestroy{
       distinctUntilChanged()
     )
   ]).pipe(
-    withLatestFrom(this.selectedParcellation$),
-    map(([[ regions, nonmixableLayerExists, clearViewFlag ], selParc]) => {
+    withLatestFrom(this.selectedATP$),
+    map(([[ regions, nonmixableLayerExists, clearViewFlag ], { atlas, parcellation, template }]) => {
       if (nonmixableLayerExists && !clearViewFlag) {
         return null
       }
-      const { ngId: defaultNgId } = selParc || {}
   
       /* selectedregionindexset needs to be updated regardless of forceshowsegment */
-      const selectedRegionIndexSet = new Set<string>(regions.map(({ngId = defaultNgId, labelIndex}) => serialiseParcellationRegion({ ngId, labelIndex })))
+      const selectedRegionIndexSet = new Set<string>(
+        regions.map(r => {
+          const ngId = getParcNgId(atlas, template, parcellation, r)
+          const label = getRegionLabelIndex(atlas, template, parcellation, r)
+          return serializeSegment(ngId, label)
+        })
+      )
       if (selectedRegionIndexSet.size > 0 && !clearViewFlag) {
         return [...selectedRegionIndexSet]
       } else {
diff --git a/src/viewerModule/nehuba/mesh.effects/mesh.effects.ts b/src/viewerModule/nehuba/mesh.effects/mesh.effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1d6fe28a1dc844f2c4e94340a7d51a0835fb0cf1
--- /dev/null
+++ b/src/viewerModule/nehuba/mesh.effects/mesh.effects.ts
@@ -0,0 +1,23 @@
+import { Injectable } from "@angular/core";
+import { createEffect } from "@ngrx/effects";
+import { select, Store } from "@ngrx/store";
+import { filter } from "jszip";
+import { combineLatest } from "rxjs";
+import { map } from "rxjs/operators";
+import { actionSetAuxMeshes } from "../store";
+
+@Injectable()
+export class MeshEffects{
+  constructor(private store: Store<any>){
+
+  }
+  // auxMeshEffect$ = createEffect(() => this.store.pipe(
+    
+  //   map(() => {
+  //     console.log("TODO need to fix")
+  //     return actionSetAuxMeshes({
+  //       payload: []
+  //     })
+  //   })
+  // ))
+}
\ No newline at end of file
diff --git a/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts b/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts
index 967762e46acb61182a31dfc625772c14da8a2dca..b5a1e065ecddaf750fdc8007bb6f02ffd7c165b1 100644
--- a/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts
+++ b/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts
@@ -2,8 +2,7 @@ import { TestBed } from "@angular/core/testing"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
 import { hot } from "jasmine-marbles"
 import { viewerStateSelectedParcellationSelector, viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState/selectors"
-import { selectorAuxMeshes } from "../store"
-import { getLayerNameIndiciesFromParcRs, collateLayerNameIndicies, findFirstChildrenWithLabelIndex, NehubaMeshService } from "./mesh.service"
+import { NehubaMeshService } from "./mesh.service"
 
 
 const fits1 = {
@@ -41,82 +40,6 @@ const nofit2 = {
 }
 
 describe('> mesh.server.ts', () => {
-  describe('> findFirstChildrenWithLabelIndex', () => {
-    it('> if root fits, return root', () => {
-      const result = findFirstChildrenWithLabelIndex({
-        ...fits1,
-        children: [fits2]
-      })
-
-      expect(result).toEqual([{
-        ...fits1,
-        children: [fits2]
-      }])
-    })
-
-    it('> if root doesnt fit, will try to find the next node, until one fits', () => {
-      const result = findFirstChildrenWithLabelIndex({
-        ...nofit1,
-        children: [fits1, fits2]
-      })
-      expect(result).toEqual([fits1, fits2])
-    })
-
-    it('> if notthings fits, will return empty array', () => {
-      const result = findFirstChildrenWithLabelIndex({
-        ...nofit1,
-        children: [nofit1, nofit2]
-      })
-      expect(result).toEqual([])
-    })
-  })
-
-  describe('> collateLayerNameIndicies', () => {
-    it('> collates same ngIds', () => {
-      const result = collateLayerNameIndicies([
-        fits1_1, fits1, fits2, fits2_1
-      ])
-      expect(result).toEqual({
-        [fits1.ngId]: [fits1_1.labelIndex, fits1.labelIndex],
-        [fits2.ngId]: [fits2.labelIndex, fits2_1.labelIndex]
-      })
-    })
-  })
-
-  describe('> getLayerNameIndiciesFromParcRs', () => {
-    const root = {
-      ...fits1,
-      children: [
-        {
-          ...nofit1,
-          children: [
-            {
-              ...fits1_1,
-              children: [
-                fits2, fits2_1
-              ]
-            }
-          ]
-        }
-      ]
-    }
-    const parc = {
-      regions: [ root ]
-    }
-    it('> if selectedRegion.length === 0, selects top most regions with labelIndex', () => {
-      const result = getLayerNameIndiciesFromParcRs(parc, [])
-      expect(result).toEqual({
-        [root.ngId]: [root.labelIndex]
-      })
-    })
-
-    it('> if selReg.length !== 0, select region ngId & labelIndex', () => {
-      const result = getLayerNameIndiciesFromParcRs(parc, [ fits1_1 ])
-      expect(result).toEqual({
-        [fits1_1.ngId]: [fits1_1.labelIndex]
-      })
-    })
-  })
 
   describe('> NehubaMeshService', () => {
     beforeEach(() => {
@@ -140,16 +63,6 @@ describe('> mesh.server.ts', () => {
       const mockStore = TestBed.inject(MockStore)
       mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [ fits1 ])
 
-      mockStore.overrideSelector(selectorAuxMeshes, [{
-        ngId: fits2.ngId,
-        labelIndicies: [11, 22],
-        "@id": '',
-        name: '',
-        rgb: [100, 100, 100],
-        visible: true,
-        displayName: ''
-      }])
-
       const service = TestBed.inject(NehubaMeshService)
       expect(
         service.loadMeshes$
diff --git a/src/viewerModule/nehuba/mesh.service/mesh.service.ts b/src/viewerModule/nehuba/mesh.service/mesh.service.ts
index dd17226af19ad4c3ec2dfc8f10dbc79a96e53635..552af17c944f40a27e8b6ec1427e7b29ad6f88ac 100644
--- a/src/viewerModule/nehuba/mesh.service/mesh.service.ts
+++ b/src/viewerModule/nehuba/mesh.service/mesh.service.ts
@@ -1,11 +1,12 @@
 import { Injectable, OnDestroy } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { combineLatest, Observable, of } from "rxjs";
-import { switchMap } from "rxjs/operators";
-import { viewerStateSelectedParcellationSelector, viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState/selectors";
+import { Observable, of } from "rxjs";
+import { map, switchMap } from "rxjs/operators";
 import { IMeshesToLoad } from '../constants'
-import { flattenReducer } from 'common/util'
-import { IAuxMesh, selectorAuxMeshes, actionSetAuxMeshes } from "../store";
+import { selectorAuxMeshes } from "../store";
+import { SAPI } from "src/atlasComponents/sapi";
+import { fromRootStore as nehubaConfigSvcFromRootStore } from "../config.service";
+import { atlasSelection } from "src/state";
 
 interface IRegion {
   ngId?: string
@@ -13,44 +14,6 @@ interface IRegion {
   children: IRegion[]
 }
 
-interface IParc {
-  ngId?: string
-  regions: IRegion[]
-}
-
-type TCollatedLayerNameIdx = {
-  [key: string]: number[]
-}
-
-export function findFirstChildrenWithLabelIndex(region: IRegion): IRegion[]{
-  if (region.ngId && region.labelIndex) {
-    return [ region ]
-  }
-  return region.children
-    .map(findFirstChildrenWithLabelIndex)
-    .reduce(flattenReducer, [])
-}
-
-export function collateLayerNameIndicies(regions: IRegion[]){
-  const returnObj: TCollatedLayerNameIdx = {}
-  for (const r of regions) {
-    if (returnObj[r.ngId]) {
-      returnObj[r.ngId].push(r.labelIndex)
-    } else {
-      returnObj[r.ngId] = [r.labelIndex]
-    }
-  }
-  return returnObj
-}
-
-export function getLayerNameIndiciesFromParcRs(parc: IParc, rs: IRegion[]): TCollatedLayerNameIdx {
-
-  const arrOfRegions = (rs.length === 0 ? parc.regions : rs)
-    .map(findFirstChildrenWithLabelIndex)
-    .reduce(flattenReducer, []) as IRegion[]
-
-  return collateLayerNameIndicies(arrOfRegions)
-}
 
 /**
  * control mesh loading etc
@@ -62,98 +25,57 @@ export class NehubaMeshService implements OnDestroy {
   private onDestroyCb: (() => void)[] = []
 
   constructor(
-    private store$: Store<any>
+    private store$: Store<any>,
+    private sapiSvc: SAPI
   ){
-    const auxMeshSub = combineLatest([
-      this.selectedTemplate$,
-      this.selectedParc$
-    ]).subscribe(([ tmpl, parc ]) => {
-      const { auxMeshes: tmplAuxMeshes = [] as IAuxMesh[] } = tmpl || {}
-      const { auxMeshes: parcAuxMeshes = [] as IAuxMesh[]} = parc || {}
-      this.store$.dispatch(
-        actionSetAuxMeshes({
-          payload: [...tmplAuxMeshes, ...parcAuxMeshes]
-        })
-      )
-    })
-    this.onDestroyCb.push(() => auxMeshSub.unsubscribe())
   }
 
   ngOnDestroy(){
     while(this.onDestroyCb.length > 0) this.onDestroyCb.pop()()
   }
 
-  private selectedTemplate$ = this.store$.pipe(
-    select(viewerStateSelectedTemplateSelector)
+  private allRegions$ = this.store$.pipe(
+    select(atlasSelection.selectors.selectedATP),
+    switchMap(({ atlas, template, parcellation }) => this.sapiSvc.getParcRegions(atlas["@id"], parcellation["@id"], template["@id"]))
   )
 
   private selectedRegions$ = this.store$.pipe(
-    select(viewerStateSelectedRegionsSelector)
+    select(atlasSelection.selectors.selectedRegions)
   )
 
-  private selectedParc$ = this.store$.pipe(
-    select(viewerStateSelectedParcellationSelector)
-  )
 
   private auxMeshes$ = this.store$.pipe(
     select(selectorAuxMeshes),
   )
 
-  public loadMeshes$: Observable<IMeshesToLoad> = combineLatest([
-    this.auxMeshes$,
-    this.selectedTemplate$,
-    this.selectedParc$,
-    this.selectedRegions$,
-  ]).pipe(
-    switchMap(([auxMeshes, template, parc, selRegions]) => {
-      
-      /**
-       * if colin 27 and julich brain 2.9.0, select all regions
-       */
-      let overrideSelRegion = null
-      if (
-        template['@id'] === 'minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992' &&
-        parc['@id'] === 'minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290'
-      ) {
-        overrideSelRegion = []
-      }
+  private ngLayers$ = this.store$.pipe(
+    nehubaConfigSvcFromRootStore.getNgLayers(this.store$, this.sapiSvc)
+  )
 
-      const obj = getLayerNameIndiciesFromParcRs(parc, overrideSelRegion || selRegions)
-      const { auxillaryMeshIndices = [] } = parc
+  public loadMeshes$: Observable<IMeshesToLoad> = this.ngLayers$.pipe(
+    switchMap(ngLayers => {
       const arr: IMeshesToLoad[] = []
-      for (const key in obj) {
-        const labelIndicies = Array.from(new Set([...obj[key], ...auxillaryMeshIndices]))
-        arr.push({
-          layer: {
-            name: key
-          },
-          labelIndicies
-        })
-      }
-      
-      const auxLayers: {
-        [key: string]: number[]
-      } = {}
-
-      for (const auxMesh of auxMeshes) {
-        const { name, ngId, labelIndicies } = auxMesh
-        if (!auxLayers[ngId]) {
-          auxLayers[ngId] = []
+      const { parcNgLayers, tmplAuxNgLayers, tmplNgLayers } = ngLayers
+      for (const ngId in tmplAuxNgLayers) {
+        const meshToLoad: IMeshesToLoad = {
+          labelIndicies: [],
+          layer: { name: ngId }
         }
-        if (auxMesh.visible) {
-          auxLayers[ngId].push(...labelIndicies)
+        for (const auxMesh of tmplAuxNgLayers[ngId].auxMeshes) {
+          meshToLoad.labelIndicies.push(...auxMesh.labelIndicies)
         }
+        arr.push(meshToLoad)
       }
-      for (const key in auxLayers) {
+
+      for (const ngId in parcNgLayers) {
+        const {labelIndicies} = parcNgLayers[ngId]
         arr.push({
-          layer: {
-            name: key
-          },
-          labelIndicies: auxLayers[key]
+          labelIndicies,
+          layer: { name: ngId }
         })
       }
 
       return of(...arr)
-    }),
+    })
   )
 }
diff --git a/src/viewerModule/nehuba/module.ts b/src/viewerModule/nehuba/module.ts
index 75dd30a18861417639d86bc543c4e368f00fc74d..96b57ff45f539d69a229efd2041f604a0be31543 100644
--- a/src/viewerModule/nehuba/module.ts
+++ b/src/viewerModule/nehuba/module.ts
@@ -28,6 +28,8 @@ import { WindowResizeModule } from "src/util/windowResize";
 import { ViewerCtrlModule } from "./viewerCtrl";
 import { DragDropFileModule } from "src/dragDropFile/module";
 import { NgLayerCtrlCmp } from "./ngLayerCtl/ngLayerCtrl.component";
+import { EffectsModule } from "@ngrx/effects";
+import { MeshEffects } from "./mesh.effects/mesh.effects";
 
 @NgModule({
   imports: [
@@ -55,6 +57,9 @@ import { NgLayerCtrlCmp } from "./ngLayerCtl/ngLayerCtrl.component";
       NEHUBA_VIEWER_FEATURE_KEY,
       reducer
     ),
+    EffectsModule.forFeature([
+      MeshEffects
+    ]),
     QuickTourModule
   ],
   declarations: [
@@ -75,6 +80,7 @@ import { NgLayerCtrlCmp } from "./ngLayerCtl/ngLayerCtrl.component";
     NgLayerCtrlCmp,
   ],
   providers: [
+    
     {
       provide: IMPORT_NEHUBA_INJECT_TOKEN,
       useFactory: importNehubaFactory,
diff --git a/src/viewerModule/nehuba/navigation.service/navigation.service.ts b/src/viewerModule/nehuba/navigation.service/navigation.service.ts
index ed751e8b85149abb089fbd5cf5adf0ec888abdee..7836d27972f0bb75906f7768e0c1d4e4c76d6f16 100644
--- a/src/viewerModule/nehuba/navigation.service/navigation.service.ts
+++ b/src/viewerModule/nehuba/navigation.service/navigation.service.ts
@@ -3,12 +3,12 @@ import { select, Store } from "@ngrx/store";
 import { Observable, ReplaySubject, Subscription } from "rxjs";
 import { debounceTime } from "rxjs/operators";
 import { selectViewerConfigAnimationFlag } from "src/services/state/viewerConfig/selectors";
-import { viewerStateChangeNavigation } from "src/services/state/viewerState/actions";
-import { viewerStateSelectorNavigation } from "src/services/state/viewerState/selectors";
 import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component";
 import { NEHUBA_INSTANCE_INJTKN } from "../util";
 import { timedValues } from 'src/util/generator'
 import { INavObj, navAdd, navMul, navObjEqual } from './navigation.util'
+import { actions } from "src/state/atlasSelection";
+import { atlasSelection } from "src/state";
 
 @Injectable()
 export class NehubaNavigationService implements OnDestroy{
@@ -52,56 +52,25 @@ export class NehubaNavigationService implements OnDestroy{
     this.subscriptions.push(
       // realtime state nav state
       this.store$.pipe(
-        select(viewerStateSelectorNavigation)
+        select(atlasSelection.selectors.navigation)
       ).subscribe(v => {
         this.storeNav = v
         // if stored nav differs from viewerNav
         if (!this.viewerNavLock && this.nehubaViewerInstance) {
           const navEql = navObjEqual(this.storeNav, this.viewerNav)
           if (!navEql) {
-            this.navigateViewer({
-              ...this.storeNav,
-              positionReal: true
-            })
+            this.navigateViewer(this.storeNav)
           }
         }
       })
     )
   }
 
-  navigateViewer(navigation: INavObj & { positionReal?: boolean, animation?: any }){
+  navigateViewer(navigation: INavObj){
     if (!navigation) return
-    const { animation, ...rest } = navigation
-    if (animation && this.globalAnimationFlag) {
-
-      const gen = timedValues()
-      const src = this.viewerNav
-
-      const dest = {
-        ...src,
-        ...navigation
-      }
-
-      const delta = navAdd(dest, navMul(src, -1))
-
-      const animate = () => {
-        const next = gen.next()
-        const d =  next.value
-
-        const n = navAdd(src, navMul(delta, d))
-        this.nehubaViewerInstance.setNavigationState({
-          ...n,
-          positionReal: true
-        })
-
-        if ( !next.done ) {
-          this.rafRef = requestAnimationFrame(() => animate())
-        }
-      }
-      this.rafRef = requestAnimationFrame(() => animate())
-    } else {
-      this.nehubaViewerInstance.setNavigationState(rest)
-    }
+    // TODO
+    // readd consider how to do animation
+    this.nehubaViewerInstance.setNavigationState(navigation)
   }
 
   setupViewerSub(){
@@ -134,7 +103,7 @@ export class NehubaNavigationService implements OnDestroy{
         
         if (!navEql) {
           this.store$.dispatch(
-            viewerStateChangeNavigation({
+            actions.navigateTo({
               navigation: roundedNav
             })
           )
diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
index 8281c6565f4f6c717e8586877285781f631a1069..c3b14f7b92e2d95e9b1bd2df9c0ed88119715bae 100644
--- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
@@ -5,8 +5,8 @@ import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.se
 import { StateInterface as ViewerConfiguration } from "src/services/state/viewerConfig.store";
 import { LoggingService } from "src/logging";
 import { bufferUntil, getExportNehuba, getViewer, setNehubaViewer, switchMapWaitFor } from "src/util/fn";
-import { NEHUBA_INSTANCE_INJTKN, scanSliceViewRenderFn } from "../util";
-import { deserialiseParcRegionId, arrayOrderedEql } from 'common/util'
+import { deserializeSegment, NEHUBA_INSTANCE_INJTKN, scanSliceViewRenderFn } from "../util";
+import { arrayOrderedEql } from 'common/util'
 import { IMeshesToLoad, SET_MESHES_TO_LOAD } from "../constants";
 import { IColorMap, SET_COLORMAP_OBS, SET_LAYER_VISIBILITY } from "../layerCtrl.service";
 
@@ -68,6 +68,9 @@ export const scanFn = (acc: LayerLabelIndex[], curr: LayerLabelIndex) => {
 
 export class NehubaViewerUnit implements OnInit, OnDestroy {
 
+
+  public ngIdSegmentsMap: Record<string, number[]> = {}
+
   private sliceviewLoading$: Observable<boolean>
 
   public overrideShowLayers: string[] = []
@@ -90,7 +93,6 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
   @Output() public mouseoverSegmentEmitter:
     EventEmitter<{
       segmentId: number | null
-      segment: string | null
       layer: {
         name?: string
         url?: string
@@ -98,10 +100,14 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     }> = new EventEmitter()
   @Output() public mouseoverLandmarkEmitter: EventEmitter<string> = new EventEmitter()
   @Output() public mouseoverUserlandmarkEmitter: EventEmitter<string> = new EventEmitter()
-  @Output() public regionSelectionEmitter: EventEmitter<{segment: number, layer: {name?: string, url?: string}}> = new EventEmitter()
+  @Output() public regionSelectionEmitter: EventEmitter<{
+    segment: number,
+    layer: {
+      name?: string,
+      url?: string
+  }}> = new EventEmitter()
   @Output() public errorEmitter: EventEmitter<any> = new EventEmitter()
 
-  public auxilaryMeshIndices: number[] = []
 
   /* only used to set initial navigation state */
   public initNav: any
@@ -185,45 +191,6 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
       })
       .catch(e => this.errorEmitter.emit(e))
 
-    /**
-     * TODO move to layerCtrl.service
-     */
-    this.ondestroySubscriptions.push(
-      fromEvent(this.workerService.worker, 'message').pipe(
-        filter((message: any) => {
-
-          if (!message) {
-            // this.log.error('worker response message is undefined', message)
-            return false
-          }
-          if (!message.data) {
-            // this.log.error('worker response message.data is undefined', message.data)
-            return false
-          }
-          if (message.data.type !== 'ASSEMBLED_LANDMARKS_VTK') {
-            /* worker responded with not assembled landmark, no need to act */
-            return false
-          }
-          if (!message.data.url) {
-            /* file url needs to be defined */
-            return false
-          }
-          return true
-        }),
-        debounceTime(100),
-        filter(e => this.templateId === e.data.template),
-        map(e => e.data.url),
-      ).subscribe(url => {
-        this.removeSpatialSearch3DLandmarks()
-        const _ = {}
-        _[NG_LANDMARK_LAYER_NAME] = {
-          type : 'mesh',
-          source : `vtk://${url}`,
-          shader : FRAGMENT_MAIN_WHITE,
-        }
-        this.loadLayer(_)
-      }),
-    )
 
     /**
      * TODO move to layerCtrl.service
@@ -338,7 +305,15 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
 
     if (this.segVis$) {
       this.ondestroySubscriptions.push(
-        this.segVis$.pipe().subscribe(val => {
+        this.segVis$.pipe(
+          switchMap(
+            switchMapWaitFor({
+              condition: () => this.nehubaViewer?.ngviewer,
+              leading: true,
+            })
+          )
+        ).subscribe(val => {
+          console.log(val)
           // null === hide all seg
           if (val === null) {
             this.hideAllSeg()
@@ -404,15 +379,6 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     }
   }
 
-  /* required to check if correct landmarks are loaded */
-  private _templateId: string
-  get templateId() {
-    return this._templateId
-  }
-  set templateId(id: string) {
-    this._templateId = id
-  }
-
   public spatialLandmarkSelectionChanged(labels: number[]) {
     const getCondition = (label: number) => `if(label > ${label - 0.1} && label < ${label + 0.1} ){${FRAGMENT_EMIT_RED}}`
     const newShader = `void main(){ ${labels.map(getCondition).join('else ')}else {${FRAGMENT_EMIT_WHITE}} }`
@@ -432,10 +398,6 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     }
   }
 
-  // TODO move region management to another service
-
-  public multiNgIdsLabelIndexMap: Map<string, Map<number, any>> = new Map()
-
   public navPosReal: [number, number, number] = [0, 0, 0]
   public navPosVoxel: [number, number, number] = [0, 0, 0]
 
@@ -579,10 +541,12 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
        * The emitted value does not affect the region selection
        * the region selection is taken care of in nehubaContainer
        */
-      const map = this.multiNgIdsLabelIndexMap.get(this.mouseOverLayer.name)
-      const region = map && map.get(this.mouseOverSegment)
+      
       if (arg === 'select') {
-        this.regionSelectionEmitter.emit({ segment: region, layer: this.mouseOverLayer })
+        this.regionSelectionEmitter.emit({
+          segment: this.mouseOverSegment,
+          layer: this.mouseOverLayer
+        })
       }
     }
 
@@ -662,23 +626,6 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     })
   }
 
-  // pos in mm
-  public addSpatialSearch3DLandmarks(geometries: any[], scale?: number, type?: 'icosahedron') {
-    this.workerService.worker.postMessage({
-      type : 'GET_LANDMARKS_VTK',
-      template : this.templateId,
-      scale: Math.min(...this.dim.map(v => v * NG_LANDMARK_CONSTANT)),
-      landmarks : geometries.map(geometry =>
-        geometry === null
-          ? null
-          // gemoetry : [number,number,number] | [ [number,number,number][], [number,number,number][] ]
-          : isNaN(geometry[0])
-            ? [geometry[0].map(triplets => triplets.map(coord => coord * 1e6)), geometry[1]]
-            : geometry.map(coord => coord * 1e6),
-      ),
-    })
-  }
-
   public setLayerVisibility(condition: {name: string|RegExp}, visible: boolean) {
     if (!this.nehubaViewer) {
       return false
@@ -728,28 +675,34 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
   }
 
   public hideAllSeg() {
-    if (!this.nehubaViewer) { return }
-    Array.from(this.multiNgIdsLabelIndexMap.keys()).forEach(ngId => {
-
-      Array.from(this.multiNgIdsLabelIndexMap.get(ngId).keys()).forEach(idx => {
+    if (!this.nehubaViewer) return
+    for (const ngId in this.ngIdSegmentsMap) {
+      for (const idx of this.ngIdSegmentsMap[ngId]) {
         this.nehubaViewer.hideSegment(idx, {
           name: ngId,
         })
-      })
+      }
+
       this.nehubaViewer.showSegment(0, {
         name: ngId,
       })
-    })
+    }
   }
 
   public showAllSeg() {
     if (!this.nehubaViewer) { return }
-    this.hideAllSeg()
-    Array.from(this.multiNgIdsLabelIndexMap.keys()).forEach(ngId => {
+    for (const ngId in this.ngIdSegmentsMap) {
+      console.log(ngId)
+      for (const idx of this.ngIdSegmentsMap[ngId]) {
+        this.nehubaViewer.showSegment(idx, {
+          name: ngId,
+        })
+      }
+
       this.nehubaViewer.hideSegment(0, {
         name: ngId,
       })
-    })
+    }
   }
 
   public showSegs(array: (number|string)[]) {
@@ -772,7 +725,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     const reduceFn: (acc: Map<string, number[]>, curr: string) => Map<string, number[]> = (acc, curr) => {
 
       const newMap = new Map(acc)
-      const { ngId, labelIndex } = deserialiseParcRegionId(curr)
+      const { ngId, label: labelIndex } = deserializeSegment(curr)
       const exist = newMap.get(ngId)
       if (!exist) {
         newMap.set(ngId, [Number(labelIndex)])
@@ -804,7 +757,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     })
   }
 
-  private vec3(pos: [number, number, number]) {
+  private vec3(pos: number[]) {
     return this.exportNehuba.vec3.fromValues(...pos)
   }
 
@@ -883,7 +836,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     /**
      * remove transparency from meshes in current layer(s)
      */
-    for (const layerKey of this.multiNgIdsLabelIndexMap.keys()) {
+    for (const layerKey in this.ngIdSegmentsMap) {
       const layer = this.nehubaViewer.ngviewer.layerManager.getLayerByName(layerKey)
       if (layer) {
         layer.layer.displayState.objectAlpha.restoreState(flag ? 0.2 : 1.0)
@@ -917,13 +870,8 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     }
 
     this._s8$ = this.nehubaViewer.mouseOver.segment.subscribe(({segment: segmentId, layer }) => {
-
-      const {name = 'unnamed'} = layer
-      const map = this.multiNgIdsLabelIndexMap.get(name)
-      const region = map && map.get(segmentId)
       this.mouseoverSegmentEmitter.emit({
         layer,
-        segment: region,
         segmentId,
       })
     })
@@ -1053,10 +1001,10 @@ const patchSliceViewPanel = (sliceViewPanel: any) => {
 }
 
 export interface ViewerState {
-  orientation: [number, number, number, number]
-  perspectiveOrientation: [number, number, number, number]
+  orientation: number[]
+  perspectiveOrientation: number[]
   perspectiveZoom: number
-  position: [number, number, number]
+  position: number[]
   positionReal: boolean
   zoom: number
 }
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
index 8aa04373cf3c7d7a8c145d221d30c3d4f1b15a3e..faa78cb3d0e330b2516c0d8c8bafe45deb94ec5e 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
@@ -9,8 +9,6 @@ import { ClickInterceptorService } from "src/glue"
 import { LayoutModule } from "src/layouts/layout.module"
 import { PANELS } from "src/services/state/ngViewerState/constants"
 import { ngViewerSelectorOctantRemoval, ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from "src/services/state/ngViewerState/selectors"
-import { uiStateMouseOverSegmentsSelector } from "src/services/state/uiState/selectors"
-import { viewerStateSetSelectedRegions } from "src/services/state/viewerState.store.helper"
 import { viewerStateCustomLandmarkSelector, viewerStateNavigationStateSelector, viewerStateSelectedRegionsSelector } from "src/services/state/viewerState/selectors"
 import { Landmark2DModule } from "src/ui/nehubaContainer/2dLandmarks/module"
 import { QuickTourModule } from "src/ui/quickTour"
@@ -139,7 +137,6 @@ describe('> nehubaViewerGlue.component.ts', () => {
     mockStore.overrideSelector(ngViewerSelectorOctantRemoval, true)
     mockStore.overrideSelector(viewerStateCustomLandmarkSelector, [])
     mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [])
-    mockStore.overrideSelector(uiStateMouseOverSegmentsSelector, [])
     mockStore.overrideSelector(viewerStateNavigationStateSelector, null)
 
     mockStore.overrideSelector(selectorAuxMeshes, [])
@@ -186,7 +183,6 @@ describe('> nehubaViewerGlue.component.ts', () => {
       const testObj1 = 'hello world'
       beforeEach(() => {
         fallbackSpy = spyOn(clickIntServ, 'fallback')
-        mockStore.overrideSelector(uiStateMouseOverSegmentsSelector, [testObj1, testObj0] as any)
         TestBed.createComponent(NehubaGlueCmp)
         clickIntServ.callRegFns(null)
       })
@@ -215,7 +211,6 @@ describe('> nehubaViewerGlue.component.ts', () => {
       }
       beforeEach(() => {
         fallbackSpy = spyOn(clickIntServ, 'fallback')
-        mockStore.overrideSelector(uiStateMouseOverSegmentsSelector, [testObj0, testObj1, testObj2] as any)
 
       })
       afterEach(() => {
@@ -225,11 +220,6 @@ describe('> nehubaViewerGlue.component.ts', () => {
         TestBed.createComponent(NehubaGlueCmp)
         clickIntServ.callRegFns(null)
         const { segment } = testObj1
-        expect(dispatchSpy).toHaveBeenCalledWith(
-          viewerStateSetSelectedRegions({
-            selectRegions: [segment]
-          } as any)
-        )
       })
       it('> fallback called (does not intercept)', () => {
         TestBed.createComponent(NehubaGlueCmp)
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
index b2e1faf29433c748c5b54d163a98b13a72359729..55ae60bb353cf0b48e9ce03bdfcb2d76a703cac4 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
@@ -1,19 +1,14 @@
-import { AfterViewInit, Component, ElementRef, EventEmitter, Inject, Input, OnChanges, OnDestroy, Optional, Output, SimpleChanges, TemplateRef, ViewChild } from "@angular/core";
+import { AfterViewInit, Component, ElementRef, EventEmitter, Inject, Input, OnDestroy, Optional, Output, TemplateRef, ViewChild } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { asyncScheduler, combineLatest, fromEvent, merge, NEVER, Observable, of, Subject, Subscription } from "rxjs";
+import { asyncScheduler, BehaviorSubject, combineLatest, fromEvent, merge, Observable, of, Subject, Subscription } from "rxjs";
 import { ngViewerActionCycleViews, ngViewerActionToggleMax } from "src/services/state/ngViewerState/actions";
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
-import { uiStateMouseOverSegmentsSelector } from "src/services/state/uiState/selectors";
 import { debounceTime, distinctUntilChanged, filter, map, mapTo, scan, shareReplay, startWith, switchMap, switchMapTo, take, tap, throttleTime } from "rxjs/operators";
-import { viewerStateAddUserLandmarks, viewerStateChangeNavigation, viewerStateMouseOverCustomLandmark, viewerStateSelectRegionWithIdDeprecated, viewerStateSetSelectedRegions, viewreStateRemoveUserLandmarks } from "src/services/state/viewerState/actions";
+import { viewerStateAddUserLandmarks, viewerStateMouseOverCustomLandmark } from "src/services/state/viewerState/actions";
 import { ngViewerSelectorPanelOrder, ngViewerSelectorPanelMode } from "src/services/state/ngViewerState/selectors";
-import { viewerStateCustomLandmarkSelector, viewerStateNavigationStateSelector } from "src/services/state/viewerState/selectors";
-import { serialiseParcellationRegion } from 'common/util'
 import { ARIA_LABELS, IDS, QUICKTOUR_DESC } from 'common/constants'
 import { PANELS } from "src/services/state/ngViewerState/constants";
 import { LoggingService } from "src/logging";
-
-import { getMultiNgIdsRegionsLabelIndexMap, SET_MESHES_TO_LOAD } from "../constants";
 import { EnumViewerEvt, IViewer, TViewerEvent } from "../../viewer.interface";
 import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component";
 import { NehubaViewerContainerDirective, TMouseoverEvent } from "../nehubaViewerInterface/nehubaViewerInterface.directive";
@@ -31,6 +26,12 @@ import { getShader } from "src/util/constants";
 import { EnumColorMapName } from "src/util/colorMaps";
 import { MatDialog } from "@angular/material/dialog";
 import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
+import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
+import { NehubaConfig, getNehubaConfig, fromRootStore, NgLayerSpec, NgPrecompMeshSpec, NgSegLayerSpec, getParcNgId, getRegionLabelIndex } from "../config.service";
+import { generalActionError } from "src/services/stateStore.helper";
+import { SET_MESHES_TO_LOAD } from "../constants";
+import { actions } from "src/state/atlasSelection";
+import { annotation, atlasSelection, userInteraction } from "src/state";
 
 export const INVALID_FILE_INPUT = `Exactly one (1) nifti file is required!`
 
@@ -72,7 +73,7 @@ export const INVALID_FILE_INPUT = `Exactly one (1) nifti file is required!`
   ]
 })
 
-export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, AfterViewInit {
+export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewInit {
 
   @ViewChild('layerCtrlTmpl', { read: TemplateRef }) layerCtrlTmpl: TemplateRef<any>
 
@@ -89,19 +90,49 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
 
   public viewerLoaded: boolean = false
 
-  private onhoverSegments = []
+  private onhoverSegments: SapiRegionModel[] = []
   private onDestroyCb: (() => void)[] = []
   private viewerUnit: NehubaViewerUnit
-  private multiNgIdsRegionsLabelIndexMap: Map<string, Map<number, any>>
+  private multiNgIdsRegionsLabelIndexMap = new Map<string, Map<number, SapiRegionModel>>()
 
+  private selectedParcellation$ = new BehaviorSubject<SapiParcellationModel>(null)
+  private _selectedParcellation: SapiParcellationModel
+  get selectedParcellation(){
+    return this._selectedParcellation
+  }
   @Input()
-  public selectedParcellation: any
+  set selectedParcellation(val: SapiParcellationModel) {
+    this._selectedParcellation = val
+    this.selectedParcellation$.next(val)
+  }
+
 
+  private selectedTemplate$ = new BehaviorSubject<SapiSpaceModel>(null)
+  private _selectedTemplate: SapiSpaceModel
+  get selectedTemplate(){
+    return this._selectedTemplate
+  }
   @Input()
-  public selectedTemplate: any
+  set selectedTemplate(val: SapiSpaceModel) {
+    this._selectedTemplate = val
+    this.selectedTemplate$.next(val)
+  }
 
-  private navigation: any
 
+  private selectedAtlas$ = new BehaviorSubject<SapiAtlasModel>(null)
+  private _selectedAtlas: SapiAtlasModel
+  get selectedAtlas(){
+    return this._selectedAtlas
+  }
+  @Input()
+  set selectedAtlas(val: SapiAtlasModel) {
+    this._selectedAtlas = val
+    this.selectedAtlas$.next(val)
+  }
+  
+
+  public nehubaConfig: NehubaConfig
+  private navigation: any
   private newViewer$ = new Subject()
 
   public showPerpsectiveScreen$: Observable<string>
@@ -129,14 +160,8 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
     description: QUICKTOUR_DESC.VIEW_ICONS,
   }
 
-  public customLandmarks$: Observable<any> = this.store$.pipe(
-    select(viewerStateCustomLandmarkSelector),
-    map(lms => lms.map(lm => ({
-      ...lm,
-      geometry: {
-        position: lm.position
-      }
-    }))),
+  public customLandmarks$ = this.store$.pipe(
+    select(annotation.selectors.annotations),
   )
 
   public filterCustomLandmark(lm: any){
@@ -149,26 +174,6 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
     shareReplay(1),
   )
 
-  ngOnChanges(sc: SimpleChanges){
-    const {
-      selectedParcellation,
-      selectedTemplate
-    } = sc
-    if (selectedTemplate) {
-      if (selectedTemplate?.currentValue?.['@id'] !== selectedTemplate?.previousValue?.['@id']) {
-
-        if (selectedTemplate?.previousValue) {
-          this.unloadTmpl(selectedTemplate?.previousValue)
-        }
-        if (selectedTemplate?.currentValue?.['@id']) {
-          this.loadTmpl(selectedTemplate.currentValue, selectedParcellation.currentValue)
-        }
-      }
-    }else if (selectedParcellation && selectedParcellation.currentValue !== selectedParcellation.previousValue) {
-      this.loadParc(selectedParcellation.currentValue)
-    }
-  }
-
   private nehubaContainerSub: Subscription
   private setupNehubaEvRelay() {
     if (this.nehubaContainerSub) this.nehubaContainerSub.unsubscribe()
@@ -201,10 +206,15 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
           payload: {
             nav,
             mouse,
-            nehuba: seg.map(v => {
+            nehuba: seg && seg.map(v => {
               return {
                 layerName: v.layer.name,
-                labelIndices: [ Number(v.segmentId) ]
+                labelIndices: [ Number(v.segmentId) ],
+                regions: (() => {
+                  const map = this.multiNgIdsRegionsLabelIndexMap.get(v.layer.name)
+                  if (!map) return []
+                  return [map.get(Number(v.segmentId))]
+                })()
               }
             })
           }
@@ -230,22 +240,25 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
     while (this.onDestroyCb.length) this.onDestroyCb.pop()()
   }
 
-  private loadParc(parcellation: any) {
+  private async loadParc(atlas: SapiAtlasModel, parcellation: SapiParcellationModel, space: SapiSpaceModel, ngLayers: Record<string, NgLayerSpec | NgPrecompMeshSpec | NgSegLayerSpec>) {
     /**
-     * parcellaiton may be undefined
+     * parcellation may be undefined
      */
-    if ( !(parcellation && parcellation.regions)) {
+    if ( !parcellation) {
       return
     }
+    const pevs = await this.sapiSvc.getParcRegions(atlas["@id"], parcellation["@id"], space["@id"])
 
-    this.multiNgIdsRegionsLabelIndexMap = getMultiNgIdsRegionsLabelIndexMap(parcellation)
-
-    this.viewerUnit.multiNgIdsLabelIndexMap = this.multiNgIdsRegionsLabelIndexMap
-    this.viewerUnit.auxilaryMeshIndices = parcellation.auxillaryMeshIndices || []
-
+    const ngIdSegmentsMap: Record<string, number[]> = {}
+    for (const key in ngLayers) {
+      if ((ngLayers[key] as NgSegLayerSpec).labelIndicies) {
+        ngIdSegmentsMap[key] = (ngLayers[key] as NgSegLayerSpec).labelIndicies
+      }
+    }
+    this.viewerUnit.ngIdSegmentsMap = ngIdSegmentsMap
   }
 
-  private unloadTmpl(tmpl: any) {
+  private unloadTmpl() {
     /**
      * clear existing container
      */
@@ -253,36 +266,45 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
     this.nehubaContainerDirective.clear()
 
     /* on selecting of new template, remove additional nglayers */
-    const baseLayerNames = Object.keys(tmpl.nehubaConfig.dataset.initialNgState.layers)
-    this.layerCtrlService.removeNgLayers(baseLayerNames)
+    if (this.nehubaConfig) {
+      const baseLayerNames = Object.keys(this.nehubaConfig.dataset.initialNgState.layers)
+      this.layerCtrlService.removeNgLayers(baseLayerNames)
+    }
   }
 
-  private async loadTmpl(_template: any, parcellation: any) {
+  private async loadTmpl(atlas: SapiAtlasModel, _template: SapiSpaceModel, parcellation: SapiParcellationModel, ngLayers: Record<string, NgLayerSpec | NgPrecompMeshSpec | NgSegLayerSpec>) {
 
     if (!_template) return
     /**
      * recalcuate zoom
      */
-    const template = (() => {
-
-      const deepCopiedState = JSON.parse(JSON.stringify(_template))
-      const initialNgState = deepCopiedState.nehubaConfig.dataset.initialNgState
-
-      if (!initialNgState || !this.navigation) {
-        return deepCopiedState
-      }
-      const overwritingInitState = this.navigation
-        ? cvtNavigationObjToNehubaConfig(this.navigation, initialNgState)
-        : {}
+    const validSpaceIds = parcellation.brainAtlasVersions.map(bas => bas.coordinateSpace["@id"] as string)
+    let template: SapiSpaceModel
+    if (validSpaceIds.indexOf(_template["@id"]) >= 0) {
+      template = _template
+    } else {
+      /**
+       * selected parc does not have space as a valid output
+       */
+      this.store$.dispatch(generalActionError({
+        message: `space ${_template.fullName} is not defined in parcellation ${parcellation.brainAtlasVersions[0].fullName}`
+      }))
+      template = await this.sapiSvc.getSpaceDetail(this.selectedAtlas["@id"], parcellation.brainAtlasVersions[0].coordinateSpace["@id"] as string)
+    }
+    const config = getNehubaConfig(template)
+    config.dataset.initialNgState.layers = ngLayers
+    const overwritingInitState = this.navigation
+      ? cvtNavigationObjToNehubaConfig(this.navigation, config.dataset.initialNgState)
+      : {}
+
+      config.dataset.initialNgState = {
+      ...config.dataset.initialNgState,
+      ...overwritingInitState,
+    }
 
-      deepCopiedState.nehubaConfig.dataset.initialNgState = {
-        ...initialNgState,
-        ...overwritingInitState,
-      }
-      return deepCopiedState
-    })()
+    this.nehubaConfig = config
 
-    this.nehubaContainerDirective.createNehubaInstance(template)
+    this.nehubaContainerDirective.createNehubaInstance(config)
     this.viewerUnit = this.nehubaContainerDirective.nehubaViewerInstance
     this.sliceRenderEvent$.pipe(
       takeOnePipe()
@@ -296,19 +318,17 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
         this.nanometersToOffsetPixelsFn[idx] = e.detail.nanometersToOffsetPixels
       }
     })
-    const foundParcellation = parcellation
-      && template?.parcellations?.find(p => parcellation.name === p.name)
-    this.loadParc(foundParcellation || template.parcellations[0])
 
-    const nehubaConfig = template.nehubaConfig
-    const initialSpec = nehubaConfig.dataset.initialNgState
+    await this.loadParc(atlas, parcellation, template, ngLayers)
+
+    const initialSpec = config.dataset.initialNgState
     const {layers} = initialSpec
 
-    const dispatchLayers = Object.keys(layers).map(key => {
+    const dispatchLayers = Object.keys(layers).map((key, idx) => {
       const layer = {
         name : key,
         source : layers[key].source,
-        mixability : layers[key].type === 'image'
+        mixability : idx === 0
           ? 'base'
           : 'mixable',
         visible : typeof layers[key].visible === 'undefined'
@@ -338,6 +358,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
     @Optional() @Inject(CLICK_INTERCEPTOR_INJECTOR) clickInterceptor: ClickInterceptor,
     @Optional() @Inject(API_SERVICE_SET_VIEWER_HANDLE_TOKEN) setViewerHandle: TSetViewerHandle,
     @Optional() private layerCtrlService: NehubaLayerControlService,
+    private sapiSvc: SAPI,
   ){
 
     /**
@@ -350,6 +371,22 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
       this.onDestroyCb.push(() => deregister(selOnhoverRegion))
     }
 
+    /**
+     * subscribe to ngIdtolblIdxToRegion
+     */
+    const ngIdSub = this.layerCtrlService.selectedATPR$.subscribe(({ atlas, parcellation, template, regions }) => {
+      this.multiNgIdsRegionsLabelIndexMap.clear()
+      for (const r of regions) {
+        const ngId = getParcNgId(atlas, template, parcellation, r)
+        const labelIndex = getRegionLabelIndex(atlas, template, parcellation, r)
+        if (!this.multiNgIdsRegionsLabelIndexMap.has(ngId)) {
+          this.multiNgIdsRegionsLabelIndexMap.set(ngId, new Map())
+        }
+        this.multiNgIdsRegionsLabelIndexMap.get(ngId).set(labelIndex, r)
+      }
+    })
+    this.onDestroyCb.push(() => ngIdSub.unsubscribe())
+
     /**
      * on layout change
      */
@@ -418,11 +455,10 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
      * on hover segment
      */
     const onhovSegSub = this.store$.pipe(
-      select(uiStateMouseOverSegmentsSelector),
+      select(userInteraction.selectors.mousingOverRegions),
       distinctUntilChanged(),
     ).subscribe(arr => {
-      const segments = arr.map(({ segment }) => segment).filter(v => !!v)
-      this.onhoverSegments = segments
+      this.onhoverSegments = arr
     })
     this.onDestroyCb.push(() => onhovSegSub.unsubscribe())
 
@@ -508,6 +544,36 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
       shareReplay(1),
     )
 
+    const newTmplSub = this.store$.pipe(
+      select(atlasSelection.selectors.selectedATP),
+      distinctUntilChanged((o, n) => {
+        return o?.template?.["@id"] === n?.template?.["@id"]
+      }),
+      switchMap(ATP => {
+        return this.store$.pipe(
+          fromRootStore.getNgLayers(this.store$, this.sapiSvc),
+          map(ngLayers => ({ ATP, ngLayers }))
+        )
+      }
+      )
+    ).subscribe(({ ATP, ngLayers }) => {
+      const { template, parcellation, atlas } = ATP
+      const { tmplNgLayers, tmplAuxNgLayers, parcNgLayers } = ngLayers
+      
+
+      // clean up previous tmpl
+      this.unloadTmpl()
+
+      const layerObj = {
+        ...tmplNgLayers,
+        ...tmplAuxNgLayers,
+        ...parcNgLayers,
+      }
+      this.loadTmpl(atlas, template, parcellation, layerObj)
+    })
+
+    this.onDestroyCb.push(() => newTmplSub.unsubscribe())
+
     const setupViewerApiSub = this.newViewer$.pipe(
       tap(() => {
         setViewerHandle && setViewerHandle(null)
@@ -519,14 +585,13 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
           position : coord,
           positionReal : typeof realSpace !== 'undefined' ? realSpace : true,
         }),
-        /* TODO introduce animation */
         moveToNavigationLoc : (coord, _realSpace?) => {
           this.store$.dispatch(
-            viewerStateChangeNavigation({
+            actions.navigateTo({
               navigation: {
-                position: coord,
-                animation: {},
-              }
+                position: coord
+              },
+              animation: true
             })
           )
         },
@@ -542,12 +607,6 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
            * TODO reenable with updated select_regions api
            */
           this.log.warn(`showSegment is temporarily disabled`)
-
-          // if(!this.selectedRegionIndexSet.has(labelIndex))
-          //   this.store.dispatch({
-          //     type : SELECT_REGIONS,
-          //     selectRegions :  [labelIndex, ...this.selectedRegionIndexSet]
-          //   })
         },
         add3DLandmarks : landmarks => {
           // TODO check uniqueness of ID
@@ -566,9 +625,11 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
           }))
         },
         remove3DLandmarks : landmarkIds => {
-          this.store$.dispatch(viewreStateRemoveUserLandmarks({
-            payload: { landmarkIds }
-          }))
+          this.store$.dispatch(
+            annotation.actions.rmAnnotations({
+              annotations: landmarkIds.map(id => ({ "@id": id }))
+            })
+          )
         },
         hideSegment : (_labelIndex) => {
           /**
@@ -576,28 +637,10 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
            */
           this.log.warn(`hideSegment is temporarily disabled`)
 
-          // if(this.selectedRegionIndexSet.has(labelIndex)){
-          //   this.store.dispatch({
-          //     type :SELECT_REGIONS,
-          //     selectRegions : [...this.selectedRegionIndexSet].filter(num=>num!==labelIndex)
-          //   })
-          // }
         },
         showAllSegments : () => {
-          const selectRegionIds = []
-          this.multiNgIdsRegionsLabelIndexMap.forEach((map, ngId) => {
-            Array.from(map.keys()).forEach(labelIndex => {
-              selectRegionIds.push(serialiseParcellationRegion({ ngId, labelIndex }))
-            })
-          })
-          this.store$.dispatch(viewerStateSelectRegionWithIdDeprecated({
-            selectRegionIds
-          }))
         },
         hideAllSegments : () => {
-          this.store$.dispatch(viewerStateSelectRegionWithIdDeprecated({
-            selectRegionIds: []
-          }))
         },
         getLayersSegmentColourMap: () => {
           if (!this.layerCtrlService) {
@@ -658,11 +701,8 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
         mouseOverNehuba : of(null).pipe(
           tap(() => console.warn('mouseOverNehuba observable is becoming deprecated. use mouseOverNehubaLayers instead.')),
         ),
-        mouseOverNehubaLayers: this.mouseoverDirective.currentOnHoverObs$.pipe(
-          map(({ segments }) => segments)
-        ),
         mouseOverNehubaUI: this.mouseoverDirective.currentOnHoverObs$.pipe(
-          map(({annotation, landmark, segments, userLandmark: customLandmark }) => ({annotation, segments, landmark, customLandmark })),
+          map(({annotation, landmark, userLandmark: customLandmark }) => ({annotation, landmark, customLandmark })),
           shareReplay(1),
         ),
         getNgHash : this.nehubaContainerDirective.nehubaViewerInstance.getNgHash,
@@ -672,8 +712,10 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
 
     // listen to navigation change from store
     const navSub = this.store$.pipe(
-      select(viewerStateNavigationStateSelector)
-    ).subscribe(nav => this.navigation = nav)
+      select(atlasSelection.selectors.navigation)
+    ).subscribe(nav => {
+      this.navigation = nav
+    })
     this.onDestroyCb.push(() => navSub.unsubscribe())
   }
 
@@ -699,8 +741,8 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
     const trueOnhoverSegments = this.onhoverSegments && this.onhoverSegments.filter(v => typeof v === 'object')
     if (!trueOnhoverSegments || (trueOnhoverSegments.length === 0)) return true
     this.store$.dispatch(
-      viewerStateSetSelectedRegions({
-        selectRegions: trueOnhoverSegments.slice(0, 1)
+      actions.selectRegions({
+        regions: trueOnhoverSegments.slice(0, 1)
       })
     )
     return true
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
index 104c5add581a8bcb216d1afe8d15b42002657938..c9eb5773a04e34b8e2a43933136edf18f6a36fe2 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
@@ -5,7 +5,7 @@
   [iav-viewer-touch-interface-v-panels]="viewPanels"
   [iav-viewer-touch-interface-vp-to-data]="iavContainer?.viewportToDatas"
   [iav-viewer-touch-interface-ngviewer]="iavContainer?.nehubaViewerInstance?.nehubaViewer?.ngviewer"
-  [iav-viewer-touch-interface-nehuba-config]="selectedTemplate?.nehubaConfig">
+  [iav-viewer-touch-interface-nehuba-config]="nehubaConfig">
 
   <div class="d-block"
     iav-nehuba-viewer-container
diff --git a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
index 1b6fb599e73e9808098fe45872860672a26b5742..59062511f3bb3a13e626dac719b48da9e2e87f91 100644
--- a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
+++ b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
@@ -3,87 +3,17 @@ import { NehubaViewerUnit, INehubaLifecycleHook } from "../nehubaViewer/nehubaVi
 import { Store, select } from "@ngrx/store";
 import { Subscription, Observable, fromEvent, asyncScheduler, combineLatest } from "rxjs";
 import { distinctUntilChanged, filter, debounceTime, scan, map, throttleTime, switchMapTo } from "rxjs/operators";
-import { takeOnePipe } from "../util";
+import { serializeSegment, takeOnePipe } from "../util";
 import { ngViewerActionNehubaReady } from "src/services/state/ngViewerState/actions";
-import { viewerStateMouseOverCustomLandmarkInPerspectiveView, viewerStateNehubaLayerchanged } from "src/services/state/viewerState/actions";
-import { viewerStateStandAloneVolumes } from "src/services/state/viewerState/selectors";
 import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState/selectors";
 import { LoggingService } from "src/logging";
 import { uiActionMouseoverLandmark, uiActionMouseoverSegments } from "src/services/state/uiState/actions";
 import { IViewerConfigState } from "src/services/state/viewerConfig.store.helper";
 import { arrayOfPrimitiveEqual } from 'src/util/fn'
 import { INavObj, NehubaNavigationService } from "../navigation.service";
+import { NehubaConfig, defaultNehubaConfig } from "../config.service";
+import { atlasSelection } from "src/state";
 
-const defaultNehubaConfig = {
-  "configName": "",
-  "globals": {
-    "hideNullImageValues": true,
-    "useNehubaLayout": {
-      "keepDefaultLayouts": false
-    },
-    "useNehubaMeshLayer": true,
-    "rightClickWithCtrlGlobal": false,
-    "zoomWithoutCtrlGlobal": false,
-    "useCustomSegmentColors": true
-  },
-  "zoomWithoutCtrl": true,
-  "hideNeuroglancerUI": true,
-  "rightClickWithCtrl": true,
-  "rotateAtViewCentre": true,
-  "enableMeshLoadingControl": true,
-  "zoomAtViewCentre": true,
-  "restrictUserNavigation": true,
-  "disableSegmentSelection": false,
-  "dataset": {
-    "imageBackground": [
-      1,
-      1,
-      1,
-      1
-    ],
-    "initialNgState": {
-      "showDefaultAnnotations": false,
-      "layers": {},
-    }
-  },
-  "layout": {
-    "views": "hbp-neuro",
-    "planarSlicesBackground": [
-      1,
-      1,
-      1,
-      1
-    ],
-    "useNehubaPerspective": {
-      "enableShiftDrag": false,
-      "doNotRestrictUserNavigation": false,
-      "perspectiveSlicesBackground": [
-        1,
-        1,
-        1,
-        1
-      ],
-      "perspectiveBackground": [
-        1,
-        1,
-        1,
-        1
-      ],
-      "mesh": {
-        "backFaceColor": [
-          1,
-          1,
-          1,
-          1
-        ],
-        "removeBasedOnNavigation": true,
-        "flipRemovedOctant": true
-      },
-      "hideImages": false,
-      "waitForMesh": false,
-    }
-  }
-}
 
 const determineProtocol = (url: string) => {
   const re = /^([a-z0-9_-]{0,}):\/\//.exec(url)
@@ -266,7 +196,7 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
 
     this.subscriptions.push(
       this.store$.pipe(
-        select(viewerStateStandAloneVolumes),
+        select(atlasSelection.selectors.standaloneVolumes),
         filter(v => v && Array.isArray(v) && v.length > 0),
         distinctUntilChanged(arrayOfPrimitiveEqual)
       ).subscribe(async volumes => {
@@ -285,7 +215,7 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
         function onInit() {
           this.overrideShowLayers = forceShowLayerNames
         }
-        this.createNehubaInstance({ nehubaConfig: copiedNehubaConfig }, { onInit })
+        this.createNehubaInstance(copiedNehubaConfig, { onInit })
       }),
 
       this.viewerPerformanceConfig$.pipe(
@@ -316,7 +246,7 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
     this.nehubaViewerInstance.toggleOctantRemoval(flag)
   }
 
-  createNehubaInstance(template: any, lifeCycle: INehubaLifecycleHook = {}){
+  createNehubaInstance(nehubaConfig: NehubaConfig, lifeCycle: INehubaLifecycleHook = {}){
     this.clear()
     this.iavNehubaViewerContainerViewerLoading.emit(true)
     this.cr = this.el.createComponent(this.nehubaViewerFactory)
@@ -328,8 +258,6 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
       }
     }
 
-    const { nehubaConfig, name } = template
-
     /**
      * apply viewer config such as gpu limit
      */
@@ -344,18 +272,13 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
       initialNgState.gpuMemoryLimit = gpuLimit
     }
 
-    /* TODO replace with id from KG */
-    this.nehubaViewerInstance.templateId = name
-
     this.nehubaViewerSubscriptions.push(
       this.nehubaViewerInstance.errorEmitter.subscribe(e => {
         console.log(e)
       }),
 
       this.nehubaViewerInstance.layersChanged.subscribe(() => {
-        this.store$.dispatch(
-          viewerStateNehubaLayerchanged()
-        )
+
       }),
 
       this.nehubaViewerInstance.nehubaReady.subscribe(() => {
@@ -387,11 +310,9 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
       this.nehubaViewerInstance.mouseoverUserlandmarkEmitter.pipe(
         throttleTime(160, asyncScheduler, {trailing: true}),
       ).subscribe(label => {
-        this.store$.dispatch(
-          viewerStateMouseOverCustomLandmarkInPerspectiveView({
-            payload: { label }
-          })
-        )
+        const idx = Number(label.replace('label=', ''))
+        // TODO 
+        // this is exclusive for vtk layer
       }),
 
       this.nehubaViewerInstance.nehubaReady.pipe(
@@ -444,15 +365,10 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
         layer: {
           name: ngId,
         },
-        segment: segment || `${ngId}#${segmentId}`,
+        segment: segment || serializeSegment(ngId, segmentId),
         segmentId
       }
     })
     this.mouseOverSegments.emit(payload)
-    this.store$.dispatch(
-      uiActionMouseoverSegments({
-        segments: payload
-      })
-    )
   }
 }
diff --git a/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts b/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts
index 7be4aa437b59c3f92b75a3eb7607f32978d46de5..14919d73d3fd7ca4e5664b18f873ad002c333a1d 100644
--- a/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts
+++ b/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts
@@ -15,8 +15,8 @@ import { UtilModule } from "src/util"
 import { viewerConfigSelectorUseMobileUi } from "src/services/state/viewerConfig.store.helper"
 import { viewerStateNavigationStateSelector, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors"
 import * as util from '../util'
-import { viewerStateChangeNavigation } from "src/services/state/viewerState/actions"
 import {QuickTourModule} from "src/ui/quickTour/module";
+import { actions } from "src/state/atlasSelection"
 
 @Directive({
   selector: '[iav-auth-auth-state]',
@@ -184,13 +184,13 @@ describe('> statusCard.component.ts', () => {
             if (method === 'position') overrideObj['position'] = mockNavState['position']
             if (method === 'zoom') overrideObj['zoom'] = mockNavState['zoom']
             expect(idspatchSpy).toHaveBeenCalledWith(
-              viewerStateChangeNavigation({
+              actions.navigateTo({
                 navigation: {
                   ...mockCurrNavigation,
                   ...overrideObj,
-                  positionReal: false,
-                  animation: {},
-                }
+                },
+                physical: true,
+                animation: true
               })
             )
           })
diff --git a/src/viewerModule/nehuba/statusCard/statusCard.component.ts b/src/viewerModule/nehuba/statusCard/statusCard.component.ts
index 6ac175a1d93dba044ed00e3a7d5e09bc6857dd31..324978a859dc62043085116ce746246397197ff8 100644
--- a/src/viewerModule/nehuba/statusCard/statusCard.component.ts
+++ b/src/viewerModule/nehuba/statusCard/statusCard.component.ts
@@ -16,11 +16,11 @@ import { MatBottomSheet } from "@angular/material/bottom-sheet";
 import { MatDialog } from "@angular/material/dialog";
 import { ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants'
 import { FormControl } from "@angular/forms";
-import { viewerStateNavigationStateSelector, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors";
 
-import { viewerStateChangeNavigation } from "src/services/state/viewerState/actions";
 import { getNavigationStateFromConfig, NEHUBA_INSTANCE_INJTKN } from '../util'
 import { IQuickTourData } from "src/ui/quickTour/constrants";
+import { actions } from "src/state/atlasSelection";
+import { atlasSelection } from "src/state";
 
 @Component({
   selector : 'iav-cmp-viewer-nehuba-status',
@@ -90,13 +90,13 @@ export class StatusCardComponent implements OnInit, OnChanges{
 
     this.subscriptions.push(
       this.store$.pipe(
-        select(viewerStateSelectedTemplatePureSelector)
+        select(atlasSelection.selectors.selectedTemplate)
       ).subscribe(n => this.selectedTemplatePure = n)
     )
 
     this.subscriptions.push(
       this.store$.pipe(
-        select(viewerStateNavigationStateSelector)
+        select(atlasSelection.selectors.navigation)
       ).subscribe(nav => this.currentNavigation = nav)
     )
   }
@@ -184,15 +184,15 @@ export class StatusCardComponent implements OnInit, OnChanges{
     } = getNavigationStateFromConfig(this.selectedTemplatePure.nehubaConfig)
 
     this.store$.dispatch(
-      viewerStateChangeNavigation({
+      actions.navigateTo({
         navigation: {
           ...this.currentNavigation,
           ...(rotationFlag ? { orientation: orientation } : {}),
           ...(positionFlag ? { position: position } : {}),
           ...(zoomFlag ? { zoom: zoom } : {}),
-          positionReal : false,
-          animation : {},
-        }
+        },
+        physical: false,
+        animation: true
       })
     )
   }
diff --git a/src/viewerModule/nehuba/store/index.ts b/src/viewerModule/nehuba/store/index.ts
index a384638d8bf82bd1b38296d9a061405b552cd7f1..bfaa5f424408a852f371a4abddc152bae202d81d 100644
--- a/src/viewerModule/nehuba/store/index.ts
+++ b/src/viewerModule/nehuba/store/index.ts
@@ -16,3 +16,5 @@ export {
   INehubaFeature,
   INgLayerInterface
 } from './type'
+
+export { fromRootStore } from './util'
\ No newline at end of file
diff --git a/src/viewerModule/nehuba/store/util.ts b/src/viewerModule/nehuba/store/util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c81635c543277325143bf69b1ac70d7fa04f01cf
--- /dev/null
+++ b/src/viewerModule/nehuba/store/util.ts
@@ -0,0 +1,90 @@
+import { select } from "@ngrx/store";
+import { forkJoin, pipe } from "rxjs";
+import { switchMap, map, take } from "rxjs/operators";
+import { SAPI, SAPIParcellation, SapiParcellationModel, SAPISpace } from "src/atlasComponents/sapi";
+import { atlasSelection } from "src/state";
+import { getRegionLabelIndex } from "../config.service/util";
+
+export type ParcVolumeSpec = {
+  volumeSrc: string
+  labelIndicies: number[]
+  parcellation: SapiParcellationModel
+  laterality: 'left hemisphere' | 'right hemisphere' | 'whole brain'
+}
+
+type NehubaRegionIdentifier = {
+  source: string
+  labelIndex: number
+}
+
+export const fromRootStore = {
+  getAuxMeshVolumes: (sapi: SAPI) => pipe(
+    select(atlasSelection.selectors.selectedTemplate),
+    switchMap(template => 
+      sapi.registry.get<SAPISpace>(template["@id"])
+        .getVolumes()
+        .then(volumes => volumes.filter(vol => "neuroglancer/precompmesh" in vol.data.detail))
+    ),
+    take(1),
+  ),
+  getTmplVolumes: (sapi: SAPI) => pipe(
+    select(atlasSelection.selectors.selectedTemplate),
+    switchMap(template => 
+      sapi.registry.get<SAPISpace>(template["@id"])
+        .getVolumes()
+        .then(volumes => volumes.filter(vol => "neuroglancer/precomputed" in vol.data.detail))
+    ),
+    take(1),
+  ),
+  getParcVolumes: (sapi: SAPI) => pipe(
+    select(atlasSelection.selectors.selectedATP),
+    switchMap(({ atlas, template, parcellation }) => 
+      forkJoin([
+        sapi.registry.get<SAPIParcellation>(parcellation["@id"])
+          .getRegions(template["@id"])
+          .then(regions => {
+            const returnArr: ParcVolumeSpec[] = []
+            for (const r of regions) {
+              const source = r?.hasAnnotation?.visualizedIn?.["@id"]
+              if (!source) continue
+              if (source.indexOf("precomputed://") < 0) continue
+              const labelIndex = getRegionLabelIndex(atlas, template, parcellation, r)
+              if (!labelIndex) continue
+              
+              const found = returnArr.find(v => v.volumeSrc === source)
+              if (found) {
+                found.labelIndicies.push(labelIndex)
+                continue
+              }
+
+              let laterality: "left hemisphere" | "right hemisphere" | "whole brain" = "whole brain"
+              if (r.name.indexOf("left") >= 0) laterality = "left hemisphere"
+              if (r.name.indexOf("right") >= 0) laterality = "right hemisphere"
+              returnArr.push({
+                volumeSrc: source,
+                labelIndicies: [labelIndex],
+                parcellation,
+                laterality,
+              })
+            }
+            return returnArr
+          }),
+        sapi.registry.get<SAPIParcellation>(parcellation["@id"]).getVolumes()
+      ]).pipe(
+        map(([ volumeSrcs, volumes ]) => {
+          return volumes.map(
+            v => {
+              const found = volumeSrcs.find(volSrc => volSrc.volumeSrc.indexOf(v.data.url) >= 0)
+              return {
+                volume: v,
+                volumeMetadata: found,
+              }
+            }).filter(
+              v => !!v.volumeMetadata?.labelIndicies
+            )
+        })
+      )
+    ),
+    take(1),
+  ),
+}
diff --git a/src/viewerModule/nehuba/types.ts b/src/viewerModule/nehuba/types.ts
index 35cca295acae535d68ba6bb98ce282650c830e45..6fd0dddab5fce72039cd81a92ac3b377c294f8fe 100644
--- a/src/viewerModule/nehuba/types.ts
+++ b/src/viewerModule/nehuba/types.ts
@@ -1,3 +1,4 @@
+import { SapiRegionModel } from "src/atlasComponents/sapi";
 import { INavObj } from "./navigation.service";
 
 export type TNehubaContextInfo = {
@@ -9,5 +10,6 @@ export type TNehubaContextInfo = {
   nehuba: {
     layerName: string
     labelIndices: number[]
+    regions: SapiRegionModel[]
   }[]
 }
diff --git a/src/viewerModule/nehuba/util.spec.ts b/src/viewerModule/nehuba/util.spec.ts
index 0b022b7281e319318a0ae261ef8827b77334e7c1..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/src/viewerModule/nehuba/util.spec.ts
+++ b/src/viewerModule/nehuba/util.spec.ts
@@ -1,141 +0,0 @@
-import { cvtNavigationObjToNehubaConfig } from './util'
-
-const currentNavigation = {
-  position: [4, 5, 6],
-  orientation: [0, 0, 0, 1],
-  perspectiveOrientation: [ 0, 0, 0, 1],
-  perspectiveZoom: 2e5,
-  zoom: 1e5
-}
-
-const defaultPerspectiveZoom = 1e6
-const defaultZoom = 1e6
-
-const defaultNavigationObject = {
-  orientation: [0, 0, 0, 1],
-  perspectiveOrientation: [0 , 0, 0, 1],
-  perspectiveZoom: defaultPerspectiveZoom,
-  zoom: defaultZoom,
-  position: [0, 0, 0],
-  positionReal: true
-}
-
-const defaultNehubaConfigObject = {
-  perspectiveOrientation: [0, 0, 0, 1],
-  perspectiveZoom: 1e6,
-  navigation: {
-    pose: {
-      position: {
-        voxelCoordinates: [0, 0, 0],
-        voxelSize: [1,1,1]
-      },
-      orientation: [0, 0, 0, 1],
-    },
-    zoomFactor: defaultZoom
-  }
-}
-
-const bigbrainNehubaConfig = {
-  "showDefaultAnnotations": false,
-  "layers": {
-  },
-  "navigation": {
-    "pose": {
-      "position": {
-        "voxelSize": [
-          21166.666015625,
-          20000,
-          21166.666015625
-        ],
-        "voxelCoordinates": [
-          -21.8844051361084,
-          16.288618087768555,
-          28.418994903564453
-        ]
-      }
-    },
-    "zoomFactor": 350000
-  },
-  "perspectiveOrientation": [
-    0.3140767216682434,
-    -0.7418519854545593,
-    0.4988985061645508,
-    -0.3195493221282959
-  ],
-  "perspectiveZoom": 1922235.5293810747
-}
-
-describe('> util.ts', () => {
-  
-  describe('> cvtNavigationObjToNehubaConfig', () => {
-    const validNavigationObj = currentNavigation
-    describe('> if inputs are malformed', () => {
-      describe('> if navigation object is malformed, uses navigation default object', () => {
-        it('> if navigation object is null', () => {
-          const v1 = cvtNavigationObjToNehubaConfig(null, bigbrainNehubaConfig)
-          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, bigbrainNehubaConfig)
-          expect(v1).toEqual(v2)
-        })
-        it('> if navigation object is undefined', () => {
-          const v1 = cvtNavigationObjToNehubaConfig(undefined, bigbrainNehubaConfig)
-          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, bigbrainNehubaConfig)
-          expect(v1).toEqual(v2)
-        })
-
-        it('> if navigation object is otherwise malformed', () => {
-          const v1 = cvtNavigationObjToNehubaConfig({foo: 'bar'}, bigbrainNehubaConfig)
-          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, bigbrainNehubaConfig)
-          expect(v1).toEqual(v2)
-
-          const v3 = cvtNavigationObjToNehubaConfig({}, bigbrainNehubaConfig)
-          const v4 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, bigbrainNehubaConfig)
-          expect(v3).toEqual(v4)
-        })
-      })
-
-      describe('> if nehubaConfig object is malformed, use default nehubaConfig obj', () => {
-        it('> if nehubaConfig is null', () => {
-          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, null)
-          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
-          expect(v1).toEqual(v2)
-        })
-
-        it('> if nehubaConfig is undefined', () => {
-          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, undefined)
-          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
-          expect(v1).toEqual(v2)
-        })
-
-        it('> if nehubaConfig is otherwise malformed', () => {
-          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, {})
-          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
-          expect(v1).toEqual(v2)
-
-          const v3 = cvtNavigationObjToNehubaConfig(validNavigationObj, {foo: 'bar'})
-          const v4 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
-          expect(v3).toEqual(v4)
-        })
-      })
-    })
-    it('> converts navigation object and reference nehuba config object to navigation object', () => {
-      const convertedVal = cvtNavigationObjToNehubaConfig(validNavigationObj, bigbrainNehubaConfig)
-      const { perspectiveOrientation, orientation, zoom, perspectiveZoom, position } = validNavigationObj
-      
-      expect(convertedVal).toEqual({
-        navigation: {
-          pose: {
-            position: {
-              voxelSize: bigbrainNehubaConfig.navigation.pose.position.voxelSize,
-              voxelCoordinates: [0, 1, 2].map(idx => position[idx] / bigbrainNehubaConfig.navigation.pose.position.voxelSize[idx])
-            },
-            orientation
-          },
-          zoomFactor: zoom
-        },
-        perspectiveOrientation: perspectiveOrientation,
-        perspectiveZoom: perspectiveZoom
-      })
-    })
-  })
-
-})
diff --git a/src/viewerModule/nehuba/util.ts b/src/viewerModule/nehuba/util.ts
index 398ad2d82aafbbdafc6c8b8c50d72239a91ded92..9c4baa3b039c4736e543ddb6e1c196e8ac2babc5 100644
--- a/src/viewerModule/nehuba/util.ts
+++ b/src/viewerModule/nehuba/util.ts
@@ -4,6 +4,8 @@ import { filter, scan, take } from 'rxjs/operators'
 import { PANELS } from 'src/services/state/ngViewerState.store.helper'
 import { getViewer } from 'src/util/fn'
 import { NehubaViewerUnit } from './nehubaViewer/nehubaViewer.component'
+import { NgConfigViewerState } from "./config.service"
+import { RecursivePartial } from './config.service/type'
 
 const flexContCmnCls = ['w-100', 'h-100', 'd-flex', 'justify-content-center', 'align-items-stretch']
 
@@ -290,7 +292,8 @@ export const takeOnePipe = () => {
 
 export const NEHUBA_INSTANCE_INJTKN = new InjectionToken<Observable<NehubaViewerUnit>>('NEHUBA_INSTANCE_INJTKN')
 
-export function cvtNavigationObjToNehubaConfig(navigationObj, nehubaConfigObj){
+
+export function cvtNavigationObjToNehubaConfig(navigationObj, ngNavigationObj: RecursivePartial<NgConfigViewerState>): Partial<NgConfigViewerState>{
   const {
     orientation = [0, 0, 0, 1],
     perspectiveOrientation = [0, 0, 0, 1],
@@ -300,15 +303,7 @@ export function cvtNavigationObjToNehubaConfig(navigationObj, nehubaConfigObj){
     positionReal = true,
   } = navigationObj || {}
 
-  const voxelSize = (() => {
-    const {
-      navigation = {}
-    } = nehubaConfigObj || {}
-    const { pose = {} } = navigation
-    const { position = {} } = pose
-    const { voxelSize = [1, 1, 1] } = position
-    return voxelSize
-  })()
+  const voxelSize = ngNavigationObj?.navigation?.pose?.position?.voxelSize || [1,1,1]
 
   return {
     perspectiveOrientation,
@@ -327,3 +322,21 @@ export function cvtNavigationObjToNehubaConfig(navigationObj, nehubaConfigObj){
     }
   }
 }
+
+export function serializeSegment(ngId: string, label: number | string){
+  return `${ngId}#${label}`
+}
+
+export function deserializeSegment(id: string) {
+  const split = id.split('#')
+  if (split.length !== 2) {
+    throw new Error(`deserializeSegment error at ${id}. expecting splitting # to result in length 2, got ${split.length}`)
+  }
+  if (isNaN(Number(split[1]))) {
+    throw new Error(`deserializeSegment error at ${id}. expecting second element to be numberable. It was not.`)
+  }
+  return {
+    ngId: split[0],
+    label: Number(split[1])
+  }
+}
diff --git a/src/viewerModule/nehuba/viewerCtrl/change-perspective-orientation/changePerspectiveOrientation.component.ts b/src/viewerModule/nehuba/viewerCtrl/change-perspective-orientation/changePerspectiveOrientation.component.ts
index 0c4bdb1300fb0e7bc094a81d2dcac2d39f67c0d1..9f9d10f7b6467a186111d749e22b17dbebeb3129 100644
--- a/src/viewerModule/nehuba/viewerCtrl/change-perspective-orientation/changePerspectiveOrientation.component.ts
+++ b/src/viewerModule/nehuba/viewerCtrl/change-perspective-orientation/changePerspectiveOrientation.component.ts
@@ -1,6 +1,6 @@
 import { Component } from '@angular/core';
-import {viewerStateChangeNavigation} from "src/services/state/viewerState/actions";
 import {Store} from "@ngrx/store";
+import { actions } from 'src/state/atlasSelection';
 
 @Component({
   selector: 'app-change-perspective-orientation',
@@ -22,10 +22,11 @@ export class ChangePerspectiveOrientationComponent {
     const orientation = this.viewOrientations[plane][view === 'first'? 0 : 1]
 
     this.store$.dispatch(
-      viewerStateChangeNavigation({
+      actions.navigateTo({
         navigation: {
           perspectiveOrientation: orientation,
-        }
+        },
+        animation: true
       })
     )
   }
diff --git a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
index d46a84cfab7d129e94d0c542fd718fa7390e0b6c..cd43851399f9b528b2c2ad1234c8774fc071a551 100644
--- a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
+++ b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
@@ -4,13 +4,13 @@ import { combineLatest, merge, Observable, of, Subscription } from "rxjs";
 import {filter, map, pairwise, withLatestFrom} from "rxjs/operators";
 import { ngViewerActionSetPerspOctantRemoval } from "src/services/state/ngViewerState/actions";
 import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState/selectors";
-import { viewerStateCustomLandmarkSelector, viewerStateGetSelectedAtlas, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors";
 import { NehubaViewerUnit } from "src/viewerModule/nehuba";
 import { NEHUBA_INSTANCE_INJTKN } from "src/viewerModule/nehuba/util";
 import { ARIA_LABELS } from 'common/constants'
 import { actionSetAuxMeshes, selectorAuxMeshes } from "../../store";
 import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
 import {PureContantService} from "src/util";
+import { atlasSelection } from "src/state";
 
 @Component({
   selector: 'viewer-ctrl-component',
@@ -57,16 +57,6 @@ export class ViewerCtrlCmp{
     select(ngViewerSelectorOctantRemoval),
   )
 
-  public customLandmarks$: Observable<any> = this.store$.pipe(
-    select(viewerStateCustomLandmarkSelector),
-    map(lms => lms.map(lm => ({
-      ...lm,
-      geometry: {
-        position: lm.position
-      }
-    }))),
-  )
-
   public auxMeshFormGroup: FormGroup
   private auxMeshesNamesSet: Set<string> = new Set()
   public auxMeshes$ = this.store$.pipe(
@@ -89,35 +79,34 @@ export class ViewerCtrlCmp{
     this.auxMeshFormGroup = formBuilder.group({})
   
 
-    if (this.nehubaInst$) {
-      this.sub.push(
-        combineLatest([
-          this.customLandmarks$,
-          this.nehubaInst$,
-        ]).pipe(
-          filter(([_, nehubaInst]) => !!nehubaInst),
-        ).subscribe(([landmarks, nehubainst]) => {
-          this.setOctantRemoval(landmarks.length === 0)
-          nehubainst.updateUserLandmarks(landmarks)
-        }),
-        this.nehubaInst$.subscribe(nehubaInst => this.nehubaInst = nehubaInst)
-      )
-    } else {
-      console.warn(`NEHUBA_INSTANCE_INJTKN not provided`)
-    }
+    // TODO move this to... nehubadirective?
+    // if (this.nehubaInst$) {
+    //   this.sub.push(
+    //     combineLatest([
+    //       this.customLandmarks$,
+    //       this.nehubaInst$,
+    //     ]).pipe(
+    //       filter(([_, nehubaInst]) => !!nehubaInst),
+    //     ).subscribe(([landmarks, nehubainst]) => {
+    //       this.setOctantRemoval(landmarks.length === 0)
+    //       nehubainst.updateUserLandmarks(landmarks)
+    //     }),
+    //     this.nehubaInst$.subscribe(nehubaInst => this.nehubaInst = nehubaInst)
+    //   )
+    // } else {
+    //   console.warn(`NEHUBA_INSTANCE_INJTKN not provided`)
+    // }
 
     this.sub.push(
-      this.store$.select(viewerStateGetSelectedAtlas)
-        .pipe(filter(a => !!a))
-        .subscribe(sa => this.selectedAtlasId = sa['@id']),
       this.store$.pipe(
-        select(viewerStateSelectedTemplatePureSelector)
-      ).subscribe(tmpl => {
-        this.selectedTemplateId = tmpl['@id']
-        const { useTheme } = tmpl || {}
-        this.darktheme = useTheme === 'dark'
+        select(atlasSelection.selectors.selectedATP)
+      ).subscribe(({ atlas, parcellation, template }) => {
+        this.selectedAtlasId = atlas["@id"]
+        this.selectedTemplateId = template["@id"]
       }),
 
+      this.pureConstantService.darktheme$.subscribe(darktheme => this.darktheme = darktheme),
+
       this.nehubaViewerPerspectiveOctantRemoval$.subscribe(
         flag => this.removeOctantFlag = flag
       ),
diff --git a/src/viewerModule/pipes/nehubaVCtxToBbox.pipe.ts b/src/viewerModule/pipes/nehubaVCtxToBbox.pipe.ts
index 623dc87ce9795ef650afe07a2fe621e59f9e4e5c..e3ceaad4673e198e11eba7ca257ed0a334bb1ac6 100644
--- a/src/viewerModule/pipes/nehubaVCtxToBbox.pipe.ts
+++ b/src/viewerModule/pipes/nehubaVCtxToBbox.pipe.ts
@@ -24,6 +24,9 @@ export class NehubaVCtxToBbox implements PipeTransform{
       divisor = 1e6
     }
     const { payload } = event as TContextArg<'nehuba'>
+    
+    if (!payload.nav) return null
+
     const { position, zoom } = payload.nav
     // position is in nm
     // zoom can be directly applied as a multiple
diff --git a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts
index a00b376604e92ed7e4328b4289c227813f475836..0a62b9a08053b43328afd1300ae638d2c3c90e17 100644
--- a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts
+++ b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts
@@ -7,15 +7,14 @@ import { Observable, Subject } from "rxjs";
 import { debounceTime, filter, switchMap } from "rxjs/operators";
 import { ComponentStore } from "src/viewerModule/componentStore";
 import { select, Store } from "@ngrx/store";
-import { viewerStateChangeNavigation, viewerStateSetSelectedRegions } from "src/services/state/viewerState/actions";
-import { viewerStateSelectorNavigation } from "src/services/state/viewerState/selectors";
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
-import { REGION_OF_INTEREST } from "src/util/interfaces";
 import { MatSnackBar } from "@angular/material/snack-bar";
 import { CONST } from 'common/constants'
 import { API_SERVICE_SET_VIEWER_HANDLE_TOKEN, TSetViewerHandle } from "src/atlasViewer/atlasViewer.apiService.service";
 import { getUuid, switchMapWaitFor } from "src/util/fn";
 import { AUTO_ROTATE, TInteralStatePayload, ViewerInternalStateSvc } from "src/viewerModule/viewerInternalState.service";
+import { actions } from "src/state/atlasSelection";
+import { atlasSelection } from "src/state";
 
 const viewerType = 'ThreeSurfer'
 type TInternalState = {
@@ -39,7 +38,7 @@ type THandlingCustomEv = {
 }
 
 type TCameraOrientation = {
-  perspectiveOrientation: [number, number, number, number]
+  perspectiveOrientation: number[]
   perspectiveZoom: number
 }
 
@@ -112,7 +111,6 @@ export class ThreeSurferGlueCmp implements IViewer<'threeSurfer'>, OnChanges, Af
     private navStateStoreRelay: ComponentStore<{ perspectiveOrientation: [number, number, number, number], perspectiveZoom: number }>,
     private snackbar: MatSnackBar,
     @Optional() intViewerStateSvc: ViewerInternalStateSvc,
-    @Optional() @Inject(REGION_OF_INTEREST) private roi$: Observable<any>,
     @Optional() @Inject(CLICK_INTERCEPTOR_INJECTOR) clickInterceptor: ClickInterceptor,
     @Optional() @Inject(API_SERVICE_SET_VIEWER_HANDLE_TOKEN) setViewerHandle: TSetViewerHandle,
   ){
@@ -193,7 +191,6 @@ export class ThreeSurferGlueCmp implements IViewer<'threeSurfer'>, OnChanges, Af
         hideSegment: nyi,
         mouseEvent: null, 
         mouseOverNehuba: null,
-        mouseOverNehubaLayers: null,
         mouseOverNehubaUI: null,
         moveToNavigationLoc: null,
         moveToNavigationOri: null,
@@ -211,40 +208,52 @@ export class ThreeSurferGlueCmp implements IViewer<'threeSurfer'>, OnChanges, Af
       () => setViewerHandle(null)
     )
 
-    if (this.roi$) {
-      const sub = this.roi$.pipe(
-        switchMap(switchMapWaitFor({
-          condition: () => this.colormapLoaded
-        }))
-      ).subscribe(r => {
-        try {
-          if (!r) throw new Error(`No region selected.`)
-          const cmap = this.getColormapCopy()
-          const hemisphere = getHemisphereKey(r)
-          if (!hemisphere) {
-            this.snackbar.open(CONST.CANNOT_DECIPHER_HEMISPHERE, 'Dismiss', {
-              duration: 3000
-            })
-            throw new Error(CONST.CANNOT_DECIPHER_HEMISPHERE)
-          }
-          for (const [ hem, m ] of cmap.entries()) {
-            for (const lbl of m.keys()) {
-              if (hem !== hemisphere || lbl !== r.labelIndex) {
-                m.set(lbl, [1, 1, 1])
-              }
-            }
-          }
-          this.internalHemisphLblColorMap = cmap
-        } catch (e) {
-          this.internalHemisphLblColorMap = null
-        }
+    const sub = this.store$.pipe(
+      select(atlasSelection.selectors.selectedRegions)
+    ).subscribe(() => {
 
-        this.applyColorMap()
-      })
-      this.onDestroyCb.push(
-        () => sub.unsubscribe()
-      )
-    }
+      /**
+       * TODO
+       * fix ... this?
+       */
+
+      // if (this.roi$) {
+      //   const sub = this.roi$.pipe(
+      //     switchMap(switchMapWaitFor({
+      //       condition: () => this.colormapLoaded
+      //     }))
+      //   ).subscribe(r => {
+      //     try {
+      //       if (!r) throw new Error(`No region selected.`)
+      //       const cmap = this.getColormapCopy()
+      //       const hemisphere = getHemisphereKey(r)
+      //       if (!hemisphere) {
+      //         this.snackbar.open(CONST.CANNOT_DECIPHER_HEMISPHERE, 'Dismiss', {
+      //           duration: 3000
+      //         })
+      //         throw new Error(CONST.CANNOT_DECIPHER_HEMISPHERE)
+      //       }
+      //       for (const [ hem, m ] of cmap.entries()) {
+      //         for (const lbl of m.keys()) {
+      //           if (hem !== hemisphere || lbl !== r.labelIndex) {
+      //             m.set(lbl, [1, 1, 1])
+      //           }
+      //         }
+      //       }
+      //       this.internalHemisphLblColorMap = cmap
+      //     } catch (e) {
+      //       this.internalHemisphLblColorMap = null
+      //     }
+
+      //     this.applyColorMap()
+      //   })
+      //   this.onDestroyCb.push(
+      //     () => sub.unsubscribe()
+      //   )
+      // }
+
+    })
+    this.onDestroyCb.push(() => sub.unsubscribe())
 
     /**
      * intercept click and act
@@ -264,10 +273,11 @@ export class ThreeSurferGlueCmp implements IViewer<'threeSurfer'>, OnChanges, Af
           })
           return true
         }
+
+        // TODO check why typing is all messed up here
+        const regions = this.mouseoverRegions.slice(0, 1) as any[]
         this.store$.dispatch(
-          viewerStateSetSelectedRegions({
-            selectRegions: this.mouseoverRegions
-          })
+          actions.selectRegions({ regions })
         )
         return true
       }
@@ -315,7 +325,7 @@ export class ThreeSurferGlueCmp implements IViewer<'threeSurfer'>, OnChanges, Af
      */
     const navStateSub = this.navStateStoreRelay.select(s => s).subscribe(v => {
       this.store$.dispatch(
-        viewerStateChangeNavigation({
+        actions.navigateTo({
           navigation: {
             position: [0, 0, 0],
             orientation: [0, 0, 0, 1],
@@ -335,7 +345,7 @@ export class ThreeSurferGlueCmp implements IViewer<'threeSurfer'>, OnChanges, Af
      * subscribe to main store and negotiate with relay to set camera
      */
     const navSub = this.store$.pipe(
-      select(viewerStateSelectorNavigation)
+      select(atlasSelection.selectors.navigation)
     ).subscribe(nav => {
       const { perspectiveOrientation, perspectiveZoom } = nav
       this.mainStoreCameraNav = {
diff --git a/src/viewerModule/viewerCmp/viewerCmp.component.spec.ts b/src/viewerModule/viewerCmp/viewerCmp.component.spec.ts
index c67f26f8dcb0be058be3f01c97138a0371dfc4d6..10bb20122d19b73aadd5f7f55b6f065320d055e9 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.component.spec.ts
+++ b/src/viewerModule/viewerCmp/viewerCmp.component.spec.ts
@@ -1,9 +1,6 @@
 import { TestBed } from "@angular/core/testing"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
-import { hot } from "jasmine-marbles"
-import { Observable, of, throwError } from "rxjs"
-import { viewerStateContextedSelectedRegionsSelector } from "src/services/state/viewerState/selectors"
-import { ROIFactory } from "./viewerCmp.component"
+
 
 describe('> viewerCmp.component.ts', () => {
   let mockStore: MockStore
@@ -15,111 +12,4 @@ describe('> viewerCmp.component.ts', () => {
     })
     mockStore = TestBed.inject(MockStore)
   })
-  describe('> ROIFactory', () => {
-    const mockDetail = {
-      foo: 'bar'
-    }
-    class MockPCSvc {
-      getRegionDetail(){
-        return of(mockDetail)
-      }
-    }
-    const pcsvc = new MockPCSvc()
-    let getRegionDetailSpy:  jasmine.Spy
-
-    beforeEach(() => {
-      getRegionDetailSpy = spyOn(pcsvc, 'getRegionDetail')
-      mockStore.overrideSelector(viewerStateContextedSelectedRegionsSelector, [])
-    })
-    
-    afterEach(() => {
-      getRegionDetailSpy.calls.reset()
-    })
-
-    describe('> if regoinselected is empty array', () => {
-      let returnVal: Observable<any>
-      beforeEach(() => {
-        getRegionDetailSpy.and.callThrough()
-        returnVal = ROIFactory(mockStore, pcsvc as any)
-      })
-      it('> returns null', () => {
-        expect(
-          returnVal
-        ).toBeObservable(hot('a', {
-          a: null
-        }))
-      })
-
-      it('> regionDetail not called', () => {
-        expect(getRegionDetailSpy).not.toHaveBeenCalled()
-      })
-    })
-
-    describe('> if regionselected is nonempty', () => {
-      const mockRegion = {
-        context: {
-          template: {
-            '@id': 'template-id'
-          },
-          parcellation: {
-            '@id': 'parcellation-id'
-          },
-          atlas: {
-            '@id': 'atlas-id'
-          }
-        },
-        ngId: 'foo-bar',
-        labelIndex: 123
-      }
-      const returnDetail = {
-        map: {
-          hello: 'world'
-        }
-      }
-      let returnVal: Observable<any>
-      beforeEach(() => {
-        getRegionDetailSpy.and.callFake(() => of(returnDetail))
-        mockStore.overrideSelector(viewerStateContextedSelectedRegionsSelector, [mockRegion])
-        returnVal = ROIFactory(mockStore, pcsvc as any)
-      })
-
-      // TODO check why marble is acting weird
-      // and that null is not emitted
-      it('> returns as expected', () => {
-        expect(returnVal).toBeObservable(
-          hot('(ab)', {
-            a: null,
-            b: {
-              ...mockRegion,
-              ...returnDetail
-            }
-          })
-        )
-        const { context } = mockRegion
-        expect(getRegionDetailSpy).toHaveBeenCalledWith(
-          context.atlas["@id"],
-          context.parcellation["@id"],
-          context.template["@id"],
-          mockRegion
-        )
-      })
-
-      it('> if getRegionDetail throws, at least return original region', () => {
-        getRegionDetailSpy.and.callFake(() => throwError('blabla'))
-        expect(returnVal).toBeObservable(
-          hot('(ab)', {
-            a: null,
-            b: mockRegion
-          })
-        )
-        const { context } = mockRegion
-        expect(getRegionDetailSpy).toHaveBeenCalledWith(
-          context.atlas["@id"],
-          context.parcellation["@id"],
-          context.template["@id"],
-          mockRegion
-        )
-      })
-    })
-  })
 })
diff --git a/src/viewerModule/viewerCmp/viewerCmp.component.ts b/src/viewerModule/viewerCmp/viewerCmp.component.ts
index 7103e137e423fd320dd69a6ef7e42f6f988a0562..00ac6d7e2551046ff3c50838bec54c7da57b5a42 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.component.ts
+++ b/src/viewerModule/viewerCmp/viewerCmp.component.ts
@@ -1,63 +1,24 @@
-import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ComponentFactory, ComponentFactoryResolver, Inject, Injector, Input, OnDestroy, Optional, TemplateRef, ViewChild, ViewContainerRef } from "@angular/core";
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, TemplateRef, ViewChild, ViewContainerRef } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { combineLatest, merge, NEVER, Observable, of, Subscription } from "rxjs";
-import {catchError, debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith, switchMap } from "rxjs/operators";
-import { actionViewerStateSelectFeature, viewerStateChangeNavigation, viewerStateSetSelectedRegions } from "src/services/state/viewerState/actions";
-import {
-  viewerStateContextedSelectedRegionsSelector,
-  viewerStateGetSelectedAtlas,
-  viewerStateSelectedParcellationSelector,
-  viewerStateSelectedTemplateSelector,
-  viewerStateSelectorFeatureSelector,
-  viewerStateStandAloneVolumes,
-  viewerStateViewerModeSelector
-} from "src/services/state/viewerState/selectors"
+import { combineLatest, NEVER, Observable, of, Subscription } from "rxjs";
+import { debounceTime, map, shareReplay, startWith, switchMap } from "rxjs/operators";
 import { CONST, ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants'
-import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN, REGION_OF_INTEREST } from "src/util/interfaces";
+import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN } from "src/util/interfaces";
 import { animate, state, style, transition, trigger } from "@angular/animations";
 import { IQuickTourData } from "src/ui/quickTour";
-import { PureContantService } from "src/util";
 import { EnumViewerEvt, TContextArg, TSupportedViewers, TViewerEvent } from "../viewer.interface";
-import { getGetRegionFromLabelIndexId, switchMapWaitFor } from "src/util/fn";
 import { ContextMenuService, TContextMenuReg } from "src/contextMenuModule";
 import { ComponentStore } from "../componentStore";
-import { MAT_DIALOG_DATA } from "@angular/material/dialog";
-import { GenericInfoCmp } from "src/atlasComponents/regionalFeatures/bsFeatures/genericInfo";
-import { _PLI_VOLUME_INJ_TOKEN, _TPLIVal } from "src/glue";
-import { uiActionSetPreviewingDatasetFiles } from "src/services/state/uiState.store.helper";
-import { viewerStateSetViewerMode } from "src/services/state/viewerState.store.helper";
 import { DialogService } from "src/services/dialogService.service";
-import { SapiVoiResponse } from "src/atlasComponents/sapi/type"
+import { SAPI, SapiRegionModel } from "src/atlasComponents/sapi";
+import { actions } from "src/state/atlasSelection";
+import { atlasSelection, userInterface, userInteraction } from "src/state";
+import { SapiSpatialFeatureModel } from "src/atlasComponents/sapi/type";
 
 type TCStoreViewerCmp = {
   overlaySideNav: any
 }
 
-export function ROIFactory(store: Store<any>, svc: PureContantService){
-  return store.pipe(
-    select(viewerStateContextedSelectedRegionsSelector),
-    switchMap(r => {
-      if (!r[0]) return of(null)
-      const { context } = r[0]
-      const { atlas, template, parcellation } = context || {}
-      return merge(
-        of(null),
-        svc.getRegionDetail(atlas['@id'], parcellation['@id'], template['@id'], r[0]).pipe(
-          map(det => {
-            return {
-              ...r[0],
-              ...det,
-            }
-          }),
-          // in case detailed requests fails
-          catchError((_err, _obs) => of(r[0])),
-        )
-      )
-    }),
-    shareReplay(1)
-  )
-}
-
 @Component({
   selector: 'iav-cmp-viewer-container',
   templateUrl: './viewerCmp.template.html',
@@ -98,11 +59,6 @@ export function ROIFactory(store: Store<any>, svc: PureContantService){
     ]),
   ],
   providers: [
-    {
-      provide: REGION_OF_INTEREST,
-      useFactory: ROIFactory,
-      deps: [ Store, PureContantService ]
-    },
     {
       provide: OVERWRITE_SHOW_DATASET_DIALOG_TOKEN,
       useFactory: (cStore: ComponentStore<TCStoreViewerCmp>) => {
@@ -121,12 +77,12 @@ export function ROIFactory(store: Store<any>, svc: PureContantService){
 })
 
 export class ViewerCmp implements OnDestroy {
-  public _pliTitle = "Fiber structures of a human hippocampus based on joint DMRI, 3D-PLI, and TPFM acquisitions"
-  public _pliDesc = "The collected datasets provide real multimodal, multiscale structural connectivity insights into the human hippocampus. One post mortem hippocampus was scanned with Anatomical and Diffusion MRI (dMRI) [1], 3D Polarized Light Imaging (3D-PLI) [2], and Two-Photon Fluorescence Microscopy (TPFM) [3] using protocols specifically developed during SGA1 and SGA2, rendering joint tissue imaging possible. MRI scanning was performed with a 11.7 T Preclinical MRI system (gradients: 760 mT/m, slew rate: 9500 T/m/s) yielding T1-w and T2-w maps at 200 µm and dMRI-based maps at 300 µm resolution. During tissue sectioning (60 µm thickness) blockface (en-face) images were acquired from the surface of the frozen brain block, serving as reference for data integration/co-alignment. 530 brain sections were scanned with 3D-PLI. HPC-based image analysis provided transmittance, retardation, and fiber orientation maps at 1.3 µm in-plane resolution. TPFM was finally applied to selected brain sections utilizing autofluorescence properties of the fibrous tissue which appears after PBS washing (MAGIC protocol). The TPFM measurements provide a resolution of 0.44 µm x 0.44 µm x 1 µm."
-  public _pliLink = "https://doi.org/10.25493/JQ30-E08"
+
   public CONST = CONST
   public ARIA_LABELS = ARIA_LABELS
 
+  public overlaySidenav$ = NEVER
+
   @ViewChild('genericInfoVCR', { read: ViewContainerRef })
   genericInfoVCR: ViewContainerRef
 
@@ -145,53 +101,72 @@ export class ViewerCmp implements OnDestroy {
   private onDestroyCb: (() => void)[]  = []
   public viewerLoaded: boolean = false
 
-  public templateSelected$ = this.store$.pipe(
-    select(viewerStateSelectedTemplateSelector),
-    distinctUntilChanged(),
+  private selectedATP = this.store$.pipe(
+    select(atlasSelection.selectors.selectedATP),
+    shareReplay(1)
+  )
+
+  public selectedAtlas$ = this.selectedATP.pipe(
+    map(({ atlas }) => atlas)
   )
-  public parcellationSelected$ = this.store$.pipe(
-    select(viewerStateSelectedParcellationSelector),
-    distinctUntilChanged(),
+  public templateSelected$ = this.selectedATP.pipe(
+    map(({ template }) => template)
+  )
+  public parcellationSelected$ = this.selectedATP.pipe(
+    map(({ parcellation }) => parcellation)
   )
 
   public selectedRegions$ = this.store$.pipe(
-    select(viewerStateContextedSelectedRegionsSelector),
-    distinctUntilChanged(),
+    select(atlasSelection.selectors.selectedRegions),
   )
 
   public isStandaloneVolumes$ = this.store$.pipe(
-    select(viewerStateStandAloneVolumes),
+    select(atlasSelection.selectors.standaloneVolumes),
     map(v => v.length > 0)
   )
 
   public viewerMode$: Observable<string> = this.store$.pipe(
-    select(viewerStateViewerModeSelector),
-    shareReplay(1),
-  )
-
-  public overlaySidenav$ = this.cStore.select(s => s.overlaySideNav).pipe(
+    select(atlasSelection.selectors.viewerMode),
     shareReplay(1),
   )
 
   public useViewer$: Observable<TSupportedViewers | 'notsupported'> = combineLatest([
-    this.templateSelected$,
+    this.store$.pipe(
+      select(atlasSelection.selectors.selectedATP),
+      switchMap(({ atlas, template }) => atlas && template
+        ? this.sapi.getSpace(atlas["@id"], template["@id"]).getVolumes()
+        : of(null)),
+      map(vols => {
+        const flags = {
+          isNehuba: false,
+          isThreeSurfer: false
+        }
+        if (!vols) return null
+        if (vols.find(vol => vol.data.volume_type === "neuroglancer/precomputed")) {
+          flags.isNehuba = true
+        }
+
+        if (vols.find(vol => vol.data.volume_type === "gii")) {
+          flags.isThreeSurfer = true
+        }
+        return flags
+      })
+    ),
     this.isStandaloneVolumes$,
   ]).pipe(
-    map(([t, isSv]) => {
+    map(([flags, isSv]) => {
       if (isSv) return 'nehuba'
-      if (!t) return null
-      if (!!t['nehubaConfigURL'] || !!t['nehubaConfig']) return 'nehuba'
-      if (!!t['three-surfer']) return 'threeSurfer'
+      if (!flags) return null
+      if (flags.isNehuba) return 'nehuba'
+      if (flags.isThreeSurfer) return 'threeSurfer'
       return 'notsupported'
     })
   )
 
-  public viewerCtx$ = this.viewerModuleSvc.context$
-
-  public pliVol$ = this._pliVol$ || NEVER
+  public viewerCtx$ = this.ctxMenuSvc.context$
 
   public selectedFeature$ = this.store$.pipe(
-    select(viewerStateSelectorFeatureSelector)
+    select(userInterface.selectors.selectedFeature)
   )
 
   /**
@@ -202,15 +177,12 @@ export class ViewerCmp implements OnDestroy {
    */
   public onlyShowMiniTray$: Observable<boolean> = combineLatest([
     this.selectedRegions$,
-    this.pliVol$.pipe(
-      startWith([])
-    ),
     this.viewerMode$.pipe(
       startWith(null as string)
     ),
     this.selectedFeature$,
   ]).pipe(
-    map(([ regions, layers, viewerMode, selectedFeature ]) => regions.length === 0 && layers.length === 0 && !viewerMode && !selectedFeature)
+    map(([ regions, viewerMode, selectedFeature ]) => regions.length === 0 && !viewerMode && !selectedFeature)
   )
 
   @ViewChild('viewerStatusCtxMenu', { read: TemplateRef })
@@ -223,37 +195,20 @@ export class ViewerCmp implements OnDestroy {
   private templateSelected: any
   private getRegionFromlabelIndexId: (arg: {labelIndexId: string}) => any
 
-  private genericInfoCF: ComponentFactory<GenericInfoCmp>
-
-  public selectedAtlas$ = this.store$.pipe(
-    select(viewerStateGetSelectedAtlas),
-  )
-
-  public clearVoi(){
-    this.store$.dispatch(
-      uiActionSetPreviewingDatasetFiles({
-        previewingDatasetFiles: []
-      })
-    )
-  }
   constructor(
     private store$: Store<any>,
-    private viewerModuleSvc: ContextMenuService<TContextArg<'threeSurfer' | 'nehuba'>>,
+    private ctxMenuSvc: ContextMenuService<TContextArg<'threeSurfer' | 'nehuba'>>,
     private cStore: ComponentStore<TCStoreViewerCmp>,
-    cfr: ComponentFactoryResolver,
     private dialogSvc: DialogService,
     private cdr: ChangeDetectorRef,
-    @Optional() @Inject(_PLI_VOLUME_INJ_TOKEN) private _pliVol$: Observable<_TPLIVal[]>,
-    @Optional() @Inject(REGION_OF_INTEREST) public regionOfInterest$: Observable<any>
+    private sapi: SAPI,
   ){
 
-    this.genericInfoCF = cfr.resolveComponentFactory(GenericInfoCmp)
-
     this.subscriptions.push(
       this.selectedRegions$.subscribe(() => {
         this.clearPreviewingDataset()
       }),
-      this.viewerModuleSvc.context$.subscribe(
+      this.ctxMenuSvc.context$.subscribe(
         (ctx: any) => this.context = ctx
       ),
       this.templateSelected$.subscribe(
@@ -261,9 +216,7 @@ export class ViewerCmp implements OnDestroy {
       ),
       this.parcellationSelected$.subscribe(
         p => {
-          this.getRegionFromlabelIndexId = !!p
-            ? getGetRegionFromLabelIndexId({ parcellation: p })
-            : null
+          this.getRegionFromlabelIndexId = null
         }
       ),
       combineLatest([
@@ -283,7 +236,7 @@ export class ViewerCmp implements OnDestroy {
           message.push(`- _${atlas.name}_`)
         }
         if (checkPrerelease(tmpl)) {
-          message.push(`- _${tmpl.name}_`)
+          message.push(`- _${tmpl.fullName}_`)
         }
         if (checkPrerelease(parc)) {
           message.push(`- _${parc.name}_`)
@@ -328,19 +281,7 @@ export class ViewerCmp implements OnDestroy {
       let hoveredRegions = []
       if (context.viewerType === 'nehuba') {
         hoveredRegions = (context as TContextArg<'nehuba'>).payload.nehuba.reduce(
-          (acc, curr) => acc.concat(
-            curr.labelIndices.map(
-              lblIdx => {
-                const labelIndexId = `${curr.layerName}#${lblIdx}`
-                if (!!this.getRegionFromlabelIndexId) {
-                  return this.getRegionFromlabelIndexId({
-                    labelIndexId: `${curr.layerName}#${lblIdx}`
-                  })
-                }
-                return labelIndexId
-              }
-            )
-          ),
+          (acc, curr) => acc.concat(...curr.regions),
           []
         )
       }
@@ -348,6 +289,7 @@ export class ViewerCmp implements OnDestroy {
       if (context.viewerType === 'threeSurfer') {
         hoveredRegions = (context as TContextArg<'threeSurfer'>).payload._mouseoverRegion
       }
+      console.log('hoveredRegions', hoveredRegions)
 
       if (hoveredRegions.length > 0) {
         append({
@@ -362,31 +304,9 @@ export class ViewerCmp implements OnDestroy {
 
       return true
     }
-    this.viewerModuleSvc.register(cb)
+    this.ctxMenuSvc.register(cb)
     this.onDestroyCb.push(
-      () => this.viewerModuleSvc.deregister(cb)
-    )
-    this.subscriptions.push(
-      this.overlaySidenav$.pipe(
-        switchMap(switchMapWaitFor({
-          condition: () => !!this.genericInfoVCR
-        }))
-      ).subscribe(data => {
-        if (!this.genericInfoVCR) {
-          console.warn(`genericInfoVCR not defined!`)
-          return
-        }
-        const injector = Injector.create({
-          providers: [{
-            provide: MAT_DIALOG_DATA,
-            useValue: data
-          }]
-        })
-
-        this.genericInfoVCR.clear()
-        this.genericInfoVCR.createComponent(this.genericInfoCF, null, injector)
-        this.cdr.markForCheck()
-      })
+      () => this.ctxMenuSvc.deregister(cb)
     )
   }
 
@@ -395,19 +315,17 @@ export class ViewerCmp implements OnDestroy {
     while (this.onDestroyCb.length > 0) this.onDestroyCb.pop()()
   }
 
-  public selectRoi(roi: any) {
+  public selectRoi(roi: SapiRegionModel) {
     this.store$.dispatch(
-      viewerStateSetSelectedRegions({
-        selectRegions: [ roi ]
+      actions.selectRegions({
+        regions: [ roi ]
       })
     )
   }
 
   public exitSpecialViewMode(){
     this.store$.dispatch(
-      viewerStateSetViewerMode({
-        payload: null
-      })
+      actions.clearViewerMode()
     )
   }
 
@@ -426,37 +344,46 @@ export class ViewerCmp implements OnDestroy {
       this.viewerLoaded = event.data
       break
     case EnumViewerEvt.VIEWER_CTX:
-      this.viewerModuleSvc.context$.next(event.data)
+      this.ctxMenuSvc.context$.next(event.data)
+      if (event.data.viewerType === "nehuba") {
+        const { nehuba } = (event.data as TContextArg<"nehuba">).payload
+        const mousingOverRegions = (nehuba || []).reduce((acc, { regions }) => acc.concat(...regions), [])
+        this.store$.dispatch(
+          userInteraction.actions.mouseoverRegions({
+            regions: mousingOverRegions
+          })
+        )
+      }
       break
     default:
     }
   }
 
   public disposeCtxMenu(){
-    this.viewerModuleSvc.dismissCtxMenu()
+    this.ctxMenuSvc.dismissCtxMenu()
   }
 
-  showSpatialDataset(feature: SapiVoiResponse) {
+  showSpatialDataset(feature: SapiSpatialFeatureModel) {
     this.store$.dispatch(
-      viewerStateChangeNavigation({
+      actions.navigateTo({
         navigation: {
           orientation: [0, 0, 0, 1],
-          position: feature.location.center.map(v => v * 1e6),
-          animation: {}
-        }
+          position: feature.location.center.coordinates.map(v => (v.unit as number) * 1e6)
+        },
+        animation: true
       })
     )
 
     this.store$.dispatch(
-      actionViewerStateSelectFeature({ feature })
+      userInterface.actions.showFeature({
+        feature
+      })
     )
   }
 
   clearSelectedFeature(){
     this.store$.dispatch(
-      actionViewerStateSelectFeature({
-        feature: null
-      })
+      userInterface.actions.clearShownFeature()
     )
   }
 }
diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html
index e557965486969e1cda62c84c719537bbdf84e3c0..ff6bd01addf7111c741f5c5b919c003bd2ee3ccb 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.template.html
+++ b/src/viewerModule/viewerCmp/viewerCmp.template.html
@@ -164,11 +164,9 @@
   <!-- if pli voi is visible, show pli template
   otherwise show region tmpl -->
   <ng-template
-    [ngTemplateOutlet]="(pliVol$ | async)?.[0]
-      ? voiTmpl
-      : (selectedFeature$ | async)
-        ? selectedFeatureTmpl
-        : sidenavRegionTmpl"
+    [ngTemplateOutlet]="(selectedFeature$ | async)
+      ? selectedFeatureTmpl
+      : sidenavRegionTmpl"
     [ngTemplateOutletContext]="{
       drawer: drawer,
       showFullSidenavSwitch: showFullSidenavSwitch,
@@ -390,6 +388,7 @@
         (viewerEvent)="handleViewerEvent($event)"
         [selectedTemplate]="templateSelected$ | async"
         [selectedParcellation]="parcellationSelected$ | async"
+        [selectedAtlas]="selectedAtlas$ | async"
         #iavCmpViewerNehubaGlue="iavCmpViewerNehubaGlue">
       </iav-cmp-viewer-nehuba-glue>
 
@@ -534,32 +533,6 @@
   </button>
 </ng-template>
 
-<!-- VOI sidenav tmpl -->
-<ng-template #voiTmpl>
-  <ng-container *ngTemplateOutlet="sapiBaseFeatureTmpl; context: {
-    backCb: clearVoi.bind(this),
-    title: _pliTitle,
-    subtitle: 'Dataset preview',
-    description: _pliDesc,
-    url: [{
-      doi: _pliLink
-    }],
-    contentTmpl: pliDetailTmpl 
-  }">
-  </ng-container>
-
-  <ng-template #pliDetailTmpl>
-    <mat-expansion-panel class="sidenav-cover-header-container">
-      <mat-expansion-panel-header>
-        <mat-panel-title>
-          Registered Volumes
-        </mat-panel-title>
-      </mat-expansion-panel-header>
-      <layer-browser></layer-browser>
-    </mat-expansion-panel>
-  </ng-template>
-</ng-template>
-
 
 <!-- region sidenav tmpl -->
 <ng-template #sidenavRegionTmpl
@@ -582,7 +555,7 @@
       <ng-template [ngIf]="selectedRegions.length === 1" [ngIfElse]="multiRegionWrapperTmpl">
         <!-- a series of bugs result in requiring this hacky -->
         <!-- see https://github.com/HumanBrainProject/interactive-viewer/issues/698 -->
-        <ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: (regionOfInterest$ | async) }">
+        <ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: selectedRegions[0] }">
         </ng-container>
       </ng-template>
 
@@ -619,6 +592,9 @@
 <ng-template #singleRegionTmpl let-region="region">
   <!-- region detail -->
   <region-menu
+    [atlas]="selectedAtlas$ | async"
+    [template]="templateSelected$ | async"
+    [parcellation]="parcellationSelected$ | async"
     [region]="region"
     class="flex-grow-1 bs-border-box mat-elevation-z4">
   </region-menu>
@@ -780,6 +756,7 @@
   </mat-card>
 </ng-template>
 
+
 <!-- viewer status ctx menu -->
 <ng-template #viewerStatusCtxMenu let-data>
   <mat-list>
@@ -826,31 +803,43 @@
   </mat-list>
 </ng-template>
 
+
+<!-- viewer state hover ctx menu -->
 <ng-template #viewerStatusRegionCtxMenu let-data>
   <!-- hovered ROIs -->
   <mat-list>
-    <mat-list-item *ngFor="let hoveredR of data.metadata.hoveredRegions; let first = first">
+    <mat-list-item *ngFor="let region of data.metadata.hoveredRegions; let first = first">
       <mat-divider class="top-0" *ngIf="!first"></mat-divider>
-      <span mat-line>
-        {{ hoveredR.displayName || hoveredR.name }}
-      </span>
-      <span mat-line class="text-muted">
-        <i class="fas fa-brain"></i>
-        <span>
-          Brain region
-        </span>
-      </span>
 
-      <!-- lookup region -->
-      <button mat-icon-button
-        (click)="selectRoi(hoveredR)"
-        ctx-menu-dismiss>
-        <i class="fas fa-search"></i>
-      </button>
+      <ng-container *ngTemplateOutlet="viewerStateSapiRegionTmpl; context: { $implicit: region }">
+      </ng-container>
+
     </mat-list-item>
   </mat-list>
 </ng-template>
 
+
+<!-- sapi region tmpl -->
+<ng-template #viewerStateSapiRegionTmpl let-region>
+  <span mat-line>
+    {{ region.name }}
+  </span>
+  <span mat-line class="text-muted">
+    <i class="fas fa-brain"></i>
+    <span>
+      Brain region
+    </span>
+  </span>
+
+  <!-- lookup region -->
+  <button mat-icon-button
+    (click)="selectRoi(region)"
+    ctx-menu-dismiss>
+    <i class="fas fa-search"></i>
+  </button>
+</ng-template>
+
+
 <!-- feature tmpls -->
 <ng-template #sapiBaseFeatureTmpl
   let-backCb="backCb"
diff --git a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.component.ts b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.component.ts
index 5a4bea443845687db10084cd253a18ec1c44bb17..a2b0b594b3ab0e2f002e2ab140aefe54f289d3da 100644
--- a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.component.ts
+++ b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.component.ts
@@ -1,13 +1,13 @@
-import { Component, EventEmitter, Output, Pipe, PipeTransform } from "@angular/core";
+import { Component, EventEmitter, Output } from "@angular/core";
 import { IQuickTourData } from "src/ui/quickTour";
 import { CONST, ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants'
 import { select, Store } from "@ngrx/store";
-import { viewerStateContextedSelectedRegionsSelector, viewerStateGetOverlayingAdditionalParcellations, viewerStateParcVersionSelector, viewerStateSelectedParcellationSelector } from "src/services/state/viewerState/selectors";
 import { distinctUntilChanged, map } from "rxjs/operators";
-import { viewerStateHelperSelectParcellationWithId, viewerStateRemoveAdditionalLayer, viewerStateSetSelectedRegions } from "src/services/state/viewerState.store.helper";
 import { ngViewerActionClearView, ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState.store.helper";
 import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN } from "src/util/interfaces";
-import { TDatainfosDetail, TSimpleInfo } from "src/util/siibraApiConstants/types";
+import { atlasSelection } from "src/state"
+import { NEVER, of } from "rxjs";
+import { SapiParcellationModel } from "src/atlasComponents/sapi";
 
 @Component({
   selector: 'viewer-state-breadcrumb',
@@ -40,33 +40,24 @@ export class ViewerStateBreadCrumb {
     select(ngViewerSelectorClearViewEntries)
   )
 
-  public selectedAdditionalLayers$ = this.store$.pipe(
-    select(viewerStateGetOverlayingAdditionalParcellations),
-  )
+  // TODO what is this observable anyway?
+  public selectedAdditionalLayers$ = of([])
 
   public parcellationSelected$ = this.store$.pipe(
-    select(viewerStateSelectedParcellationSelector),
+    select(atlasSelection.selectors.selectedParcellation),
     distinctUntilChanged(),
+    
   )
 
   public selectedRegions$ = this.store$.pipe(
-    select(viewerStateContextedSelectedRegionsSelector),
+    select(atlasSelection.selectors.selectedRegions),
     distinctUntilChanged(),
   )
 
-  public selectedLayerVersions$ = this.store$.pipe(
-    select(viewerStateParcVersionSelector),
-    map(arr => arr.map(item => {
-      const overwrittenName = item['@version'] && item['@version']['name']
-      return overwrittenName
-        ? { ...item, displayName: overwrittenName }
-        : item
-    }))
-  )
-
+  // TODO add version info in siibra-api/siibra-python
+  public selectedLayerVersions$ = NEVER
 
   constructor(private store$: Store<any>){
-
   }
 
   handleChipClick(){
@@ -75,9 +66,7 @@ export class ViewerStateBreadCrumb {
 
   public clearSelectedRegions(){
     this.store$.dispatch(
-      viewerStateSetSelectedRegions({
-        selectRegions: []
-      })
+      atlasSelection.actions.clearSelectedRegions()
     )
   }
 
@@ -91,16 +80,14 @@ export class ViewerStateBreadCrumb {
 
   public clearAdditionalLayer(layer: { ['@id']: string }){
     this.store$.dispatch(
-      viewerStateRemoveAdditionalLayer({
-        payload: layer
-      })
+      atlasSelection.actions.clearNonBaseParcLayer()
     )
   }
 
-  public selectParcellation(parc: any) {
+  public selectParcellationWithId(parcId: string) {
     this.store$.dispatch(
-      viewerStateHelperSelectParcellationWithId({
-        payload: parc
+      atlasSelection.actions.selectATPById({
+        parcellationId: parcId
       })
     )
   }
@@ -114,28 +101,3 @@ export class ViewerStateBreadCrumb {
   }
 
 }
-
-@Pipe({
-  name: 'originalDatainfoPriorityPipe'
-})
-
-export class OriginalDatainfoPipe implements PipeTransform{
-  public transform(arr: (TSimpleInfo | TDatainfosDetail)[]): TDatainfosDetail[]{
-    const detailedInfos = arr.filter(item => item['@type'] === 'minds/core/dataset/v1.0.0') as TDatainfosDetail[]
-    const simpleInfos = arr.filter(item => item['@type'] === 'fzj/tmp/simpleOriginInfo/v0.0.1') as TSimpleInfo[]
-
-    if (detailedInfos.length > 0) return detailedInfos
-    if (simpleInfos.length > 0) {
-      return arr.map(d => {
-        return {
-          '@type': 'minds/core/dataset/v1.0.0',
-          name: d.name,
-          description: d.name,
-          urls: [],
-          useClassicUi: false
-        }
-      })
-    }
-    return []
-  }
-}
diff --git a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html
index a80037b10ee223444d42bfe1f144872b82fa0fa2..bb2b36c8cf56e8e59bea040460409e36c5c56051 100644
--- a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html
+++ b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html
@@ -27,7 +27,7 @@
     [matMenuTriggerData]="{ layerVersionMenuTrigger: layerVersionMenuTrigger }"
     #layerVersionMenuTrigger="matMenuTrigger">
 
-    <ng-template [ngIf]="addParc.length > 0" [ngIfElse]="defaultParcTmpl">
+    <ng-template [ngIf]="addParc && addParc.length > 0" [ngIfElse]="defaultParcTmpl">
       <ng-container *ngFor="let p of addParc">
         <ng-container *ngTemplateOutlet="chipTmpl; context: {
           parcel: p,
@@ -150,7 +150,7 @@
             class: 'w-100',
             ariaLabel: parcVer.displayName || parcVer.name,
             onclick: bindFns([
-              [ selectParcellation.bind(this), parcVer ],
+              [ selectParcellationWithId.bind(this), parcVer['@id'] ],
               [ layerVersionMenuTrigger.closeMenu.bind(layerVersionMenuTrigger) ]
             ])
           }">
@@ -181,15 +181,15 @@
     </span>
 
     <!-- info icon -->
-    <ng-container *ngFor="let originDatainfo of (parcel.originDatainfos | originalDatainfoPriorityPipe)">
+    <ng-container *ngFor="let originDatainfo of (parcel | originDatainfoPipe)">
       
       <mat-icon
         fontSet="fas"
         fontIcon="fa-info-circle"
         iav-stop="click"
         iav-dataset-show-dataset-dialog
-        [iav-dataset-show-dataset-dialog-name]="originDatainfo.name"
-        [iav-dataset-show-dataset-dialog-description]="originDatainfo.description"
+        [iav-dataset-show-dataset-dialog-name]="originDatainfo.metadata.fullName"
+        [iav-dataset-show-dataset-dialog-description]="originDatainfo.metadata.description"
         [iav-dataset-show-dataset-dialog-urls]="originDatainfo.urls">
       </mat-icon>
 
diff --git a/src/viewerModule/viewerStateBreadCrumb/module.ts b/src/viewerModule/viewerStateBreadCrumb/module.ts
index ba53571ed934fe530330bd5b96fa2064484151e3..28de784c3e4c6e44fa6257f13604794066d9726a 100644
--- a/src/viewerModule/viewerStateBreadCrumb/module.ts
+++ b/src/viewerModule/viewerStateBreadCrumb/module.ts
@@ -1,11 +1,12 @@
 import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
 import { ParcellationRegionModule } from "src/atlasComponents/parcellationRegion";
-import { KgDatasetModule } from "src/atlasComponents/regionalFeatures/bsFeatures/kgDataset";
 import { QuickTourModule } from "src/ui/quickTour";
 import { AngularMaterialModule } from "src/sharedModules";
 import { UtilModule } from "src/util";
-import { OriginalDatainfoPipe, ViewerStateBreadCrumb } from "./breadcrumb/breadcrumb.component";
+import { ViewerStateBreadCrumb } from "./breadcrumb/breadcrumb.component";
+import { OriginalDatainfoPipe } from "./pipes/originDataInfo.pipe"
+import { DialogInfoModule } from "src/ui/dialogInfo";
 
 @NgModule({
   imports: [
@@ -13,8 +14,8 @@ import { OriginalDatainfoPipe, ViewerStateBreadCrumb } from "./breadcrumb/breadc
     AngularMaterialModule,
     QuickTourModule,
     ParcellationRegionModule,
-    KgDatasetModule,
     UtilModule,
+    DialogInfoModule,
   ],
   declarations: [
     ViewerStateBreadCrumb,
diff --git a/src/viewerModule/viewerStateBreadCrumb/pipes/originDataInfo.pipe.ts b/src/viewerModule/viewerStateBreadCrumb/pipes/originDataInfo.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3c8676554dd7c1b766878d579b42b9a2bdbfc2ce
--- /dev/null
+++ b/src/viewerModule/viewerStateBreadCrumb/pipes/originDataInfo.pipe.ts
@@ -0,0 +1,24 @@
+import { Pipe, PipeTransform } from "@angular/core"
+import {
+  SapiDatasetModel,
+  SapiParcellationModel,
+  SapiRegionModel,
+} from "src/atlasComponents/sapi"
+
+@Pipe({
+  name: 'originDatainfoPipe'
+})
+
+export class OriginalDatainfoPipe implements PipeTransform{
+  public transform(obj: SapiParcellationModel | SapiRegionModel): SapiDatasetModel[]{
+    
+    if (obj["@type"] === "minds/core/parcellationatlas/v1.0.0") {
+      const ds = (obj as SapiParcellationModel).datasets[0]
+      return (obj as SapiParcellationModel).datasets
+    }
+    if (obj["@type"] === "https://openminds.ebrains.eu/sands/ParcellationEntityVersion") {
+      (obj as SapiRegionModel)
+      return []
+    }
+  }
+}
diff --git a/worker/worker.js b/worker/worker.js
index 04a3db58bd8cbac500f2ab0dedc896ea2de7f979..8889abb92c88f400260cd4f391551e7ad7277c51 100644
--- a/worker/worker.js
+++ b/worker/worker.js
@@ -17,7 +17,6 @@ if (typeof self.importScripts === 'function')  self.importScripts('./worker-type
  */
 
 const validTypes = [
-  'GET_LANDMARKS_VTK',
   'GET_USERLANDMARKS_VTK',
   'PROPAGATE_PARC_REGION_ATTR'
 ]
@@ -35,7 +34,6 @@ const VALID_METHODS = [
 ]
 
 const validOutType = [
-  'ASSEMBLED_LANDMARKS_VTK',
   'ASSEMBLED_USERLANDMARKS_VTK',
 ]
 
@@ -170,32 +168,6 @@ const parseLmToVtk = (landmarks, scale) => {
     .concat(reduce.labelString.join('\n'))
 }
 
-let landmarkVtkUrl
-
-const getLandmarksVtk = (action) => {
-
-  // landmarks are array of triples in nm (array of array of numbers)
-  const landmarks = action.landmarks
-  const template = action.template
-  const scale = action.scale
-    ? action.scale
-    : 2.8
-
-  const vtk = parseLmToVtk(landmarks, scale)
-
-  if(!vtk) return
-
-  // when new set of landmarks are to be displayed, the old landmarks will be discarded
-  if(landmarkVtkUrl) URL.revokeObjectURL(landmarkVtkUrl)
-
-  landmarkVtkUrl = URL.createObjectURL(new Blob( [encoder.encode(vtk)], {type : 'application/octet-stream'} ))
-  postMessage({
-    type : 'ASSEMBLED_LANDMARKS_VTK',
-    template,
-    url : landmarkVtkUrl
-  })
-}
-
 let userLandmarkVtkUrl
 
 const getuserLandmarksVtk = (action) => {
@@ -327,9 +299,6 @@ onmessage = (message) => {
 
   if(validTypes.findIndex(type => type === message.data.type) >= 0){
     switch(message.data.type){
-      case 'GET_LANDMARKS_VTK':
-        getLandmarksVtk(message.data)
-        return
       case 'GET_USERLANDMARKS_VTK':
         getuserLandmarksVtk(message.data)
         return