diff --git a/deploy/regionalFeatures/index.js b/deploy/regionalFeatures/index.js
index 009125ea42b90b88e711a024d8b0e3e9f8763940..14828c5c00eaa99be9f8a2e5a5ca129eb63ba4fa 100644
--- a/deploy/regionalFeatures/index.js
+++ b/deploy/regionalFeatures/index.js
@@ -1,4 +1,5 @@
 const router = require('express').Router()
+const { parse } = require('path')
 const request = require('request')
 
 /**
@@ -29,49 +30,69 @@ const ITERABLE_KEY_SYMBOL = Symbol('ITERABLE_KEY_SYMBOL')
  * async await would mean it is fetched one at a time
  */
 
+const processRegionalFeatureObj = ({ regions, data, ['@id']: datasetId, type, name }) => {
+  
+  datasetIdDetailMap.set(datasetId, {
+    ['@id']: datasetId,
+    type,
+    name
+  })
+  for (const { status, ['@id']: regionId, name, files } of regions) {
+    if (regionIdToDataIdMap.has(regionId)) {
+      const existingObj = regionIdToDataIdMap.get(regionId)
+      /**
+       * existingObj[datasetId] may be undefined
+       */
+      if (!existingObj[datasetId]) {
+        existingObj[datasetId] = {
+          type,
+        }
+        existingObj[ITERABLE_KEY_SYMBOL] = existingObj[ITERABLE_KEY_SYMBOL].concat(datasetId)
+      }
+      existingObj[datasetId][status] = (existingObj[datasetId][status] || []).concat(files)
+      existingObj[datasetId][ITERABLE_KEY_SYMBOL] = (existingObj[datasetId][ITERABLE_KEY_SYMBOL] || []).concat(status)
+    } else {
+      const datasetObj = {
+        [status]: files,
+        type,
+      }
+      datasetObj[ITERABLE_KEY_SYMBOL] = [status]
+      const obj = {
+        name,
+        '@id': regionId,
+        [datasetId]: datasetObj
+      }
+      obj[ITERABLE_KEY_SYMBOL] = [datasetId]
+      regionIdToDataIdMap.set(regionId, obj)
+    }
+  }
+  
+  const dataIdToDataMap = new Map()
+  datasetIdToDataMap.set(datasetId, dataIdToDataMap)
+
+  for (const { ['@id']: dataId, contact_points: contactPoints, referenceSpaces, ...rest } of data) {
+    dataIdToDataMap.set(dataId, {
+      ['@id']: dataId,
+      contactPoints,
+      referenceSpaces,
+      ...rest
+    })
+  }
+}
+
 Promise.all(
   arrayToFetch.map(url =>
     new Promise((rs, rj) => {
       request.get(url, (err, _resp, body) => {
         if (err) return rj(err)
-        const { regions, data, ['@id']: datasetId, type, name } = JSON.parse(body)
-        datasetIdDetailMap.set(datasetId, {
-          ['@id']: datasetId,
-          type,
-          name
-        })
-        for (const { status, ['@id']: regionId, name, files } of regions) {
-          if (regionIdToDataIdMap.has(regionId)) {
-            const existingObj = regionIdToDataIdMap.get(regionId)
-            existingObj[datasetId][status] = (existingObj[datasetId][status] || []).concat(files)
-            existingObj[datasetId][ITERABLE_KEY_SYMBOL] = existingObj[datasetId][ITERABLE_KEY_SYMBOL].concat(status)
-          } else {
-            const datasetObj = {
-              [status]: files,
-              type,
-            }
-            datasetObj[ITERABLE_KEY_SYMBOL] = [status]
-            const obj = {
-              name,
-              '@id': regionId,
-              [datasetId]: datasetObj
-            }
-            obj[ITERABLE_KEY_SYMBOL] = [datasetId]
-            regionIdToDataIdMap.set(regionId, obj)
-          }
-        }
-        
-        const dataIdToDataMap = new Map()
-        datasetIdToDataMap.set(datasetId, dataIdToDataMap)
-
-        for (const { ['@id']: dataId, contact_points: contactPoints, referenceSpaces, ...rest } of data) {
-          dataIdToDataMap.set(dataId, {
-            ['@id']: dataId,
-            contactPoints,
-            referenceSpaces,
-            ...rest
-          })
+        const parsedObj = JSON.parse(body)
+
+        if (Array.isArray(parsedObj)) {
+          parsedObj.map(processRegionalFeatureObj)
+        } else {
+          processRegionalFeatureObj(parsedObj)
         }
+
         rs()
       })
     })
@@ -195,7 +216,7 @@ const byRegionMiddleware = (req, res, next) => {
           if (
             !!referenceSpaceId
             && !! dataObj['referenceSpaces']
-            && dataObj['referenceSpaces'].every(rs => rs['fullId'] !== referenceSpaceId)
+            && dataObj['referenceSpaces'].every(rs => rs['fullId'] !== '*' && rs['fullId'] !== referenceSpaceId)
           ) {
             continue
           }
diff --git a/docs/releases/v2.3.0.md b/docs/releases/v2.3.0.md
index 4d6fc0859d24b48fd83fd7329d4dfd88fe88a7f1..bd3c04a72e17891577f1027cb2da88d59d969b3d 100644
--- a/docs/releases/v2.3.0.md
+++ b/docs/releases/v2.3.0.md
@@ -13,6 +13,7 @@
 - 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`
 - Added short bundle HCP to the supported atlas
+- reworked regional dataset previews (iEEG & receptor density)
 - **experimental** : previewing of curated regional features: iEEG coordinates
 
 ## Bugfixes:
diff --git a/src/ui/databrowserModule/singleDataset/sideNavView/sDsSideNavView.template.html b/src/ui/databrowserModule/singleDataset/sideNavView/sDsSideNavView.template.html
index e71d9cc744e8d596f258d4bd00a9a99e502a83ac..ba6354fc96315db3206186e7a152d01ffee08516 100644
--- a/src/ui/databrowserModule/singleDataset/sideNavView/sDsSideNavView.template.html
+++ b/src/ui/databrowserModule/singleDataset/sideNavView/sDsSideNavView.template.html
@@ -74,7 +74,7 @@
         </ng-template>
       </mat-expansion-panel>
 
-      <!-- features -->
+      <!-- Features -->
       <div class="hidden"
         [region]="region$ | async"
         (loadingStateChanged)="detectChange()"
@@ -83,19 +83,19 @@
       </div>
 
       <ng-container *ngFor="let feature of (rfGetAllFeatures.features | filterRegionFeaturesById : fullId)">
-        <mat-expansion-panel hideToggle>
+        <mat-expansion-panel hideToggle
+          #matExpansionPanel>
           <mat-expansion-panel-header>
             <mat-panel-title>
               {{ feature.type }}
             </mat-panel-title>
           </mat-expansion-panel-header>
 
-          <ng-template matExpansionPanelContent>
-            <feature-explorer [feature]="feature"
-              [region]="region$ | async"
-              (feature-explorer-is-loading)="detectChange()">
-  
-            </feature-explorer>
+          <ng-template [ngIf]="matExpansionPanel.expanded">
+            <feature-container
+              [feature]="feature"
+              [region]="region$ | async">
+            </feature-container>
           </ng-template>
         </mat-expansion-panel>
       </ng-container>
diff --git a/src/ui/regionalFeatures/featureContainer/featureContainer.component.ts b/src/ui/regionalFeatures/featureContainer/featureContainer.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d6752dae47b53d81f94c067ff653366f59c1a375
--- /dev/null
+++ b/src/ui/regionalFeatures/featureContainer/featureContainer.component.ts
@@ -0,0 +1,51 @@
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ComponentFactoryResolver, ComponentRef, Input, OnChanges, SimpleChanges, ViewContainerRef } from "@angular/core";
+import { Subscription } from "rxjs";
+import { IFeature, RegionalFeaturesService } from "../regionalFeature.service";
+import { ISingleFeature } from "../singleFeatures/interfaces";
+
+@Component({
+  selector: 'feature-container',
+  template: '',
+  changeDetection: ChangeDetectionStrategy.OnPush,
+})
+
+export class FeatureContainer implements OnChanges{
+  @Input()
+  feature: IFeature
+
+  @Input()
+  region: any
+
+  private cr: ComponentRef<ISingleFeature>
+  
+  constructor(
+    private vCRef: ViewContainerRef,
+    private rService: RegionalFeaturesService,
+    private cfr: ComponentFactoryResolver,
+    private cdr: ChangeDetectorRef
+  ){
+  }
+
+  private viewChangedSub: Subscription
+
+  ngOnChanges(simpleChanges: SimpleChanges){
+    if (!simpleChanges.feature) return
+    const { currentValue, previousValue } = simpleChanges.feature
+    if (currentValue === previousValue) return
+    this.clear()
+    /**
+     * TODO catch if map is undefined
+     */
+    const comp = this.rService.mapFeatToCmp.get(currentValue.type)
+    const cf = this.cfr.resolveComponentFactory<ISingleFeature>(comp)
+    this.cr = this.vCRef.createComponent(cf)
+    this.cr.instance.feature = this.feature
+    this.cr.instance.region = this.region
+    this.viewChangedSub = this.cr.instance.viewChanged.subscribe(() => this.cdr.detectChanges())
+  }
+
+  clear(){
+    if (this.viewChangedSub) this.viewChangedSub.unsubscribe()
+    this.vCRef.clear()
+  }
+}
diff --git a/src/ui/regionalFeatures/interactivity.directive.ts b/src/ui/regionalFeatures/interactivity.directive.ts
deleted file mode 100644
index a5c24ff8f456e762a01da417307f504790b3c148..0000000000000000000000000000000000000000
--- a/src/ui/regionalFeatures/interactivity.directive.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { Directive, Inject, EventEmitter, OnDestroy, Optional, Output } from "@angular/core";
-import { take } from "rxjs/operators";
-import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
-import { RegionalFeaturesService } from "./regionalFeature.service";
-
-@Directive({
-  selector: '[regional-feature-interactiviity]',
-  exportAs: 'regionalFeatureInteractivity'
-})
-
-export class RegionalFeatureInteractivity implements OnDestroy{
-
-  @Output('rf-interact-onclick-3d-landmark')
-  onClick3DLandmark: EventEmitter<{ landmark: any, next: Function }> = new EventEmitter()
-
-  private onDestroyCb: Function[] = []
-
-  constructor(
-    private regionalFeatureService: RegionalFeaturesService,
-    @Optional() @Inject(CLICK_INTERCEPTOR_INJECTOR) private regClickIntp: ClickInterceptor,
-  ){
-
-    if (this.regClickIntp) {
-      const { deregister, register } = this.regClickIntp
-      const clickIntp = this.clickIntp.bind(this)
-      register(clickIntp)
-      this.onDestroyCb.push(() => {
-        deregister(clickIntp)
-      })
-    }
-
-  }
-
-  ngOnDestroy(){
-    while (this.onDestroyCb.length > 0) this.onDestroyCb.pop()()
-  }
-
-  private clickIntp(ev: any, next: Function) {
-    let hoveredLandmark = null
-    this.regionalFeatureService.onHoverLandmarks$.pipe(
-      take(1)
-    ).subscribe(val => {
-      hoveredLandmark = val
-    })
-    if (hoveredLandmark) {
-      this.onClick3DLandmark.emit({
-        landmark: hoveredLandmark,
-        next
-      })
-    } else {
-      next()
-    }
-  }
-}
diff --git a/src/ui/regionalFeatures/module.ts b/src/ui/regionalFeatures/module.ts
index 60cf760553927deafe08f244a51269ab271f7543..f90b3a6ee0593d324d30394b8ba746541f8fa2c0 100644
--- a/src/ui/regionalFeatures/module.ts
+++ b/src/ui/regionalFeatures/module.ts
@@ -2,30 +2,32 @@ import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
 import { UtilModule } from "src/util";
 import { AngularMaterialModule } from "../sharedModules/angularMaterial.module";
-import { FeatureExplorer } from "./featureExplorer/featureExplorer.component";
-import { RegionalFeatureInteractivity } from "./interactivity.directive";
+import { FeatureContainer } from "./featureContainer/featureContainer.component";
 import { FilterRegionalFeaturesByTypePipe } from "./pipes/filterRegionalFeaturesByType.pipe";
 import { FilterRegionFeaturesById } from "./pipes/filterRegionFeaturesById.pipe";
 import { FindRegionFEatureById } from "./pipes/findRegionFeatureById.pipe";
 import { RegionalFeaturesService } from "./regionalFeature.service";
 import { RegionGetAllFeaturesDirective } from "./regionGetAllFeatures.directive";
+import { FeatureIEEGRecordings } from "./singleFeatures/iEEGRecordings/module";
+import { ReceptorDensityModule } from "./singleFeatures/receptorDensity/module";
 
 @NgModule({
   imports: [
     CommonModule,
     UtilModule,
     AngularMaterialModule,
+    FeatureIEEGRecordings,
+    ReceptorDensityModule,
   ],
   declarations: [
     /**
      * components
      */
-    FeatureExplorer,
+    FeatureContainer,
 
     /**
      * Directives
      */
-    RegionalFeatureInteractivity,
     RegionGetAllFeaturesDirective,
 
     /**
@@ -36,9 +38,9 @@ import { RegionGetAllFeaturesDirective } from "./regionGetAllFeatures.directive"
     FilterRegionFeaturesById,
   ],
   exports: [
-    FeatureExplorer,
     RegionGetAllFeaturesDirective,
     FilterRegionFeaturesById,
+    FeatureContainer,
   ],
   providers: [
     RegionalFeaturesService,
diff --git a/src/ui/regionalFeatures/regionFeature.base.ts b/src/ui/regionalFeatures/regionFeature.base.ts
deleted file mode 100644
index 1064b07239661673f592fc9f4daa66ca9bed14ad..0000000000000000000000000000000000000000
--- a/src/ui/regionalFeatures/regionFeature.base.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Input, SimpleChanges } from "@angular/core"
-import { BehaviorSubject, of } from "rxjs"
-import { IFeature, RegionalFeaturesService } from "./regionalFeature.service"
-
-export class RegionFeatureBase{
-
-  @Input()
-  public region: any
-
-  public features: IFeature[] = []
-
-  /**
-   * using isLoading flag for conditional rendering of root element (or display loading spinner)
-   * this is necessary, or the transcluded tab will always be the active tab,
-   * as this.features as populated via async
-   */
-  public isLoading$ = new BehaviorSubject(false)
-  private _isLoading: boolean = false
-  get isLoading(){
-    return this._isLoading
-  }
-  set isLoading(val){
-    if (val !== this._isLoading)
-      this._isLoading = val
-    this.isLoading$.next(val)
-  }
-
-  ngOnChanges(changes: SimpleChanges){
-    if (changes.region && changes.region.previousValue !== changes.region.currentValue) {
-      this.isLoading = true
-      this.features = []
-      
-      const _ = (changes.region.currentValue
-        ? this._regionalFeatureService.getAllFeaturesByRegion(changes.region.currentValue)
-        : of([])
-      ).pipe(
-
-      ).subscribe({
-        next: features => this.features = features,
-        complete: () => this.isLoading = false
-      })
-    }
-  }
-
-  constructor(
-    private _regionalFeatureService: RegionalFeaturesService
-  ){
-
-  }
-}
diff --git a/src/ui/regionalFeatures/regionGetAllFeatures.directive.ts b/src/ui/regionalFeatures/regionGetAllFeatures.directive.ts
index ae26c853c294a91b554e615cf4a58264fcb7b32f..920e1f0a98c7cd791514755d48351b63d4005684 100644
--- a/src/ui/regionalFeatures/regionGetAllFeatures.directive.ts
+++ b/src/ui/regionalFeatures/regionGetAllFeatures.directive.ts
@@ -1,7 +1,7 @@
 import { Directive, EventEmitter, OnDestroy, OnInit, Output } from "@angular/core";
 import { Subscription } from "rxjs";
 import { RegionalFeaturesService } from "./regionalFeature.service";
-import { RegionFeatureBase } from "./regionFeature.base";
+import { RegionFeatureBase } from "./singleFeatures/base/regionFeature.base";
 
 @Directive({
   selector: '[region-get-all-features-directive]',
diff --git a/src/ui/regionalFeatures/regionalFeature.service.ts b/src/ui/regionalFeatures/regionalFeature.service.ts
index 8e47bfeb5b62c14e243bb2df909d2af5e4030ba0..e10a5390ba9d3dac1c68fcacc9b7b351686e5a1e 100644
--- a/src/ui/regionalFeatures/regionalFeature.service.ts
+++ b/src/ui/regionalFeatures/regionalFeature.service.ts
@@ -36,6 +36,8 @@ export class RegionalFeaturesService implements OnDestroy{
     )
   }
 
+  public mapFeatToCmp = new Map<string, any>()
+
   ngOnDestroy(){
     while (this.subs.length > 0) this.subs.pop().unsubscribe()
   }
@@ -46,7 +48,6 @@ export class RegionalFeaturesService implements OnDestroy{
 
   public getAllFeaturesByRegion(region: {['fullId']: string}){
     if (!region.fullId) throw new Error(`getAllFeaturesByRegion - region does not have fullId defined`)
-    const regionFullId = getIdFromFullId(region.fullId)
     const regionFullIds = getStringIdsFromRegion(region)
     const hemisphereObj = (() => {
       const hemisphere = getRegionHemisphere(region)
diff --git a/src/ui/regionalFeatures/singleFeatures/base/regionFeature.base.ts b/src/ui/regionalFeatures/singleFeatures/base/regionFeature.base.ts
new file mode 100644
index 0000000000000000000000000000000000000000..27c68f8e64429401e3fc7c36a095fef498e8d01c
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/base/regionFeature.base.ts
@@ -0,0 +1,91 @@
+import { EventEmitter, Input, Output, SimpleChanges } from "@angular/core"
+import { BehaviorSubject, forkJoin, Observable, of } from "rxjs"
+import { shareReplay, switchMap, tap } from "rxjs/operators"
+import { IHasId } from "src/util/interfaces"
+import { IFeature, RegionalFeaturesService } from "../../regionalFeature.service"
+
+export class RegionFeatureBase{
+
+  private _feature: IFeature
+
+  private feature$ = new BehaviorSubject(null)
+  @Input()
+  set feature(val) {
+    this._feature = val
+    this.feature$.next(val)
+  }
+  get feature(){
+    return this._feature
+  }
+
+  @Input()
+  public region: any
+
+  @Output('feature-explorer-is-loading')
+  public dataIsLoadingEventEmitter: EventEmitter<boolean> = new EventEmitter()
+
+  public features: IFeature[] = []
+  public data$: Observable<IHasId[]>
+
+  /**
+   * using isLoading flag for conditional rendering of root element (or display loading spinner)
+   * this is necessary, or the transcluded tab will always be the active tab,
+   * as this.features as populated via async
+   */
+  public isLoading$ = new BehaviorSubject(false)
+  private _isLoading: boolean = false
+  get isLoading(){
+    return this._isLoading
+  }
+  set isLoading(val){
+    if (val !== this._isLoading)
+      this._isLoading = val
+    this.isLoading$.next(val)
+  }
+
+  public dataIsLoading$ = new BehaviorSubject(false)
+  private _dataIsLoading = false
+  set dataIsLoading(val) {
+    if (val === this._dataIsLoading) return
+    this._dataIsLoading = val
+    this.dataIsLoading$.next(val)
+    this.dataIsLoadingEventEmitter.next(val)
+  }
+  get dataIsLoading(){
+    return this._dataIsLoading
+  }
+
+  ngOnChanges(changes: SimpleChanges){
+    if (changes.region && changes.region.previousValue !== changes.region.currentValue) {
+      this.isLoading = true
+      this.features = []
+      
+      const _ = (changes.region.currentValue
+        ? this._regionalFeatureService.getAllFeaturesByRegion(changes.region.currentValue)
+        : of([])
+      ).pipe(
+
+      ).subscribe({
+        next: features => this.features = features,
+        complete: () => this.isLoading = false
+      })
+    }
+  }
+
+  constructor(
+    private _regionalFeatureService: RegionalFeaturesService
+  ){
+
+    /**
+    * once feature stops loading, watch for input feature
+    */
+    this.data$ = this.feature$.pipe(
+      tap(() => this.dataIsLoading = true),
+      switchMap((feature: IFeature) => forkJoin(
+        feature.data.map(datum => this._regionalFeatureService.getFeatureData(this.region, feature, datum)))
+      ),
+      tap(() => this.dataIsLoading = false),
+      shareReplay(1),
+    )
+  }
+}
diff --git a/src/ui/regionalFeatures/featureExplorer/featureExplorer.component.ts b/src/ui/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts
similarity index 59%
rename from src/ui/regionalFeatures/featureExplorer/featureExplorer.component.ts
rename to src/ui/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts
index 007a41c1acbe0b73e5845570c8bc15b87d005db5..9648e856a40f8f71f81a7f415a56f3f6a4bcec3f 100644
--- a/src/ui/regionalFeatures/featureExplorer/featureExplorer.component.ts
+++ b/src/ui/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts
@@ -1,58 +1,44 @@
-import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core";
-import { BehaviorSubject, forkJoin, merge, Observable, Subject, Subscription } from "rxjs";
-import { debounceTime, map, scan, shareReplay, switchMap, tap } from "rxjs/operators";
+import { Component, Inject, Optional, EventEmitter } from "@angular/core";
+import { merge, Subject, Subscription } from "rxjs";
+import { debounceTime, map, scan, take } from "rxjs/operators";
+import { RegionalFeaturesService } from "src/ui/regionalFeatures/regionalFeature.service";
+import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
 import { IHasId } from "src/util/interfaces";
-import { IFeature, RegionalFeaturesService } from "../regionalFeature.service";
+import { RegionFeatureBase } from "../../base/regionFeature.base";
+import { ISingleFeature } from '../../interfaces'
 
 const selectedColor = [ 255, 0, 0 ]
 
 @Component({
-  selector: 'feature-explorer',
-  templateUrl: './featureExplorer.template.html',
+  templateUrl: './iEEGRecordings.template.html',
   styleUrls: [
-    './featureExplorer.style.css'
+    './iEEGRecordings.style.css'
   ]
 })
 
-export class FeatureExplorer implements OnInit, OnDestroy{
-
+export class IEEGRecordingsCmp extends RegionFeatureBase implements ISingleFeature{
   private landmarksLoaded: IHasId[] = []
   private onDestroyCb: Function[] = []
   private sub: Subscription[] = []
-  private _feature: IFeature
-
-  private feature$ = new BehaviorSubject(null)
-  @Input()
-  set feature(val) {
-    this._feature = val
-    this.feature$.next(val)
-  }
-
-  @Input()
-  private region: any
-
-  public data$: Observable<IHasId[]>
-
-  @Output('feature-explorer-is-loading')
-  public dataIsLoadingEventEmitter: EventEmitter<boolean> = new EventEmitter()
 
   constructor(
     private regionFeatureService: RegionalFeaturesService,
+    @Optional() @Inject(CLICK_INTERCEPTOR_INJECTOR) private regClickIntp: ClickInterceptor,
   ){
-    /**
-    * once feature stops loading, watch for input feature
-    */
-    this.data$ = this.feature$.pipe(
-      tap(() => this.dataIsLoading = true),
-      switchMap((feature: IFeature) => forkJoin(
-        feature.data.map(datum => this.regionFeatureService.getFeatureData(this.region, feature, datum)))
-      ),
-      tap(() => this.dataIsLoading = false),
-      shareReplay(1),
-    )
+    super(regionFeatureService)
   }
 
+  public viewChanged = new EventEmitter<null>()
+
   ngOnInit(){
+    if (this.regClickIntp) {
+      const { deregister, register } = this.regClickIntp
+      const clickIntp = this.clickIntp.bind(this)
+      register(clickIntp)
+      this.onDestroyCb.push(() => {
+        deregister(clickIntp)
+      })
+    }
     this.sub.push(
       this.data$.subscribe(data => {
         const landmarksTobeLoaded: IHasId[] = []
@@ -105,17 +91,6 @@ export class FeatureExplorer implements OnInit, OnDestroy{
     )
   }
 
-  public dataIsLoading$ = new BehaviorSubject(false)
-  private _dataIsLoading = false
-  set dataIsLoading(val) {
-    if (val === this._dataIsLoading) return
-    this._dataIsLoading = val
-    this.dataIsLoading$.next(val)
-    this.dataIsLoadingEventEmitter.next(val)
-  }
-  get dataIsLoading(){
-    return this._dataIsLoading
-  }
 
   ngOnDestroy(){
     while(this.onDestroyCb.length > 0) this.onDestroyCb.pop()()
@@ -155,21 +130,18 @@ export class FeatureExplorer implements OnInit, OnDestroy{
     }, [])
   )
 
-  handleLandmarkClick(arg: { landmark: any, next: Function }) {
-    const { landmark, next } = arg
-
-    /**
-     * there may be other custom landmarks
-     * so check if the landmark clicked is one that's managed by this cmp
-     */
+  private clickIntp(ev: any, next: Function) {
+    let hoveredLandmark = null
+    this.regionFeatureService.onHoverLandmarks$.pipe(
+      take(1)
+    ).subscribe(val => {
+      hoveredLandmark = val
+    })
+    if (!hoveredLandmark) return next()
     const isOne = this.landmarksLoaded.some(lm => {
-      return lm['_']['electrodeId'] === landmark['_']['electrodeId']
+      return lm['_']['electrodeId'] === hoveredLandmark['_']['electrodeId']
     })
-
-    if (isOne) {
-      this.exploreElectrode$.next(landmark['_']['electrodeId'])
-    } else {
-      next()
-    }
+    if (!isOne) return next()
+    this.exploreElectrode$.next(hoveredLandmark['_']['electrodeId'])
   }
 }
diff --git a/src/ui/regionalFeatures/featureExplorer/featureExplorer.style.css b/src/ui/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.style.css
similarity index 100%
rename from src/ui/regionalFeatures/featureExplorer/featureExplorer.style.css
rename to src/ui/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.style.css
diff --git a/src/ui/regionalFeatures/featureExplorer/featureExplorer.template.html b/src/ui/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.template.html
similarity index 90%
rename from src/ui/regionalFeatures/featureExplorer/featureExplorer.template.html
rename to src/ui/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.template.html
index 7c5f3cf3367c8ca0408a1279f2ec8046dc66819b..f1389020cd588b1c507aef061ef62464bb7cfcc1 100644
--- a/src/ui/regionalFeatures/featureExplorer/featureExplorer.template.html
+++ b/src/ui/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.template.html
@@ -1,10 +1,7 @@
 <ng-container *ngIf="!dataIsLoading; else loadingTmpl">
   
   <mat-accordion
-    class="ml-24px-n mr-24px-n d-block"
-    regional-feature-interactiviity
-    (rf-interact-onclick-3d-landmark)="handleLandmarkClick($event)"
-    #interactDir="regionalFeatureInteractivity">
+    class="ml-24px-n mr-24px-n d-block">
     <mat-expansion-panel *ngFor="let datum of (data$ | async)"
       [expanded]="openElectrodeId$ | async | arrayContains : datum['@id']"
       (opened)="handleDatumExpansion(datum['@id'], true)"
diff --git a/src/ui/regionalFeatures/singleFeatures/iEEGRecordings/module.ts b/src/ui/regionalFeatures/singleFeatures/iEEGRecordings/module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6a099cad95c2c4500b8737f1a52f25e8ac12f626
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/iEEGRecordings/module.ts
@@ -0,0 +1,28 @@
+import { CommonModule } from "@angular/common";
+import { NgModule } from "@angular/core";
+import { AngularMaterialModule } from "src/ui/sharedModules/angularMaterial.module";
+import { UtilModule } from "src/util";
+import { RegionalFeaturesService } from "../../regionalFeature.service";
+import { IEEGRecordingsCmp } from "./iEEGRecordings/iEEGRecordings.component";
+
+@NgModule({
+  imports: [
+    CommonModule,
+    UtilModule,
+    AngularMaterialModule,
+  ],
+  declarations: [
+    IEEGRecordingsCmp
+  ],
+  exports: [
+    IEEGRecordingsCmp
+  ]
+})
+
+export class FeatureIEEGRecordings{
+  constructor(
+    rService: RegionalFeaturesService
+  ){
+    rService.mapFeatToCmp.set('iEEG recording', IEEGRecordingsCmp)
+  }
+}
diff --git a/src/ui/regionalFeatures/singleFeatures/interfaces.ts b/src/ui/regionalFeatures/singleFeatures/interfaces.ts
new file mode 100644
index 0000000000000000000000000000000000000000..37abcd4479aa87e9dabed72e589d2a3b82a091bd
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/interfaces.ts
@@ -0,0 +1,8 @@
+import { EventEmitter } from "@angular/core";
+import { IFeature } from "../regionalFeature.service";
+
+export interface ISingleFeature{
+  feature: IFeature
+  region: any
+  viewChanged: EventEmitter<null>
+}
diff --git a/src/ui/regionalFeatures/singleFeatures/receptorDensity/filterReceptorBytype.pipe.ts b/src/ui/regionalFeatures/singleFeatures/receptorDensity/filterReceptorBytype.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1b0a91dd80079acf6e3cc6709c4ac3cc74ec5f97
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/receptorDensity/filterReceptorBytype.pipe.ts
@@ -0,0 +1,13 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { IHasId } from "src/util/interfaces";
+
+@Pipe({
+  name: 'filterReceptorByType',
+  pure: true
+})
+
+export class FilterReceptorByType implements PipeTransform{
+  public transform(arr: IHasId[], qualifer: string): IHasId[]{
+    return (arr || []).filter(({ ['@id']: dId }) => dId.indexOf(qualifer) >= 0)
+  }
+}
diff --git a/src/ui/regionalFeatures/singleFeatures/receptorDensity/getAllReceptors.pipe.ts b/src/ui/regionalFeatures/singleFeatures/receptorDensity/getAllReceptors.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ba3016186957b4851e469792cc834110152ddb1b
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/receptorDensity/getAllReceptors.pipe.ts
@@ -0,0 +1,17 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { IHasId } from "src/util/interfaces";
+
+@Pipe({
+  name: 'getAllReceptors',
+  pure: true
+})
+
+export class GetAllReceptorsPipe implements PipeTransform{
+  public transform(arr: IHasId[]): string[]{
+    return (arr || []).reduce((acc, curr) => {
+      const thisType = /_(pr|ar)_([a-zA-Z0-9_]+)\./.exec(curr['@id'])
+      if (!thisType) return acc
+      return new Set(acc).has(thisType) ? acc : acc.concat(thisType[2])
+    }, [])
+  }
+}
\ No newline at end of file
diff --git a/src/ui/regionalFeatures/singleFeatures/receptorDensity/getId.pipe.ts b/src/ui/regionalFeatures/singleFeatures/receptorDensity/getId.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3af1a02bd4a98455bc9b0166ff4adfc5afa53646
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/receptorDensity/getId.pipe.ts
@@ -0,0 +1,13 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+  name: 'getId',
+  pure: true
+})
+
+export class GetIdPipe implements PipeTransform{
+  public transform(fullId: string): string{
+    const re = /\/([a-f0-9-]+)$/.exec(fullId)
+    return (re && re[1]) || null
+  }
+}
diff --git a/src/ui/regionalFeatures/singleFeatures/receptorDensity/module.ts b/src/ui/regionalFeatures/singleFeatures/receptorDensity/module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b090a287314d4371c393a45b6102251a99122880
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/receptorDensity/module.ts
@@ -0,0 +1,32 @@
+import { CommonModule } from "@angular/common";
+import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
+import { AngularMaterialModule } from "src/ui/sharedModules/angularMaterial.module";
+import { RegionalFeaturesService } from "../../regionalFeature.service";
+import { FilterReceptorByType } from "./filterReceptorBytype.pipe";
+import { GetAllReceptorsPipe } from "./getAllReceptors.pipe";
+import { GetIdPipe } from "./getId.pipe";
+import { ReceptorDensityFeatureCmp } from "./receptorDensity/receptorDensity.component";
+
+@NgModule({
+  imports: [
+    CommonModule,
+    AngularMaterialModule,
+  ],
+  declarations: [
+    ReceptorDensityFeatureCmp,
+    FilterReceptorByType,
+    GetIdPipe,
+    GetAllReceptorsPipe,
+  ],
+  schemas: [
+    CUSTOM_ELEMENTS_SCHEMA
+  ]
+})
+
+export class ReceptorDensityModule{
+  constructor(
+    rService: RegionalFeaturesService
+  ){
+    rService.mapFeatToCmp.set(`Receptor density measurement`, ReceptorDensityFeatureCmp)
+  }
+}
diff --git a/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.component.ts b/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..77aad9acc9a4b057464ba003d48d97c46153965c
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.component.ts
@@ -0,0 +1,31 @@
+import { Component, EventEmitter, OnDestroy } from "@angular/core";
+import { Subscription } from "rxjs";
+import { RegionalFeaturesService } from "src/ui/regionalFeatures/regionalFeature.service";
+import { RegionFeatureBase } from "../../base/regionFeature.base";
+import { ISingleFeature } from "../../interfaces";
+
+@Component({
+  templateUrl: './receptorDensity.template.html',
+  styleUrls: [
+    './receptorDensity.style.css'
+  ]
+})
+
+export class ReceptorDensityFeatureCmp extends RegionFeatureBase implements ISingleFeature, OnDestroy{
+  public DS_PREVIEW_URL = DATASET_PREVIEW_URL
+  viewChanged: EventEmitter<null> = new EventEmitter()
+
+  private subs: Subscription[] = []
+
+  constructor(
+    regService: RegionalFeaturesService
+  ){
+    super(regService)
+  }
+
+  public selectedReceptor: string
+
+  ngOnDestroy(){
+    while(this.subs.length > 0) this.subs.pop().unsubscribe()
+  }
+}
diff --git a/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.style.css b/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.style.css
new file mode 100644
index 0000000000000000000000000000000000000000..7b0d7bbed20b91de0a5e85f7516b4c23af593ceb
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.style.css
@@ -0,0 +1,5 @@
+kg-dataset-previewer
+{
+  display: block;
+  height: 20em;
+}
diff --git a/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.template.html b/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.template.html
new file mode 100644
index 0000000000000000000000000000000000000000..a061700c4a95b5e1ee3dab4ed0d6d5c32ffb0a1e
--- /dev/null
+++ b/src/ui/regionalFeatures/singleFeatures/receptorDensity/receptorDensity/receptorDensity.template.html
@@ -0,0 +1,50 @@
+<label for="fingerprint-cmp" class="d-block mat-h4 mt-4 text-muted">
+  Fingerprint
+</label>
+<kg-dataset-previewer
+  *ngFor="let datum of (data$ | async | filterReceptorByType : '_fp_')"
+  id="fingerprint-cmp"
+  (renderEvent)="viewChanged.emit()"
+  [backendUrl]="DS_PREVIEW_URL"
+  [kgId]="feature['@id'] | getId"
+  [filename]="datum['@id']">
+</kg-dataset-previewer>
+
+<mat-form-field class="mt-2">
+  <mat-label>
+    Select a receptor
+  </mat-label>
+  <mat-select [(value)]="selectedReceptor">
+    <mat-option
+      *ngFor="let receptor of (data$ | async | getAllReceptors)"
+      [value]="receptor">
+      {{ receptor }}
+    </mat-option>
+  </mat-select>
+</mat-form-field>
+
+<ng-template [ngIf]="selectedReceptor">
+  <ng-container *ngTemplateOutlet="prArTmpl; context: { filter: '_pr_', label: 'Profile' }">
+  </ng-container>
+  <ng-container *ngTemplateOutlet="prArTmpl; context: { filter: '_ar_', label: 'Autoradiograph' }">
+  </ng-container>
+</ng-template>
+
+<!-- ar/pr template -->
+<ng-template #prArTmpl let-label="label" let-filter="filter">
+  <ng-container *ngFor="let datum of (data$ | async | filterReceptorByType : selectedReceptor | filterReceptorByType : filter); let first = first">
+    <ng-template [ngIf]="first">
+      <label [attr.for]="label + '-cmp'" class="d-block mat-h4 mt-4 text-muted">
+        {{ label }}
+      </label>
+    </ng-template>
+
+    <kg-dataset-previewer
+      [attr.id]="label + '-cmp'"
+      (renderEvent)="viewChanged.emit()"
+      [backendUrl]="DS_PREVIEW_URL"
+      [kgId]="feature['@id'] | getId"
+      [filename]="datum['@id']">
+    </kg-dataset-previewer>
+  </ng-container>
+</ng-template>