diff --git a/common/constants.js b/common/constants.js
index 284345dec61ce5f62edaa1770fbb7b799abec7d6..d94ab3a30d5d7c6fbafb2380aadc40a725e28fed 100644
--- a/common/constants.js
+++ b/common/constants.js
@@ -17,6 +17,8 @@
     DOWNLOAD_PREVIEW_CSV: `Download CSV`,
     DATASET_FILE_PREVIEW: `Preview of dataset`,
     PIN_DATASET: 'Toggle pinning dataset',
+    TEXT_INPUT_SEARCH_REGION: 'Search for any region of interest in the atlas selected',
+    CLEAR_SELECTED_REGION: 'Clear selected region',
 
     // overlay/layout specific
     SELECT_ATLAS: 'Select a different atlas',
@@ -29,6 +31,7 @@
     SHOW_FULL_STATUS_PANEL: 'Show full status panel',
     HIDE_FULL_STATUS_PANEL: 'Hide full status panel',
     TOGGLE_SIDE_PANEL: 'Toggle side panel',
+    TOGGLE_ATLAS_LAYER_SELECTOR: 'Toggle atlas layer selector',
 
     // sharing module
     SHARE_BTN: `Share this view`,
@@ -45,10 +48,15 @@
 
     // additional volumes
     TOGGLE_SHOW_LAYER_CONTROL: `Show layer control`,
+    ADDITIONAL_VOLUME_CONTROL: 'Additional volumes control'
   }
 
   exports.IDS = {
     // mesh loading status
     MESH_LOADING_STATUS: 'mesh-loading-status'
   }
+
+  exports.CONST = {
+    REGIONAL_FEATURES: 'Regional features'
+  }
 })(typeof exports === 'undefined' ? module.exports : exports)
diff --git a/common/util.js b/common/util.js
index cb1004eef1be8f19a56e9745911148ccaff0d9ba..1dc315089e67f3e98dd219161b7d66d9cb669872 100644
--- a/common/util.js
+++ b/common/util.js
@@ -34,6 +34,13 @@
     return returnV
   }
 
+  exports.getUniqueRegionId = (template, parcellation, region) => {
+    const templateId = template ? (template['@id'] || template['name']) : `untitled-template`
+    const parcId = parcellation ? (parcellation['@id'] || parcellation['name']) : `untitled-parcellation`
+    const regionId = region ? region['name'] : `untitled-region`
+    return `${templateId}/${parcId}/${regionId}`
+  }
+
   exports.getIdObj = getIdObj
 
   exports.getIdFromFullId = fullId => {
diff --git a/deploy/datasets/index.js b/deploy/datasets/index.js
index dc98c0bae950722a2d2b7ec7b4c68490d3c94fd0..502a4c3500f702740814cfc136cc3137f3553605 100644
--- a/deploy/datasets/index.js
+++ b/deploy/datasets/index.js
@@ -2,7 +2,7 @@ const express = require('express')
 const path = require('path')
 const fs = require('fs')
 const datasetsRouter = express.Router()
-const { init, getDatasets, getPreview, getDatasetFromId, getExternalSchemaDatasets, getDatasetFileAsZip, getTos, hasPreview } = require('./query')
+const { init, getDatasets, getPreview, getDatasetFromId, getExternalSchemaDatasets, getDatasetFileAsZip, getTos, hasPreview, getDatasetsByRegion } = require('./query')
 const { retry } = require('./util')
 const url = require('url')
 const qs = require('querystring')
@@ -72,6 +72,13 @@ datasetsRouter.get('/templateNameParcellationName/:templateName/:parcellationNam
     })
 })
 
+datasetsRouter.get('/byRegion/:regionId', noCacheMiddleWare, async (req, res) => {
+  const { regionId } = req.params
+  const { user } = req
+  const ds = await getDatasetsByRegion({ regionId, user })
+  res.status(200).json(ds)
+})
+
 const deprecatedNotice = (_req, res) => {
   res.status(400).send(`querying datasets with /templateName or /parcellationName separately have been deprecated. Please use /templateNameParcellationName/:templateName/:parcellationName instead`)
 }
diff --git a/deploy/datasets/query.js b/deploy/datasets/query.js
index c1a11c28d29a617f4a99427c4c99191abbff39d5..091bc7fcdbae436da2a2f6b2f150eb0b5b7cb33d 100644
--- a/deploy/datasets/query.js
+++ b/deploy/datasets/query.js
@@ -4,7 +4,7 @@ const URL = require('url')
 const path = require('path')
 const archiver = require('archiver')
 const { getPreviewFile, hasPreview } = require('./supplements/previewFile')
-const { constants, init: kgQueryUtilInit, getUserKGRequestParam, filterDatasets } = require('./util')
+const { constants, init: kgQueryUtilInit, getUserKGRequestParam, filterDatasets, filterDatasetsByRegion } = require('./util')
 const ibc = require('./importIBS')
 
 let cachedData = null
@@ -126,6 +126,14 @@ const init = async () => {
   return await getPublicDs()
 }
 
+const getDatasetsByRegion = async ({ regionId, user }) => {
+  /**
+   * potentially add other sources of datasets
+   */
+  const kgDatasets = await getDs({ user })
+  return filterDatasetsByRegion(kgDatasets, regionId)
+}
+
 const getDatasets = ({ templateName, parcellationName, user }) => {
   // Get Local datasets
   const localDatasets = [
@@ -136,7 +144,6 @@ const getDatasets = ({ templateName, parcellationName, user }) => {
   // Get all datasets and merge local ones
   return getDs({ user })
     .then(json => {
-      // console.log(json.map(j=> j.parcellationRegion))
       json = [...json, ...localDatasets]
       return filterDatasets(json, { templateName, parcellationName })
     })
@@ -233,6 +240,7 @@ module.exports = {
   getPreview,
   hasPreview,
   getTos,
-  getExternalSchemaDatasets
+  getExternalSchemaDatasets,
+  getDatasetsByRegion,
 }
 
diff --git a/deploy/datasets/util.js b/deploy/datasets/util.js
index eea0c8f742b4d1cdfb8142168c09ff0892f171e8..ae9a088df528fbd27db3d64b15e96976f1af68d8 100644
--- a/deploy/datasets/util.js
+++ b/deploy/datasets/util.js
@@ -3,7 +3,7 @@ const { getCommonSenseDsFilter } = require('./supplements/commonSense')
 const { hasPreview } = require('./supplements/previewFile')
 const path = require('path')
 const fs = require('fs')
-const { getIdFromFullId, retry, flattenRegions } = require('../../common/util')
+const { getIdFromFullId, retry, flattenRegions, getUniqueRegionId } = require('../../common/util')
 
 let getPublicAccessToken
 
@@ -79,6 +79,57 @@ const populateSet = (flattenedRegions, set = new Set()) => {
 
 const initPrArray = []
 
+/**
+ * regionMap maps schema/id to { parent, children }
+ */
+const regionMap = new Map()
+
+const getParseRegion = (template, parcellation) => {
+
+  const getRegionIdFromRegion = region => {
+    return region.fullId
+      ? getIdFromFullId(region.fullId)
+      : getUniqueRegionId(template, parcellation, region)
+  }
+  
+  const parseRegion = (region, parent) => {
+    const regionId = getRegionIdFromRegion(region)
+    const { children, relatedAreas } = region
+    const childrenIds = [
+      ...(children || []).map(getRegionIdFromRegion)
+    ]
+
+    const alternateIds = [
+      ...(relatedAreas || []).map(getRegionIdFromRegion)
+    ]
+
+    regionMap.set(regionId, {
+      parent,
+      self: [ regionId, ...alternateIds ],
+      children: childrenIds
+    })
+    for (const altId of alternateIds) {
+      regionMap.set(altId, {
+        parent,
+        self: [ regionId, ...alternateIds ],
+        children: childrenIds
+      })
+    }
+    for (const c of (children || [])) {
+      parseRegion(c, regionId)
+    }
+  }
+  return parseRegion  
+}
+
+const processParc = (t, p) => {
+  const parseRegion = getParseRegion(t, p)
+  const { regions } = p
+  for (const r of regions) {
+    parseRegion(r)
+  }
+}
+
 let juBrainSet = new Set(),
   bigbrainCytoSet = new Set()
   shortBundleSet = new Set(),
@@ -93,6 +144,9 @@ initPrArray.push(
   readConfigFile('bigbrain.json')
     .then(data => JSON.parse(data))
     .then(json => {
+      for (const p of json.parcellations) {
+        processParc(json, p)
+      }
       const bigbrainCyto = flattenRegions(json.parcellations.find(({ name }) => name === 'Cytoarchitectonic Maps').regions)
       bigbrainCytoSet = populateSet(bigbrainCyto)
     })
@@ -103,6 +157,9 @@ initPrArray.push(
   readConfigFile('MNI152.json')
     .then(data => JSON.parse(data))
     .then(json => {
+      for (const p of json.parcellations) {
+        processParc(json, p)
+      }
       const longBundle = flattenRegions(json.parcellations.find(({ ['@id']: id }) => id === KG_IDS.PARCELLATIONS.LONG_BUNDLE).regions)
       const shortBundle = flattenRegions(json.parcellations.find(({ ['@id']: id }) =>  id === KG_IDS.PARCELLATIONS.SHORT_BUNDLE).regions)
       const jubrain = flattenRegions(json.parcellations.find(({ ['@id']: id }) => id === KG_IDS.PARCELLATIONS.JULICH_BRAIN).regions)
@@ -117,6 +174,9 @@ initPrArray.push(
   readConfigFile('waxholmRatV2_0.json')
     .then(data => JSON.parse(data))
     .then(json => {
+      for (const p of json.parcellations) {
+        processParc(json, p)
+      }
       const waxholm3 = flattenRegions(json.parcellations[0].regions)
       const waxholm2 = flattenRegions(json.parcellations[1].regions)
       const waxholm1 = flattenRegions(json.parcellations[2].regions)
@@ -132,6 +192,9 @@ initPrArray.push(
   readConfigFile('allenMouse.json')
     .then(data => JSON.parse(data))
     .then(json => {
+      for (const p of json.parcellations) {
+        processParc(json, p)
+      }
       const flattenedAllen2017 = flattenRegions(json.parcellations[0].regions)
       allen2017Set = populateSet(flattenedAllen2017)
 
@@ -197,6 +260,33 @@ const datasetBelongToParcellation = ({ parcellationName = null, dataset = {parce
   ? true
   : (dataset.parcellationAtlas || []).some(({ name }) => name === parcellationName)
 
+const relatedRegionsCache = new Map()
+const traverseRegionMap = regionSchemaId => {
+  if (relatedRegionsCache.has(regionSchemaId)) return relatedRegionsCache.get(regionSchemaId)
+  const out = regionMap.get(regionSchemaId)
+  if (!out) {
+    return []
+  }
+  const { parent, self, children } = out
+
+  /**
+   * how to determine how to traverse the tree to determine related regions?
+   * for now, will traverse towards the parents
+   * ie, when selecting a leaf node, all nodes up to the root will be considered important
+   */
+
+  const relatedSchemaIds = self.concat(
+    parent ? traverseRegionMap(parent) : []
+  )
+  relatedRegionsCache.set(regionSchemaId, relatedSchemaIds)
+  return relatedSchemaIds
+}
+
+const filterDatasetsByRegion = async (datasets = [], regionSchemaId) => {
+  const allRelevantSchemaSet = new Set(traverseRegionMap(regionSchemaId))
+  return datasets.filter(ds => ds['parcellationRegion'].some(pr => allRelevantSchemaSet.has(getIdFromFullId(pr.fullId))))
+}
+
 /**
  * NB: if changed, also change ~/docs/advanced/dataset.md
  * @param {*} dataset 
@@ -309,6 +399,7 @@ module.exports = {
   datasetBelongToParcellation,
   datasetRegionExistsInParcellationRegion,
   datasetBelongsInTemplate,
+  filterDatasetsByRegion,
   _getParcellations: async () => {
     await Promise.all(initPrArray)
     return {
diff --git a/deploy/datasets/util.spec.js b/deploy/datasets/util.spec.js
index aadd7283fceb90aeedf8abb429e4e2087470a237..802edd6620f5f3869d77111233f287bd4ebba410 100644
--- a/deploy/datasets/util.spec.js
+++ b/deploy/datasets/util.spec.js
@@ -1,4 +1,4 @@
-const { populateSet, datasetBelongToParcellation, retry, datasetBelongsInTemplate, filterDatasets, datasetRegionExistsInParcellationRegion, _getParcellations } = require('./util')
+const { populateSet, datasetBelongToParcellation, retry, datasetBelongsInTemplate, filterDatasets, datasetRegionExistsInParcellationRegion, _getParcellations, filterDatasetsByRegion } = require('./util')
 const { fake } = require('sinon')
 const { assert, expect } = require('chai')
 const waxholmv2 = require('./testData/waxholmv2')
@@ -289,4 +289,73 @@ describe('datasets/util.js', () => {
       ])
     })
   })
+
+  describe('filterDatasetsByRegion', () => {
+
+    const idHumanArea7ASPL = 'minds/core/parcellationregion/v1.0.0/e26e999f-77ad-4934-9569-8290ed05ebda'
+    const idHumanArea7A = `minds/core/parcellationregion/v1.0.0/811f4adb-4a7c-45c1-8034-4afa9edf586a`
+    const idMouseWholeBrain = `minds/core/parcellationregion/v1.0.0/be45bc91-8db5-419f-9471-73a320f44e06`
+    const idMousePrimaryMotor = `minds/core/parcellationregion/v1.0.0/a07b4390-62db-451b-b211-a45f67c6b18e`
+    const idMousePrimarySomatosensory = `minds/core/parcellationregion/v1.0.0/f99995b6-a3d0-42be-88c3-eff8a83e60ea`
+
+    const dataHumanArea7ASPL = {
+      name: 'dataHumanArea7ASPL',
+      parcellationRegion: [{
+        fullId: idHumanArea7ASPL
+      }]
+    }
+    const dataMouseWholeBrain = {
+      name: 'dataMouseWholeBrain',
+      parcellationRegion: [{
+        fullId: idMouseWholeBrain
+      }]
+    }
+
+    const dataMousePrimaryMotor = {
+      name: 'dataMousePrimaryMotor',
+      parcellationRegion: [{
+        // Mouse Primary motor area (2017)
+        fullId: idMousePrimaryMotor
+      }]
+    }
+
+    describe('human parc regions', () => {
+      it('should leave in data with matching reference space', async () => {
+        const result = await filterDatasetsByRegion([dataHumanArea7ASPL], idHumanArea7ASPL)
+        expect(result).to.deep.equal([dataHumanArea7ASPL])
+      })
+      it('should filter out data with no matching reference space', async () => {
+        const result = await filterDatasetsByRegion([dataMouseWholeBrain], idHumanArea7ASPL)
+        expect(result).to.deep.equal([])
+      })
+      it('if query region is relatedAreas, should also leave in dataset', async () => {
+        const result = await filterDatasetsByRegion([dataHumanArea7ASPL], idHumanArea7A)
+        expect(result).to.deep.equal([dataHumanArea7ASPL])
+      })
+    })
+
+    describe('mouse parc regions', () => {
+      
+      it('should leave in data with matchin reference space', async () => {
+        const result = await filterDatasetsByRegion([dataMouseWholeBrain], idMouseWholeBrain)
+        expect(result).to.deep.equal([dataMouseWholeBrain])
+
+        const result2 = await filterDatasetsByRegion([dataMousePrimaryMotor], idMousePrimaryMotor)
+        expect(result2).to.deep.equal([dataMousePrimaryMotor])
+      })
+      it('should filter out data with no matching referene space', async () => {
+        const result = await filterDatasetsByRegion([dataHumanArea7ASPL], idMouseWholeBrain)
+        expect(result).to.deep.equal([])
+      })
+      it('should filter out data if sup region is selected', async () => {
+        // example: whole brain is selected, but dataset in primary motor area will be FILTERED OUT
+        const result = await filterDatasetsByRegion([dataMousePrimaryMotor], idMouseWholeBrain)
+        expect(result).to.deep.equal([])
+      })
+      it('should leave in data when sub region is selected', async () => {
+        const result = await filterDatasetsByRegion([dataMouseWholeBrain], idMousePrimaryMotor)
+        expect(result).to.deep.equal([dataMouseWholeBrain])
+      })
+    })
+  })
 })
diff --git a/docs/advanced/datasets.md b/docs/advanced/datasets.md
index ac2602eddf1f292e21a2355b009b7f5bb81e75dc..c9d837b79e3fe245cfc8853eab5d1ce84ec55539 100644
--- a/docs/advanced/datasets.md
+++ b/docs/advanced/datasets.md
@@ -2,248 +2,9 @@
 
 Human Brain Project Knowledge Graph is a metadata database consisting of datasets contributed by collaborators of the Human Brain Project and curated by human curoators in order to ensure the highest standards. 
 
-The interactive atlas viewer fetches the datasets relevant to the template space and parcellation atlas selected by the user using the following conditions:
+!!! note
+    v2.3.0 changed the way datasets are fetched from the knowledge graph.
 
-## Species
+Datasets are now fetched from the knowledge graph on a region of interest basis.
 
-The relevant species of datasets catalogued by Knowledge Graph are obtained from the following links:
-
-```json
-{
-  "fieldname": "query:species",
-  "relative_path": [
-    "https://schema.hbp.eu/minds/specimen_group",
-    "https://schema.hbp.eu/minds/subjects",
-    "https://schema.hbp.eu/minds/species",
-    "http://schema.org/name"
-  ]
-}
-```
-
-Depending on the selected template space and/or parcellation atlas, the datasets will be filtered to include only datasets from the relevant species.
-
-### Human
-
-If the selected template is any of:
-
-- Big Brain (Histology)
-- MNI Colin 27
-- MNI 152 ICBM 2009c Nonlinear Asymmetric
-
-**or**, the selected parcellation is any of:
-
-- Grey/White matter
-- Cytoarchitectonic Maps
-- BigBrain Cortical Layers Segmentation
-- JuBrain Cytoarchitectonic Atlas
-- Fibre Bundle Atlas - Short Bundle
-- Fibre Bundle Atlas - Long Bundle
-- Cytoarchitectonic Maps
-
-Then datasets which have *`Homo sapiens`* as one of its species described above will proceed to the next filter.
-
-### Rat
-
-And selected parcellation is any of:
-
-- Waxholm Space rat brain atlas v1
-- Waxholm Space rat brain atlas v2
-- Waxholm Space rat brain atlas v3
-
-Then datasets which have *`Rattus norvegicus`* as one of its species described above will proceed to the next filter.
-
-### Mouse
-
-And selected parcellation is any of:
-
-- Allen Mouse Common Coordinate Framework v3 2017
-- Allen Mouse Common Coordinate Framework v3 2015
-
-Then datasets which have *`Mus musculus`* as one of its species described above will proceed to the next filter.
-
-
-## Selected template space and parcellation atlas
-
-The datasets are then filtered based on the selected template space and parcellation atlas. 
-
-The dataset may satisfy either conditionals to be presented to the user.
-
-### Template space
-
-The reference space associated with datasets are queried with the following querying links:
-
-```json
-{
-  "fieldname": "query:referenceSpaces",
-  "fields": [
-    {
-      "fieldname": "query:name",
-      "relative_path": "http://schema.org/name"
-    },
-    {
-      "fieldname": "query:fullId",
-      "relative_path": "@id"
-    }
-  ],
-  "relative_path": "https://schema.hbp.eu/minds/reference_space"
-}
-```
-
-The dataset is considered relevant if the stripped `fullId` attribute[^1]  of any of the reference spaces matches to:
-
-[^1]: `fullId` is a URI, which in the case of Human Brain Project Knowledge Graph, always starts with `https://nexus.humanbrainproject.org/v0/data/`. Stripping the domain allows for easier comparison.
-
-| Selected template space | fullId |
-| --- | --- |
-| Big Brain (Histology) | minds/core/dataset/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588 |
-| MNI 152 ICBM 2009c Nonlinear Asymmetric | minds/core/dataset/v1.0.0/dafcffc5-4826-4bf1-8ff6-46b8a31ff8e2 |
-| MNI Colin 27 | minds/core/dataset/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992 |
-
-### Parcellation atlas
-
-The parcellation atlas associated with the dataset are quried with the following querying links:
-
-```json
-{
-  "fieldname": "query:parcellationAtlas",
-  "fields": [
-    {
-      "fieldname": "query:name",
-      "relative_path": "http://schema.org/name"
-    },
-    {
-      "fieldname": "query:fullId",
-      "relative_path": "@id"
-    },
-    {
-      "fieldname": "query:id",
-      "relative_path": "http://schema.org/identifier"
-    }
-  ],
-  "relative_path": "https://schema.hbp.eu/minds/parcellationAtlas"
-}
-```
-
-The parcellation region associated with the dataset are queried with the following querying links:
-
-```json
-{
-  "fieldname": "query:parcellationRegion",
-  "fields": [
-    {
-      "fieldname": "query:name",
-      "relative_path": "http://schema.org/name"
-    },
-    {
-      "fieldname": "query:species",
-      "fields": [
-        {
-          "fieldname": "query:name",
-          "relative_path": "http://schema.org/name"
-        },
-        {
-          "fieldname": "query:fullId",
-          "relative_path": "@id"
-        },
-        {
-          "fieldname": "query:identifier",
-          "relative_path": "http://schema.org/identifier"
-        }
-      ],
-      "relative_path": "https://schema.hbp.eu/minds/species"
-    },
-    {
-      "fieldname": "query:alias",
-      "relative_path": "https://schema.hbp.eu/minds/alias"
-    }
-  ],
-  "relative_path": "https://schema.hbp.eu/minds/parcellationRegion"
-}
-```
-
-A dataset is considered relevant if **both** of the following conditionals are true:
-
-#### Parcellation name
-
-If the name of the selected parcellation in interactive atlas viewer matches exactly with either name of any of the `parcellationAtlas`, or any of its aliases listed below
-
-| `parcellationAtlas` name | aliases |
-| --- | --- |
-| Jülich Cytoarchitechtonic Brain Atlas (human) | Cytoarchitectonic Maps |
-| Jülich Cytoarchitechtonic Brain Atlas (human) | JuBrain Cytoarchitectonic Atlas |
-
-!!! important
-    If the dataset does not have any `parcellationAtlas` defined, it is considered relevant, and will return `true` for this conditional.
-
-#### Parcellation region
-
-To determine if the dataset is relevant based on the parcellation region, **either one** of the following conditions needs to be met:
-
-- If the fullId of any of the `parcellationRegion` matches any of the fullId of a region described under the selected parcellation
-- If the fullId of any of the `parcellationRegion` matches the fullId of any `relatedAreas` of a region described under the selected parcellation.
-
-For example, the following datasets ...
-
-```json
-{
-  "name": "foo",
-  "parcellationRegion": [
-    {
-      "species": [],
-      "name": "Area 44d",
-      "fullId": "minds/core/parcellationregion/v1.0.0/8aeae833-81c8-4e27-a8d6-deee339d6052",
-      "alias": null
-    }
-  ]
-}
-
-```
-
-```json
-{
-  "name": "bar",
-  "parcellationRegion": [
-    {
-      "species": [],
-      "name": "Area 44 (IFG)",
-      "fullId": "minds/core/parcellationregion/v1.0.0/8a6be82c-5947-4fff-8348-cf9bf73e4f40",
-      "alias": null
-    }
-  ]
-}
-```
-
-... will be considered relevant to `JuBrain Cytoarchitectonic Atlas`, as it has an region entry with the following attributes:
-
-```json
-
-{
-  "name": "Area 44 (IFG)",
-  "fullId": {
-    "kg": {
-      "kgSchema": "minds/core/parcellationregion/v1.0.0",
-      "kgId": "8a6be82c-5947-4fff-8348-cf9bf73e4f40"
-    }
-  },
-  "relatedAreas": [
-    {
-      "name": "Area 44v",
-      "fullId": {
-        "kg": {
-          "kgSchema": "minds/core/parcellationregion/v1.0.0",
-          "kgId": "7e5e7aa8-28b8-445b-8980-2a6f3fa645b3"
-        }
-      }
-    },
-    {
-      "name": "Area 44d",
-      "fullId": {
-        "kg": {
-          "kgSchema": "minds/core/parcellationregion/v1.0.0",
-          "kgId": "8aeae833-81c8-4e27-a8d6-deee339d6052"
-        }
-      }
-    }
-  ]
-}
-```
\ No newline at end of file
+Currently, only parcellation regions are supported.
diff --git a/docs/releases/v2.3.0.md b/docs/releases/v2.3.0.md
index 732dcb1511938b623ca35407e851e5e5ea610c53..a0c965335ab9379b2a8ebfd3f29282255fd9a360 100644
--- a/docs/releases/v2.3.0.md
+++ b/docs/releases/v2.3.0.md
@@ -13,8 +13,12 @@
 - showing contributors to a regional feature/dataset if publications are not available
 - added the ability to customize preview origin dataset to labels other to `View probability map`
 
-# Bugfixes:
+## Bugfixes:
 
 - dataset list view explicitly show loading status
 - fixed a few typos
 - fixed the reference space name of `ICBM 152 2009c Nonlinear Asymmetric`
+
+## Under the hood stuff
+
+- Updated how dataset retrieval work. It will now query on a region basis
diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js
index 4169f0e15599004cd2d40fd785a7a8d23125b1e0..5b97da11f2556d369ae5f7c7e1a807a63b19fd38 100644
--- a/e2e/protractor.conf.js
+++ b/e2e/protractor.conf.js
@@ -4,16 +4,16 @@
 const chromeOpts = require('./chromeOpts')
 const SELENIUM_ADDRESS = process.env.SELENIUM_ADDRESS
 
-const bsTestname = process.env.BROWSERSTACK_TEST_NAME
-const bsUsername = process.env.BROWSERSTACK_USERNAME
-const bsAccessKey = process.env.BROWSERSTACK_ACCESS_KEY
+const {
+  BROWSERSTACK_TEST_NAME,
+  BROWSERSTACK_USERNAME,
+  BROWSERSTACK_ACCESS_KEY,
+} = process.env
 const directConnect = !!process.env.DIRECT_CONNECT
 
 const PROTRACTOR_SPECS = process.env.PROTRACTOR_SPECS
 
-const localConfig = bsUsername && bsAccessKey
-  ? {}
-  : {
+const localConfig = {
   ...(SELENIUM_ADDRESS
     ? { seleniumAddress: SELENIUM_ADDRESS }
     : { directConnect: true } 
@@ -45,55 +45,55 @@ let bsLocal
  * MIT licensed
  */
 const bsConfig = {
-  'browserstackUser': bsUsername,
-  'browserstackKey': bsAccessKey,
+  'browserstackUser': BROWSERSTACK_USERNAME,
+  'browserstackKey': BROWSERSTACK_ACCESS_KEY,
   
   'capabilities': {
     'build': 'protractor-browserstack',
-    'name': bsTestname || 'iav_e2e',
+    'name': BROWSERSTACK_TEST_NAME || 'iav_e2e',
     "os" : "Windows",
     "osVersion" : "10",
     'browserName': 'chrome',
-    // 'browserstack.local': false,
+    'browserstack.local': true,
     "seleniumVersion" : "4.0.0-alpha-2",
     'browserstack.debug': 'true'
   },
   "browserName" : "Chrome",
   "browserVersion" : "83.0",
 
-  // // Code to start browserstack local before start of test
-  // beforeLaunch: function(){
-  //   console.log("Connecting local");
-  //   return new Promise(function(resolve, reject){
-  //     bsLocal = new Local();
-  //     bsLocal.start({'key': bsAccessKey }, function(error) {
-  //       if (error) return reject(error);
-  //       console.log('Connected. Now testing...');
+  // Code to start browserstack local before start of test
+  beforeLaunch: function(){
+    console.log("Connecting local");
+    return new Promise(function(resolve, reject){
+      bsLocal = new Local();
+      bsLocal.start({'key': BROWSERSTACK_ACCESS_KEY }, function(error) {
+        if (error) return reject(error);
+        console.log('Connected. Now testing...');
 
-  //       resolve();
-  //     });
-  //   });
-  // },
+        resolve();
+      });
+    });
+  },
 
-  // // Code to stop browserstack local after end of test
-  // afterLaunch: function(){
-  //   return new Promise(function(resolve, reject){
-  //     if (bsLocal) bsLocal.stop(resolve)
-  //     else resolve()
-  //   });
-  // }
+  // Code to stop browserstack local after end of test
+  afterLaunch: function(){
+    return new Promise(function(resolve, reject){
+      if (bsLocal) bsLocal.stop(resolve)
+      else resolve()
+    });
+  }
 }
 
 exports.config = {
   specs: [
-    (PROTRACTOR_SPECS && PROTRACTOR_SPECS) || './src/**/*.prod.e2e-spec.js'
+    PROTRACTOR_SPECS || './src/**/*.prod.e2e-spec.js'
   ],
   jasmineNodeOpts: {
     defaultTimeoutInterval: 1000 * 60 * 10
   },
   
   ...(
-    bsAccessKey && bsUsername
+    BROWSERSTACK_ACCESS_KEY && BROWSERSTACK_USERNAME
     ? bsConfig
     : localConfig
   ),
diff --git a/e2e/src/advanced/browsingForDatasets.prod.e2e-spec.js b/e2e/src/advanced/browsingForDatasets.prod.e2e-spec.js
index 97c8fd98255902cf3bb3ee7bacbe03c467747528..87099a58e463dedc82b7c57680badd71f30013c5 100644
--- a/e2e/src/advanced/browsingForDatasets.prod.e2e-spec.js
+++ b/e2e/src/advanced/browsingForDatasets.prod.e2e-spec.js
@@ -1,30 +1,86 @@
 const { AtlasPage } = require('../util')
 const { ARIA_LABELS } = require('../../../common/constants')
+const { retry } = require('../../../common/util')
 const { TOGGLE_EXPLORE_PANEL, MODALITY_FILTER, DOWNLOAD_PREVIEW, DOWNLOAD_PREVIEW_CSV } = ARIA_LABELS
 
+const atlasName = `Multilevel Human Atlas`
+
 const templates = [
   'MNI Colin 27',
-  'ICBM 2009c Nonlinear Asymmetric'
+  'ICBM 152 2009c Nonlinear Asymmetric'
 ]
 
-const areasShouldHaveRecptor = [
-  'Area 7A (SPL)',
-  'Area 3b (PostCG)',
-  'Area PFm (IPL)',
-  'Area PFop (IPL)',
-  'Area PF (IPL)',
-  'Area PGp (IPL)',
-  'Area PGa (IPL)',
-  'Area PFt (IPL)',
-  'Area PFcm (IPL)',
-  'Area hOc1 (V1, 17, CalcS)',
-  'Area 44 (IFG)',
-  'Area 45 (IFG)',
-  'Area 4p (PreCG)',
-  'Area TE 1.0 (HESCHL)',
-  'Area FG1 (FusG)',
-  'Area FG2 (FusG)'
-]
+const newShouldHaveReceptor = [
+  ["Area 4p (PreCG)", 1, 1, 1],
+  ["Area 3b (PostCG)", 1, 1, 1],
+  ["DG (Hippocampus)", 0, 0, 1],
+  ["Area FG2 (FusG)", 0, 1, 1],
+  ["Area hOc1 (V1, 17, CalcS)" ,1,  1, 1],
+  ["Area PFm (IPL)", 0, 1, 1],
+  ["Area 44 (IFG)", 0, 0, 1],
+  ["CA3 (Hippocampus)", 0, 0, 1],
+  ["CA2 (Hippocampus)", 0, 0, 1],
+  ["CA1 (Hippocampus)", 0, 0, 1],
+  ["Area PGp (IPL)", 0, 0, 1],
+  ["CA1 (Hippocampus)", 0, 0, 1],
+  ["Area 45 (IFG)", 1, 1, 1],
+  ["Area hOc3v (LingG)", 0, 0, 1],
+  ["Area hOc3d (Cuneus)", 0, 0, 1],
+  ["Area 7A (SPL)", 1, 1, 1],
+  ["Area 44 (IFG)", 1, 1, 1],
+  ["Area hOc2 (V2, 18)", 0, 0, 1],
+  ["Area PFop (IPL)", 0, 0, 1],
+  ["Area PF (IPL)", 0, 0, 1],
+  ["CA2 (Hippocampus)", 0, 0, 1],
+  ["Area PFt (IPL)", 0, 0, 1],
+  ["Area TE 2.1 (STG)", 0, 0, 1],
+  ["Area PFcm (IPL)", 0, 0, 1],
+  ["CA3 (Hippocampus)", 0, 0, 1],
+  ["DG (Hippocampus)", 0, 0, 1],
+  ["CA3 (Hippocampus)", 0, 0, 1],
+  ["CA2 (Hippocampus)", 0, 0, 1],
+  ["CA1 (Hippocampus)", 0, 0, 1],
+  ["CA3 (Hippocampus)", 0, 0, 1],
+  ["CA2 (Hippocampus)", 0, 0, 1],
+  ["CA1 (Hippocampus)", 0, 0, 1],
+  ["Area FG1 (FusG)", 0, 1, 1],
+  ["CA3 (Hippocampus)", 0, 0, 1],
+  ["Area TE 1.0 (HESCHL)", 0, 0, 1],
+  ["CA1 (Hippocampus)", 0, 0, 1],
+  ["Area hOc2 (V2, 18)", 0, 0, 1],
+  ["CA2 (Hippocampus)", 0, 0, 1],
+  ["CA3 (Hippocampus)", 0, 0, 1],
+  ["CA2 (Hippocampus)", 0, 0, 1],
+  ["CA1 (Hippocampus)", 0, 0, 1],
+  ["Area PGa (IPL)", 0, 0, 1],
+].filter(
+  ([ name ]) =>
+    /**
+     * somehow CA2 CA3 is a repeat of CA1 ???
+     */
+    name !== 'CA2 (Hippocampus)' && name !== 'CA3 (Hippocampus)'
+    /**
+     * not yet in dev branch
+     */
+    && name !== 'Area TE 2.1 (STG)'
+).map(
+  /**
+   * change remaining CA1 Hippocampus to searchable name
+   */
+  ([ name, ...rest ]) => name === 'CA1 (Hippocampus)'
+    ? [ 'CA (Hippocampus)', ...rest ]
+    : [ name, ...rest ]
+).reduce((acc, curr) => {
+  const [ name, pr, ar, fp ] = curr
+  const foundIdx = acc.findIndex(([ accName ]) => name === accName )
+  return foundIdx >= 0
+    ? acc.map((el, idx) => idx === foundIdx
+      ? [ name, el[1] + pr, el[2] + ar, el[3] + fp ]
+      : el)
+    : acc.concat([curr])
+  
+}, [])
+
 
 describe('> dataset browser', () => {
   let iavPage
@@ -37,27 +93,34 @@ describe('> dataset browser', () => {
     describe(`> in template: ${template}`, () => {
       beforeAll(async () => {
         await iavPage.goto()
-        await iavPage.selectTitleCard(template)
-        await iavPage.wait(500)
+        await iavPage.selectAtlasTemplateParcellation(atlasName, template)
+
+        // account for linear template translation backend
+        await iavPage.wait(5000)
         await iavPage.waitUntilAllChunksLoaded()
       })
 
       afterEach(async () => {
-        await iavPage.clearSearchRegionWithText()
-        await iavPage.clearAllSelectedRegions()
+        
       })
-      for (const area of areasShouldHaveRecptor) {
+      for (const [ area, ...rest ] of newShouldHaveReceptor) {
         it(`> receptor data ${area} should be able to be found`, async () => {
           await iavPage.searchRegionWithText(area)
           await iavPage.wait(2000)
           await iavPage.selectSearchRegionAutocompleteWithText()
-          await iavPage.dismissModal()
-          await iavPage.searchRegionWithText('')
-
+          await retry(async () => {
+            await iavPage.dismissModal()
+            await iavPage._setRegionalFeaturesExpanded(true)
+          }, {
+            timeout: 2000,
+            retries: 10
+          })
+          await iavPage.wait(2000)
+          await iavPage.waitUntilAllChunksLoaded()
           const datasets = await iavPage.getVisibleDatasets()
           const filteredDs = datasets.filter(ds => ds.toLowerCase().indexOf('receptor') >= 0)
           expect(filteredDs.length).toBeGreaterThan(0)
-          //TODO
+          
         })
       }
     })
@@ -69,147 +132,147 @@ const area = 'Area hOc1 (V1, 17, CalcS)'
 
 const receptorName = `Density measurements of different receptors for Area hOc1 (V1, 17, CalcS) [human, v1.0]`
 
-describe('> receptor dataset previews', () => {
-  let iavPage
-  beforeEach(async () => {
-    iavPage = new AtlasPage()
-    await iavPage.init()
-    await iavPage.goto()
-    await iavPage.selectTitleCard(template)
-    await iavPage.wait(500)
-    await iavPage.waitUntilAllChunksLoaded()
-
-    await iavPage.searchRegionWithText(area)
-    await iavPage.wait(2000)
-    await iavPage.selectSearchRegionAutocompleteWithText()
-    await iavPage.dismissModal()
-    await iavPage.searchRegionWithText('')
-
-    const datasets = await iavPage.getVisibleDatasets()
-    const receptorIndex = datasets.indexOf(receptorName)
-
-    await iavPage.clickNthDataset(receptorIndex)
-    await iavPage.wait(500)
-    await iavPage.click(`[aria-label="${ARIA_LABELS.SHOW_DATASET_PREVIEW}"]`)
-    await iavPage.waitFor(true, true)
-  })
-
-  describe('> can display graph', () => {
-
-    it('> can display radar graph', async () => {
-      const files = await iavPage.getBottomSheetList()
-      const fingerprintIndex = files.findIndex(file => /fingerprint/i.test(file))
-      await iavPage.clickNthItemFromBottomSheetList(fingerprintIndex)
-      await iavPage.waitFor(true, true)
-      const modalHasCanvas = await iavPage.modalHasChild('canvas')
-      expect(modalHasCanvas).toEqual(true)
-
-      await iavPage.wait(500)
-
-      const modalHasDownloadBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW}"]`)
-      const modalHasDownloadCSVBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW_CSV}"]`)
-
-      expect(modalHasDownloadBtn).toEqual(true)
-      expect(modalHasDownloadCSVBtn).toEqual(true)
-    })
-
-    it('> can display profile', async () => {
-
-      const files = await iavPage.getBottomSheetList()
-      const profileIndex = files.findIndex(file => /profile/i.test(file))
-      await iavPage.clickNthItemFromBottomSheetList(profileIndex)
-      await iavPage.waitFor(true, true)
-      const modalHasCanvas = await iavPage.modalHasChild('canvas')
-      expect(modalHasCanvas).toEqual(true)
-
-      await iavPage.wait(500)
-
-      const modalHasDownloadBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW}"]`)
-      const modalHasDownloadCSVBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW_CSV}"]`)
-
-      expect(modalHasDownloadBtn).toEqual(true)
-      expect(modalHasDownloadCSVBtn).toEqual(true)
-    })
-  })
-  it('> can display image', async () => {
-    const files = await iavPage.getBottomSheetList()
-    const imageIndex = files.findIndex(file => /image\//i.test(file))
-    await iavPage.clickNthItemFromBottomSheetList(imageIndex)
-    await iavPage.wait(500)
-    const modalHasImage = await iavPage.modalHasChild('div[data-img-src]')
-    expect(modalHasImage).toEqual(true)
-
-    await iavPage.wait(500)
-
-    const modalHasDownloadBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW}"]`)
-    const modalHasDownloadCSVBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW_CSV}"]`)
-
-    expect(modalHasDownloadBtn).toEqual(true)
-    expect(modalHasDownloadCSVBtn).toEqual(false)
-  })
-})
-
-describe('> modality picker', () => {
-  let iavPage
-  beforeAll(async () => {
-    iavPage = new AtlasPage()
-    await iavPage.init()
-    await iavPage.goto()
-  })
-  it('> sorted alphabetically', async () => {
-    await iavPage.selectTitleCard(templates[1])
-    await iavPage.wait(500)
-    await iavPage.waitUntilAllChunksLoaded()
-    await iavPage.click(`[aria-label="${TOGGLE_EXPLORE_PANEL}"]`)
-    await iavPage.wait(500)
-    await iavPage.clearAlerts()
-    await iavPage.click(`[aria-label="${MODALITY_FILTER}"]`)
-    await iavPage.wait(500)
-    const modalities = await iavPage.getModalities()
-    for (let i = 1; i < modalities.length; i ++) {
-      expect(
-        modalities[i].charCodeAt(0)
-      ).toBeGreaterThanOrEqual(
-        modalities[i - 1].charCodeAt(0)
-      )
-    }
-  })
-})
-
-
-describe('> pmap dataset preview', () => {
-  let iavPage
-
-  beforeAll(async () => {
-    // loads pmap and centers on hot spot
-    const url = `/?templateSelected=MNI+152+ICBM+2009c+Nonlinear+Asymmetric&parcellationSelected=JuBrain+Cytoarchitectonic+Atlas&cNavigation=0.0.0.-W000..2_ZG29.-ASCS.2-8jM2._aAY3..BSR0..dABI~.525x0~.7iMV..1EPC&niftiLayers=https%3A%2F%2Fneuroglancer.humanbrainproject.eu%2Fprecomputed%2FJuBrain%2F17%2Ficbm152casym%2Fpmaps%2FVisual_hOc1_l_N10_nlin2MNI152ASYM2009C_2.4_publicP_d3045ee3c0c4de9820eb1516d2cc72bb.nii.gz&previewingDatasetFiles=%5B%7B"datasetId"%3A"minds%2Fcore%2Fdataset%2Fv1.0.0%2F5c669b77-c981-424a-858d-fe9f527dbc07"%2C"filename"%3A"Area+hOc1+%28V1%2C+17%2C+CalcS%29+%5Bv2.4%2C+ICBM+2009c+Asymmetric%2C+left+hemisphere%5D"%7D%5D`
-    iavPage = new AtlasPage()
-    await iavPage.init()
-    await iavPage.goto(url)
-    await iavPage.waitUntilAllChunksLoaded()
-  })
-
-  it('> can display pmap', async () => {
-    const { red, green, blue } = await iavPage.getRgbAt({position: [200, 597]})
-    expect(red).toBeGreaterThan(green)
-    expect(red).toBeGreaterThan(blue)
-  })
-
-  it('> on update of layer control, pmap retains', async () => {
-    // by default, additional layer control is collapsed
-    await iavPage.toggleLayerControl()
-    await iavPage.wait(500)
-    await iavPage.toggleNthLayerControl(0)
-    await iavPage.wait(5500)
-
-    // interact with control
-    await iavPage.click(`[aria-label="Remove background"]`)
-    await iavPage.wait(500)
-
-    // color map should be unchanged
-    const { red, green, blue } = await iavPage.getRgbAt({position: [200, 597]})
-    expect(red).toBeGreaterThan(green)
-    expect(red).toBeGreaterThan(blue)
+// describe('> receptor dataset previews', () => {
+//   let iavPage
+//   beforeEach(async () => {
+//     iavPage = new AtlasPage()
+//     await iavPage.init()
+//     await iavPage.goto()
+//     await iavPage.selectTitleCard(template)
+//     await iavPage.wait(500)
+//     await iavPage.waitUntilAllChunksLoaded()
+
+//     await iavPage.searchRegionWithText(area)
+//     await iavPage.wait(2000)
+//     await iavPage.selectSearchRegionAutocompleteWithText()
+//     await iavPage.dismissModal()
+//     await iavPage.searchRegionWithText('')
+
+//     const datasets = await iavPage.getVisibleDatasets()
+//     const receptorIndex = datasets.indexOf(receptorName)
+
+//     await iavPage.clickNthDataset(receptorIndex)
+//     await iavPage.wait(500)
+//     await iavPage.click(`[aria-label="${ARIA_LABELS.SHOW_DATASET_PREVIEW}"]`)
+//     await iavPage.waitFor(true, true)
+//   })
+
+//   describe('> can display graph', () => {
+
+//     it('> can display radar graph', async () => {
+//       const files = await iavPage.getBottomSheetList()
+//       const fingerprintIndex = files.findIndex(file => /fingerprint/i.test(file))
+//       await iavPage.clickNthItemFromBottomSheetList(fingerprintIndex)
+//       await iavPage.waitFor(true, true)
+//       const modalHasCanvas = await iavPage.modalHasChild('canvas')
+//       expect(modalHasCanvas).toEqual(true)
+
+//       await iavPage.wait(500)
+
+//       const modalHasDownloadBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW}"]`)
+//       const modalHasDownloadCSVBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW_CSV}"]`)
+
+//       expect(modalHasDownloadBtn).toEqual(true)
+//       expect(modalHasDownloadCSVBtn).toEqual(true)
+//     })
+
+//     it('> can display profile', async () => {
+
+//       const files = await iavPage.getBottomSheetList()
+//       const profileIndex = files.findIndex(file => /profile/i.test(file))
+//       await iavPage.clickNthItemFromBottomSheetList(profileIndex)
+//       await iavPage.waitFor(true, true)
+//       const modalHasCanvas = await iavPage.modalHasChild('canvas')
+//       expect(modalHasCanvas).toEqual(true)
+
+//       await iavPage.wait(500)
+
+//       const modalHasDownloadBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW}"]`)
+//       const modalHasDownloadCSVBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW_CSV}"]`)
+
+//       expect(modalHasDownloadBtn).toEqual(true)
+//       expect(modalHasDownloadCSVBtn).toEqual(true)
+//     })
+//   })
+//   it('> can display image', async () => {
+//     const files = await iavPage.getBottomSheetList()
+//     const imageIndex = files.findIndex(file => /image\//i.test(file))
+//     await iavPage.clickNthItemFromBottomSheetList(imageIndex)
+//     await iavPage.wait(500)
+//     const modalHasImage = await iavPage.modalHasChild('div[data-img-src]')
+//     expect(modalHasImage).toEqual(true)
+
+//     await iavPage.wait(500)
+
+//     const modalHasDownloadBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW}"]`)
+//     const modalHasDownloadCSVBtn = await iavPage.modalHasChild(`[aria-label="${DOWNLOAD_PREVIEW_CSV}"]`)
+
+//     expect(modalHasDownloadBtn).toEqual(true)
+//     expect(modalHasDownloadCSVBtn).toEqual(false)
+//   })
+// })
+
+// describe('> modality picker', () => {
+//   let iavPage
+//   beforeAll(async () => {
+//     iavPage = new AtlasPage()
+//     await iavPage.init()
+//     await iavPage.goto()
+//   })
+//   it('> sorted alphabetically', async () => {
+//     await iavPage.selectTitleCard(templates[1])
+//     await iavPage.wait(500)
+//     await iavPage.waitUntilAllChunksLoaded()
+//     await iavPage.click(`[aria-label="${TOGGLE_EXPLORE_PANEL}"]`)
+//     await iavPage.wait(500)
+//     await iavPage.clearAlerts()
+//     await iavPage.click(`[aria-label="${MODALITY_FILTER}"]`)
+//     await iavPage.wait(500)
+//     const modalities = await iavPage.getModalities()
+//     for (let i = 1; i < modalities.length; i ++) {
+//       expect(
+//         modalities[i].charCodeAt(0)
+//       ).toBeGreaterThanOrEqual(
+//         modalities[i - 1].charCodeAt(0)
+//       )
+//     }
+//   })
+// })
+
+
+// describe('> pmap dataset preview', () => {
+//   let iavPage
+
+//   beforeAll(async () => {
+//     // loads pmap and centers on hot spot
+//     const url = `/?templateSelected=MNI+152+ICBM+2009c+Nonlinear+Asymmetric&parcellationSelected=JuBrain+Cytoarchitectonic+Atlas&cNavigation=0.0.0.-W000..2_ZG29.-ASCS.2-8jM2._aAY3..BSR0..dABI~.525x0~.7iMV..1EPC&niftiLayers=https%3A%2F%2Fneuroglancer.humanbrainproject.eu%2Fprecomputed%2FJuBrain%2F17%2Ficbm152casym%2Fpmaps%2FVisual_hOc1_l_N10_nlin2MNI152ASYM2009C_2.4_publicP_d3045ee3c0c4de9820eb1516d2cc72bb.nii.gz&previewingDatasetFiles=%5B%7B"datasetId"%3A"minds%2Fcore%2Fdataset%2Fv1.0.0%2F5c669b77-c981-424a-858d-fe9f527dbc07"%2C"filename"%3A"Area+hOc1+%28V1%2C+17%2C+CalcS%29+%5Bv2.4%2C+ICBM+2009c+Asymmetric%2C+left+hemisphere%5D"%7D%5D`
+//     iavPage = new AtlasPage()
+//     await iavPage.init()
+//     await iavPage.goto(url)
+//     await iavPage.waitUntilAllChunksLoaded()
+//   })
+
+//   it('> can display pmap', async () => {
+//     const { red, green, blue } = await iavPage.getRgbAt({position: [200, 597]})
+//     expect(red).toBeGreaterThan(green)
+//     expect(red).toBeGreaterThan(blue)
+//   })
+
+//   it('> on update of layer control, pmap retains', async () => {
+//     // by default, additional layer control is collapsed
+//     // await iavPage.toggleLayerControl() // deprecated
+//     await iavPage.wait(500)
+//     await iavPage.toggleNthLayerControl(0)
+//     await iavPage.wait(5500)
+
+//     // interact with control
+//     await iavPage.click(`[aria-label="Remove background"]`)
+//     await iavPage.wait(500)
+
+//     // color map should be unchanged
+//     const { red, green, blue } = await iavPage.getRgbAt({position: [200, 597]})
+//     expect(red).toBeGreaterThan(green)
+//     expect(red).toBeGreaterThan(blue)
     
-  })
-})
+//   })
+// })
diff --git a/e2e/src/advanced/nonAtlasImages.prod.e2e-spec.js b/e2e/src/advanced/nonAtlasImages.prod.e2e-spec.js
index 71fc460e0815675cad1393fffd808bcf82ea749b..d9e46c2364b528cbe9c5d44000861c63a766bab2 100644
--- a/e2e/src/advanced/nonAtlasImages.prod.e2e-spec.js
+++ b/e2e/src/advanced/nonAtlasImages.prod.e2e-spec.js
@@ -35,7 +35,7 @@ describe('> non-atlas images', () => {
       searchParam.set('standaloneVolumes', '["precomputed://https://object.cscs.ch/v1/AUTH_08c08f9f119744cbbf77e216988da3eb/imgsvc-46d9d64f-bdac-418e-a41b-b7f805068c64"]')
 
       await iavPage.goto(`/?${searchParam.toString()}`, { interceptHttp: true, doNotAutomate: true })
-      await iavPage.wait(10000)
+      await iavPage.wait(30000)
       const interceptedCalls = await iavPage.getInterceptedHttpCalls()
 
       expect(
@@ -78,31 +78,19 @@ describe('> non-atlas images', () => {
       searchParam.set('previewingDatasetFiles', JSON.stringify(previewingDatasetFiles))
       
       await iavPage.goto(`/?${searchParam.toString()}`, { interceptHttp: true, doNotAutomate: true })
-      await iavPage.wait(10000)
+      await iavPage.wait(30000)
       const interceptedCalls = await iavPage.getInterceptedHttpCalls()
 
       const array = [
-        'BI-FOM-HSV_R',
-        'BI-FOM-HSV_G',
-        'BI-FOM-HSV_B',
-        'BI',
-        'BI-TIM',
-        'BI-MRI',
-        'BI-MRS',
+        "PLI Fiber Orientation Red Channel",
+        "PLI Fiber Orientation Green Channel",
+        "PLI Fiber Orientation Blue Channel",
+        "Blockface Image",
+        "PLI Transmittance",
+        "T2w MRI",
+        "MRI Labels"
       ]
 
-      for (const item of array) {
-        expect(
-          interceptedCalls.find(({
-            method,
-            url
-          }) => {
-            const regex = new RegExp(item)
-            return method === 'GET' && regex.test(url)
-          })
-        ).toBeTruthy()
-      }
-
       expect(
         interceptedCalls
       ).toContain(
@@ -188,6 +176,7 @@ describe('> non-atlas images', () => {
         )
       )
     })
+  
   })
 
   describe('> controls for non atlas volumes', () => {
@@ -230,41 +219,11 @@ describe('> non-atlas images', () => {
       await iavPage.goto(`/?${searchParam.toString()}`, { forceTimeout: 20000 })
       await iavPage.wait(2000)
       
-      const additionalLayerCtrlIsExpanded2 = await iavPage.additionalLayerControlIsExpanded()
-      expect(additionalLayerCtrlIsExpanded2).toEqual(false)
-
-    })
-
-    it('if additional volumes are being shown, it can be toggled', async () => {
-
-      const searchParam = new URLSearchParams()
-      searchParam.set('templateSelected', 'Big Brain (Histology)')
-      searchParam.set('parcellationSelected', 'Grey/White matter')
-  
-      const previewingDatasetFiles = [
-        {
-          "datasetId":"minds/core/dataset/v1.0.0/b08a7dbc-7c75-4ce7-905b-690b2b1e8957",
-          "filename":"Overlay of data modalities"
-        }
-      ]
-      searchParam.set('previewingDatasetFiles', JSON.stringify(previewingDatasetFiles))
-      
-      await iavPage.goto(`/?${searchParam.toString()}`, { forceTimeout: 20000 })
-      await iavPage.wait(2000)
-      
-      const additionalLayerCtrlIsExpanded = await iavPage.additionalLayerControlIsExpanded()
-      expect(additionalLayerCtrlIsExpanded).toEqual(false)
-
-      await iavPage.toggleLayerControl()
-
       const additionalLayerCtrlIsExpanded2 = await iavPage.additionalLayerControlIsExpanded()
       expect(additionalLayerCtrlIsExpanded2).toEqual(true)
 
-      await iavPage.toggleLayerControl()
-
-      const additionalLayerCtrlIsExpanded3 = await iavPage.additionalLayerControlIsExpanded()
-      expect(additionalLayerCtrlIsExpanded3).toEqual(false)
-
     })
+
   })
+
 })
diff --git a/e2e/src/util.js b/e2e/src/util.js
index 7b67ea2b20255879ebc8696d85dcb1bbd5e453c3..26d9e739bcb6e256ee0b97b30e2d6dd6230fa349 100644
--- a/e2e/src/util.js
+++ b/e2e/src/util.js
@@ -8,7 +8,7 @@ const { By, Key, until } = require('selenium-webdriver')
 const CITRUS_LIGHT_URL = `https://unpkg.com/citruslight@0.1.0/citruslight.js`
 const { polyFillClick } = require('./material-util')
 
-const { ARIA_LABELS } = require('../../common/constants')
+const { ARIA_LABELS, CONST } = require('../../common/constants')
 const { retry } = require('../../common/util')
 
 function getActualUrl(url) {
@@ -26,8 +26,6 @@ async function _getIndexFromArrayOfWebElements(search, webElements) {
   return texts.findIndex(text => text.indexOf(search) >= 0)
 }
 
-const regionSearchAriaLabelText = 'Search for any region of interest in the atlas selected'
-
 const verifyPosition = position => {
 
   if (!position) throw new Error(`cursorGoto: position must be defined!`)
@@ -550,8 +548,8 @@ class WdLayoutPage extends WdBase{
 
   async _findTitleCard(title) {
     const titleCards = await this._browser
-      .findElement( By.tagName('ui-splashscreen') )
-      .findElements( By.tagName('mat-card') )
+      .findElement( By.css('ui-splashscreen') )
+      .findElements( By.css('mat-card') )
     const idx = await _getIndexFromArrayOfWebElements(title, titleCards)
     if (idx >= 0) return titleCards[idx]
     else throw new Error(`${title} does not fit any titleCards`)
@@ -563,17 +561,106 @@ class WdLayoutPage extends WdBase{
   }
 
   async selectTitleTemplateParcellation(templateName, parcellationName){
-    const titleCard = await this._findTitleCard(templateName)
-    const parcellations = await titleCard
-      .findElement( By.css('mat-card-content.available-parcellations-container') )
-      .findElements( By.tagName('button') )
-    const idx = await _getIndexFromArrayOfWebElements( parcellationName, parcellations )
-    if (idx >= 0) await parcellations[idx].click()
-    else throw new Error(`parcellationName ${parcellationName} does not exist`)
+    throw new Error(`selectTitleTemplateParcellation has been deprecated. use selectAtlasTemplateParcellation`)
+  }
+
+  /**
+   * _setAtlasSelectorExpanded
+   * toggle/set the open state of the atlas-layer-selector element
+   * If the only argument (flag) is not provided, it will toggle the atlas-layer-selector
+   * 
+   * Will throw if atlas-layer-selector is not in the DOM
+   * 
+   * @param {boolean} flag 
+   * 
+   */
+  async _setAtlasSelectorExpanded(flag) {
+    const atlasLayerSelectorEl = this._browser.findElement(
+      By.css('atlas-layer-selector')
+    )
+    const openedFlag = (await atlasLayerSelectorEl.getAttribute('data-opened')) === 'true'
+    if (typeof flag === 'undefined' || flag !== openedFlag) {
+      await atlasLayerSelectorEl.findElement(By.css(`button[aria-label="${ARIA_LABELS.TOGGLE_ATLAS_LAYER_SELECTOR}"]`)).click()
+    }
+  }
+
+  async changeTemplate(templateName){
+    if (!templateName) throw new Error(`templateName needs to be provided`)
+    await this._setAtlasSelectorExpanded(true)
+    await this.wait(1000)
+    const allTiles = await this._browser
+      .findElement( By.css('atlas-layer-selector') )
+      .findElements( By.css(`mat-grid-tile`) )
+
+    const idx = await _getIndexFromArrayOfWebElements(templateName, allTiles)
+    if (idx >= 0) await allTiles[idx].click()
+    else throw new Error(`#changeTemplate: templateName ${templateName} cannot be found.`)
   }
 
+  async changeParc(parcName) {
+    throw new Error(`changeParc NYI`)
+  }
+
+  async selectAtlasTemplateParcellation(atlasName, templateName, parcellationName, parcVersion) {
+    if (!atlasName) throw new Error(`atlasName needs to be provided`)
+    try {
+      /**
+       * if at title screen
+       */
+      await (await this._findTitleCard(atlasName)).click()
+    } catch (e) {
+      /**
+       * if not at title screen
+       * select from dropdown
+       */
+    }
+
+    if (templateName) {
+      await this.wait(1000)
+      await this.waitUntilAllChunksLoaded()
+      await this.changeTemplate(templateName)
+    }
+    
+    if (parcellationName) {
+      await this.wait(1000)
+      await this.waitUntilAllChunksLoaded()
+      await this.changeParc(parcellationName)
+    }
+
+    await this._setAtlasSelectorExpanded(false)
+  }
 
   // SideNav
+  _getSideNavPrimary(){
+    return this._browser.findElement(
+      By.css('mat-drawer[data-mat-drawer-primary-open]')
+    )
+  }
+
+  async _getSideNavPrimaryExpanded(){
+    return (await this._getSideNavPrimary()
+      .getAttribute('data-mat-drawer-primary-open')) === 'true'
+  }
+
+  _getSideNavSecondary(){
+    return this._browser.findElement(
+      By.css('mat-drawer[data-mat-drawer-secondary-open]')
+    )
+  }
+
+  async _getSideNavSecondaryExpanded(){
+    return (await this._getSideNavSecondary()
+      .getAttribute('data-mat-drawer-secondary-open')) === 'true'
+  }
+
+  async _setSideNavPrimaryExpanded(flag) {
+    const matDrawerPrimaryEl = this._getSideNavPrimary()
+    const openedFlag = await this._getSideNavPrimaryExpanded()
+    if (typeof flag === 'undefined' || flag !== openedFlag) {
+      await this._browser.findElement(By.css(`button[aria-label="${ARIA_LABELS.TOGGLE_SIDE_PANEL}"]`)).click()
+    }
+  }
+
   _getSideNav() {
     throw new Error(`side bar no longer exist`)
   }
@@ -645,7 +732,7 @@ class WdLayoutPage extends WdBase{
 
   _getAdditionalLayerControl(){
     return this._browser.findElement(
-      By.css('[aria-label="Additional volumes control"]')
+      By.css(`[aria-label="${ARIA_LABELS.ADDITIONAL_VOLUME_CONTROL}"]`)
     )
   }
 
@@ -661,20 +748,11 @@ class WdLayoutPage extends WdBase{
   additionalLayerControlIsExpanded() {
     return this._getAdditionalLayerControl()
       .findElement(
-        By.tagName('layer-browser')
+        By.css('layer-browser')
       )
       .isDisplayed()
   }
 
-  // will throw if additional layer control is not visible
-  async toggleLayerControl(){
-    return this._getAdditionalLayerControl()
-      .findElement(
-        By.css('[aria-label="Toggle expansion state of additional layer browser"]')
-      )
-      .click()
-  }
-
   async toggleNthLayerControl(idx) {
     const els = await this._getAdditionalLayerControl()
       .findElements( By.css(`[aria-label="${ARIA_LABELS.TOGGLE_SHOW_LAYER_CONTROL}"]`))
@@ -796,7 +874,7 @@ class WdIavPage extends WdLayoutPage{
 
   async clearAllSelectedRegions() {
     const clearAllRegionBtn = await this._browser.findElement(
-      By.css('[aria-label="Clear all regions"]')
+      By.css(`[aria-label="${ARIA_LABELS.CLEAR_SELECTED_REGION}"]`)
     )
     await clearAllRegionBtn.click()
     await this.wait(500)
@@ -807,7 +885,10 @@ class WdIavPage extends WdLayoutPage{
       const els = await this._browser.findElements(
         By.css('div.loadingIndicator')
       )
-      return els.length === 0
+      const els2 = await this._browser.findElements(
+        By.css('.spinnerAnimationCircle')
+      )
+      return [...els, ...els2].length === 0
     }, 1e3 * 60 * 10)
   }
 
@@ -843,9 +924,15 @@ class WdIavPage extends WdLayoutPage{
     else throw new Error(`${title} is not found as one of the dropdown templates`)
   }
 
-  _getSearchRegionInput(){
-    return this._getSideNav()
-      .findElement( By.css(`[aria-label="${regionSearchAriaLabelText}"]`) )
+  async _getSearchRegionInput(){
+    await this._setSideNavPrimaryExpanded(true)
+    await this.wait(500)
+    const secondaryOpen = await this._getSideNavSecondaryExpanded()
+    if (secondaryOpen) {
+      return this._getSideNavSecondary().findElement( By.css(`[aria-label="${ARIA_LABELS.TEXT_INPUT_SEARCH_REGION}"]`) )
+    } else {
+      return this._getSideNavPrimary().findElement( By.css(`[aria-label="${ARIA_LABELS.TEXT_INPUT_SEARCH_REGION}"]`) )
+    }
   }
 
   async searchRegionWithText(text=''){
@@ -897,8 +984,8 @@ class WdIavPage extends WdLayoutPage{
 
   _getModalityListView(){
     return this._browser
-      .findElement( By.tagName('modality-picker') )
-      .findElements( By.tagName('mat-checkbox') )
+      .findElement( By.css('modality-picker') )
+      .findElements( By.css('mat-checkbox') )
   }
 
   async getModalities(){
@@ -914,9 +1001,22 @@ class WdIavPage extends WdLayoutPage{
 
   _getSingleDatasetListView(){
     return this._browser
-      .findElement( By.tagName('data-browser') )
-      .findElement( By.css('div.cdk-virtual-scroll-content-wrapper') )
-      .findElements( By.tagName('single-dataset-list-view') )
+      .findElement( By.css('data-browser') )
+      .findElements( By.css('single-dataset-list-view') )
+  }
+
+  _getRegionalFeatureEl(){
+    return this._getSideNavSecondary().findElement(
+      By.css(`mat-expansion-panel[data-mat-expansion-title="${CONST.REGIONAL_FEATURES}"]`)
+    )
+  }
+
+  async _setRegionalFeaturesExpanded(flag){
+    const regionFeatureExpEl = this._getRegionalFeatureEl()
+    const openedFlag = (await regionFeatureExpEl.getAttribute('data-opened')) === 'true'
+    if (typeof flag === 'undefined' || flag !== openedFlag) {
+      await regionFeatureExpEl.findElement(By.css(`mat-expansion-panel-header`)).click()
+    }
   }
 
   async getVisibleDatasets() {
diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index deff73cac89cb51f169c118d55326a0a26030c18..1f656a997099789e1bc3c06e1ea8189e4741881a 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -41,7 +41,7 @@ import { MIN_REQ_EXPLAINER } from 'src/util/constants'
 import { SlServiceService } from "src/spotlight/sl-service.service";
 import { PureContantService } from "src/util";
 import { viewerStateSetSelectedRegions, viewerStateRemoveAdditionalLayer, viewerStateHelperSelectParcellationWithId } from "src/services/state/viewerState.store.helper";
-import { viewerStateGetOverlayingAdditionalParcellations, viewerStateParcVersionSelector } from "src/services/state/viewerState/selectors";
+import { viewerStateGetOverlayingAdditionalParcellations, viewerStateParcVersionSelector, viewerStateStandAloneVolumes } from "src/services/state/viewerState/selectors";
 import { ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState/selectors";
 import { ngViewerActionClearView } from "src/services/state/ngViewerState/actions";
 import { uiStateMouseOverSegmentsSelector } from "src/services/state/uiState/selectors";
@@ -108,6 +108,10 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
 
   public MIN_REQ_EXPLAINER = MIN_REQ_EXPLAINER
 
+  public isStandaloneVolumes$ = this.store.pipe(
+    select(viewerStateStandAloneVolumes),
+    map(v => v.length > 0)
+  )
 
   public selectedAdditionalLayers$ = this.store.pipe(
     select(viewerStateGetOverlayingAdditionalParcellations),
diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html
index 737414db6911778f0b7f7a399c5b24ce0e11e456..d09b5dfa6b0a0097677655890d531a69eed68aab 100644
--- a/src/atlasViewer/atlasViewer.template.html
+++ b/src/atlasViewer/atlasViewer.template.html
@@ -78,7 +78,7 @@
       <div ui-nehuba-container-overlay-bottom-left class="d-inline-flex pe-none w-100 align-items-end m-2 mb-4">
 
         <!-- only load atlas layer selector and chips if viewer is loaded -->
-        <ng-template [ngIf]="uiNehubaContainer.viewerLoaded">
+        <ng-template [ngIf]="uiNehubaContainer.viewerLoaded  && !(isStandaloneVolumes$ | async)">
 
           <!-- Viewer Selector Container-->
           <atlas-layer-selector
diff --git a/src/atlasViewer/atlasViewer.urlUtil.spec.ts b/src/atlasViewer/atlasViewer.urlUtil.spec.ts
index 2aff96c2df6af1d1a02b27b2f12d3710399a78d0..01787b3b1631a2d108b09f8d3e633bda635df160 100644
--- a/src/atlasViewer/atlasViewer.urlUtil.spec.ts
+++ b/src/atlasViewer/atlasViewer.urlUtil.spec.ts
@@ -2,7 +2,7 @@
 
 import {} from 'jasmine'
 import { defaultRootState } from 'src/services/stateStore.service'
-import { cvtSearchParamToState, PARSING_SEARCHPARAM_ERROR, cvtStateToSearchParam } from './atlasViewer.urlUtil'
+import { cvtSearchParamToState, cvtStateToSearchParam } from './atlasViewer.urlUtil'
 
 const bigbrainJson = require('!json-loader!src/res/ext/bigbrain.json')
 const colin = require('!json-loader!src/res/ext/colin.json')
diff --git a/src/glue.spec.ts b/src/glue.spec.ts
index 60fc226caabed63a8d90fdf7202cc7866ac8036a..7f0e62218fa393fbf97bdefa7f19bd2d53e9caca 100644
--- a/src/glue.spec.ts
+++ b/src/glue.spec.ts
@@ -1,9 +1,9 @@
-import { TestBed, tick, fakeAsync, discardPeriodicTasks, flush } from "@angular/core/testing"
+import { TestBed, tick, fakeAsync, discardPeriodicTasks } from "@angular/core/testing"
 import { DatasetPreviewGlue, glueSelectorGetUiStatePreviewingFiles, glueActionRemoveDatasetPreview, datasetPreviewMetaReducer, glueActionAddDatasetPreview, GlueEffects } from "./glue"
 import { ACTION_TO_WIDGET_TOKEN, EnumActionToWidget } from "./widget"
 import { provideMockStore, MockStore } from "@ngrx/store/testing"
 import { getRandomHex } from 'common/util'
-import { EnumWidgetTypes, TypeOpenedWidget, uiActionSetPreviewingDatasetFiles } from "./services/state/uiState.store.helper"
+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'
@@ -14,6 +14,9 @@ import { EnumColorMapName } from "./util/colorMaps"
 import { ngViewerSelectorClearView } from "./services/state/ngViewerState/selectors"
 import { tap, ignoreElements } from "rxjs/operators"
 import { merge, of } from "rxjs"
+import { GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME } from "./ui/databrowserModule/pure"
+import { viewerStateSelectedTemplateSelector } from "./services/state/viewerState/selectors"
+import { generalActionError } from "./services/stateStore.helper"
 
 const mockActionOnSpyReturnVal0 = { 
   id: getRandomHex(),
@@ -909,6 +912,50 @@ describe('> glue.ts', () => {
 
   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,
@@ -919,16 +966,46 @@ describe('> glue.ts', () => {
         previewingDatasetFiles: []
       }
     }
-    beforeEach(() => {
 
+    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$', () => {
@@ -986,5 +1063,146 @@ describe('> glue.ts', () => {
         )
       })
     })
+    
+  
+    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 ]
+            })
+          })
+        )
+
+      })
+      
+    })
+
   })
 })
diff --git a/src/glue.ts b/src/glue.ts
index 4cac5d819d134b19a9fcf0a74bcb22983772a8ca..e5eedb9ff59eb2e55e21f4ea0259c96f655ab646 100644
--- a/src/glue.ts
+++ b/src/glue.ts
@@ -1,7 +1,7 @@
 import { uiActionSetPreviewingDatasetFiles, IDatasetPreviewData, uiStateShowBottomSheet, uiStatePreviewingDatasetFilesSelector } from "./services/state/uiState.store.helper"
 import { OnDestroy, Injectable, Optional, Inject, InjectionToken } from "@angular/core"
-import { PreviewComponentWrapper, DatasetPreview, determinePreviewFileType, EnumPreviewFileTypes, IKgDataEntry, getKgSchemaIdFromFullId } from "./ui/databrowserModule/pure"
-import { Subscription, Observable, forkJoin, of, merge } from "rxjs"
+import { PreviewComponentWrapper, DatasetPreview, determinePreviewFileType, EnumPreviewFileTypes, IKgDataEntry, getKgSchemaIdFromFullId, GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME } from "./ui/databrowserModule/pure"
+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, bufferTime } from "rxjs/operators"
 import { TypeActionToWidget, EnumActionToWidget, ACTION_TO_WIDGET_TOKEN } from "./widget"
@@ -17,6 +17,7 @@ import { Effect } from "@ngrx/effects"
 import { viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector, viewerStateSelectedParcellationSelector } from "./services/state/viewerState/selectors"
 import { ngViewerSelectorClearView } from "./services/state/ngViewerState/selectors"
 import { ngViewerActionClearView } from './services/state/ngViewerState/actions'
+import { generalActionError } from "./services/stateStore.helper"
 
 const PREVIEW_FILE_TYPES_NO_UI = [
   EnumPreviewFileTypes.NIFTI,
@@ -100,6 +101,83 @@ export class GlueEffects {
     }))
   )
 
+  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),
@@ -115,9 +193,9 @@ export class GlueEffects {
   )
 
   constructor(
-    private store$: Store<any>
+    private store$: Store<any>,
+    @Inject(GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME) private getDatasetPreviewFromId: (arg) => Observable<any|null>
   ){
-
   }
 }
 
@@ -195,10 +273,10 @@ export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{
     switchMap(({ prvToShow, prvToDismiss }) => {
       return forkJoin({
         prvToShow: prvToShow.length > 0 
-          ? forkJoin(...prvToShow.map(val => this.getDatasetPreviewFromId(val)))
+          ? forkJoin(prvToShow.map(val => this.getDatasetPreviewFromId(val)))
           : of([]),
         prvToDismiss: prvToDismiss.length > 0 
-          ? forkJoin(...prvToDismiss.map(val => this.getDatasetPreviewFromId(val)))
+          ? forkJoin(prvToDismiss.map(val => this.getDatasetPreviewFromId(val)))
           : of([])
       })
     }),
@@ -229,7 +307,7 @@ export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{
 
   public onRegionSelectChangeShowPreview$ = this.selectedRegionPreview$.pipe(
     switchMap(arr => arr.length > 0
-      ? forkJoin(...arr.map(({ kgId, kgSchema, filename }) => this.getDatasetPreviewFromId({ datasetId: kgId, datasetSchema: kgSchema, filename })))
+      ? forkJoin(arr.map(({ kgId, kgSchema, filename }) => this.getDatasetPreviewFromId({ datasetId: kgId, datasetSchema: kgSchema, filename })))
       : of([])
     ),
     map(arr => arr.filter(item => !!item)),
@@ -238,7 +316,7 @@ export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{
 
   public onRegionDeselectRemovePreview$ = this.onRegionSelectChangeShowPreview$.pipe(
     pairwise(),
-    map(([oArr, nArr]) => oArr.filter(item => {
+    map(([oArr, nArr]) => oArr.filter((item: any) => {
       return !nArr
         .map(DatasetPreviewGlue.GetDatasetPreviewId)
         .includes(
diff --git a/src/main.module.ts b/src/main.module.ts
index 0db27419f6de9bac7eb7b000e3506a1d12139f79..c55025199c41b7e7c32a17da846975f26f86fd96 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -57,6 +57,7 @@ import { DatasetPreviewGlue, datasetPreviewMetaReducer, IDatasetPreviewGlue, Glu
 import { viewerStateHelperReducer, viewerStateFleshOutDetail, viewerStateMetaReducers, ViewerStateHelperEffect } from './services/state/viewerState.store.helper';
 import { take } from 'rxjs/operators';
 import { TOS_OBS_INJECTION_TOKEN } from './ui/kgtos/kgtos.component';
+import { UiEffects } from './services/state/uiState/ui.effects';
 
 export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
   return function(state, action) {
@@ -99,7 +100,8 @@ export const GET_STATE_SNAPSHOT_TOKEN = new InjectionToken('GET_STATE_SNAPSHOT_T
       UiStateUseEffect,
       NewTemplateUseEffect,
       ViewerStateHelperEffect,
-      GlueEffects
+      GlueEffects,
+      UiEffects,
     ]),
     StoreModule.forRoot({
       pluginState,
diff --git a/src/services/state/uiState.store.ts b/src/services/state/uiState.store.ts
index d050b1a52450afe26a31eee9e0a2f5e4ad05b5e2..94d4d765e88e835e974fb08a45410bf466b588a3 100644
--- a/src/services/state/uiState.store.ts
+++ b/src/services/state/uiState.store.ts
@@ -9,8 +9,8 @@ import { IavRootStoreInterface, GENERAL_ACTION_TYPES } from '../stateStore.servi
 import { MatBottomSheetRef, MatBottomSheet } from '@angular/material/bottom-sheet';
 import { uiStateCloseSidePanel, uiStateOpenSidePanel, uiStateCollapseSidePanel, uiStateExpandSidePanel, uiActionSetPreviewingDatasetFiles, uiStateShowBottomSheet, uiActionShowSidePanelConnectivity } from './uiState.store.helper';
 import { viewerStateMouseOverCustomLandmark } from './viewerState/actions';
-
-export const defaultState: StateInterface = {
+import { IUiState } from './uiState/common'
+export const defaultState: IUiState = {
   previewingDatasetFiles: [],
 
   mouseOverSegments: [],
@@ -32,7 +32,9 @@ export const defaultState: StateInterface = {
   agreedKgTos: localStorage.getItem(LOCAL_STORAGE_CONST.AGREE_KG_TOS) === KG_TOS_VERSION,
 }
 
-export const getStateStore = ({ state = defaultState } = {}) => (prevState: StateInterface = state, action: ActionInterface) => {
+export { IUiState }
+
+export const getStateStore = ({ state = defaultState } = {}) => (prevState: IUiState = state, action: ActionInterface) => {
   switch (action.type) {
   
   case uiActionSetPreviewingDatasetFiles.type: {
@@ -144,30 +146,6 @@ export function stateStore(state, action) {
   return defaultStateStore(state, action)
 }
 
-export interface StateInterface {
-  previewingDatasetFiles: {datasetId: string, filename: string}[]
-
-  mouseOverSegments: Array<{
-    layer: {
-      name: string
-    }
-    segment: any | null
-  }>
-  sidePanelIsOpen: boolean
-  sidePanelExploreCurrentViewIsOpen: boolean
-  mouseOverSegment: any | number
-
-  mouseOverLandmark: any
-  mouseOverUserLandmark: any
-
-  focusedSidePanel: string | null
-
-  snackbarMessage: string
-
-  agreedCookies: boolean
-  agreedKgTos: boolean
-}
-
 export interface ActionInterface extends Action {
   segment: any | number
   landmark: any
diff --git a/src/services/state/uiState/common.ts b/src/services/state/uiState/common.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5416ff23e75ef56a934aeb514865596b121fbe8f
--- /dev/null
+++ b/src/services/state/uiState/common.ts
@@ -0,0 +1,23 @@
+export interface IUiState{
+  previewingDatasetFiles: {datasetId: string, filename: string}[]
+
+  mouseOverSegments: Array<{
+    layer: {
+      name: string
+    }
+    segment: any | null
+  }>
+  sidePanelIsOpen: boolean
+  sidePanelExploreCurrentViewIsOpen: boolean
+  mouseOverSegment: any | number
+
+  mouseOverLandmark: any
+  mouseOverUserLandmark: any
+
+  focusedSidePanel: string | null
+
+  snackbarMessage: string
+
+  agreedCookies: boolean
+  agreedKgTos: boolean
+}
diff --git a/src/services/state/uiState/selectors.ts b/src/services/state/uiState/selectors.ts
index a004f0598d0e2cfc538c952f275855134bd26264..3a8e3f913b509c03cf4f0bd8e767b9bd3c098ad3 100644
--- a/src/services/state/uiState/selectors.ts
+++ b/src/services/state/uiState/selectors.ts
@@ -1,8 +1,9 @@
 import { createSelector } from "@ngrx/store";
+import { IUiState } from './common'
 
 export const uiStatePreviewingDatasetFilesSelector = createSelector(
   state => state['uiState'],
-  uiState => uiState['previewingDatasetFiles']
+  (uiState: IUiState) => uiState['previewingDatasetFiles']
 )
 
 export const uiStateMouseOverSegmentsSelector = createSelector(
diff --git a/src/services/state/uiState/ui.effects.ts b/src/services/state/uiState/ui.effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2f9287652937e0d517e59c1ebfc939f61b56e211
--- /dev/null
+++ b/src/services/state/uiState/ui.effects.ts
@@ -0,0 +1,25 @@
+import { Injectable, OnDestroy } from "@angular/core";
+import { Actions, ofType } from "@ngrx/effects";
+import { Subscription } from "rxjs";
+import { generalActionError } from "src/services/stateStore.helper";
+
+@Injectable({
+  providedIn: 'root'
+})
+
+export class UiEffects implements OnDestroy{
+
+  private subscriptions: Subscription[] = []
+
+  constructor(private actions$: Actions){
+    this.subscriptions.push(
+      this.actions$.pipe(
+        ofType(generalActionError.type)
+      ).subscribe(console.log)
+    )
+  }
+
+  ngOnDestroy(){
+    while (this.subscriptions.length > 0) this.subscriptions.pop().unsubscribe()
+  }
+}
diff --git a/src/services/state/viewerState/selectors.ts b/src/services/state/viewerState/selectors.ts
index 6a2a7e912f6641b28454676e374014cc50709a9b..b7a091bdcb30bd333cca026e685b46516cbbd71c 100644
--- a/src/services/state/viewerState/selectors.ts
+++ b/src/services/state/viewerState/selectors.ts
@@ -48,6 +48,11 @@ export const viewerStateAllRegionsFlattenedRegionSelector = createSelector(
   }
 )
 
+export const viewerStateStandAloneVolumes = createSelector(
+  state => state['viewerState'],
+  viewerState => viewerState['standaloneVolumes']
+)
+
 export const viewerStateGetOverlayingAdditionalParcellations = createSelector(
   state => state[viewerStateHelperStoreName],
   state => state['viewerState'],
diff --git a/src/services/stateStore.helper.ts b/src/services/stateStore.helper.ts
index 34393f8cc8ead35f081435bd3721565f1a2ab588..172c58258dec163d118529afe22aeb3ef4af1ce4 100644
--- a/src/services/stateStore.helper.ts
+++ b/src/services/stateStore.helper.ts
@@ -1,7 +1,6 @@
 import { createAction, props } from "@ngrx/store";
 
 export const GENERAL_ACTION_TYPES = {
-  ERROR: 'ERROR',
   APPLY_STATE: 'APPLY_STATE',
 }
 
@@ -9,3 +8,8 @@ export const generalApplyState = createAction(
   GENERAL_ACTION_TYPES.APPLY_STATE,
   props<{ state: any }>()
 )
+
+export const generalActionError = createAction(
+  `[generalActionError]`,
+  props<{ message: string }>()
+)
diff --git a/src/services/stateStore.service.ts b/src/services/stateStore.service.ts
index 32d4f68bca8b24d53bed3ed9d7e23c155866fa65..1dcde5194a5a12f343646f0f056b4574265bcf60 100644
--- a/src/services/stateStore.service.ts
+++ b/src/services/stateStore.service.ts
@@ -16,7 +16,7 @@ import {
 import {
   ActionInterface as UIActionInterface,
   defaultState as uiDefaultState,
-  StateInterface as UIStateInterface,
+  IUiState,
   stateStore as uiState,
 } from './state/uiState.store'
 import {
@@ -46,7 +46,7 @@ export { pluginState }
 export { viewerConfigState }
 export { NgViewerStateInterface, NgViewerActionInterface, ngViewerState }
 export { ViewerStateInterface, ViewerActionInterface, viewerState }
-export { UIStateInterface, UIActionInterface, uiState }
+export { IUiState, UIActionInterface, uiState }
 export { userConfigState,  USER_CONFIG_ACTION_TYPES}
 
 export { CHANGE_NAVIGATION, DESELECT_LANDMARKS, FETCHED_TEMPLATE, NEWVIEWER, SELECT_LANDMARKS, SELECT_PARCELLATION, SELECT_REGIONS, USER_LANDMARKS } from './state/viewerState.store'
@@ -54,7 +54,7 @@ export { IDataEntry, IParcellationRegion, FETCHED_DATAENTRIES, FETCHED_SPATIAL_D
 export { CLOSE_SIDE_PANEL, MOUSE_OVER_LANDMARK, 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 } from './stateStore.helper'
+export { GENERAL_ACTION_TYPES, generalActionError } from './stateStore.helper'
 
 // TODO deprecate
 export function safeFilter(key: string) {
@@ -190,7 +190,7 @@ export interface IavRootStoreInterface {
   ngViewerState: NgViewerStateInterface
   viewerState: ViewerStateInterface
   dataStore: any
-  uiState: UIStateInterface
+  uiState: IUiState
   userConfigState: UserConfigStateInterface
 }
 
diff --git a/src/ui/atlasLayerSelector/atlasLayerSelector.component.ts b/src/ui/atlasLayerSelector/atlasLayerSelector.component.ts
index af2558291cf788adc461fee55246ee886dcb36a0..fe54b4608c26d5acb2d88274c9625bd46721d802 100644
--- a/src/ui/atlasLayerSelector/atlasLayerSelector.component.ts
+++ b/src/ui/atlasLayerSelector/atlasLayerSelector.component.ts
@@ -1,12 +1,12 @@
-import {Component, OnInit, ViewChildren, QueryList, Output, EventEmitter} from "@angular/core";
+import { Component, OnInit, ViewChildren, QueryList, HostBinding } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { safeFilter } from "src/services/stateStore.service";
-import { distinctUntilChanged, map, withLatestFrom, shareReplay, groupBy, mergeMap, toArray, switchMap, scan, tap, filter } from "rxjs/operators";
+import { distinctUntilChanged, map, withLatestFrom, shareReplay, groupBy, mergeMap, toArray, switchMap, scan, filter } from "rxjs/operators";
 import { Observable, Subscription, from, zip, of, combineLatest } from "rxjs";
 import { viewerStateSelectTemplateWithId, viewerStateToggleLayer } from "src/services/state/viewerState.store.helper";
 import { MatMenuTrigger } from "@angular/material/menu";
 import { viewerStateGetSelectedAtlas, viewerStateAtlasLatestParcellationSelector } from "src/services/state/viewerState/selectors";
-import {CLEAR_CONNECTIVITY_REGION, SET_CONNECTIVITY_VISIBLE} from "src/services/state/viewerState.store";
+import { ARIA_LABELS } from 'common/constants'
 
 @Component({
   selector: 'atlas-layer-selector',
@@ -16,6 +16,8 @@ import {CLEAR_CONNECTIVITY_REGION, SET_CONNECTIVITY_VISIBLE} from "src/services/
 })
 export class AtlasLayerSelector implements OnInit {
 
+    public TOGGLE_ATLAS_LAYER_SELECTOR = ARIA_LABELS.TOGGLE_ATLAS_LAYER_SELECTOR
+
     @ViewChildren(MatMenuTrigger) matMenuTriggers: QueryList<MatMenuTrigger>
     public atlas: any
 
@@ -30,6 +32,7 @@ export class AtlasLayerSelector implements OnInit {
     public selectedAtlas$: Observable<any>
     private subscriptions: Subscription[] = []
 
+    @HostBinding('attr.data-opened')
     public selectorExpanded: boolean = false
     public selectedTemplatePreviewUrl: string = ''
 
diff --git a/src/ui/atlasLayerSelector/atlasLayerSelector.template.html b/src/ui/atlasLayerSelector/atlasLayerSelector.template.html
index fa3219cf970e7a16d54954de32ba2b8aeac3c5db..2398853b09ed27ada1222680313ea93dc03a97ef 100644
--- a/src/ui/atlasLayerSelector/atlasLayerSelector.template.html
+++ b/src/ui/atlasLayerSelector/atlasLayerSelector.template.html
@@ -65,7 +65,7 @@
                 matTooltip="Select layer"
                 mat-mini-fab
                 *ngIf="((availableTemplates$ | async).length > 1) || ((groupedLayers$ | async).length + (nonGroupedLayers$ | async).length > 1)"
-                aria-label="Layer selector expand button"
+                [attr.aria-label]="TOGGLE_ATLAS_LAYER_SELECTOR"
                 (click)="selectorExpanded = !selectorExpanded">
             <i class="fas fa-layer-group"></i>
         </button>
diff --git a/src/ui/databrowserModule/constants.ts b/src/ui/databrowserModule/constants.ts
index 58ec6aa0808c2f532bdc1e218d295c9aa0c1887c..aaed7658f9b1a6bd79d2f56b0932c7319abafe79 100644
--- a/src/ui/databrowserModule/constants.ts
+++ b/src/ui/databrowserModule/constants.ts
@@ -95,4 +95,4 @@ export interface DatasetPreview {
   filename: string
 }
 
-export const GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME: InjectionToken<({ datasetSchema, datasetId, filename }) => Observable<any>> = new InjectionToken('GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME')
+export const GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME = new InjectionToken<({ datasetSchema, datasetId, filename }) => Observable<any|null>>('GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME')
diff --git a/src/ui/databrowserModule/databrowser.service.ts b/src/ui/databrowserModule/databrowser.service.ts
index 3f9c3245c99328afaca798d939e68c67e2850265..8d3828f0b5cf21b0c9105aeacddc0b1fd62667d9 100644
--- a/src/ui/databrowserModule/databrowser.service.ts
+++ b/src/ui/databrowserModule/databrowser.service.ts
@@ -1,7 +1,7 @@
 import { HttpClient } from "@angular/common/http";
 import {ComponentRef, Injectable, OnDestroy} from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { BehaviorSubject, combineLatest, from, fromEvent, Observable, of, Subscription } from "rxjs";
+import { BehaviorSubject, combineLatest, forkJoin, from, fromEvent, Observable, of, Subscription } from "rxjs";
 import { catchError, debounceTime, distinctUntilChanged, filter, map, shareReplay, switchMap, tap, withLatestFrom } from "rxjs/operators";
 import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service";
 import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
@@ -12,12 +12,13 @@ import { WidgetUnit } from "src/widget";
 import { LoggingService } from "src/logging";
 import { SHOW_KG_TOS } from "src/services/state/uiState.store";
 import { FETCHED_DATAENTRIES, FETCHED_SPATIAL_DATA, IavRootStoreInterface, IDataEntry, safeFilter } from "src/services/stateStore.service";
-import { regionFlattener } from "src/util/regionFlattener";
 import { DataBrowser } from "./databrowser/databrowser.component";
 import { NO_METHODS } from "./util/filterDataEntriesByMethods.pipe";
 import { FilterDataEntriesByRegion } from "./util/filterDataEntriesByRegion.pipe";
 import { datastateActionToggleFav, datastateActionUnfavDataset, datastateActionFavDataset } from "src/services/state/dataState/actions";
 
+import { getIdFromFullId } from 'common/util'
+
 const noMethodDisplayName = 'No methods described'
 
 /**
@@ -62,12 +63,10 @@ export class DatabrowserService implements OnDestroy {
     })
   }
   public createDatabrowser: (arg: {regions: any[], template: any, parcellation: any}) => {dataBrowser: ComponentRef<DataBrowser>, widgetUnit: ComponentRef<WidgetUnit>}
-  public getDataByRegion: ({regions, parcellation, template}: {regions: any[], parcellation: any, template: any}) => Promise<IDataEntry[]> = ({regions, parcellation, template}) => new Promise((resolve, reject) => {
-    this.lowLevelQuery(template.name, parcellation.name)
-      .then(de => this.filterDEByRegion.transform(de, regions, parcellation.regions.map(regionFlattener).reduce((acc, item) => acc.concat(item), [])))
-      .then(resolve)
-      .catch(reject)
-  })
+  public getDataByRegion: ({ regions, parcellation, template }: {regions: any[], parcellation: any, template: any}) => Promise<IDataEntry[]> = ({regions, parcellation, template}) => 
+    forkJoin(regions.map(this.getDatasetsByRegion.bind(this))).pipe(
+      map((arrOfArr: IDataEntry[][]) => arrOfArr.reduce((acc, curr) => acc.concat(curr), []))
+    ).toPromise()
 
   private filterDEByRegion: FilterDataEntriesByRegion = new FilterDataEntriesByRegion()
   private dataentries: IDataEntry[] = []
@@ -258,6 +257,16 @@ export class DatabrowserService implements OnDestroy {
   public fetchingFlag: boolean = false
   private mostRecentFetchToken: any
 
+  private getDatasetsByRegion(region: { fullId: string }){
+    return this.http.get<IDataEntry>(
+      `${this.constantService.backendUrl}datasets/byRegion/${encodeURIComponent(getIdFromFullId(region.fullId))}`,
+      {
+        headers: this.constantService.getHttpHeader(),
+        responseType: 'json'
+      }
+    )
+  }
+
   private lowLevelQuery(templateName: string, parcellationName: string): Promise<IDataEntry[]> {
     const encodedTemplateName = encodeURIComponent(templateName)
     const encodedParcellationName = encodeURIComponent(parcellationName)
diff --git a/src/ui/databrowserModule/databrowser/databrowser.base.ts b/src/ui/databrowserModule/databrowser/databrowser.base.ts
index ce800d094acbb676deaddd5f55fa2eda71f36366..04b10b309035401615f612bb784f06c70aa979bb 100644
--- a/src/ui/databrowserModule/databrowser/databrowser.base.ts
+++ b/src/ui/databrowserModule/databrowser/databrowser.base.ts
@@ -3,6 +3,7 @@ import { LoggingService } from "src/logging"
 import { DatabrowserService } from "../singleDataset/singleDataset.base"
 import { Observable } from "rxjs"
 import { IDataEntry } from "src/services/stateStore.service"
+import { getUniqueRegionId } from 'common/util'
 
 export class DatabrowserBase{
 
@@ -35,17 +36,18 @@ export class DatabrowserBase{
 
   ngOnChanges(){
 
-
+    const { regions, parcellation, template } = this
     this.regions = this.regions.map(r => {
       /**
        * TODO to be replaced with properly region UUIDs from KG
        */
+      const uniqueRegionId = getUniqueRegionId(template, parcellation, r)
       return {
-        id: `${this.parcellation?.name || 'untitled_parcellation'}/${r.name}`,
+        fullId: uniqueRegionId,
+        id: uniqueRegionId,
         ...r,
       }
     })
-    const { regions, parcellation, template } = this
     this.fetchingFlag = true
 
     // input may be undefined/null
diff --git a/src/ui/databrowserModule/databrowser/databrowser.template.html b/src/ui/databrowserModule/databrowser/databrowser.template.html
index 27e4efbc014223045688118abe5981214a85cae8..0621b5e538c5e4b3f8afb84083b15331a9b2c991 100644
--- a/src/ui/databrowserModule/databrowser/databrowser.template.html
+++ b/src/ui/databrowserModule/databrowser/databrowser.template.html
@@ -72,7 +72,8 @@
         minBufferPx="200"
         maxBufferPx="400"
         itemSize="50">
-        <div class="virtual-scroll-element overflow-hidden" *cdkVirtualFor="let dataset of filteredDataEntry; trackBy: trackByFn; templateCacheSize: 20; let index = index">
+        <div *cdkVirtualFor="let dataset of filteredDataEntry; trackBy: trackByFn; templateCacheSize: 20; let index = index"
+          class="virtual-scroll-element overflow-hidden">
 
           <!-- divider, show if not first -->
           <mat-divider *ngIf="index !== 0"></mat-divider>
diff --git a/src/ui/databrowserModule/preview/shownPreviews.directive.ts b/src/ui/databrowserModule/preview/shownPreviews.directive.ts
index bdebaf94796d878e4cfa2974b7b2820f3613a7f9..c90350c64a1a2a39aebe631c1896371e97d24691 100644
--- a/src/ui/databrowserModule/preview/shownPreviews.directive.ts
+++ b/src/ui/databrowserModule/preview/shownPreviews.directive.ts
@@ -2,9 +2,10 @@ import { Directive, Optional, Inject, Output, EventEmitter, OnDestroy } from "@a
 import { Store, select } from "@ngrx/store";
 import { uiStatePreviewingDatasetFilesSelector } from "src/services/state/uiState/selectors";
 import { EnumPreviewFileTypes } from "../pure";
-import { switchMap, map, startWith } from "rxjs/operators";
+import { switchMap, map, startWith, withLatestFrom } from "rxjs/operators";
 import { forkJoin, of, Subscription } from "rxjs";
 import { GET_KGDS_PREVIEW_INFO_FROM_ID_FILENAME } from "../pure";
+import { viewerStateSelectedTemplateSelector } from "src/services/state/viewerState/selectors";
 
 @Directive({
   selector: '[iav-shown-previews]',
@@ -18,14 +19,18 @@ export class ShownPreviewsDirective implements OnDestroy{
   @Output()
   emitter: EventEmitter<any[]> = new EventEmitter()
 
+  private templateSelected$ = this.store$.pipe(
+    select(viewerStateSelectedTemplateSelector)
+  )
+
   public iavAdditionalLayers$ = this.store$.pipe(
     select(uiStatePreviewingDatasetFilesSelector),
     switchMap(prevs => prevs.length > 0
-      ? forkJoin(...prevs.map(
-        prev => this.getDatasetPreviewFromId
+      ? forkJoin(
+        prevs.map(prev => this.getDatasetPreviewFromId
           ? this.getDatasetPreviewFromId(prev)
           : of(null)
-      )
+        )
       )
       : of([])
     ),
diff --git a/src/ui/databrowserModule/util/filterDataEntriesByRegion.pipe.ts b/src/ui/databrowserModule/util/filterDataEntriesByRegion.pipe.ts
index d976cba7a58f733ac321420e21af3ec9f7ea3073..cea1159819a66e785405a6eb0fb40445f7a8edf4 100644
--- a/src/ui/databrowserModule/util/filterDataEntriesByRegion.pipe.ts
+++ b/src/ui/databrowserModule/util/filterDataEntriesByRegion.pipe.ts
@@ -12,13 +12,17 @@ export const regionsEqual = (r1, r2) => {
 }
 
 const isSubRegion = (high, low) => regionsEqual(high, low)
-  ? true
-  : high.children && Array.isArray(high.children)
-    ? high.children.some(r => isSubRegion(r, low))
-    : false
+  || (
+    high.children
+    && Array.isArray(high.children)
+    && high.children.some(r => isSubRegion(r, low))
+  )
+    
 
-const filterSubSelect = (dataEntry, selectedRegions) =>
-  dataEntry.parcellationRegion.some(pr => selectedRegions.some(sr => isSubRegion(pr, sr)))
+const filterSubSelect = (dataEntry, selectedRegions) => {
+  if (dataEntry.name === 'Density measurements of different receptors for Area 7A (SPL) [human, v1.0]') console.log(dataEntry)
+  return dataEntry.parcellationRegion.some(pr => selectedRegions.some(sr => isSubRegion(pr, sr)))
+}
 
 @Pipe({
   name: 'filterDataEntriesByRegion',
@@ -27,8 +31,7 @@ const filterSubSelect = (dataEntry, selectedRegions) =>
 export class FilterDataEntriesByRegion implements PipeTransform {
   public transform(dataentries: IDataEntry[], selectedRegions: any[], flattenedAllRegions: any[]) {
     return dataentries && selectedRegions && selectedRegions.length > 0
-      ? dataentries
-        .filter(de => filterSubSelect(de, selectedRegions))
+      ? dataentries.filter(de => filterSubSelect(de, selectedRegions))
       : dataentries
   }
 }
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.spec.ts b/src/ui/nehubaContainer/nehubaContainer.component.spec.ts
index a8e45f21d612af7f801d4a0998514526b22e9043..0d3f098c077e9b26853c1a0fb5177a67d90c89dc 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.spec.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.spec.ts
@@ -260,7 +260,7 @@ describe('> nehubaContainer.component.ts', () => {
           const toggleBtn = fixture.debugElement.query( By.css(`[aria-label="${TOGGLE_SIDE_PANEL}"]`) )
           toggleBtn.triggerEventHandler('click', null)
           fixture.detectChanges()
-          const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${EXPAND}"]`) )
+          const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-secondary-open="true"] [aria-label="${EXPAND}"]`) )
           expect(expandRegionFeatureBtn).toBeNull()
         })
         it('> collapse btn should not be visible', () => {
@@ -271,7 +271,7 @@ describe('> nehubaContainer.component.ts', () => {
           const toggleBtn = fixture.debugElement.query( By.css(`[aria-label="${TOGGLE_SIDE_PANEL}"]`) )
           toggleBtn.triggerEventHandler('click', null)
           fixture.detectChanges()
-          const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${COLLAPSE}"]`) )
+          const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-secondary-open="true"] [aria-label="${COLLAPSE}"]`) )
           expect(expandRegionFeatureBtn).toBeNull()
         })
       })
@@ -347,7 +347,7 @@ describe('> nehubaContainer.component.ts', () => {
           const fixture = TestBed.createComponent(NehubaContainer)
           fixture.componentInstance.currentOnHoverObs$ = hot('')
           fixture.detectChanges()
-          const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${COLLAPSE}"]`) )
+          const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-secondary-open="true"] [aria-label="${COLLAPSE}"]`) )
           expect(collapseRegionFeatureBtn).not.toBeNull()
         })
         it('> clicking on collapse btn should minimize 1 drawer', () => {
@@ -355,7 +355,7 @@ describe('> nehubaContainer.component.ts', () => {
           const fixture = TestBed.createComponent(NehubaContainer)
           fixture.componentInstance.currentOnHoverObs$ = hot('')
           fixture.detectChanges()
-          const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${COLLAPSE}"]`) )
+          const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-secondary-open="true"] [aria-label="${COLLAPSE}"]`) )
           collapseRegionFeatureBtn.triggerEventHandler('click', null)
           fixture.detectChanges()
           expect(
@@ -381,10 +381,10 @@ describe('> nehubaContainer.component.ts', () => {
           const fixture = TestBed.createComponent(NehubaContainer)
           fixture.componentInstance.currentOnHoverObs$ = hot('')
           fixture.detectChanges()
-          const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${COLLAPSE}"]`) )
+          const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-secondary-open="true"] [aria-label="${COLLAPSE}"]`) )
           collapseRegionFeatureBtn.triggerEventHandler('click', null)
           fixture.detectChanges()
-          const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${EXPAND}"]`) )
+          const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-primary-open="true"] [aria-label="${EXPAND}"]`) )
           expandRegionFeatureBtn.triggerEventHandler('click', null)
           fixture.detectChanges()
 
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts
index 36126aa35f494a9f60d5578cdfde1a3e79589592..7f0e469ac660e75d0e8109ca52611ca80884c554 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.ts
@@ -25,7 +25,7 @@ import { AtlasViewerAPIServices, IUserLandmark } from "src/atlasViewer/atlasView
 import { NehubaViewerUnit } from "./nehubaViewer/nehubaViewer.component";
 import { compareLandmarksChanged } from "src/util/constants";
 import { PureContantService } from "src/util";
-import { ARIA_LABELS, IDS } from 'common/constants'
+import { ARIA_LABELS, IDS, CONST } from 'common/constants'
 import { ngViewerActionSetPerspOctantRemoval, PANELS, ngViewerActionToggleMax, ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer } from "src/services/state/ngViewerState.store.helper";
 import { viewerStateSelectRegionWithIdDeprecated, viewerStateAddUserLandmarks, viewreStateRemoveUserLandmarks, viewerStateCustomLandmarkSelector, viewerStateSelectedParcellationSelector, viewerStateSelectedTemplateSelector } from 'src/services/state/viewerState.store.helper'
 import { SwitchDirective } from "src/util/directives/switch.directive";
@@ -99,7 +99,8 @@ const {
   ZOOM_OUT,
   TOGGLE_SIDE_PANEL,
   EXPAND,
-  COLLAPSE
+  COLLAPSE,
+  ADDITIONAL_VOLUME_CONTROL
 } = ARIA_LABELS
 
 @Component({
@@ -145,12 +146,14 @@ const {
 
 export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
 
+  public CONST = CONST
   public ARIA_LABEL_ZOOM_IN = ZOOM_IN
   public ARIA_LABEL_ZOOM_OUT = ZOOM_OUT
   public ARIA_LABEL_TOGGLE_SIDE_PANEL = TOGGLE_SIDE_PANEL
   public ARIA_LABEL_EXPAND = EXPAND
   public ARIA_LABEL_COLLAPSE = COLLAPSE
-
+  public ARIA_LABEL_ADDITIONAL_VOLUME_CONTROL = ADDITIONAL_VOLUME_CONTROL
+  
   public ID_MESH_LOADING_STATUS = MESH_LOADING_STATUS
 
   @ViewChild(NehubaViewerContainerDirective,{static: true})
diff --git a/src/ui/nehubaContainer/nehubaContainer.template.html b/src/ui/nehubaContainer/nehubaContainer.template.html
index 9be5d81f9eb6e105a7afad321f177b0b8bf905b9..6aee271815eb369c30ee9b753afaf8abc1355963 100644
--- a/src/ui/nehubaContainer/nehubaContainer.template.html
+++ b/src/ui/nehubaContainer/nehubaContainer.template.html
@@ -48,7 +48,7 @@
     <!-- sidenav-content -->
     <mat-drawer class="box-shadow-none border-0 pe-none bg-none col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2"
       mode="side"
-      [attr.data-mat-drawer-open]="matDrawerMaster.opened"
+      [attr.data-mat-drawer-primary-open]="matDrawerMaster.opened"
       [opened]="sideNavMasterSwitch.switchState"
       [autoFocus]="false"
       (closedStart)="sideNavSwitch.switchState && matDrawerMinor.close()"
@@ -121,7 +121,7 @@
     <!-- sidenav-content -->
     <mat-drawer class="darker-bg iv-custom-comp visible col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2 d-flex flex-column pe-all"
       mode="push"
-      [attr.data-mat-drawer-open]="matDrawerMinor.opened"
+      [attr.data-mat-drawer-secondary-open]="matDrawerMinor.opened"
       [autoFocus]="false"
       #matDrawerMinor="matDrawer"
       (openedChange)="$event && sideNavSwitch.open()"
@@ -221,6 +221,7 @@
   <div class="w-100 flex-grow-1 d-flex flex-column">
 
     <preview-card class="d-block side-nav-cover flex-grow-1"
+      [attr.aria-label]="ARIA_LABEL_ADDITIONAL_VOLUME_CONTROL"
       [datasetId]="datasetId"
       [filename]="filename">
     </preview-card>
@@ -308,6 +309,8 @@
       let-iavNgIf="iavNgIf"
       let-content="content">
       <mat-expansion-panel class="mt-1 mb-1"
+        [attr.data-opened]="expansionPanel.expanded"
+        [attr.data-mat-expansion-title]="title"
         hideToggle
         *ngIf="iavNgIf"
         #expansionPanel="matExpansionPanel">
@@ -388,7 +391,7 @@
     </ng-template>
 
     <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-      title: 'Regional features',
+      title: CONST.REGIONAL_FEATURES,
       desc: iavDbDirective?.dataentries?.length,
       iconClass: 'fas fa-database',
       iconTooltip: iavDbDirective?.dataentries?.length | regionAccordionTooltipTextPipe : 'regionalFeatures',
@@ -446,7 +449,7 @@
       [attr.id]="ID_MESH_LOADING_STATUS"
       role="status">
 
-      <div class="spinnerAnimationCircle">
+      <div [ngClass]="{spinnerAnimationCircle: !!(showPerpsectiveScreen$ | async)}">
       </div>
       <mat-list>
         <mat-list-item>
diff --git a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
index 7c2dbe4bbb169f6aa43a9a24d267c09d73cc496e..c65df9baadcdfb7e58d3b840f85353c9b7d0aa98 100644
--- a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
+++ b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
@@ -119,15 +119,15 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
       : [1.5e9, 1.5e9, 1.5e9]
   }
 
-  public _s1$: any
-  public _s2$: any
-  public _s3$: any
-  public _s4$: any
-  public _s5$: any
-  public _s6$: any
-  public _s7$: any
-  public _s8$: any
-  public _s9$: any
+  public _s1$: any = null
+  public _s2$: any = null
+  public _s3$: any = null
+  public _s4$: any = null
+  public _s5$: any = null
+  public _s6$: any = null
+  public _s7$: any = null
+  public _s8$: any = null
+  public _s9$: any = null
 
   public _s$: any[] = [
     this._s1$,
diff --git a/src/ui/nehubaContainer/nehubaViewerInterface/nehubaViewerInterface.directive.ts b/src/ui/nehubaContainer/nehubaViewerInterface/nehubaViewerInterface.directive.ts
index 613bc6621a70f4cab31f8e36037e3c1d8bc4e2ba..74d8f40197f3b99d1d672888dea30c05ff03028f 100644
--- a/src/ui/nehubaContainer/nehubaViewerInterface/nehubaViewerInterface.directive.ts
+++ b/src/ui/nehubaContainer/nehubaViewerInterface/nehubaViewerInterface.directive.ts
@@ -12,6 +12,7 @@ import { MOUSE_OVER_SEGMENTS, MOUSE_OVER_LANDMARK } from "src/services/state/uiS
 import { takeOnePipe } from "../nehubaContainer.component";
 import { ngViewerActionNehubaReady } from "src/services/state/ngViewerState/actions";
 import { viewerStateMouseOverCustomLandmarkInPerspectiveView } from "src/services/state/viewerState/actions";
+import { viewerStateStandAloneVolumes } from "src/services/state/viewerState/selectors";
 
 const defaultNehubaConfig = {
   "configName": "",
@@ -324,8 +325,7 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
 
     this.subscriptions.push(
       this.store$.pipe(
-        select('viewerState'),
-        select('standaloneVolumes'),
+        select(viewerStateStandAloneVolumes),
         filter(v => v && Array.isArray(v) && v.length > 0),
         distinctUntilChanged()
       ).subscribe(async volumes => {
diff --git a/src/ui/viewerStateController/regionSearch/regionSearch.component.ts b/src/ui/viewerStateController/regionSearch/regionSearch.component.ts
index 2d6acd658d2d607e50db8f4f511586b451114bee..43fbe572221841a757c11b22d14a3faacd0c9c43 100644
--- a/src/ui/viewerStateController/regionSearch/regionSearch.component.ts
+++ b/src/ui/viewerStateController/regionSearch/regionSearch.component.ts
@@ -11,6 +11,7 @@ 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 } from 'common/constants'
 
 const filterRegionBasedOnText = searchTerm => region => region.name.toLowerCase().includes(searchTerm.toLowerCase())
   || (region.relatedAreas && region.relatedAreas.some(relatedArea => relatedArea.name && relatedArea.name.toLowerCase().includes(searchTerm.toLowerCase())))
@@ -36,7 +37,9 @@ export class RegionTextSearchAutocomplete {
 
   public compareFn = compareFn
 
-  @Input() public ariaLabel: string = `Search for any region of interest in the atlas selected`
+  public CLEAR_SELECTED_REGION = ARIA_LABELS.CLEAR_SELECTED_REGION
+
+  @Input() public ariaLabel: string = ARIA_LABELS.TEXT_INPUT_SEARCH_REGION
   @Input() public showBadge: boolean = false
   @Input() public showAutoComplete: boolean = true
 
diff --git a/src/ui/viewerStateController/regionSearch/regionSearch.template.html b/src/ui/viewerStateController/regionSearch/regionSearch.template.html
index 42ddf8f77117bd4897e826ff407e1f203bbabc4c..b2f5434124d1a2d5e89c7b5bb1227f1f3c74f914 100644
--- a/src/ui/viewerStateController/regionSearch/regionSearch.template.html
+++ b/src/ui/viewerStateController/regionSearch/regionSearch.template.html
@@ -17,6 +17,7 @@
       <!-- close region selection -->
       <button *ngIf="(regionsSelected$ | async)?.length > 0"
         mat-icon-button
+        [attr.aria-label]="CLEAR_SELECTED_REGION"
         (click)="optionSelected()"  
         matSuffix>
         <i class="fas fa-times"></i>
diff --git a/src/ui/viewerStateController/viewerState.useEffect.ts b/src/ui/viewerStateController/viewerState.useEffect.ts
index d64b634afac2105eb2f34199e43b5b1259dae2ec..8edba98ef705137f2a8256a9725e06e5d95e20a9 100644
--- a/src/ui/viewerStateController/viewerState.useEffect.ts
+++ b/src/ui/viewerStateController/viewerState.useEffect.ts
@@ -2,13 +2,13 @@ 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 } from "rxjs/operators";
+import { distinctUntilChanged, filter, map, shareReplay, withLatestFrom, switchMap, mapTo } from "rxjs/operators";
 import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service";
-import { CHANGE_NAVIGATION, FETCHED_TEMPLATE, GENERAL_ACTION_TYPES, IavRootStoreInterface, NEWVIEWER, SELECT_PARCELLATION, SELECT_REGIONS, viewerState } from "src/services/stateStore.service";
+import { CHANGE_NAVIGATION, FETCHED_TEMPLATE, IavRootStoreInterface, NEWVIEWER, SELECT_PARCELLATION, SELECT_REGIONS, generalActionError } from "src/services/stateStore.service";
 import { VIEWERSTATE_CONTROLLER_ACTION_TYPES } from "./viewerState.base";
-import {TemplateCoordinatesTransformation} from "src/services/templateCoordinatesTransformation.service";
+import { TemplateCoordinatesTransformation } from "src/services/templateCoordinatesTransformation.service";
 import { CLEAR_STANDALONE_VOLUMES } from "src/services/state/viewerState.store";
-import { viewerStateToggleRegionSelect, viewerStateHelperSelectParcellationWithId, viewerStateSelectTemplateWithId, viewerStateNavigateToRegion, viewerStateHelperStoreName, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState.store.helper";
+import { viewerStateToggleRegionSelect, viewerStateHelperSelectParcellationWithId, viewerStateSelectTemplateWithId, viewerStateNavigateToRegion, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState.store.helper";
 import { ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState/selectors";
 import { ngViewerActionClearView } from "src/services/state/ngViewerState/actions";
 
@@ -124,12 +124,9 @@ export class ViewerStateControllerUseEffect implements OnDestroy {
         const { parcellations: availableParcellations } = templateSelected
         const newParcellation = availableParcellations.find(t => t['@id'] === id)
         if (!newParcellation) {
-          return {
-            type: GENERAL_ACTION_TYPES.ERROR,
-            payload: {
-              message: 'Selected parcellation not found.',
-            },
-          }
+          return generalActionError({
+            message: 'Selected parcellation not found.'
+          })
         }
         return {
           type: SELECT_PARCELLATION,
@@ -217,12 +214,9 @@ export class ViewerStateControllerUseEffect implements OnDestroy {
       map(({ newTemplateId, templateSelected, newParcellationId, fetchedTemplates, translatedCoordinate, navigation, parcellationSelected }) => {
         const newTemplateTobeSelected = fetchedTemplates.find(t => t['@id'] === newTemplateId)
         if (!newTemplateTobeSelected) {
-          return {
-            type: GENERAL_ACTION_TYPES.ERROR,
-            payload: {
-              message: 'Selected template not found.',
-            },
-          }
+          return generalActionError({
+            message: 'Selected template not found.'
+          })
         }
 
         const selectParcellationWithTemplate = (newParcellationId && newTemplateTobeSelected['parcellations'].find(p => p['@id'] === newParcellationId))
@@ -262,22 +256,16 @@ export class ViewerStateControllerUseEffect implements OnDestroy {
         const { payload = {} } = action as ViewerStateAction
         const { region } = payload
         if (!region) {
-          return {
-            type: GENERAL_ACTION_TYPES.ERROR,
-            payload: {
-              message: `Go to region: region not defined`,
-            },
-          }
+          return generalActionError({
+            message: `Go to region: region not defined`
+          })
         }
 
         const { position } = region
         if (!position) {
-          return {
-            type: GENERAL_ACTION_TYPES.ERROR,
-            payload: {
-              message: `${region.name} - does not have a position defined`,
-            },
-          }
+          return generalActionError({
+            message: `${region.name} - does not have a position defined`
+          })
         }
 
         return {
@@ -302,12 +290,9 @@ export class ViewerStateControllerUseEffect implements OnDestroy {
          * if region does not have labelIndex (not tree leaf), for now, return error
          */
         if (!region.labelIndex) {
-          return {
-            type: GENERAL_ACTION_TYPES.ERROR,
-            payload: {
-              message: 'Currently, only regions at the lowest hierarchy can be selected.',
-            },
-          }
+          return generalActionError({
+            message: 'Currently, only regions at the lowest hierarchy can be selected.'
+          })
         }
 
         /**