diff --git a/src/ui/databrowserModule/databrowser.service.ts b/src/ui/databrowserModule/databrowser.service.ts
index 65be98caebc16638f21d51d78a1f54469cd716a7..24b811e80dc8983d10183d068677123e2a8c3473 100644
--- a/src/ui/databrowserModule/databrowser.service.ts
+++ b/src/ui/databrowserModule/databrowser.service.ts
@@ -4,8 +4,9 @@ import { ViewerConfiguration } from "src/services/state/viewerConfig.store";
 import { SELECT_REGIONS, extractLabelIdx, CHANGE_NAVIGATION, DataEntry, File, safeFilter, isDefined, getLabelIndexMap, FETCHED_DATAENTRIES, SELECT_PARCELLATION, ADD_NG_LAYER, NgViewerStateInterface, REMOVE_NG_LAYER } from "src/services/stateStore.service";
 import { WidgetServices } from "src/atlasViewer/widgetUnit/widgetService.service";
 import { map, distinctUntilChanged, filter, debounceTime } from "rxjs/operators";
-import { Subscription, combineLatest, Observable, BehaviorSubject } from "rxjs";
+import { Subscription, combineLatest, Observable, BehaviorSubject, fromEvent } from "rxjs";
 import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service";
+import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
 
 export function temporaryFilterDataentryName(name: string):string{
   return /autoradiography/.test(name)
@@ -27,6 +28,9 @@ export class DatabrowserService implements OnDestroy{
 
   public selectedRegions$: Observable<any[]>
   public selectedRegions: any[] = []
+  public rebuiltSelectedRegions: any[] = []
+  public rebuiltSomeSelectedRegions: any[] = []
+
   public regionsLabelIndexMap: Map<number, any> = new Map()
 
   public fetchingFlag: boolean = false
@@ -42,7 +46,8 @@ export class DatabrowserService implements OnDestroy{
   constructor(
     private constantService: AtlasViewerConstantsServices,
     private store: Store<ViewerConfiguration>,
-    private widgetService: WidgetServices
+    private widgetService: WidgetServices,
+    private workerService: AtlasWorkerService
   ){
 
     this.subscriptions.push(
@@ -86,7 +91,15 @@ export class DatabrowserService implements OnDestroy{
     )
 
     this.subscriptions.push(
-      this.selectedRegions$.subscribe(r => this.selectedRegions = r)
+      this.selectedRegions$.subscribe(r => {
+        this.selectedRegions = r
+        console.log(r)
+        this.workerService.worker.postMessage({
+          type: 'BUILD_REGION_SELECTION_TREE',
+          selectedRegions: r,
+          regions: this.selectedParcellation.regions
+        })
+      })
     )
 
     this.fetchDataObservable$ = combineLatest(
@@ -110,6 +123,21 @@ export class DatabrowserService implements OnDestroy{
         debounceTime(16)
       ).subscribe((param : [string, string, null] ) => this.fetchData(param[0], param[1]))
     )
+
+    this.subscriptions.push(
+      fromEvent(this.workerService.worker, 'message').pipe(
+        filter((message:MessageEvent) => message && message.data && message.data.type === 'RETURN_REBUILT_REGION_SELECTION_TREE'),
+        map(message => message.data),
+      ).subscribe((payload:any) => {
+        /**
+         * rebuiltSelectedRegion contains super region that are 
+         * selected as a result of all of its children that are selectted
+         */
+        const { rebuiltSelectedRegions, rebuiltSomeSelectedRegions } = payload
+        this.rebuiltSomeSelectedRegions = rebuiltSomeSelectedRegions
+        this.rebuiltSelectedRegions = rebuiltSelectedRegions
+      })
+    )
   }
 
   ngOnDestroy(){
@@ -117,12 +145,25 @@ export class DatabrowserService implements OnDestroy{
   }
   
   public updateRegionSelection(regions: any[]) {
+    const filteredRegion = regions.filter(r => r.labelIndex !== null && typeof r.labelIndex !== 'undefined')
     this.store.dispatch({
       type: SELECT_REGIONS,
-      selectRegions: regions
+      selectRegions: filteredRegion
     })
   }
 
+  public deselectRegion(region) {
+    const regionsToDelect = []
+    const recursiveFlatten = (region:any) => {
+      regionsToDelect.push(region)
+      if (region.children && region.children.map)
+        region.children.map(recursiveFlatten)
+    }
+    recursiveFlatten(region)
+    const selectedRegions = this.selectedRegions.filter(r => !regionsToDelect.some(deR => deR.name === r.name))
+    this.updateRegionSelection(selectedRegions)
+  }
+
   public changeParcellation({ current, previous }){
     if (previous && current && current.name === previous.name)
       return
@@ -134,13 +175,13 @@ export class DatabrowserService implements OnDestroy{
 
   public singleClickRegion(region) {
     const selectedSet = new Set(extractLabelIdx(region))
-    const intersection = new Set([...this.selectedRegions.map(r => r.labelIndex)].filter(v => selectedSet.has(v)))
-    this.store.dispatch({
-      type: SELECT_REGIONS,
-      selectRegions: intersection.size > 0
-        ? this.selectedRegions.filter(v => !intersection.has(v.labelIndex))
-        : this.selectedRegions.concat([...selectedSet].map(idx => this.regionsLabelIndexMap.get(idx)))
-    })
+    const filteredSelectedRegion = this.selectedRegions.filter(r => r.labelIndex)
+    const intersection = new Set([...filteredSelectedRegion.map(r => r.labelIndex)].filter(v => selectedSet.has(v)))
+    this.updateRegionSelection(
+      intersection.size > 0
+        ? filteredSelectedRegion.filter(v => !intersection.has(v.labelIndex))
+        : filteredSelectedRegion.concat([...selectedSet].map(idx => this.regionsLabelIndexMap.get(idx)))
+    )
   }
 
   public doubleClickRegion(region) {
diff --git a/src/ui/databrowserModule/databrowser/databrowser.component.ts b/src/ui/databrowserModule/databrowser/databrowser.component.ts
index 07890a3b0221645facf01409ebddd9c25b36ad2f..182a0cea7e9e06115ff764424b94808e9133231b 100644
--- a/src/ui/databrowserModule/databrowser/databrowser.component.ts
+++ b/src/ui/databrowserModule/databrowser/databrowser.component.ts
@@ -3,6 +3,7 @@ import { DataEntry } from "src/services/stateStore.service";
 import { Subscription, merge } from "rxjs";
 import { DatabrowserService } from "../databrowser.service";
 import { ModalityPicker } from "../modalityPicker/modalityPicker.component";
+import { skip } from "rxjs/operators";
 
 @Component({
   selector : 'data-browser',
@@ -23,6 +24,10 @@ export class DataBrowser implements OnDestroy,OnInit{
     return this.dbService.selectedRegions
   }
 
+  get rebuiltSomeSelectedRegions(){
+    return this.dbService.rebuiltSomeSelectedRegions
+  }
+
   get selectedParcellation(){
     return this.dbService.selectedParcellation
   }
@@ -65,7 +70,7 @@ export class DataBrowser implements OnDestroy,OnInit{
   ngOnInit(){
     this.subscriptions.push(
       merge(
-        this.dbService.selectedRegions$,
+        // this.dbService.selectedRegions$,
         this.dbService.fetchDataObservable$
       ).subscribe(() => {
         this.resetCurrentPage()
@@ -96,14 +101,11 @@ export class DataBrowser implements OnDestroy,OnInit{
 
   public showParcellationList: boolean = false
   
+  /**
+   * when user clicks x on region selector
+   */
   deselectRegion(region:any){
-    /**
-     * when user clicks x on region selector
-     */
-    
-    this.dbService.updateRegionSelection(
-      this.selectedRegions.filter(r => r.name !== region.name)
-    )
+    this.dbService.deselectRegion(region)
   }
 
   uncheckModality(modality:string){
diff --git a/src/ui/databrowserModule/databrowser/databrowser.template.html b/src/ui/databrowserModule/databrowser/databrowser.template.html
index 4653194a66a2cb74139b1cfe4d2aaf2376a1752a..825ebced1fb43775b8ad60a7ac8910cc41d1585d 100644
--- a/src/ui/databrowserModule/databrowser/databrowser.template.html
+++ b/src/ui/databrowserModule/databrowser/databrowser.template.html
@@ -91,6 +91,7 @@
 <ng-template #showData>
   <!-- datawrapper -->
   <div
+    *ngIf="dbService.fetchedDataEntries$ | async | filterDataEntriesByMethods : modalityFilter | filterDataEntriesByRegion : rebuiltSomeSelectedRegions as filteredDataEntry"
     [ngStyle]="filePreviewName ? {'transform': 'translateX(-50%)'} : {}"
     class="dataEntryWrapper">
 
@@ -100,8 +101,8 @@
         <i *ngIf="dbService.fetchedDataEntries$ | async">
           {{ (dbService.fetchedDataEntries$ | async).length }} total results. 
           <span
-            *ngIf="selectedRegions.length + modalityFilter.length > 0 "> 
-            {{ (dbService.fetchedDataEntries$ | async | filterDataEntriesByMethods : modalityFilter | filterDataEntriesByRegion : selectedRegions).length }} 
+            *ngIf="rebuiltSomeSelectedRegions.length + modalityFilter.length > 0 "> 
+            {{ filteredDataEntry.length }} 
             filtered results.
             <a
               href="#"
@@ -117,7 +118,7 @@
       <div *ngIf="dbService.fetchedDataEntries$ | async">
         <dataset-viewer
           class="mt-1"
-          *ngFor="let dataset of dbService.fetchedDataEntries$ | async | filterDataEntriesByMethods : modalityFilter | filterDataEntriesByRegion : selectedRegions | searchResultPagination : currentPage : hitsPerPage"
+          *ngFor="let dataset of filteredDataEntry | searchResultPagination : currentPage : hitsPerPage"
           (showPreviewDataset)="onShowPreviewDataset($event)"
           [dataset]="dataset">
         </dataset-viewer>
@@ -127,7 +128,7 @@
         *ngIf="dbService.fetchedDataEntries$ | async"
         (paginationChange)="currentPage = $event"
         [hitsPerPage]="hitsPerPage"
-        [total]="(dbService.fetchedDataEntries$ | async | filterDataEntriesByMethods : modalityFilter | filterDataEntriesByRegion : selectedRegions).length"
+        [total]="filteredDataEntry.length"
         [currentPage]="currentPage">
       </pagination-component>
     </div>
diff --git a/src/ui/databrowserModule/fileviewer/fileviewer.component.ts b/src/ui/databrowserModule/fileviewer/fileviewer.component.ts
index a044db495e675dfcfc22a264c06c9e0109b365e2..1048721014ffc5d81ff849ec2ccb635c2611e6ee 100644
--- a/src/ui/databrowserModule/fileviewer/fileviewer.component.ts
+++ b/src/ui/databrowserModule/fileviewer/fileviewer.component.ts
@@ -53,8 +53,6 @@ export class FileViewer implements OnChanges,OnDestroy,OnInit{
       switchMap(()=>from(new Promise((rs,rj)=>{
         if(!this.childChart)
           return rj('chart not defined after 500ms')
-        
-        debugger
         this.childChart.canvas.nativeElement.toBlob((blob)=>{
           blob ? rs(blob) : rj('blob is undefined')
           
diff --git a/src/ui/databrowserModule/util/filterDataEntriesByMethods.pipe.ts b/src/ui/databrowserModule/util/filterDataEntriesByMethods.pipe.ts
index 3e010621c216d8ec9846f8273b127beedc40e5c0..b6ffded850a9f1765b736142c2eb7a1071c6b44e 100644
--- a/src/ui/databrowserModule/util/filterDataEntriesByMethods.pipe.ts
+++ b/src/ui/databrowserModule/util/filterDataEntriesByMethods.pipe.ts
@@ -8,7 +8,7 @@ import { temporaryFilterDataentryName } from '../databrowser.service'
 
 export class FilterDataEntriesbyMethods implements PipeTransform{
   public transform(dataEntries:DataEntry[],showDataMethods:string[]):DataEntry[]{
-    return showDataMethods.length > 0
+    return dataEntries && showDataMethods && showDataMethods.length > 0
       ? dataEntries.filter(dataEntry => {
           return dataEntry.activity.some(a => a.methods.some(m => showDataMethods.findIndex(dm => dm === temporaryFilterDataentryName(m)) >= 0))
         })
diff --git a/src/ui/databrowserModule/util/filterDataEntriesByRegion.pipe.ts b/src/ui/databrowserModule/util/filterDataEntriesByRegion.pipe.ts
index 1924a87ccae557fbf348092dad369e1c7e67ce68..9c6208dcf613643f7618dcb3379a12a49de85c1c 100644
--- a/src/ui/databrowserModule/util/filterDataEntriesByRegion.pipe.ts
+++ b/src/ui/databrowserModule/util/filterDataEntriesByRegion.pipe.ts
@@ -7,7 +7,7 @@ import { DataEntry } from "src/services/stateStore.service";
 
 export class FilterDataEntriesByRegion implements PipeTransform{
   public transform(dataentries: DataEntry[], selectedRegions: any[]) {
-    return selectedRegions.length > 0
+    return dataentries && selectedRegions && selectedRegions.length > 0
       ? dataentries.filter(de => 
           de.parcellationRegion.some(pr => {
 
@@ -15,7 +15,7 @@ export class FilterDataEntriesByRegion implements PipeTransform{
              * TODO: temporary hack, some dataset region name is not exactly the same as region
              */
             /* https://stackoverflow.com/a/9310752/6059235 */
-            const regex = new RegExp(pr.name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'))
+            const regex = new RegExp(pr.name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'), 'i')
             return selectedRegions.some(sr => regex.test(sr.name))
             /**
              * more correct, but probably should use UUID in the future
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts
index b9215eadfef0737d0e0ccf48594e784f212350ae..0cb0bf48b152b3642fddc7aaee99185b500bdfd7 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.ts
@@ -756,6 +756,10 @@ export class NehubaContainer implements OnInit, OnDestroy{
         filter(results => results[1] === null),
         map(results => results[0])
       ).subscribe((region:any) => {
+        /**
+         * TODO
+         * region may have labelIndex as well as children
+         */
         this.selectedRegionIndexSet.has(region.labelIndex) ?
           this.store.dispatch({
             type : SELECT_REGIONS,
diff --git a/src/util/pipes/groupDataEntriesByRegion.pipe.ts b/src/util/pipes/groupDataEntriesByRegion.pipe.ts
index 6778b49808d0483a0a357ae417d5cbf89ae794ae..f4c326b4c253340fa04c819af0b637b85c974a60 100644
--- a/src/util/pipes/groupDataEntriesByRegion.pipe.ts
+++ b/src/util/pipes/groupDataEntriesByRegion.pipe.ts
@@ -5,8 +5,7 @@ import { DataEntry } from "../../services/stateStore.service";
   name : 'groupDatasetByRegion'
 })
 export class GroupDatasetByRegion implements PipeTransform{
-  public transform(datasets:DataEntry[], regions:any[]): {region:any|null,searchResults:DataEntry[]}[]
-  {
+  public transform(datasets:DataEntry[], regions:any[]): {region:any|null,searchResults:DataEntry[]}[]{
     
     return datasets.reduce((acc,curr)=>{
       return (curr.parcellationRegion && curr.parcellationRegion.length > 0)
diff --git a/src/util/worker.js b/src/util/worker.js
index 2d804bf5f8388c5b715655f97f74374bd5b6272d..ba6b1627b9adf00e861f08ba494594118bc0dc2b 100644
--- a/src/util/worker.js
+++ b/src/util/worker.js
@@ -1,5 +1,5 @@
-const validTypes = ['CHECK_MESHES', 'GET_LANDMARKS_VTK', 'GET_USERLANDMARKS_VTK']
-const validOutType = ['CHECKED_MESH', 'ASSEMBLED_LANDMARKS_VTK', 'ASSEMBLED_USERLANDMARKS_VTK']
+const validTypes = ['CHECK_MESHES', 'GET_LANDMARKS_VTK', 'GET_USERLANDMARKS_VTK', 'BUILD_REGION_SELECTION_TREE']
+const validOutType = ['CHECKED_MESH', 'ASSEMBLED_LANDMARKS_VTK', 'ASSEMBLED_USERLANDMARKS_VTK', 'RETURN_REBUILT_REGION_SELECTION_TREE']
 
 const checkMeshes = (action) => {
   
@@ -219,9 +219,42 @@ const getuserLandmarksVtk = (action) => {
   })
 }
 
+const rebuildSelectedRegion = (payload) => {
+  const { selectedRegions, regions } = payload
+
+  /**
+   * active tree branch
+   * branch is active if ALL children are active
+   */
+  const activeTreeBranch = []
+  const isRegionActive = (region) => selectedRegions.some(r => r.name === region.name)
+    || region.children && region.children.length > 0 && region.children.every(isRegionActive)
+  
+  /**
+   * some active tree branch
+   * branch is active if SOME children are active
+   */
+  const someActiveTreeBranch = []
+  const isSomeRegionActive = (region) => selectedRegions.some(r => r.name === region.name)
+    || region.children && region.children.length > 0 && region.children.some(isSomeRegionActive)
+
+  const handleRegion = (r) => {
+    isRegionActive(r) ? activeTreeBranch.push(r) : {}
+    isSomeRegionActive(r) ? someActiveTreeBranch.push(r) : {}
+    if (r.children && r.children.length > 0) 
+      r.children.forEach(handleRegion)
+  }
+  regions.forEach(handleRegion)
+  postMessage({
+    type: 'RETURN_REBUILT_REGION_SELECTION_TREE',
+    rebuiltSelectedRegions: activeTreeBranch,
+    rebuiltSomeSelectedRegions: someActiveTreeBranch
+  })
+}
+
 onmessage = (message) => {
   
-  if(validTypes.findIndex(type => type === message.data.type)>=0){
+  if(validTypes.findIndex(type => type === message.data.type) >= 0){
     switch(message.data.type){
       case 'CHECK_MESHES':
         checkMeshes(message.data)
@@ -232,6 +265,9 @@ onmessage = (message) => {
       case 'GET_USERLANDMARKS_VTK':
         getuserLandmarksVtk(message.data)
         return
+      case 'BUILD_REGION_SELECTION_TREE':
+        rebuildSelectedRegion(message.data)
+        return
       default:
         console.warn('unhandled worker action', message)
     }