11import { pubSubServiceInterface } from '@ohif/core' ;
2- import {
3- EVENTS as CS_EVENTS ,
4- eventTarget as CornerstoneEventTarget ,
5- getEnabledElement ,
6- cache ,
7- Enums as CSCORE_ENUMS
2+ import {
3+ EVENTS as CS_EVENTS ,
4+ eventTarget as CornerstoneEventTarget ,
5+ getEnabledElement ,
6+ cache ,
7+ Enums as CSCORE_ENUMS ,
88} from '@cornerstonejs/core' ;
99import { Enums as CSTOOLS_ENUMS } from '@cornerstonejs/tools' ;
1010
@@ -16,181 +16,173 @@ import {
1616import { getSegDisplaysetsOfReferencedImagesIds } from '../utils' ;
1717
1818const EVENTS = {
19- CROP_DISPLAY_AREA_INIT : 'event::gradienthealth::CropDisplayAreaService:init' ,
19+ CROP_DISPLAY_AREA_INIT : 'event::gradienthealth::CropDisplayAreaService:init' ,
2020} ;
2121
2222export default class CropDisplayAreaService {
23- private serviceManager ;
24- private listeners ;
25- public EVENTS ;
26-
27- constructor ( serviceManager ) {
28- this . serviceManager = serviceManager ;
29- this . listeners = { } ;
30- this . EVENTS = EVENTS ;
31- window . tf = tf ;
32- Object . assign ( this , pubSubServiceInterface ) ;
33- }
23+ private serviceManager ;
24+ private listeners ;
25+ public EVENTS ;
26+
27+ constructor ( serviceManager ) {
28+ this . serviceManager = serviceManager ;
29+ this . listeners = { } ;
30+ this . EVENTS = EVENTS ;
31+ window . tf = tf ;
32+ Object . assign ( this , pubSubServiceInterface ) ;
33+ }
3434
35- init ( ) {
36- CornerstoneEventTarget . addEventListener ( CS_EVENTS . STACK_VIEWPORT_NEW_STACK , ( evt ) => {
37- const { HangingProtocolService } = this . serviceManager . services
38- if ( HangingProtocolService . protocol . id === 'breast' ) this . handleBreastDensityHP ( evt )
39- } )
35+ init ( ) {
36+ CornerstoneEventTarget . addEventListener (
37+ CS_EVENTS . STACK_VIEWPORT_NEW_STACK ,
38+ ( evt ) => {
39+ const { HangingProtocolService } = this . serviceManager . services ;
40+ if ( HangingProtocolService . protocol . id === 'breast' )
41+ this . handleBreastDensityHP ( evt ) ;
42+ }
43+ ) ;
44+ }
45+
46+ private handleBreastDensityHP ( evt ) {
47+ const { HangingProtocolService, cornerstoneViewportService } =
48+ this . serviceManager . services ;
49+ const { element, viewportId } = evt . detail ;
50+ const enabledElement = getEnabledElement ( element ) ;
51+ const viewport = enabledElement ?. viewport ;
52+ if ( ! viewport ) return ;
53+
54+ const { voiRange, invert } = ( viewport as IStackViewport ) . getProperties ( ) ;
55+ const cutoff = invert ? voiRange ?. upper : voiRange ?. lower ;
56+ if ( cutoff === undefined || cutoff === null ) {
57+ return ;
4058 }
4159
42- private handleBreastDensityHP ( evt ) {
43- const { HangingProtocolService, cornerstoneViewportService } =
44- this . serviceManager . services ;
45- const { element, viewportId } = evt . detail ;
46- const enabledElement = getEnabledElement ( element ) ;
47- const viewport = enabledElement ?. viewport ;
48- if ( ! viewport ) return ;
49-
50- const { voiRange, invert } = ( viewport as IStackViewport ) . getProperties ( ) ;
51- let cutoff ;
52- if ( voiRange ?. lower && ! invert ) {
53- cutoff = voiRange ?. lower ;
54- }
55- if ( voiRange ?. upper && invert ) {
56- cutoff = voiRange ?. upper ;
57- }
58- if ( ! cutoff ) {
59- return ;
60- }
60+ const viewportInfo = cornerstoneViewportService . getViewportInfo ( viewportId ) ;
61+ const matchedDisplaySets = Array . from (
62+ HangingProtocolService . displaySetMatchDetails . values ( )
63+ ) ;
64+ const matchedDisplaySetIndex = matchedDisplaySets . findIndex (
65+ ( displayset ) =>
66+ displayset . displaySetInstanceUID ===
67+ viewportInfo . viewportData . data . displaySetInstanceUID
68+ ) ;
6169
62- const viewportInfo =
63- cornerstoneViewportService . getViewportInfo ( viewportId ) ;
64- const matchedDisplaySets = Array . from (
65- HangingProtocolService . displaySetMatchDetails . values ( )
66- ) ;
67- const matchedDisplaySetIndex = matchedDisplaySets . findIndex (
68- ( displayset ) =>
69- displayset . displaySetInstanceUID ===
70- viewportInfo . viewportData . data . displaySetInstanceUID
71- ) ;
70+ const matchedDisplaySetKeys = Array . from (
71+ HangingProtocolService . displaySetMatchDetails . keys ( )
72+ ) ;
73+ const matchedDisplaySet = matchedDisplaySetKeys [ matchedDisplaySetIndex ] ;
74+ if ( ! matchedDisplaySet ) return ;
75+
76+ const imageData = viewport . getImageData ( ) ;
77+ const scalarData = imageData ?. scalarData ;
78+ const dimensions = imageData ?. dimensions ;
79+ if ( ! scalarData || ! dimensions ) return ;
80+
81+ // probably will need to account for
82+ // imageData.direction
83+ // interesting that dim[1], dim[0] are reversed for vtk.js => tf.js
84+ // assume this direction does not change
85+ const { bboxWidth, bboxHeight, width, height } = tf . tidy ( ( ) => {
86+ const tensor = tf . tensor2d ( new Float32Array ( scalarData ) , [
87+ dimensions [ 1 ] ,
88+ dimensions [ 0 ] ,
89+ ] ) ;
90+ const mask = tensor . greater ( cutoff ) ; // get boolean
91+ const widthBool = mask . any ( 0 ) ; // height?
92+ const heightBool = mask . any ( 1 ) ; // width?
93+
94+ // get bbox
95+ const left = widthBool . argMax ( ) ;
96+ const right = widthBool . reverse ( ) . argMax ( ) . mul ( - 1 ) . add ( widthBool . size ) ;
97+ const top = heightBool . argMax ( ) ;
98+ const bottom = heightBool . reverse ( ) . argMax ( ) . mul ( - 1 ) . add ( heightBool . size ) ;
99+
100+ // get percentage difference in width and height
101+ const bboxWidth = right . sub ( left ) . dataSync ( ) [ 0 ] ;
102+ const bboxHeight = bottom . sub ( top ) . dataSync ( ) [ 0 ] ;
103+ const width = widthBool . size ;
104+ const height = heightBool . size ;
105+
106+ return {
107+ bboxWidth,
108+ bboxHeight,
109+ width,
110+ height,
111+ } ;
112+ } ) ;
72113
73- const matchedDisplaySetKeys = Array . from (
74- HangingProtocolService . displaySetMatchDetails . keys ( )
75- ) ;
76- const matchedDisplaySet = matchedDisplaySetKeys [ matchedDisplaySetIndex ] ;
77- if ( ! matchedDisplaySet ) return ;
78-
79- const imageData = viewport . getImageData ( ) ;
80- const scalarData = imageData ?. scalarData ;
81- const dimensions = imageData ?. dimensions ;
82- if ( ! scalarData || ! dimensions ) return ;
83-
84- // probably will need to account for
85- // imageData.direction
86- // interesting that dim[1], dim[0] are reversed for vtk.js => tf.js
87- // assume this direction does not change
88- const { bboxWidth, bboxHeight, width, height } = tf . tidy ( ( ) => {
89- const tensor = tf . tensor2d ( new Float32Array ( scalarData ) , [
90- dimensions [ 1 ] ,
91- dimensions [ 0 ] ,
92- ] ) ;
93- const mask = tensor . greater ( cutoff ) ; // get boolean
94- const widthBool = mask . any ( 0 ) ; // height?
95- const heightBool = mask . any ( 1 ) ; // width?
96-
97- // get bbox
98- const left = widthBool . argMax ( ) ;
99- const right = widthBool . reverse ( ) . argMax ( ) . mul ( - 1 ) . add ( widthBool . size ) ;
100- const top = heightBool . argMax ( ) ;
101- const bottom = heightBool
102- . reverse ( )
103- . argMax ( )
104- . mul ( - 1 )
105- . add ( heightBool . size ) ;
106-
107- // get percentage difference in width and height
108- const bboxWidth = right . sub ( left ) . dataSync ( ) [ 0 ] ;
109- const bboxHeight = bottom . sub ( top ) . dataSync ( ) [ 0 ] ;
110- const width = widthBool . size ;
111- const height = heightBool . size ;
112-
113- return {
114- bboxWidth,
115- bboxHeight,
116- width,
117- height,
118- } ;
119- } ) ;
120-
121- const bboxAspectRatio = bboxWidth / bboxHeight ;
122- const canvasAspectRatio = viewport . sWidth / viewport . sHeight ;
123- // console.log({bboxAspectRatio, canvasAspectRatio})
124- // if(bboxAspectRatio > canvasAspectRatio){
125- // bboxWidth = canvasAspectRatio*bboxHeight
126- // bboxAspectRatio = bboxWidth/bboxHeight
127- // console.log('changed', {bboxAspectRatio, canvasAspectRatio})
128- // }
129-
130- const bboxWidthPercentage = bboxWidth / width ; // add buffer
131- const bboxHeightPercentage = bboxHeight / height ;
132-
133- // TODO do not hard code, pick the max between bboxwidth and aspect ratio height
134- const areaZoom = bboxWidthPercentage ;
135- //const panAmount = (1 - areaZoom) / 2;
136-
137- if ( matchedDisplaySet === 'LMLO' ) {
138- viewport . setDisplayArea (
139- {
140- imageArea : [ areaZoom , areaZoom ] ,
141- imageCanvasPoint : {
142- canvasPoint : [ 0 , 0.5 ] ,
143- imagePoint : [ 0 , 0.5 ] ,
144- } ,
145- storeAsInitialCamera : true ,
114+ const bboxAspectRatio = bboxWidth / bboxHeight ;
115+ const canvasAspectRatio = viewport . sWidth / viewport . sHeight ;
116+ // console.log({bboxAspectRatio, canvasAspectRatio})
117+ // if(bboxAspectRatio > canvasAspectRatio){
118+ // bboxWidth = canvasAspectRatio*bboxHeight
119+ // bboxAspectRatio = bboxWidth/bboxHeight
120+ // console.log('changed', {bboxAspectRatio, canvasAspectRatio})
121+ // }
122+
123+ const bboxWidthPercentage = bboxWidth / width ; // add buffer
124+ const bboxHeightPercentage = bboxHeight / height ;
125+
126+ // TODO do not hard code, pick the max between bboxwidth and aspect ratio height
127+ const areaZoom = bboxWidthPercentage ;
128+ //const panAmount = (1 - areaZoom) / 2;
129+
130+ if ( matchedDisplaySet === 'LMLO' ) {
131+ viewport . setDisplayArea (
132+ {
133+ imageArea : [ areaZoom , areaZoom ] ,
134+ imageCanvasPoint : {
135+ canvasPoint : [ 0 , 0.5 ] ,
136+ imagePoint : [ 0 , 0.5 ] ,
146137 } ,
147- true
148- ) ;
149- }
150- if ( matchedDisplaySet === 'RMLO' ) {
151- viewport . setDisplayArea (
152- {
153- imageArea : [ areaZoom , areaZoom ] ,
154- imageCanvasPoint : {
155- canvasPoint : [ 1 , 0.5 ] ,
156- imagePoint : [ 1 , 0.5 ] ,
157- } ,
158- storeAsInitialCamera : true ,
138+ storeAsInitialCamera : true ,
139+ } ,
140+ true
141+ ) ;
142+ }
143+ if ( matchedDisplaySet === 'RMLO' ) {
144+ viewport . setDisplayArea (
145+ {
146+ imageArea : [ areaZoom , areaZoom ] ,
147+ imageCanvasPoint : {
148+ canvasPoint : [ 1 , 0.5 ] ,
149+ imagePoint : [ 1 , 0.5 ] ,
159150 } ,
151+ storeAsInitialCamera : true ,
152+ } ,
160153
161- true
162- ) ;
163- }
164- if ( matchedDisplaySet === 'LCC' ) {
165- viewport . setDisplayArea (
166- {
167- imageArea : [ areaZoom , areaZoom ] ,
168- imageCanvasPoint : {
169- canvasPoint : [ 0 , 0.5 ] ,
170- imagePoint : [ 0 , 0.5 ] ,
171- } ,
172- storeAsInitialCamera : true ,
154+ true
155+ ) ;
156+ }
157+ if ( matchedDisplaySet === 'LCC' ) {
158+ viewport . setDisplayArea (
159+ {
160+ imageArea : [ areaZoom , areaZoom ] ,
161+ imageCanvasPoint : {
162+ canvasPoint : [ 0 , 0.5 ] ,
163+ imagePoint : [ 0 , 0.5 ] ,
173164 } ,
174- true
175- ) ;
176- }
177- if ( matchedDisplaySet === 'RCC' ) {
178- viewport . setDisplayArea (
179- {
180- imageArea : [ areaZoom , areaZoom ] ,
181- imageCanvasPoint : {
182- canvasPoint : [ 1 , 0.5 ] ,
183- imagePoint : [ 1 , 0.5 ] ,
184- } ,
185- storeAsInitialCamera : true ,
165+ storeAsInitialCamera : true ,
166+ } ,
167+ true
168+ ) ;
169+ }
170+ if ( matchedDisplaySet === 'RCC' ) {
171+ viewport . setDisplayArea (
172+ {
173+ imageArea : [ areaZoom , areaZoom ] ,
174+ imageCanvasPoint : {
175+ canvasPoint : [ 1 , 0.5 ] ,
176+ imagePoint : [ 1 , 0.5 ] ,
186177 } ,
187- true
188- ) ;
189- }
178+ storeAsInitialCamera : true ,
179+ } ,
180+ true
181+ ) ;
190182 }
183+ }
191184
192- destroy ( ) {
193- }
185+ destroy ( ) { }
194186
195187 public async focusToSegment ( segmentationId , segmentIndex ) {
196188 const {
@@ -201,7 +193,9 @@ export default class CropDisplayAreaService {
201193 } = this . serviceManager . services ;
202194
203195 const segmentation = segmentationService . getSegmentation ( segmentationId ) ;
204- const segDisplayset = displaySetService . getDisplaySetByUID ( segmentation . displaySetInstanceUID ) ;
196+ const segDisplayset = displaySetService . getDisplaySetByUID (
197+ segmentation . displaySetInstanceUID
198+ ) ;
205199 if ( segDisplayset . Modality !== 'SEG' ) {
206200 return ;
207201 }
@@ -271,11 +265,16 @@ export default class CropDisplayAreaService {
271265 return { xMax, yMax, xMin, yMin } ;
272266 } ) ;
273267
274- const referencedDisplaySetInstanceUID = segDisplayset . referencedDisplaySetInstanceUID ;
268+ const referencedDisplaySetInstanceUID =
269+ segDisplayset . referencedDisplaySetInstanceUID ;
275270 const { viewports, activeViewportId } = viewportGridService . getState ( ) ;
276271 const viewportsWithSegmentation : IStackViewport | IVolumeViewport = [ ] ;
277272 viewports . forEach ( ( viewport ) => {
278- if ( viewport . displaySetInstanceUIDs . includes ( referencedDisplaySetInstanceUID ) ) {
273+ if (
274+ viewport . displaySetInstanceUIDs . includes (
275+ referencedDisplaySetInstanceUID
276+ )
277+ ) {
279278 viewportsWithSegmentation . push (
280279 cornerstoneViewportService . getCornerstoneViewport ( viewport . viewportId )
281280 ) ;
@@ -402,4 +401,4 @@ const correctZoomFactors = (
402401
403402 zoomFactors . x /= zoomOutPercentatage / 100 ;
404403 zoomFactors . y /= zoomOutPercentatage / 100 ;
405- } ;
404+ } ;
0 commit comments