[go: up one dir, main page]

0% found this document useful (0 votes)
58 views9 pages

First Aid For PRIDE Programming

first aide pride

Uploaded by

tungolcild
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
58 views9 pages

First Aid For PRIDE Programming

first aide pride

Uploaded by

tungolcild
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 9

Internal Use

First Aid for PRIDE Programming

MR - Software / PRIDE

AUTHOR: A.M.C. van Muiswinkel


DOC. ID: XJS155-7905
REV. LEVEL: 0.1
DATE: 02-05-2002
STATUS: Authorized

Doc.file: 539271304.doc

Draft: Reviewers: You will be invited for a review meeting.


Commentators: Comments within 2 weeks to author.

Concept: Reviewers: Comments within 2 weeks to author.

Authorized: This is your personal copy. Destroy all previous levels

Philips Medical Systems

TRAD Philips’ proprietary,  2002 Philips Electronics N.V. All rights reserved
XJS155-7905 / 0.1 First Aid for PRIDE Programming Page 2 of 9
MR - Software Internal use 02-05-2002

1. How to get a specific image with PRIDE/IDL from Intera/Disk


on my screen?
Use this document while starting the development of a new PRIDE application. It describes the actions
needed to build a GUI, select and display data, interactive windowing and finally quit the application.
The files that should be used together with this document are rw_standard_functions, your_application_rest
and your_application_ui, this files all resist in the directory: your_application.
The contents of the your_application files are also displayed in Appendix A and B.

1.1. Create UI entries


Create UI entries for the selection of data from a local Disk or directly from the Intera Scanner. The
following code creates an entry with two sub-entries in the menu bar.

; create the top-UI


application_name = ‘Your Application’
top_wid = WIDGET_BASE(COLUMN=2, TITLE=application_name, $
XOFFSET = 0, YOFFSET = 0, MBAR=bar, KILL_NOTIFY='rw_kill_cb')

; Fill the menu bar


data_menu = WIDGET_BUTTON(bar, VALUE='File', /MENU)
db_disk_wid = WIDGET_BUTTON(data_menu, $
VALUE='Data From Disk', EVENT_PRO='rw_select_new_series_cb')
db_intera_wid = WIDGET_BUTTON(data_menu, $
VALUE='Data From Intera', EVENT_PRO='rw_select_new_series_cb')

Create an info structure, with at least the following parameters, connected to the UI.
; Create an "INFO" structure for program info. Store in top widget.
application_name = ‘Title of the application’

info = { application_name: application_name, $; Name of the application


db_intera_wid: db_intera_wid, $; DB Intera widget (used in: db_select_new_series_cb)
dmi_connection: OBJ_NEW(), $; DMI Connection when Intera DB is used
image_aptr: PTR_NEW(), $; image array ( all images )
read_bulk: 0, $; read bulk data when selecting images (0=no, 1=yes)
series_present: 0, $; Is there a dataset current
series_object: OBJ_NEW(), $; the current series object
top_wid: top_wid} ; The top level widget

; Move the info structure into the top level widget.


WIDGET_CONTROL, top_wid, SET_UVALUE=info, /NO_COPY

1.2. Open connection (Intera or Disk)


Don’t change the following functions: rw_select_new_series_cb , rw_select_dmi_database and rw_read_data. The
complete functions are present in rw_standard_functions.

1.3. Fill some usefull parameters, including the image attributes


Immediately after selecting new data the following function is called, which needs to be adapted to the application.
Don’t change the name of this function, it is called from rw_select_new_series_cb directly.
PRO db_update_for_new_data, info
; update sliders
; erase old images, old info, etc.
; fill GUI with the new data (or empty if no data is selected)
; etc.

TRAD Philips’ proprietary, © 2002 Philips Electronics N.V. All rights reserved
XJS155-7905 / 0.1 First Aid for PRIDE Programming Page 3 of 9
MR - Software Internal use 02-05-2002

END

1.4. Find an image index using the image keys


Use the image keys to find the index of a specific image in the current read series. This index can then be
used to actually get the image. (see next paragraph)
; Get all image keys
keys = *(info.series_object->get_image_key_list())

As an example we are looking for the index of ‘dynamic 9’


index = WHERE (keys.dynamic EQ 9)
The value of index[0] can now be –1 (no slice 9 present), one positive value (exactly one image for slice 9
present), or an array with positive values (multiple images for slice 9 present).

A more complex example: ‘Echo 2 of slice 3’


index = WHERE ((keys.echo EQ 2) AND (keys.slice EQ 3))

Check the index


IF ( index[0] NE –1 ) THEN BEGIN
; the image index has been found
; continue with next paragraph.
END

1.5. Scaling/windowing of an image


Choose an image ‘index’, range from 0 to number of images – 1.
; get the pixel values (image), read some attributes, convert to external values (image2)
image = *(((*info.image_aptr)[index])->get_pixmap())
im_attr = *(((*info.image_aptr)[index])->get_attributes())
image2 = image*im_attr.rescale_slope + im_attr.rescale_intercept

; Scale the image using the window center, width, rescale-slope


center = im_attr.window_center
width = im_attr.window_width
image3 = BYTSCL(image2, MIN=center - 0.5*width , MAX=center + 0.5*width )

; Resize to size of the viewport (REBIN or CONGRID)


image4 = REBIN(image3, 256, 256)

TV, image4, /ORDER

1.6. Interactive windowing of an image


To use interactive windowing (=changing windowing with the right mouse button) do the following. Add
some parameters to the info structure:
info.prev_position: [0,0], $; previous position of the mouse
info.button_down: 0, $; right button pressed
info.window_width: 2, $; window width
info.window_center: 2, $: window center
Call your event_handler (at the end of defining the general application GUI):
; Hand control of the GUI over the the XManager.
XMANAGER, info.application_name, top_wid, $
EVENT_HANDLER = 'your_event_handler', /NO_BLOCK

Add you event_handler to your code, fill in the part for re-display of the images.

TRAD Philips’ proprietary, © 2002 Philips Electronics N.V. All rights reserved
XJS155-7905 / 0.1 First Aid for PRIDE Programming Page 4 of 9
MR - Software Internal use 02-05-2002

Copy rw_event_handler from rw_standard_files, rename it to your_event_handler (or something smarter),


and add the part where the images will be re_displayed.

1.7. Exit: free DB and memory


UI entries for exit: rw_kill_cb in top_wid (for pressing the ‘x’ in the right upper corner) and
rw_quit_application_cb (for pressing an official ‘quit’ button):

quit = WIDGET_BUTTON(data_menu, VALUE='Quit',


EVENT_PRO='rw_quit_application_cb')

The two callback functions that belong to quiting (rw_kill_cb, rw_quit_application_cb) are present in
rw_standard_functions

Check if all memory is free by pressing ‘Ctrl-R’ after quiting the application. No memory messages may
appear in the debug window. Examples of ‘wrong’ messages:

<PtrHeapVar8180>
OBJREF = Array[150]
<PtrHeapVar8182>
STRUCT = -> IMAGE_KEY_STRUCT Array[150]
<PtrHeapVar8185>
FLOAT = Array[256, 256]

If some memory is still allocated some lines could be added to rw_kill_cb…

TRAD Philips’ proprietary, © 2002 Philips Electronics N.V. All rights reserved
XJS155-7905 / 0.1 First Aid for PRIDE Programming Page 5 of 9
MR - Software Internal use 02-05-2002

Appendix A.

;+
; NAME:
; your_application_rest (Local function prefix: rest)
;

;-------------------------------------------------------------------------------
; Update the GUI and the info structure for the new data
; This function is called when new data is selected (or no data selected)
; name of this function can not be changed. It is called from within:
; rw_standard_functions.
;-------------------------------------------------------------------------------
PRO db_update_for_new_data, info

ok = info.series_present

; Erase possible images on the viewport.


WSET, info.draw_area_idx
ERASE

IF (ok ) THEN BEGIN


; Set other parameters
info.window_width = 0
info.window_center = 0

; Show first image


rest_show_image, info
END
END

; show the first image from the dataset


PRO rest_show_image, info
IF ( info.series_present ) THEN BEGIN
index = 0 ; or any other image index

; get the pixel values (image), read some attributes,


; convert to external values (image2)
image = *(((*info.image_aptr)[index])->get_pixmap())
im_attr = *(((*info.image_aptr)[index])->get_attributes())
IF ( info.window_width EQ 0 ) THEN BEGIN
; get new window values from the database
info.window_center = im_attr.window_center
info.window_width = im_attr.window_width
END
image2 = image*im_attr.rescale_slope + im_attr.rescale_intercept

; Scale the image using the window center, width


center = info.window_center
width = info.window_width
image3 = BYTSCL(image2, MIN=center - 0.5*width , MAX=center + 0.5*width )

; Resize to size of the viewport (REBIN or CONGRID)


image4 = REBIN(image3, 256, 256)

TV, image4, /ORDER


END

TRAD Philips’ proprietary, © 2002 Philips Electronics N.V. All rights reserved
XJS155-7905 / 0.1 First Aid for PRIDE Programming Page 6 of 9
MR - Software Internal use 02-05-2002

END

TRAD Philips’ proprietary, © 2002 Philips Electronics N.V. All rights reserved
XJS155-7905 / 0.1 First Aid for PRIDE Programming Page 7 of 9
MR - Software Internal use 02-05-2002

Appendix B.
;+
; NAME:
; your_application_ui (Local function prefix: your)
;
;--------------------------------------------------------------------------------
; PROCEDURE NAME: your_application
;
; DESCRIPTION:
; The main and only exported procedure of this package. Calling this
; procedure will display the tool's GUI. The procedure will then fill in the
; information structure with initial values and hand over control to xmanager
; which then handles the GUI events.
;===============================================================================
PRO your_application
; Perform general data interface library initialization.
rw_define_symbols

;--------------------------------------------------------------------------
; Start creating the actual GUI.
;--------------------------------------------------------------------------
; Create the top level widget, with 2 columns and the main frame's close
; button (the 'X' at the top right) disabled.
application_name = 'Your New Application'
top_wid = WIDGET_BASE(COLUMN=2, TITLE=application_name, $
XOFFSET = 0, YOFFSET = 0,MBAR=bar, $
KILL_NOTIFY='rw_kill_cb')

; Create the base widgets for the two columns defined in the frame.
control_base_wid = WIDGET_BASE(top_wid, COLUMN=1)
viewbase_wid = WIDGET_BASE(top_wid, COLUMN=1)

; Fill the menu bar


data_menu = WIDGET_BUTTON(bar, VALUE='File', /MENU)
dummy_wid = WIDGET_BUTTON(data_menu, $
VALUE='Data From Disk', $
EVENT_PRO='rw_select_new_series_cb')
db_intera_wid = WIDGET_BUTTON(data_menu, $
VALUE='Data From Intera', $
EVENT_PRO='rw_select_new_series_cb')
quit = WIDGET_BUTTON(data_menu, $
VALUE='Quit', $
EVENT_PRO='rw_exit_application_cb')

; Set the warning labels as a button in the MBar


caution_str = " CAUTION: Investigation Device. "
limited_str = " Limited by Federal Law to investigational use."
dummy_wid = WIDGET_BUTTON(bar, FONT="Courier*14", VALUE = caution_str)
dummy_wid = WIDGET_BUTTON(bar, FONT="Courier*14", VALUE = limited_str)

; Fill (control) column with sliders and buttons.


dummy_wid = WIDGET_LABEL(control_base_wid, YSIZE=50, $
VALUE=' ')
dummy_wid = WIDGET_LABEL(control_base_wid, YSIZE=50, $
VALUE='Add Labels, Sliders and Buttons in this area')
dummy_wid = WIDGET_LABEL(control_base_wid, /ALIGN_LEFT, $

TRAD Philips’ proprietary, © 2002 Philips Electronics N.V. All rights reserved
XJS155-7905 / 0.1 First Aid for PRIDE Programming Page 8 of 9
MR - Software Internal use 02-05-2002

VALUE='Press "File" to select a dataset')


dummy_wid = WIDGET_LABEL(control_base_wid, /ALIGN_LEFT, $
VALUE='Use right mouse button to window the image')

; Create a widget in the viewing area


draw_area = WIDGET_DRAW(viewbase_wid, $
XSIZE=256, YSIZE=256, /BUTTON_EVENTS, /MOTION_EVENTS)

; Realize and make draw WIDGET active


WIDGET_CONTROL, top_wid, /REALIZE
WIDGET_CONTROL, draw_area, GET_VALUE=draw_area_idx

; Ensure that TRUE/HIGH colour users correctly see the data.


DEVICE, DECOMPOSED=0

; Create an "INFO" structure for program info. Store in top widget.


; To keep things as simple as possible, some hard-coded defaults are used.
info = { $
application_name: application_name, $; name of the application
button_down: 0, $; Right mouse button down
dmi_connection: OBJ_NEW(), $; DMI Connection when used
draw_area_idx: draw_area_idx, $; draw area index in GUI
image_aptr: PTR_NEW(), $; image array ( all images )
db_intera_wid: db_intera_wid, $; DMI series button widget
prev_position: [0, 0], $; Previous mouse location
read_bulk: 0, $; read bulk when needed
window_width: 0, $; window_width
window_center: 0, $; window_center
series_present: 0, $; Is there a dataset current
series_object: OBJ_NEW(), $; the current series object
top_wid: top_wid} ; The top level widget

; Move the info structure into the top level widget.


WIDGET_CONTROL, top_wid, SET_UVALUE=info, /NO_COPY

; Hand control of the GUI over the the XManager.


XMANAGER, 'PRIDE application', top_wid, $
EVENT_HANDLER = 'your_event_handler', /NO_BLOCK
END

; General GUI event handling function:


; This procedure is called when an event generated by the XMANAGER.
; The procedure separates the events according to the mouse events
; (Button Pressed, Button Release, Motion)
; Since only one action (right mouse button) is handled, al the event handling
; is done internally within this function.
;-------------------------------------------------------------------------------
PRO your_event_handler, event
; Get the info structure.
WIDGET_CONTROL, event.top, GET_UVALUE=info, /NO_COPY

CASE event.type OF
; 0 = Mouse button pressed, store initial data for later.
0: BEGIN
IF((info.series_present) AND (event.press EQ 4)) THEN BEGIN

TRAD Philips’ proprietary, © 2002 Philips Electronics N.V. All rights reserved
XJS155-7905 / 0.1 First Aid for PRIDE Programming Page 9 of 9
MR - Software Internal use 02-05-2002

; Store the position of the mouse click


info.prev_position = [event.x, event.y]
info.button_down = 1
END
END

; 1 = Mouse button released, update info structure


1: BEGIN
IF (info.series_present AND info.button_down) THEN BEGIN
info.button_down = 0
END
END

; 2 = Mouse movement over widget. If needed, actually window the data.


2: BEGIN
; Only act if the right-mouse button is pressed.
IF(info.button_down AND info.series_present) THEN BEGIN
; Find the current offset from the previous point.
diff_x = event.x - info.prev_position[0]
diff_y = event.y - info.prev_position[1]

; Store the current mouse position as the next A point.


info.prev_position[0] = event.x
info.prev_position[1] = event.y

; Update the actual window width and center values.


info.window_width = info.window_width + diff_x
info.window_center = info.window_center+ diff_y
IF(info.window_width LE 1) THEN info.window_width= 2

; add here the re-display of all images with the new window_values
;.....
rest_show_image, info

; end of re-display of the images


END
END
ELSE: ; Unexpected event, let XMANAGER handle it.
ENDCASE

; Move info structure back.


WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
END

<<< END OF DOCUMENT >>>

TRAD Philips’ proprietary, © 2002 Philips Electronics N.V. All rights reserved

You might also like