diff --git a/src/atlasViewer/atlasViewer.apiService.service.spec.ts b/src/atlasViewer/atlasViewer.apiService.service.spec.ts
index e49cdacd44bb66b9690c1ac802a4e4c7fc275a40..846b29bd7c57d4ae34735873fa9029fb3ac2619d 100644
--- a/src/atlasViewer/atlasViewer.apiService.service.spec.ts
+++ b/src/atlasViewer/atlasViewer.apiService.service.spec.ts
@@ -76,6 +76,44 @@ describe('atlasViewer.apiService.service.ts', () => {
         })
       })
 
+      describe('> getUserToSelectRoi', () => {
+        it('> calling getUserToSelectRoi without spec throws error', () => {
+          const service = TestBed.inject(AtlasViewerAPIServices)
+          expect(() => {
+            service.interactiveViewer.uiHandle.getUserToSelectRoi('hello world')
+          }).toThrow()
+        })
+
+        it('> calling getUserToSelectRoi without spec.type throws', () => {
+          const service = TestBed.inject(AtlasViewerAPIServices)
+          expect(() => {
+            service.interactiveViewer.uiHandle.getUserToSelectRoi('hello world', { foo: 'bar' } as any)
+          }).toThrow()
+        })
+
+        it('> calling getUserToSelectRoi populates getUserToSelectRegion with malformed spec.type is fine', () => {
+          const service = TestBed.inject(AtlasViewerAPIServices)
+          expect(() => {
+            service.interactiveViewer.uiHandle.getUserToSelectRoi('hello world', { type: 'foobar' })
+          }).not.toThrow()
+        })
+        it('> calling getUserToSelectRoi populates getUserToSelectRegion', () => {
+
+          const service = TestBed.inject(AtlasViewerAPIServices)
+
+          const pr = service.interactiveViewer.uiHandle.getUserToSelectRoi('hello world', { type: 'POINT' })
+          
+          expect(service.getUserToSelectRegion.length).toEqual(1)
+          const { promise, message, spec, rs, rj } = service.getUserToSelectRegion[0]
+          expect(promise).toEqual(pr)
+          expect(message).toEqual('hello world')
+          expect(spec).toEqual({ type: 'POINT' })
+          
+          expect(rs).not.toBeFalsy()
+          expect(rj).not.toBeFalsy()
+        })
+      })
+
       describe('cancelPromise', () => {
         it('calling cancelPromise removes pr from getUsertoSelectRegion', done => {
 
@@ -243,9 +281,10 @@ describe('atlasViewer.apiService.service.ts', () => {
   describe('overrideNehubaClickFactory', () => {
 
     const OVERRIDE_NEHUBA_TOKEN = 'OVERRIDE_NEHUBA_TOKEN'
-    const MOCK_GET_MOUSEOVER_SEGMENTS_TOKEN = 'MOCK_GET_MOUSEOVER_SEGMENTS_TOKEN'
+    const MOCK_GET_STATE_SNAPSHOT_TOKEN = 'MOCK_GET_STATE_SNAPSHOT_TOKEN'
 
     let mockGetMouseOverSegments = []
+    let mousePositionReal = [1,2,3]
     
     afterEach(() => {
       mockGetMouseOverSegments = []
@@ -264,13 +303,22 @@ describe('atlasViewer.apiService.service.ts', () => {
             useFactory: overrideNehubaClickFactory,
             deps: [
               AtlasViewerAPIServices,
-              MOCK_GET_MOUSEOVER_SEGMENTS_TOKEN,
+              MOCK_GET_STATE_SNAPSHOT_TOKEN,
             ]
           },
           {
-            provide: MOCK_GET_MOUSEOVER_SEGMENTS_TOKEN,
+            provide: MOCK_GET_STATE_SNAPSHOT_TOKEN,
             useValue: () => {
-              return mockGetMouseOverSegments
+              return {
+                state: {
+                  uiState: {
+                    mouseOverSegments: mockGetMouseOverSegments
+                  }
+                },
+                other: {
+                  mousePositionReal
+                }
+              }
             }
           },
           {
@@ -288,142 +336,316 @@ describe('atlasViewer.apiService.service.ts', () => {
       expect(fn).not.toBeNull()
     })
 
-    it('by default, next fn will be called', () => {
-      const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
-      const nextSpy = jasmine.createSpy('next')
-      fn(nextSpy)
-      expect(nextSpy).toHaveBeenCalled()
-    })
+    describe('> if getUserToSelectRegion.length === 0', () => {
 
-    it('if both apiService.getUserToSelectRegion.length > 0 and mouseoverSegment.length >0, then next will not be called, but rs will be', () => {
-      const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
-      const apiService = TestBed.inject(AtlasViewerAPIServices)
-
-      const rsSpy = jasmine.createSpy('rs') 
-      const rjSpy = jasmine.createSpy('rj')
-      apiService.getUserToSelectRegion = [
-        {
-          message: 'test',
-          promise: null,
-          rs: rsSpy,
-          rj: rjSpy,
-        }
-      ]
-
-      const mockSegment = {
-        layer: {
-          name: 'apple'
-        },
-        segment: {
-          name: 'bananas'
-        }
-      }
-      mockGetMouseOverSegments = [ mockSegment ]
-      
-      const nextSpy = jasmine.createSpy('next')
-      fn(nextSpy)
-
-      expect(nextSpy).not.toHaveBeenCalled()
-      expect(rsSpy).toHaveBeenCalledWith(mockSegment)
-    })
+      it('by default, next fn will be called', () => {
+        const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+        const nextSpy = jasmine.createSpy('next')
+        fn(nextSpy)
+        expect(nextSpy).toHaveBeenCalled()
+      })
   
-    it('if apiService.getUserToSelectRegion.length === 0, and mouseoversegment.length > 0 calls next', () => {
-      const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
-
-      const mockSegment = {
-        layer: {
-          name: 'apple'
-        },
-        segment: {
-          name: 'bananas'
-        }
-      }
-      mockGetMouseOverSegments = [ mockSegment ]
-      
-      const nextSpy = jasmine.createSpy('next')
-      fn(nextSpy)
-
-      expect(nextSpy).toHaveBeenCalled()
-    })
-
-    it('if apiService.getUserToSelectRegion.length > 0, but mouseoversegment.length ===0, will not call next, will not rs, will not call rj', () => {
-      const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
-      const apiService = TestBed.inject(AtlasViewerAPIServices)
-
-      const rsSpy = jasmine.createSpy('rs') 
-      const rjSpy = jasmine.createSpy('rj')
-      apiService.getUserToSelectRegion = [
-        {
-          message: 'test',
-          promise: null,
-          rs: rsSpy,
-          rj: rjSpy,
+      it('if apiService.getUserToSelectRegion.length === 0, and mouseoversegment.length > 0 calls next', () => {
+        const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+  
+        const mockSegment = {
+          layer: {
+            name: 'apple'
+          },
+          segment: {
+            name: 'bananas'
+          }
         }
-      ]
-      
-      const nextSpy = jasmine.createSpy('next')
-      fn(nextSpy)
-
-      expect(rsSpy).not.toHaveBeenCalled()
-      expect(nextSpy).toHaveBeenCalled()
-      expect(rjSpy).not.toHaveBeenCalled()
+        mockGetMouseOverSegments = [ mockSegment ]
+        
+        const nextSpy = jasmine.createSpy('next')
+        fn(nextSpy)
+  
+        expect(nextSpy).toHaveBeenCalled()
+      })
     })
-    it('if muliple getUserToSelectRegion handler exists, it resolves in a FIFO manner', () => {
-      const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
-      const apiService = TestBed.inject(AtlasViewerAPIServices)
-
-      const rsSpy1 = jasmine.createSpy('rs1') 
-      const rjSpy1 = jasmine.createSpy('rj1')
-
-      const rsSpy2 = jasmine.createSpy('rs2') 
-      const rjSpy2 = jasmine.createSpy('rj2')
-      apiService.getUserToSelectRegion = [
-        {
-          message: 'test1',
-          promise: null,
-          rs: rsSpy1,
-          rj: rjSpy1,
-        },
-        {
-          message: 'test2',
-          promise: null,
-          rs: rsSpy2,
-          rj: rjSpy2,
+    describe('> if getUserToSelectRegion.length > 0', () => {
+      it('if both apiService.getUserToSelectRegion.length > 0 and mouseoverSegment.length >0, then next will not be called, but rs will be', () => {
+        const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+        const apiService = TestBed.inject(AtlasViewerAPIServices)
+  
+        const rsSpy = jasmine.createSpy('rs') 
+        const rjSpy = jasmine.createSpy('rj')
+        apiService.getUserToSelectRegion = [
+          {
+            message: 'test',
+            promise: null,
+            rs: rsSpy,
+            rj: rjSpy,
+          }
+        ]
+  
+        const mockSegment = {
+          layer: {
+            name: 'apple'
+          },
+          segment: {
+            name: 'bananas'
+          }
         }
-      ]
-      
-      const mockSegment = {
-        layer: {
-          name: 'apple'
-        },
-        segment: {
-          name: 'bananas'
+        mockGetMouseOverSegments = [ mockSegment ]
+        
+        const nextSpy = jasmine.createSpy('next')
+        fn(nextSpy)
+  
+        expect(nextSpy).not.toHaveBeenCalled()
+        expect(rsSpy).toHaveBeenCalledWith(mockSegment)
+      })
+      it('if multiple getUserToSelectRegion handler exists, it resolves in a LIFO manner', () => {
+        const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+        const apiService = TestBed.inject(AtlasViewerAPIServices)
+  
+        const rsSpy1 = jasmine.createSpy('rs1') 
+        const rjSpy1 = jasmine.createSpy('rj1')
+  
+        const rsSpy2 = jasmine.createSpy('rs2') 
+        const rjSpy2 = jasmine.createSpy('rj2')
+        apiService.getUserToSelectRegion = [
+          {
+            message: 'test1',
+            promise: null,
+            rs: rsSpy1,
+            rj: rjSpy1,
+          },
+          {
+            message: 'test2',
+            promise: null,
+            rs: rsSpy2,
+            rj: rjSpy2,
+          }
+        ]
+        
+        const mockSegment = {
+          layer: {
+            name: 'apple'
+          },
+          segment: {
+            name: 'bananas'
+          }
         }
-      }
-
-      mockGetMouseOverSegments = [ mockSegment ]
+  
+        mockGetMouseOverSegments = [ mockSegment ]
+  
+        const nextSpy1 = jasmine.createSpy('next1')
+        fn(nextSpy1)
+  
+        expect(rsSpy2).toHaveBeenCalledWith(mockSegment)
+        expect(rjSpy2).not.toHaveBeenCalled()
+  
+        expect(nextSpy1).not.toHaveBeenCalled()
+        expect(rsSpy1).not.toHaveBeenCalled()
+        expect(rjSpy1).not.toHaveBeenCalled()
+  
+        const nextSpy2 = jasmine.createSpy('next2')
+        fn(nextSpy2)
+  
+        expect(nextSpy2).not.toHaveBeenCalled()
+        expect(rsSpy1).toHaveBeenCalledWith(mockSegment)
+        expect(rjSpy1).not.toHaveBeenCalled()
+  
+        const nextSpy3 = jasmine.createSpy('next3')
+        fn(nextSpy3)
+  
+        expect(nextSpy3).toHaveBeenCalled()
+      })
 
-      const nextSpy1 = jasmine.createSpy('next1')
-      fn(nextSpy1)
+      describe('> if spec is not set (defaults to parcellation region mode)', () => {
 
-      expect(rsSpy2).toHaveBeenCalledWith(mockSegment)
-      expect(rjSpy2).not.toHaveBeenCalled()
+        it('if apiService.getUserToSelectRegion.length > 0, but mouseoversegment.length ===0, will not call next, will not rs, will not call rj', () => {
+          const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+          const apiService = TestBed.inject(AtlasViewerAPIServices)
+    
+          const rsSpy = jasmine.createSpy('rs') 
+          const rjSpy = jasmine.createSpy('rj')
+          apiService.getUserToSelectRegion = [
+            {
+              message: 'test',
+              promise: null,
+              rs: rsSpy,
+              rj: rjSpy,
+            }
+          ]
+          
+          const nextSpy = jasmine.createSpy('next')
+          fn(nextSpy)
+    
+          expect(rsSpy).not.toHaveBeenCalled()
+          expect(nextSpy).toHaveBeenCalled()
+          expect(rjSpy).not.toHaveBeenCalled()
+        })
+      })
 
-      expect(nextSpy1).not.toHaveBeenCalled()
-      expect(rsSpy1).not.toHaveBeenCalled()
-      expect(rjSpy1).not.toHaveBeenCalled()
+      describe('> if spec is set', () => {
+        describe('> if spec is set to PARCELLATION_REGION', () => {
 
-      const nextSpy2 = jasmine.createSpy('next2')
-      fn(nextSpy2)
+          it('> mouseoversegment.length === 0, will not call next, will not rs, will not call rj', () => {
+            const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+            const apiService = TestBed.inject(AtlasViewerAPIServices)
+      
+            const rsSpy = jasmine.createSpy('rs') 
+            const rjSpy = jasmine.createSpy('rj')
+            apiService.getUserToSelectRegion = [
+              {
+                message: 'test',
+                promise: null,
+                spec: {
+                  type: 'PARCELLATION_REGION'
+                },
+                rs: rsSpy,
+                rj: rjSpy,
+              }
+            ]
+            
+            const nextSpy = jasmine.createSpy('next')
+            fn(nextSpy)
+      
+            expect(rsSpy).not.toHaveBeenCalled()
+            expect(nextSpy).toHaveBeenCalled()
+            expect(rjSpy).not.toHaveBeenCalled()
+          })
+          
+          it('> mouseoversegment.length > 0, will not call next, will call rs', () => {
+            const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+            const apiService = TestBed.inject(AtlasViewerAPIServices)
+      
+            const mockSegment = {
+              layer: {
+                name: 'apple'
+              },
+              segment: {
+                name: 'bananas'
+              }
+            }
+            mockGetMouseOverSegments = [ mockSegment ]
 
-      expect(nextSpy2).not.toHaveBeenCalled()
-      expect(rsSpy1).toHaveBeenCalledWith(mockSegment)
-      expect(rjSpy1).not.toHaveBeenCalled()
+            const rsSpy = jasmine.createSpy('rs') 
+            const rjSpy = jasmine.createSpy('rj')
+            apiService.getUserToSelectRegion = [
+              {
+                message: 'test',
+                promise: null,
+                spec: {
+                  type: 'PARCELLATION_REGION'
+                },
+                rs: rsSpy,
+                rj: rjSpy,
+              }
+            ]
+            
+            const nextSpy = jasmine.createSpy('next')
+            fn(nextSpy)
+      
+            expect(rsSpy).toHaveBeenCalled()
+            expect(nextSpy).not.toHaveBeenCalled()
+            expect(rjSpy).not.toHaveBeenCalled()
+          })
+        })
 
-      const nextSpy3 = jasmine.createSpy('next3')
-      fn(nextSpy3)
+        describe('> if spec is set to POINT', () => {
+          it('> rs is called if mouseoversegment.length === 0', () => {
+            const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+            const apiService = TestBed.inject(AtlasViewerAPIServices)
+      
+            const rsSpy = jasmine.createSpy('rs') 
+            const rjSpy = jasmine.createSpy('rj')
+            apiService.getUserToSelectRegion = [
+              {
+                message: 'test',
+                promise: null,
+                spec: {
+                  type: 'POINT'
+                },
+                rs: rsSpy,
+                rj: rjSpy,
+              }
+            ]
+            
+            const nextSpy = jasmine.createSpy('next')
+            fn(nextSpy)
+      
+            expect(rsSpy).toHaveBeenCalled()
+            expect(nextSpy).not.toHaveBeenCalled()
+            expect(rjSpy).not.toHaveBeenCalled()
+          })
+          it('> rs is called with correct arg if mouseoversegment.length > 0', () => {
+            const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+            const apiService = TestBed.inject(AtlasViewerAPIServices)
+      
+            const rsSpy = jasmine.createSpy('rs') 
+            const rjSpy = jasmine.createSpy('rj')
+            apiService.getUserToSelectRegion = [
+              {
+                message: 'test',
+                promise: null,
+                spec: {
+                  type: 'POINT'
+                },
+                rs: rsSpy,
+                rj: rjSpy,
+              }
+            ]
+            
+            const nextSpy = jasmine.createSpy('next')
+            fn(nextSpy)
+      
+            expect(rsSpy).toHaveBeenCalledWith({
+              type: 'POINT',
+              payload: mousePositionReal
+            })
+            expect(nextSpy).not.toHaveBeenCalled()
+            expect(rjSpy).not.toHaveBeenCalled()
+          })
+        })
 
-      expect(nextSpy3).toHaveBeenCalled()
+        describe('> if multiple getUserToSelectRegion exist', () => {
+          it('> only the last Promise will be evaluated', () => {
+            const fn = TestBed.inject(OVERRIDE_NEHUBA_TOKEN as any) as (next: () => void) => void
+            const apiService = TestBed.inject(AtlasViewerAPIServices)
+      
+            const rsSpy1 = jasmine.createSpy('rs1') 
+            const rjSpy1 = jasmine.createSpy('rj1')
+      
+            const rsSpy2 = jasmine.createSpy('rs2') 
+            const rjSpy2 = jasmine.createSpy('rj2')
+            apiService.getUserToSelectRegion = [
+              {
+                message: 'test1',
+                promise: null,
+                spec: {
+                  type: 'POINT'
+                },
+                rs: rsSpy1,
+                rj: rjSpy1,
+              },
+              {
+                message: 'test2',
+                promise: null,
+                spec: {
+                  type: 'PARCELLATION_REGION'
+                },
+                rs: rsSpy2,
+                rj: rjSpy2,
+              }
+            ]
+      
+            const nextSpy1 = jasmine.createSpy('next1')
+            fn(nextSpy1)
+      
+            expect(rsSpy2).not.toHaveBeenCalled()
+            expect(rjSpy2).not.toHaveBeenCalled()
+      
+            expect(nextSpy1).toHaveBeenCalled()
+            expect(rsSpy1).not.toHaveBeenCalled()
+            expect(rjSpy1).not.toHaveBeenCalled()
+      
+          })
+        })
+      })
     })
   })
 })
diff --git a/src/atlasViewer/atlasViewer.apiService.service.ts b/src/atlasViewer/atlasViewer.apiService.service.ts
index 8aa0c991a4d648a1d990b73eb8021f2dddb5aeb7..60640949036f453d1cabb41e94515b0a68f02729 100644
--- a/src/atlasViewer/atlasViewer.apiService.service.ts
+++ b/src/atlasViewer/atlasViewer.apiService.service.ts
@@ -24,6 +24,7 @@ interface IRejectUserInput{
 interface IGetUserSelectRegionPr{
   message: string
   promise: Promise<any>
+  spec?: ICustomRegionSpec
   rs: (region: any) => void
   rj: (reject: IRejectUserInput) => void
 }
@@ -60,15 +61,20 @@ export class AtlasViewerAPIServices implements OnDestroy{
   public getUserToSelectRegion: IGetUserSelectRegionPr[] = []
   public getUserToSelectRegionUI$: Subject<IGetUserSelectRegionPr[]> = new Subject()
 
-  public getUserRegionSelectHandler: () => IGetUserSelectRegionPr = () => {
+  public getNextUserRegionSelectHandler: () => IGetUserSelectRegionPr = () => {
     if (this.getUserToSelectRegion.length > 0) {
-      const handler =  this.getUserToSelectRegion.pop()
-      this.getUserToSelectRegionUI$.next([...this.getUserToSelectRegion])
-      return handler
+      return this.getUserToSelectRegion[this.getUserToSelectRegion.length - 1]
     } 
     else return null
   }
 
+  public popUserRegionSelectHandler = () => {
+    if (this.getUserToSelectRegion.length > 0) {
+      this.getUserToSelectRegion.pop()
+      this.getUserToSelectRegionUI$.next([...this.getUserToSelectRegion])
+    } 
+  }
+
   private s: Subscription[] = []
 
   constructor(
@@ -217,8 +223,32 @@ export class AtlasViewerAPIServices implements OnDestroy{
         getUserConfirmation: config => this.dialogService.getUserConfirm(config),
 
         getUserToSelectARegion: message => {
+          console.warn(`interactiveViewer.uiHandle.getUserToSelectARegion is becoming deprecated. Use getUserToSelectRoi instead`)
+          const obj = {
+            message,
+            promise: null,
+            rs: null,
+            rj: null
+          }
+          const pr = new Promise((rs, rj) => {
+            obj.rs = rs
+            obj.rj = rj
+          })
+
+          obj.promise = pr
+
+          this.getUserToSelectRegion.push(obj)
+          this.getUserToSelectRegionUI$.next([...this.getUserToSelectRegion])
+          this.zone.run(() => {
+
+          })
+          return pr
+        },
+        getUserToSelectRoi: (message: string, spec: ICustomRegionSpec) => {
+          if (!spec || !spec.type) throw new Error(`spec.type must be defined for getUserToSelectRoi`)
           const obj = {
             message,
+            spec,
             promise: null,
             rs: null,
             rj: null
@@ -331,7 +361,8 @@ export interface IInteractiveViewerInterface {
     getUserInput: (config: IGetUserInputConfig) => Promise<string>
     getUserConfirmation: (config: IGetUserConfirmation) => Promise<any>
     getUserToSelectARegion: (selectingMessage: any) => Promise<any>
-    cancelPromise: (pr) => void
+    getUserToSelectRoi: (selectingMessage: string, spec?: ICustomRegionSpec) => Promise<any>
+    cancelPromise: (pr: Promise<any>) => void
   }
 
   pluginControl: {
@@ -355,16 +386,63 @@ export interface IUserLandmark {
   name: string
   position: [number, number, number]
   id: string /* probably use the it to track and remove user landmarks */
-  highlight: boolean
+  color: [ number, number, number ]
+}
+
+export enum EnumCustomRegion{
+  POINT = 'POINT',
+  PARCELLATION_REGION = 'PARCELLATION_REGION',
 }
 
-export const overrideNehubaClickFactory = (apiService: AtlasViewerAPIServices, getMouseoverSegments: () => any [] ) => {
+export interface ICustomRegionSpec{
+  type: string // type of EnumCustomRegion
+}
+
+export const overrideNehubaClickFactory = (apiService: AtlasViewerAPIServices, getState: () => any ) => {
   return (next: () => void) => {
-    const moSegments = getMouseoverSegments()
-    if (!!moSegments && Array.isArray(moSegments) && moSegments.length > 0) {
-      const { rs } = apiService.getUserRegionSelectHandler() || {}
-      if (!!rs) {
-        return rs(moSegments[0])
+    const { state, other } = getState()
+    const moSegments = state?.uiState?.mouseOverSegments
+    const { mousePositionReal } = other || {}
+    const { rs, spec } = apiService.getNextUserRegionSelectHandler() || {}
+    if (!!rs) {
+
+      /**
+       * getROI api
+       */
+      if (spec) {
+
+        /**
+         * if spec of overwrite click is for a point
+         */
+        if (spec.type === EnumCustomRegion.POINT) {
+          apiService.popUserRegionSelectHandler()
+          return rs({
+            type: spec.type,
+            payload: mousePositionReal
+          })
+        }
+
+        /**
+         * if spec of overwrite click is for a point
+         */
+        if (spec.type === EnumCustomRegion.PARCELLATION_REGION) {
+          if (!!moSegments && Array.isArray(moSegments) && moSegments.length > 0) {
+            apiService.popUserRegionSelectHandler()
+            return rs({
+              type: spec.type,
+              payload: moSegments
+            })
+          }
+        }
+      } else {
+        /**
+         * selectARegion API
+         * TODO deprecate
+         */
+        if (!!moSegments && Array.isArray(moSegments) && moSegments.length > 0) {
+          apiService.popUserRegionSelectHandler()
+          return rs(moSegments[0])
+        }
       }
     }
     next()
diff --git a/src/main.module.ts b/src/main.module.ts
index be401e8923810618d16b6bae7e6a5413e241b61d..51e875ff0926cbfba5f0d487c1b93b4786a11773 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -1,6 +1,6 @@
 import { DragDropModule } from '@angular/cdk/drag-drop'
 import { CommonModule } from "@angular/common";
-import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
+import { CUSTOM_ELEMENTS_SCHEMA, NgModule, InjectionToken } from "@angular/core";
 import { FormsModule } from "@angular/forms";
 import { StoreModule, Store, ActionReducer } from "@ngrx/store";
 import { AngularMaterialModule } from 'src/ui/sharedModules/angularMaterial.module'
@@ -38,7 +38,7 @@ import { UtilModule } from "src/util";
 import { SpotLightModule } from 'src/spotlight/spot-light.module'
 import { TryMeComponent } from "./ui/tryme/tryme.component";
 import { MouseHoverDirective, MouseOverIconPipe, MouseOverTextPipe } from "./atlasViewer/mouseOver.directive";
-import { UiStateUseEffect, getMouseoverSegmentsFactory, GET_MOUSEOVER_SEGMENTS_TOKEN } from "src/services/state/uiState.store";
+import { UiStateUseEffect } from "src/services/state/uiState.store";
 import { AtlasViewerHistoryUseEffect } from "./atlasViewer/atlasViewer.history.service";
 import { PluginServiceUseEffect } from './services/effect/pluginUseEffect';
 import { TemplateCoordinatesTransformation } from "src/services/templateCoordinatesTransformation.service";
@@ -56,6 +56,7 @@ import 'src/res/css/version.css'
 import 'src/theme.scss'
 import { DatasetPreviewGlue, datasetPreviewMetaReducer, IDatasetPreviewGlue, GlueEffects } from './glue';
 import { viewerStateHelperReducer, viewerStateFleshOutDetail, viewerStateMetaReducers, ViewerStateHelperEffect } from './services/state/viewerState.store.helper';
+import { take } from 'rxjs/operators';
 
 export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
   return function(state, action) {
@@ -65,7 +66,8 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
     return reducer(state, action);
   };
 }
- 
+
+export const GET_STATE_SNAPSHOT_TOKEN = new InjectionToken('GET_STATE_SNAPSHOT_TOKEN')
 
 @NgModule({
   imports : [
@@ -155,12 +157,30 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
       useFactory: overrideNehubaClickFactory,
       deps: [
         AtlasViewerAPIServices,
-        GET_MOUSEOVER_SEGMENTS_TOKEN
+        GET_STATE_SNAPSHOT_TOKEN
       ]
     },
     {
-      provide: GET_MOUSEOVER_SEGMENTS_TOKEN,
-      useFactory: getMouseoverSegmentsFactory,
+      provide: GET_STATE_SNAPSHOT_TOKEN,
+      useFactory: (store: Store<any>) => {
+        return () => {
+          const other: any = {}
+          let state
+          // rather than commiting mousePositionReal in state via action, do a single subscription instead.
+          // otherwise, the state gets updated way too often
+          if (window && (window as any).nehubaViewer) {
+            (window as any).nehubaViewer.mousePosition.inRealSpace
+              .take(1)
+              .subscribe(floatArr => {
+                other.mousePositionReal = floatArr && Array.from(floatArr).map((val: number) => val / 1e6)
+              })
+          }
+          store.pipe(
+            take(1)
+          ).subscribe(v => state = v)
+          return { state, other }
+        }
+      },
       deps: [ Store ]
     },
     {
diff --git a/src/plugin_examples/plugin_api.md b/src/plugin_examples/plugin_api.md
index f2860cdee059fda4503534d222a99f41b6146112..425daa034f1679b47c29ddeadcc6e53e9d5d7389 100644
--- a/src/plugin_examples/plugin_api.md
+++ b/src/plugin_examples/plugin_api.md
@@ -166,18 +166,45 @@ window.interactiveViewer
   }
   ```
   - *getUserToSelectARegion(message)* returns a `Promise`
+  
+    **To be deprecated**
+
+    _input_
+    
+    | input | type | desc |
+    | --- | --- | --- |
+    | message | `string` | human readable message displayed to the user | 
+    | spec.type | `'POINT'` `'PARCELLATION_REGION'` **default** | type of region to be returned. |
+
+    _returns_
+
+    `Promise`, resolves to return array of region clicked, rejects with error object `{ userInitiated: boolean }`
+    
+    Requests user to select a region of interest. Resolving to the region selected by the user. Rejects if either user cancels by pressing `Esc` or `Cancel`, or by developer calling `cancelPromise`
+
+  - *getUserToSelectRoi(message, spec)* returns a `Promise`
 
     _input_
     
     | input | type | desc |
     | --- | --- | --- |
     | message | `string` | human readable message displayed to the user | 
+    | spec.type | `POINT` `PARCELLATION_REGION` | type of ROI to be returned. |
 
     _returns_
 
-    `Promise`, resolves to return `RegionSelectedByUser`, rejects with error object `{ userInitiated: boolean }`
+    `Promise`
+    
+    **resolves**: return `{ type, payload }`. `type` is the same as `spec.type`, and `payload` differs depend on the type requested:
+    
+    | type | payload | example |
+    | --- | --- | --- |
+    | `POINT` | array of number in mm | `[12.2, 10.1, -0.3]` |
+    | `PARCELLATION_REGOIN` | non empty array of region selected | `[{ "layer": { "name" : " viewer specific layer name " }, "segment": {} }]` |
+    
+    **rejects**: with error object `{ userInitiated: boolean }`
     
-    Requests user to select a parcellation region, displaying the message. Resolving to the region selected by the user. Rejects if either user cancels by pressing `Esc` or `Cancel`, or by developer calling `cancelPromise`
+    Requests user to select a region of interest. If the `spec.type` input is missing, it is assumed to be `'PARCELLATION_REGION'`. Resolving to the region selected by the user. Rejects if either user cancels by pressing `Esc` or `Cancel`, or by developer calling `cancelPromise`
   
   - *cancelPromise(promise)* returns `void`
   
diff --git a/src/services/state/uiState.store.spec.ts b/src/services/state/uiState.store.spec.ts
index 3ee389e6ade78280cd3ac84fbc0991180dc924a2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/src/services/state/uiState.store.spec.ts
+++ b/src/services/state/uiState.store.spec.ts
@@ -1,65 +0,0 @@
-import { TestBed, async } from "@angular/core/testing"
-import { Component, Inject } from "@angular/core"
-import { getMouseoverSegmentsFactory } from "./uiState.store"
-import { Store } from "@ngrx/store"
-import { provideMockStore } from "@ngrx/store/testing"
-import { defaultRootState } from "../stateStore.service"
-
-const INJECTION_TOKEN = `INJECTION_TOKEN`
-
-@Component({
-  template: ''
-})
-class TestCmp{
-  constructor(
-    @Inject(INJECTION_TOKEN) public getMouseoverSegments: Function
-  ){
-
-  }
-}
-
-const dummySegment = {
-  layer: {
-    name: 'apple'
-  },
-  segment: {
-    hello: 'world'
-  }
-}
-
-describe('getMouseoverSegmentsFactory', () => {
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      declarations: [
-        TestCmp
-      ],
-      providers: [
-        {
-          provide: INJECTION_TOKEN,
-          useFactory: getMouseoverSegmentsFactory,
-          deps: [ Store ]
-        },
-        provideMockStore({
-          initialState: {
-            ...defaultRootState,
-            uiState: {
-              ...defaultRootState.uiState,
-              mouseOverSegments: [ dummySegment ]
-            }
-          }
-        })
-      ]
-    }).compileComponents()
-  }))
-
-  it('should compile component', () => {
-    const fixture = TestBed.createComponent(TestCmp)
-    expect(fixture).toBeTruthy()
-  })
-
-  it('function should return dummy segment', () => {
-    const fixutre = TestBed.createComponent(TestCmp)
-    const result = fixutre.componentInstance.getMouseoverSegments()
-    expect(result).toEqual([dummySegment])
-  })
-})
\ No newline at end of file
diff --git a/src/services/state/uiState.store.ts b/src/services/state/uiState.store.ts
index 68ea3630fcc45e031addf8ce6dae518de5fc4603..a3969dd32db093e163891ac794ce2f4c0efa5041 100644
--- a/src/services/state/uiState.store.ts
+++ b/src/services/state/uiState.store.ts
@@ -192,20 +192,6 @@ export interface ActionInterface extends Action {
   payload: any
 }
 
-export const GET_MOUSEOVER_SEGMENTS_TOKEN = `GET_MOUSEOVER_SEGMENTS_TOKEN`
-
-export const getMouseoverSegmentsFactory = (store: Store<IavRootStoreInterface>) => {
-  return () => {
-    let moSegments
-    store.pipe(
-      select('uiState'),
-      select('mouseOverSegments'),
-      take(1)
-    ).subscribe(v => moSegments = v)
-    return moSegments
-  }
-}
-
 @Injectable({
   providedIn: 'root',
 })