confirm_scan.pro 0100755 0000621 0000620 00000005220 06414021700 013215 0 ustar epics epics pro confirm_scan
;+
; NAME:
; CONFIRM_SCAN
; PURPOSE:
; Echoes the scan parameters for the scan and prompts the user to confirm
; that they are acceptable.
; CALLING SEQUENCE:
; CONFIRM_SCAN
; INPUTS:
; None
; OUTPUTS:
; None
; COMMON BLOCKS:
; SCAN_COMMON which contains the current scan parameters.
; SIDE EFFECTS
; If the user does not accept the scan (types "No") then this routine
; returns by calling MESSAGE. The calling routine should thus issue
; the approriate ON_ERROR call before calling CONFIRM_SCAN.
; PROCEDURE:
; Types out fields in scan descriptor (SD) structure. Prompts for whether
; these parameters are OK.
; MODIFICATION HISTORY:
; Created Dec. 1991 by Mark Rivers
; Modified Mar. 1995 by Harvey Rarback to do piecewise linear scans
;-
@scan_common
print, ' '
print, ' SUMMARY OF SCAN'
print, 'Scan type: ', scan_types(sd.scan_type)
if sd.n_dims eq 1 then begin
print, '1-D scan, number of points = ', sd.dims(0), format = '(a, i0)'
endif else begin
print, '2-D scan, number of points = [', sd.dims(0), ', ', sd.dims(1), ']', $
format = '(a, i0, a, i0, a)'
endelse
for i=0, sd.n_motors-1 do begin
print, 'Motor ', md(i).name, ':'
for l = 0, md(i).n_parts-1 do begin
if l gt 0 then print, ' '
if md(i).n_parts gt 1 then print, ' Region ', l+1, ':', format = '(a,i0,a)'
print, ' Start = ', md(i).start(l)
print, ' Stop = ', md(i).stop(l)
print, ' Step size = ', md(i).inc(l)
print, ' Range = ', md(i).stop(l) - md(i).start(l)
endfor
endfor
total_time = sd.dwell_time * (sd.dims(0)) * (sd.dims(1))
print, 'Total collection time: ', $
total_time, ' (seconds) = ', $
total_time/60., ' (minutes) = ', $
total_time/3600., ' (hours)', format='(a,f8.1,a,f7.2,a,f6.2,a)'
if (sd.scan_type eq ROI_SCAN) then begin
print, ' '
print, ' ROI Left Right Title'
print, ' Energy Channel Energy Channel
for i = 0, sd.n_rois-1 do begin
left_energy = sd.mca->chan_to_energy(sd.roi(i).left_chan)
right_energy = sd.mca->chan_to_energy(sd.roi(i).right_chan)
print, i, left_energy, sd.roi(i).left_chan, $
right_energy, sd.roi(i).right_chan, sd.roi(i).name, $
format='(i3, f, i6, f, i6, 5x, a)'
endfor
endif
if (sd.scan_type eq SCALER_SCAN) or $
(sd.scan_type eq ROI_SCAN) or $
(sd.scan_type eq SPECTRUM_SCAN) or $
(sd.scan_type eq GE13_SCAN) then begin
print, ' '
print, 'Scaler Title'
for i = 0, sd.n_scalers-1 do begin
print, i, sd.scalers[i].title, format='(i3, 6x, a, 6x, a)'
endfor
print, ' '
endif
end
copy_bytes.pro 0100664 0000621 0000620 00000002377 07231401676 012761 0 ustar epics epics pro copy_bytes, n, source, dest
;+
; NAME:
; COPY_BYTES.PRO
; PURPOSE:
; Copies bytes between a source and destination regardless of whether or
; not they have the same structure. It can be useful for copying, for
; instance between a byte array and a structure. It must be used
; with care.
; CALLING SEQUENCE:
; COPY_BYTES, n_bytes, source, destination
; INPUTS:
; N_BYTES
; The number of bytes to copy.
; SOURCE
; The location to copy from.
; OUTPUTS:
; DESTINATION
; The location to copy to.
; RESTRICTIONS:
; This routine does not do any error checking. The user must ensure that
; SOURCE and DESTINATION can each hold N_BYTES.
; Under UNIX the use must have write permission in the current default
; directory.
; PROCEDURE:
; Under VMS uses Run-Time Library routine LIB$MOVC3.
; Under UNIX opens a file, write out the source, reads back into
; destination.
; MODIFICATION HISTORY:
; Created Nov. 1991 by Mark Rivers
;-
if !version.os eq 'vms' then begin
lib$movc3, n, source, dest
endif else begin
get_lun, lun
openw, lun, 'scratch.jnk'
writeu, lun, source
close, lun
openr, lun, 'scratch.jnk'
readu, lun, dest
close, lun
free_lun, lun
endelse
end display_point.pro 0100755 0000621 0000620 00000012113 06470125425 013444 0 ustar epics epics pro display_point, row, col, rescale=rescale
;+
; NAME:
; DISPLAY_POINT
; PURPOSE:
; To display (print and/or plot) data in real-time during a scan. This
; routine is called after each data point is collected during a scan.
; A generic version of this routine is provided in
; IDL_DIR:[USER.REAL_TIME].
; Users who want to do more specialized display at each point should
; simply create another version of DISPLAY_POINT in some other directory
; and compile it before calling routine SCAN. More specialized versions
; might plot ratios of data values, or display 2-D scans as pseudo-color
; images, etc.
; CALLING SEQUENCE:
; DISPLAY_POINT, row, col
; INPUTS:
; ROW
; The current row being collected.
; COL
; The current column being collected.
; OUTPUTS:
; None
; COMMON BLOCKS:
; Values in SCAN_COMMON and BSIF_COMMON are used. Specifically:
; in BSIF_COMMON:
; N_COLS = number of columns (fast scan direction)
; N_ROWS = number of rows (slow scan direction, =1 for a 1-D scan)
; N_DATA = number of data values (scalers, ROIs, etc.) at each point
; X_DIST(N_COLS) = calibrated units in the fast scan direction
; Y_DIST(N_ROWS) = calibrated units in the slow scan direction
; (for 2-D scans only)
; IMAGE_DATA(N_COLS, N_ROWS, N_DATA) = scan data.
; in SCAN_COMMON:
; SD = structure which contains all the parameters defining the scan.
; Some useful fields include:
;
; PROCEDURE:
; The generic version of this routine does the following:
; - Prints the current column and row, and the
; counts for each data value at each point
; - Plots the data according to the values of SD.PLOT. SD.PLOT is an
; array which lists the indices of all data values which should be
; plotted by this routine. For example, if SD.PLOT=[0,2,-1,-1,...]
; then IMAGE_DATA(*,ROW,0) and IMAGE_DATA(*,ROW,2) will be plotted.
; If all values of SD.PLOT are -1 then no data is plotted.
; The plots autoscale to the maximum value to be plotted. The first
; plots uses PSYM=-1, the second PSYM=-2, etc. so both symbols and
; connecting lines are plotted.
; The plotting is optimized so that if this point can be plotted
; without increasing the Y axis range then it uses only OPLOT.
; - Checks whether the user has typed ^P on the terminal. If so, then
; this routine stops to let the user print out or plot data. The scan
; can be aborted at this point by typing RETALL or continued by
; typing .CON.
;
; MODIFICATION HISTORY:
; Created Dec. 1991 by Mark Rivers.
; Fixed bug in display update algorithm Jan. 9, 1993
; Added ABORT_SCAN for widget scanning, modified ^P code.
; Mark Rivers, November 1997
;-
@bsif_common
@scan_common
; Anything to plot?
k = where(sd.plot gt 0, nplot)
if (nplot eq 0) then goto, skip_plot
big = max(image_data(0:col, row, k))
small = min(image_data(0:col, row, k))
if (col eq 0) or (small lt !y.range(0)) or (big gt !y.range(1)) or $
keyword_set(rescale) then begin
; Must rescale plot axes, redraw all data so far
!y.range = [small - 0.2*abs(small), big + 0.2*abs(big)]
plot, x_dist, image_data(0:col,row,k(0)), psym=-1, $
xtitle = x_title, $
ytitle = y_title, $
title = image_title
for i=1, n_elements(k)-1 do begin
oplot, x_dist, image_data(0:col,row,k(i)), psym=-(i+1)
endfor
endif else begin
; No need to replot axes. Just draw previous point and current one.
for i=0, n_elements(k)-1 do begin
oplot, x_dist(col-1:col), image_data(col-1:col,row,k(i)), psym=-(i+1)
endfor
endelse
skip_plot:
; Print out counts on terminal
print, 'Column, row = [',col, row,'], total=[',sd.dims(0)-1,sd.dims(1)-1,']',$
format='(a,i4,i4,a,i4,i4,a)'
if (sd.scan_type eq ROI_SCAN) then begin
print, 'Rois (net): ', image_data(col, row, 0:sd.n_rois-1), $
format='(a,10i8)'
print, 'Scalers: ', $
image_data(col, row, sd.n_rois:sd.n_rois+sd.n_scalers-1), $
format='(a, 10i8)'
endif
if (sd.scan_type eq SCALER_SCAN) then begin
print, 'Scalers: ', $
image_data(col, row, 0:sd.n_scalers-1), $
format='(a, 10i8)'
endif
print
; See if the user has typed ^P on the keyboard. If so, pause. Empty typeahead
; buffer checking each character for ^P.
while 1 do begin
c = get_kbrd(0)
if c eq '' then goto, done
if (c eq string(16B)) then begin
print, "Scanning interrupted by keyboard input"
print, " To plot data:"
print, " PLOT, IMAGE_DATA()"
print, " To look at numbers:"
print, " PRINT, IMAGE_DATA()"
print, " To abort scan:"
print, " ABORT_SCAN"
print, " .CON"
print, " To continue scan"
print, " .CON "
stop
endif
endwhile
done:
; See if an ABORT_SCAN widget event has happened
if (widget_info(sd.abort_scan_widget, /VALID_ID)) then $
event = widget_event(/NOWAIT, sd.abort_scan_widget)
end
epics_motor__define.pro 0100755 0000621 0000620 00000112167 07073713371 014577 0 ustar epics epics ;*****************************************************************************
function epics_motor::get_scale
;+
; NAME:
; EPICS_MOTOR::GET_SCALE
;
; PURPOSE:
; This function returns the scale factor for the motor. The scale
; factor is the number of steps per unit motion in the user coordinate
; system. It is 1/.MRES, where .MRES is the motor resolution field of
; the EPICS motor record.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_SCALE()
;
; INPUTS:
; None:
;
; OUTPUTS:
; This function returns the scale factor for the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; scale = motor->GET_SCALE()
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caget(self.record_name + '.MRES', resolution)
return, 1./resolution
end
;*****************************************************************************
function epics_motor::get_name
;+
; NAME:
; EPICS_MOTOR::GET_NAME
;
; PURPOSE:
; This function returns the EPICS record name for the motor. The record
; name does not include any trailing period or field name.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_NAME()
;
; INPUTS:
; None:
;
; OUTPUTS:
; This function returns the name of the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos.DESC')
; print, motor->GET_NAME()
; 13IDA_Slit1_Pos
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
return, self.record_name
end
;*****************************************************************************
function epics_motor::get_description
;+
; NAME:
; EPICS_MOTOR::GET_DESCRIPTION
;
; PURPOSE:
; This function returns the .DESC field of the EPICS motor record. This
; is typically a short description of the function of the motor.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_DESCRIPTION()
;
; INPUTS:
; None:
;
; OUTPUTS:
; This function returns the description of the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; print, motor->GET_DESCRIPTION()
; Horizontal slit position
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caget(self.record_name + '.DESC', description)
return, description
end
;*****************************************************************************
pro epics_motor::set_description, description
;+
; NAME:
; EPICS_MOTOR::SET_DESCRIPTION
;
; PURPOSE:
; This procedure sets the .DESC field of the EPICS motor record. This
; is typically a short description of the function of the motor.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; motor->SET_DESCRIPTION, Description
;
; INPUTS:
; Description: A string which describes the motor
;
; OUTPUTS:
; None
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->SET_DESCRIPTION, 'Vertical slit position'
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caput(self.record_name + '.DESC', description)
end
;*****************************************************************************
function epics_motor::get_high_limit, dial=dial
;+
; NAME:
; EPICS_MOTOR::GET_HIGH_LIMIT
;
; PURPOSE:
; This function returns the software high limit for the motor.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_HIGH_LIMIT()
;
; INPUTS:
; None:
;
; KEYWORD PARAMETERS:
; DIAL: Set this keyword to return the high limit in dial coordinates.
; The default is to return the high limit in user coordinates.
;
; OUTPUTS:
; This function returns the software high limit of the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; limit = motor->GET_HIGH_LIMIT()
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
if keyword_set(dial) then begin
t = caget(self.record_name + '.DHLM', high_limit)
endif else begin
t = caget(self.record_name + '.HLM', high_limit)
endelse
return, high_limit
end
;*****************************************************************************
pro epics_motor::set_high_limit, dial=dial, high_limit
;+
; NAME:
; EPICS_MOTOR::SET_HIGH_LIMIT
;
; PURPOSE:
; This procedure sets the software high limit for the motor.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; motor->SET_HIGH_LIMIT, Limit
;
; INPUTS:
; Limit: The new software high limit for the motor.
;
; KEYWORD PARAMETERS:
; DIAL: Set this keyword to set the high limit in dial coordinates.
; The default is to set the high limit in user coordinates.
;
; OUTPUTS:
; None.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->SET_HIGH_LIMIT, 50.
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
if keyword_set(dial) then begin
t = caput(self.record_name + '.DHLM', high_limit)
endif else begin
t = caput(self.record_name + '.HLM', high_limit)
endelse
end
;*****************************************************************************
function epics_motor::get_low_limit, dial=dial
;+
; NAME:
; EPICS_MOTOR::GET_LOW_LIMIT
;
; PURPOSE:
; This function returns the software low limit for the motor.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_LOW_LIMIT()
;
; INPUTS:
; None:
;
; KEYWORD PARAMETERS:
; DIAL: Set this keyword to return the low limit in dial coordinates.
; The default is to return the low limit in user coordinates.
;
; OUTPUTS:
; This function returns the software low limit of the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; limit = motor->GET_LOW_LIMIT()
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
if keyword_set(dial) then begin
t = caget(self.record_name + '.DLLM', low_limit)
endif else begin
t = caget(self.record_name + '.LLM', low_limit)
endelse
return, low_limit
end
;*****************************************************************************
pro epics_motor::set_low_limit, dial=dial, low_limit
;+
; NAME:
; EPICS_MOTOR::SET_LOW_LIMIT
;
; PURPOSE:
; This procedure sets the software low limit for the motor.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; motor->SET_LOW_LIMIT, Limit
;
; INPUTS:
; Limit: The new software low limit for the motor.
;
; KEYWORD PARAMETERS:
; DIAL: Set this keyword to set the low limit in dial coordinates.
; The default is to set the low limit in user coordinates.
;
; OUTPUTS:
; None.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->SET_LOW_LIMIT, 50.
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
if keyword_set(dial) then begin
t = caput(self.record_name + '.DLLM', low_limit)
endif else begin
t = caput(self.record_name + '.LLM', low_limit)
endelse
end
;*****************************************************************************
function epics_motor::get_calibration, $
negative=negative, positive=positive, home=home
;+
; NAME:
; EPICS_MOTOR::GET_CALIBRATION
;
; PURPOSE:
; This function returns one of three possible calibration settings
; for the motor. The settings are negative limit, positive limit and
; home. The returned value is in dial coordinates.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
; cal = motor->GET_CALIBRATION()
;
; KEYWORD PARAMETERS:
; NEGATIVE: Set this keyword to return the calibration value at the
; negative limit switch. This is the default.
;
; POSITIVE: Set this keyword to return the calibration value at the
; positive limit switch.
;
; HOME: Set this keyword to return the calibration value at the
; home position.
;
; OUTPUTS:
; This function returns the requested calibration value in dial
; coordinates.
;
; PROCEDURE:
; There are two possible sources of the calibration information. The
; first is a file of motor calibrations. In order to use this file the
; enivronment variable MOTOR_CALIBRATION must be set to the full path
; name of this file. Each line of this file must be of the format:
; MOTOR_NAME LIMIT POSITION OPTIONAL_COMMENT
; for example:
; 13IDC:m1 NEGATIVE -5.667 ; Calibrated by MLR 4/5/2000
; 13IDA:m2 HOME 10.500 ; Calibrated by PJE 12/7/1999
;
; If the appropriate calibration cannot be found in this file then this
; function returns the following values:
; NEGATIVE motor.DLLM (Dial low limit)
; POSITIVE motor.DHLM (Dial high limit)
; HOME 0.0
;
; EXAMPLE:
; ; Get the motor calibration value at the positive limit switch
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; cal = motor->GET_CALIBRATION(/POSITIVE)
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, April 8, 2000
;-
if keyword_set(positive) then limit='POSITIVE' $
else if keyword_set(home) then limit='HOME' $
else limit='NEGATIVE'
file = getenv('MOTOR_CALIBRATION')
if (file eq '') then goto, nofile
on_ioerror, nofile
openr, lun, /get, file
line = ''
while not eof(lun) do begin
readf, lun, line
tokens = str_sep(line, ' ', /trim)
if ((tokens[0] eq self.record_name) and $
(strupcase(tokens[1]) eq limit)) then begin
cal = float(tokens[2])
free_lun, lun
return, cal
endif
endwhile
nofile:
; Could have been an error reading the file, make sure it is closed
if (n_elements(lun) ne 0) then free_lun, lun
if (limit eq 'NEGATIVE') then return, self->get_low_limit(/DIAL)
if (limit eq 'POSITIVE') then return, self->get_high_limit(/DIAL)
; Must be HOME
return, 0.0
end
;*****************************************************************************
pro epics_motor::calibrate, $
negative=negative, positive=positive, home=home, $
noconfirm=noconfirm
;+
; NAME:
; EPICS_MOTOR::CALIBRATE
;
; PURPOSE:
; This procedure calibrates a motor. It moves the motor to either the
; negative limit, positive limit or home position and then sets the dial
; position to the value returned by EPICS_MOTOR::GET_CALIBRATION().
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
; motor->CALIBRATE
;
; KEYWORD PARAMETERS:
; NEGATIVE: Set this keyword to do the calibration at the negative
; limit switch. This is the default.
;
; POSITIVE: Set this keyword to do the calibration at the positive
; limit switch.
;
; HOME: Set this keyword to do the calibration at the home position.
;
; NOCONFIRM: Set this keyword to suppress the confirmation dialog box
; before setting the new dial position.
;
; PROCEDURE:
; This procedure first determines the appropriate calibration value using
; EPICS_MOTOR::GET_CALIBRATION().
; It then does the following:
; - If the calibration is not done with /HOME
; - Saves the motor soft limit
; - Saves the motor slew speed
; - Changes the soft limit to a very large value, so that the
; hard limit can be reached.
; - Hits appropriate limit at the slew speed
; - Backs off 2000 steps
; - Hits appropriate limit at slew speed/100
; - If calibration is done with /HOME
; - Does a motor home
; - Confirms if user wants to change calibration if /NOCONFIRM not
; set
; - Puts motor in SET mode
; - Sets dial value to calibration
; - Puts motor in USE mode
; - Restores slew speed
; - Restores soft limit
;
; EXAMPLE:
; ; Get the motor calibration value at the positive limit switch
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->CALIBRATE(/POSITIVE, /NOCONFIRM)
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, April 8, 2000
;-
cal = self->get_calibration(negative=negative, positive=positive, home=home)
if keyword_set(positive) then limit='POSITIVE' $
else if keyword_set(home) then limit='HOME' $
else limit='NEGATIVE'
if (limit eq 'HOME') then begin
self->go_home, home_direction=home_direction
self->wait
endif else begin
huge = 1.e9/abs(self->get_scale())
prev_speed = self->get_slew_speed()
if (limit eq 'NEGATIVE') then begin
sign = -1.
prev_limit = self->get_low_limit(/dial)
self->set_low_limit, -2.*huge, /dial
endif else begin
sign = 1.
prev_limit = self->get_high_limit(/dial)
self->set_high_limit, 2.*huge, /dial
endelse
self->move, sign*huge, /dial, /ignore_limits
self->wait, /ignore_limits
target = self->get_position(/dial) -sign*2000./abs(self->get_scale())
self->move, target, /dial, /ignore_limits
self->wait, /ignore_limits
; There is a bug in the motor record, sometimes need to move twice if we
; are at a hard limit
self->move, target, /dial, /ignore_limits
self->wait, /ignore_limits
wait, .2
self->set_slew_speed, (prev_speed/100. > self->get_base_speed())
wait, .2
self->move, sign*huge, /dial, /ignore_limits
self->wait, /ignore_limits
endelse
; Get the current positions
current_dial = self->get_position(/dial, /readback)
current_user = self->get_position(/readback)
if (not keyword_set(NOCONFIRM)) then begin
response = dialog_message(/question, 'Reset dial value from ' + $
strtrim(current_dial,2) + ' to ' + strtrim(cal,2) + '?')
if (strupcase(response) eq 'NO') then goto, restore_settings
endif else begin
print, self.record_name + ': reset dial value from ' + $
strtrim(current_dial,2) + ' to ' + strtrim(cal,2)
endelse
; Set the dial position to the calibration value
self->set_position, cal, /dial
; Set the user position to the previous value
wait, 1 ; This delay is necessary until /wait works in caput again
self->set_position, current_user
restore_settings:
case limit of
'NEGATIVE': begin
self->set_slew_speed, prev_speed
self->set_low_limit, prev_limit, /dial
end
'POSITIVE': begin
self->set_slew_speed, prev_speed
self->set_high_limit, prev_limit, /dial
end
'HOME': begin
end
endcase
end
;*****************************************************************************
function epics_motor::get_slew_speed
;+
; NAME:
; EPICS_MOTOR::GET_SLEW_SPEED
;
; PURPOSE:
; This function returns the slew speed for the motor. The slew speed
; is the speed which the motor will use after finishing its acceleration.
; The slew speed is specified in user units per second.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_SLEW_SPEED()
;
; INPUTS:
; None:
;
; OUTPUTS:
; This function returns the slew speed for the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; speed = motor->GET_SLEW_SPEED()
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caget(self.record_name + '.VELO', slew)
return, slew
end
;*****************************************************************************
pro epics_motor::set_slew_speed, slew
;+
; NAME:
; EPICS_MOTOR::SET_SLEW_SPEED
;
; PURPOSE:
; This procedure sets the slew speed for the motor. The slew speed
; is the speed which the motor will use after finishing its acceleration.
; The slew speed is specified in user units per second.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; motor->SET_SLEW_SPEED, Slew_speed
;
; INPUTS:
; Slew_speed: The desired slew speed in user units per second.
;
; OUTPUTS:
; None
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->SET_SLEW_SPEED, .1
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caput(self.record_name + '.VELO', slew)
end
;*****************************************************************************
function epics_motor::get_base_speed
;+
; NAME:
; EPICS_MOTOR::GET_BASE_SPEED
;
; PURPOSE:
; This function returns the base speed for the motor. The base speed
; is the initial speed which the motor will use before starting to
; accelerate to the slew speed. The base speed is specified in user
; units per second.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_BASE_SPEED()
;
; INPUTS:
; None:
;
; OUTPUTS:
; This function returns the base speed for the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; speed = motor->GET_BASE_SPEED()
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caget(self.record_name + '.VBAS', base)
return, base
end
;*****************************************************************************
pro epics_motor::set_base_speed, base
;+
; NAME:
; EPICS_MOTOR::SET_BASE_SPEED
;
; PURPOSE:
; This procedure sets the base speed for the motor. The base speed
; is the initial speed which the motor will use before starting to
; accelerate to the slew speed.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; motor->SET_BASE_SPEED, Base_speed
;
; INPUTS:
; Base_speed: The desired base speed in user units per second.
;
; OUTPUTS:
; None
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->SET_BASE_SPEED, .01
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caput(self.record_name + '.VBAS', base)
end
;*****************************************************************************
function epics_motor::get_acceleration
;+
; NAME:
; EPICS_MOTOR::GET_ACCELERATION
;
; PURPOSE:
; This function returns the acceleration for the motor. The acceleration
; is the time in seconds which the motor takes to go from the base speed
; to the slew speed.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_ACCELERATION()
;
; INPUTS:
; None:
;
; OUTPUTS:
; This function returns the acceleration for the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; accel = motor->GET_ACCELERATION()
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caget(self.record_name + '.ACCL', accel)
return, accel
end
;*****************************************************************************
pro epics_motor::set_acceleration, accel
;+
; NAME:
; EPICS_MOTOR::SET_ACCELERATION
;
; PURPOSE:
; This procedure sets the acceleration for the motor. The acceleration
; is the time in seconds which the motor takes to go from the base speed
; to the slew speed.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; motor->SET_ACCELERATION, Acceleration
;
; INPUTS:
; Acceleration: The desired acceleration time in seconds.
;
; OUTPUTS:
; None
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->SET_ACCELERATION, .01
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caput(self.record_name + '.ACCL', accel)
end
;*****************************************************************************
function epics_motor::get_backlash
;+
; NAME:
; EPICS_MOTOR::GET_BACKLASH
;
; PURPOSE:
; This function returns the backlash correction distance for the motor.
; This distance is specified in user coordinate system units.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_BACKLASH()
;
; INPUTS:
; None:
;
; OUTPUTS:
; This function returns the backlash correction distance for the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; backlash = motor->GET_BACKLASH()
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caget(self.record_name + '.BDST', backlash)
return, backlash
end
;*****************************************************************************
pro epics_motor::set_backlash, backlash
;+
; NAME:
; EPICS_MOTOR::SET_BACKLASH
;
; PURPOSE:
; This procedure sets the backlash correction distance for the motor.
; This distance is specified in user coordinate system units.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; motor->SET_BACKLASH, Backlash
;
; INPUTS:
; Backlash: The desired backlash correction distance in user
; coordinates.
;
; OUTPUTS:
; None
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->SET_BACKLASH, .1
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caput(self.record_name + '.BDST', backlash)
end
;*****************************************************************************
pro epics_motor::move, relative=relative, dial=dial, steps=steps, value, $
ignore_limits=ignore_limits
;+
; NAME:
; EPICS_MOTOR::MOVE
;
; PURPOSE:
; This procedure moves the motor. The move can be specified in either
; user coordinates, dial coordinates or steps, and the position can be
; specified in either absolute or relative coordinates.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; motor->MOVE, Position
;
; INPUTS:
; Position: The desired position to move to. By default this is
; specified as an absolute position in the user coordinate
; system. The /DIAL and /STEPS keywords can be used to
; specify positions in dial coordinates or steps. The
; /RELATIVE keyword can be used to specify positions relative
; to the current position, rather than absolute positions.
;
; KEYWORD PARAMETERS:
; DIAL: Set this keyword to indicate that the position is specified
; in dial coordinates. The default is to specify the position in
; user coordinates.
;
; STEPS: Set this keyword to indicate that the position is specified
; in motor steps. The default is to specify the position in
; user coordinates.
;
; RELATIVE: Set this keyword to indicate that the position is specified
; relative to the current position. The default is to specify
; the absolute position.
;
; IGNORE_LIMITS: Set this keyword to prevent error signalling if a limit
; is hit.
;
; OUTPUTS:
; None
;
; SIDE EFFECTS:
; The routine checks whether the move caused soft limit or hard limit
; errors. If it did then the routine signals the error with the IDL
; MESSAGE procedure unless the IGNORE_LIMITS keyword is set. This will
; cause execution to halt within this routine unless an error handler
; has been established with the IDL CATCH procedure.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->MOVE, 2. ; Move to absolute position 2. in user
; ; coordinates
; motor->MOVE, 5., /DIAL ; Move to absolute position 5. in dial
; ; coordinates
; motor->MOVE, .1, /RELATIVE ; Relative move 0.1 unit in user
; ; coordinates
; motor->MOVE, 1000, /STEP, /RELATIVE ; Move 1000 steps relative to
; ; current position
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
; 08-APR-2000 MLR Added IGNORE_LIMITS keyword
;-
signal_limits = not keyword_set(ignore_limits)
if (keyword_set(dial)) then begin
; Position in dial coordinates
if (keyword_set(relative)) then begin
current = self->get_position(/dial)
t = caput(self.record_name + '.DVAL', current+value)
endif else begin
t = caput(self.record_name + '.DVAL', value)
endelse
endif else if (keyword_set(steps)) then begin
; Position in steps
if (keyword_set(relative)) then begin
t = caget(self.record_name + '.RVAL', current)
scale = self->get_scale()
t = caput(self.record_name + '.RVAL', current + value)
endif else begin
t = caput(self.record_name + '.RVAL', value)
endelse
endif else begin
; Position in user coordinates
if keyword_set(relative) then begin
t = caput(self.record_name + '.RLV', value)
endif else begin
t = caput(self.record_name + '.VAL', value)
endelse
endelse
; Check for limit violations
t = caget(self.record_name + '.LVIO', limit)
if (signal_limits and (limit ne 0)) then $
message, 'Soft limit violation on ' + self.record_name
t = caget(self.record_name + '.LLS', limit)
if (signal_limits and (limit ne 0)) then $
message, 'Low limit switch on ' + self.record_name
t = caget(self.record_name + '.HLS', limit)
if (signal_limits and (limit ne 0)) then $
message, 'High limit switch on ' + self.record_name
end
;*****************************************************************************
function epics_motor::done, ignore_limits=ignore_limits
;+
; NAME:
; EPICS_MOTOR::DONE
;
; PURPOSE:
; This function returns 1 if the motor is done moving and 0 if the motor
; is still moving.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->DONE()
;
; INPUTS:
; None
;
; KEYWORD PARAMETERS:
; IGNORE_LIMITS: Set this keyword to prevent the routine from signalling
; an error when a limit is hit.
;
; OUTPUTS:
; None
;
; SIDE EFFECTS:
; The routine checks whether the motor stopped due to a soft limit or
; hard limit error. If it did then the routine signals the error with
; the IDL MESSAGE procedure, unless the IGNORE_LIMITS keyowrd is set.
; This will cause execution to halt within this routine unless an error
; handler has been established with the IDL CATCH procedure.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->MOVE, .1, /RELATIVE ; Relative move 0.1 unit
; if (motor->DONE()) then print, 'Done moving'
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
; 08-Apr-2000 MLR Added IGNORE_LIMITS keyword
;-
signal_limits = not keyword_set(IGNORE_LIMITS)
t = caget(self.record_name + '.DMOV', done)
if (done eq 0) then return, 0 ; Motor not done moving
; Motor done moving, check for limit violations
if (signal_limits) then begin
t = caget(self.record_name + '.LVIO', limit)
if (limit ne 0) then message, 'Soft limit violation on ' + $
self.record_name
t = caget(self.record_name + '.LLS', limit)
if (limit ne 0) then message, 'Low limit switch on ' + $
self.record_name
t = caget(self.record_name + '.HLS', limit)
if (limit ne 0) then message, 'High limit switch on ' + $
self.record_name
endif
return, 1
end
;*****************************************************************************
pro epics_motor::wait, delay, ignore_limits=ignore_limits
;+
; NAME:
; EPICS_MOTOR::WAIT
;
; PURPOSE:
; This procedure waits for the motor to finish moving.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
; motor->WAIT
;
; OPTIONAL INPUTS:
; Delay The delay time between checking when the motor is done
; Default is 0.1 second
;
; KEYWORD PARAMETERS:
; IGNORE_LIMITS: This keyword is passed to EPICS_MOTOR::DONE if present.
;
; OUTPUTS:
; None
;
; SIDE EFFECTS:
; This routine calls EPICS_MOTOR::DONE every 0.1 second to check whether
; the move is complete. That routine checks whether the move terminated
; due to soft or hard limit errors. If it did then it signals the
; error with the IDL MESSAGE procedure. This will cause execution to
; halt unless an error handler has been established with the IDL
; CATCH procedure.
;
; PROCEDURE:
; Simply polls whether the motor is done moving with the
; EPICS_MOTOR::DONE function and waits 0.1 second if it is not.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->MOVE, .1, /RELATIVE ; Relative move 0.1 unit
; motor->WAIT ; Wait for it to get there
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
; 18-Sep-1998 MLR Added Delay parameter. Made it wait one delay period
; before checking, because motor moves no longer
; use channel access callbacks, so the motor may
; not have started to move when this routine is called
; 08-Apr-2000 MLR Added IGNORE_LIMITS keyword.
;-
if (n_elements(delay) eq 0) then delay=.1
repeat wait, delay until (self->done(ignore_limits=ignore_limits) ne 0)
end
;*****************************************************************************
function epics_motor::get_position, dial=dial, steps=steps, readback=readback
;+
; NAME:
; EPICS_MOTOR::GET_POSITION
;
; PURPOSE:
; This function returns the current position of the motor. It can return
; the position in user coordinates, dial coordinates or steps.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = motor->GET_POSITION()
;
; INPUTS:
; None:
;
; KEYWORD PARAMETERS:
; DIAL: Set this keyword to return the position in dial coordinates.
; The default is to return the position in user coordinates.
; STEPS: Set this keyword to return the position in steps.
; READBACK: Set this keyword to return the readback position (RBV, DRBV
; or RRBV) rather than the drive position (VAL, DVAL, RVAL)
;
; OUTPUTS:
; This function returns the current position of the motor.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; position = motor->GET_POSITION()
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
if (keyword_set(readback)) then begin
if keyword_set(dial) then begin
t = caget(self.record_name + '.DRBV', position)
endif else if keyword_set(steps) then begin
t = caget(self.record_name + '.RRBV', position)
endif else begin
t = caget(self.record_name + '.RBV', position)
endelse
endif else begin
if keyword_set(dial) then begin
t = caget(self.record_name + '.DVAL', position)
endif else if keyword_set(steps) then begin
t = caget(self.record_name + '.RVAL', position)
endif else begin
t = caget(self.record_name + '.VAL', position)
endelse
endelse
return, position
end
;*****************************************************************************
pro epics_motor::set_position, position, dial=dial, steps=steps
;+
; NAME:
; EPICS_MOTOR::SET_POSITION
;
; PURPOSE:
; This function sets the current position of the motor without moving it.
; It can set the position in user coordinates, dial coordinates or steps.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
; motor->SET_POSITION, Position
;
; INPUTS:
; Position: The new motor position.
;
; KEYWORD PARAMETERS:
; DIAL: Set this keyword to set the position in dial coordinates.
; The default is to set the position in user coordinates.
; STEPS: Set this keyword to set the position in steps.
;
; OUTPUTS:
; None.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; motor->SET_POSITION, 0.
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, April 8, 2000
;-
; Put the motor in "SET" mode
t = caput(self.record_name + '.SET', 'Set')
if keyword_set(dial) then begin
t = caput(self.record_name + '.DVAL', position)
endif else if keyword_set(steps) then begin
t = caput(self.record_name + '.RVAL', position)
endif else begin
t = caput(self.record_name + '.VAL', position)
endelse
; Put the motor back in "Use" mode
t = caput(self.record_name + '.SET', 'Use')
end
;*****************************************************************************
function epics_motor::init, record_name
;+
; NAME:
; EPICS_MOTOR::INIT
;
; PURPOSE:
; This is the initialization code which is invoked when a new object of
; type EPICS_MOTOR is created. It cannot be called directly, but only
; indirectly by the IDL OBJ_NEW() function.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
; Result = OBJ_NEW('epics_motor', Record_Name)
;
; INPUTS:
; Record_Name: The name of the EPICS motor record for the motor object
; being created. This record name can include a field
; name which will be stripped off. For example,
; '13IDA:Slit_Pos' and '13IDA:Slit_Pos.DESC' are both
; valid. This makes it convenient when dragging process
; variable names from MEDM windows to IDL windows.
;
; OUTPUTS:
; This function returns a status to indicate whether it was able to
; establish channel access communication with the specified EPICS motor
; record. This status is 1 for success, 0 for failure. This status is
; passed back indirectly to the routine which calls OBJ_NEW(). OBJ_NEW
; will return a valid object pointer if this routine succeeds, and will
; return a NULL object pointer if this routine fails. The user should
; test the return value of OBJ_NEW() with the IDL function OBJ_VALID().
;
; SIDE EFFECTS:
; The routine establishes channel access monitors on all of the fields
; in the motor record which the methods in this class will read. This
; greatly improves the speed and efficiency.
;
; RESTRICTIONS:
; This routine cannot be called directly. It is called indirectly when
; creating a new object of class EPICS_MOTOR by the IDL OBJ_NEW()
; function.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; if (OBJ_VALID(motor)) then print, 'It worked!'
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
parse_record_name, record_name, rec
self.record_name = rec
status = caget( self.record_name, temp) ; see if it exists
if status ne 0 then return, 0 ; it does not exist
; Set channel access monitors on all fields we will be reading
caStartGroup
t = casetmonitor(self.record_name + '.VAL')
t = casetmonitor(self.record_name + '.DVAL')
t = casetmonitor(self.record_name + '.RVAL')
t = casetmonitor(self.record_name + '.DMOV')
t = casetmonitor(self.record_name + '.MRES')
t = casetmonitor(self.record_name + '.HLM')
t = casetmonitor(self.record_name + '.DHLM')
t = casetmonitor(self.record_name + '.LLM')
t = casetmonitor(self.record_name + '.DLLM')
t = casetmonitor(self.record_name + '.BDST')
t = casetmonitor(self.record_name + '.VELO')
t = casetmonitor(self.record_name + '.VBAS')
t = casetmonitor(self.record_name + '.ACCL')
t = casetmonitor(self.record_name + '.DESC')
t = casetmonitor(self.record_name + '.LVIO')
t = casetmonitor(self.record_name + '.LLS')
t = casetmonitor(self.record_name + '.HLS')
t = caEndGroup()
return, 1
end
;*****************************************************************************
pro epics_motor__define
;+
; NAME:
; EPICS_MOTOR__DEFINE
;
; PURPOSE:
; This is the definition code which is invoked when a new object of
; type EPICS_MOTOR is created. It cannot be called directly, but only
; indirectly by the IDL OBJ_NEW() function,
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
; Result = OBJ_NEW('epics_motor', Record_Name)
;
; INPUTS:
; Record_Name: The name of the EPICS motor record for the motor object
; being created. This record name can include a field
; name which will be stripped off. For example,
; '13IDA:Slit_Pos' and '13IDA:Slit_Pos.DESC' are both
; valid. This makes it convenient when dragging process
; variable names from MEDM windows to IDL windows. This
; name is passed to EPICS_MOTOR::INIT().
;
; OUTPUTS:
; None (but see EPICS_MOTOR::INIT)
;
; RESTRICTIONS:
; This routine cannot be called directly. It is called indirectly when
; creating a new object of class EPICS_MOTOR by the IDL OBJ_NEW()
; function.
;
; EXAMPLE:
; motor = obj_new('epics_motor', '13IDA:Slit1_Pos')
; if (OBJ_VALID(motor)) then print, 'It worked!'
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
epics_motor = { epics_motor, record_name: ''}
end
epics_scaler__define.pro 0100755 0000621 0000620 00000033372 07250764540 014711 0 ustar epics epics ;*****************************************************************************
pro epics_scaler::wait, dwell_time
;+
; NAME:
; EPICS_SCALER::WAIT
;
; PURPOSE:
; This function waits for counting on the scaler to complete.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; scaler->WAIT
;
; INPUTS:
; None
;
; OUTPUTS:
; None
;
; PROCEDURE:
; This routine simply tests whether the scaler is done counting. If
; it is then the routine returns. If it is not it waits for 10% of the
; counting time or 0.1 second (whichever is less) and tries again.
;
; EXAMPLE:
; scaler = obj_new('epics_scaler', '13IDC:scaler1')
; scaler->start, 10. ; Start counting for 10 seconds.
; scaler->wait ; Wait for counting to complete
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
t = caget(self.record_name + '.FREQ', freq)
t = caget(self.record_name + '.PR1', preset) ; Preset counts
dwell_time = preset/freq/10. < 0.1 ; Wait for 10% of dwell time or 0.1 second,
; whichever is less
while (1) do begin
wait, dwell_time
t = caget(self.record_name + '.CNT', busy)
if (busy eq 0) then return
endwhile
end
;*****************************************************************************
function epics_scaler::read, scaler
;+
; NAME:
; EPICS_SCALER::READ
;
; PURPOSE:
; This function returns the counts on the scaler. It can either return
; the counts on a single scaler channel or on all of the scaler channels.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = scaler->READ(Channel)
;
; OPTIONAL INPUTS:
; Channel: If a channel is specified then only the counts on this
; scaler channel are returned. By default the counts on all
; scaler channels are returned. On the Joerger scaler this is
; either 8 or 16 channels, depending upon the model.
;
; OUTPUTS:
; Returns the counts. This can be a single number if the optional
; Channel input was specified, or an array of counts if Channel was not
; specified.
;
; EXAMPLE:
; scaler = obj_new('epics_scaler', '13IDC:scaler1')
; scaler->START, 10. ; Start counting for 10 seconds.
; scaler->WAIT ; Wait for counting to complete
; counts = scaler->READ() ; Read the counts on all of the channels
; counts = scaler->READ(0) ; Read the counts on the first channel,
; ; which is the preset clock.
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
; This function reads the counts on one of the scalers or all of them
if (n_elements(scaler) ne 0) then begin
field = '.S' + strtrim(scaler+1,2)
t = caget(self.record_name + field, counts)
endif else begin
counts = lonarr(self.nchans)
for i=1,self.nchans do begin
field = '.S' + strtrim(i,2)
t = caget(self.record_name + field, temp)
counts[i-1]=temp
endfor
endelse
return, counts
end
;*****************************************************************************
pro epics_scaler::start, dwell_time
;+
; NAME:
; EPICS_SCALER::START
;
; PURPOSE:
; This function starts the scaler counting.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; scaler->START, Time
;
; OPTIONAL INPUTS:
; Time: The preset counting time in seconds. If this input parameter
; is not specified then the preset time of the scaler is not
; changed.
;
; OUTPUTS:
; None
;
; SIDE EFFECTS:
; Before starting the scaler the counts on all of the channels are set
; to 0. This is how the Joerger scaler works.
;
; RESTRICTIONS:
; This routine assumes that the first channel of the scaler is used for
; for a clock. It thus assumes that there is a wire from the clock
; output of the module to the first input channel. It assumes that this
; channel has been configured to gate (perhaps EPICS_SCALER::INIT
; should do this?)
; This routine reads but does not alter the clock frequency. It assumes
; that the scaler has been set up with a reasonable clock frequency, i.e.
; one which is faster than the preset time!
;
; EXAMPLE:
; scaler = obj_new('epics_scaler', '13IDC:scaler1')
; scaler->START, 10. ; Start counting for 10 seconds.
; scaler->WAIT ; Wait for counting to complete
; counts = scaler->READ() ; Read the counts on all of the channels
; ; which is the preset clock.
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
; 18-SEP-1998 MLR Added /WAIT to caput calls, since this is not the
; default in ezcaIDL any more, and it is required
; for the scaler wait to work correctly.
; 05-MAR-2001 MLR Removed /WAIT to caput call when actually starting the
; scaler, or else it waits for the scaler to complete. This
; is because the scaler record does not fire its forward link
; now until the count is complete.
;-
if (n_elements(dwell_time) ne 0) then begin
t = caget(self.record_name + '.FREQ', freq)
t = caput(self.record_name +'.CNT', 0, /WAIT) ; Stop counting
t = caput(self.record_name +'.CONT', 0, /WAIT) ; Oneshot
t = caput(self.record_name +'.PR1', dwell_time*freq, /WAIT) ; Preset counts
t = caput(self.record_name +'.CNT', 1) ; Start counting
endif else begin
t = caput(self.record_name +'.CNT', 0, /WAIT) ; Stop counting
t = caput(self.record_name +'.CONT', 0, /WAIT) ; Oneshot
t = caput(self.record_name +'.CNT', 1) ; Start counting
endelse
end
;*****************************************************************************
pro epics_scaler::scaler_stop
;+
; NAME:
; EPICS_SCALER::SCALER_STOP
;
; PURPOSE:
; This function stops the scaler immediately from counting.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; scaler->SCALER_STOP
;
; INPUTS:
; None
;
; OUTPUTS:
; None
;
; RESTRICTIONS:
; This routine should really be named EPICS_SCALER::STOP. However, there
; is a bug in IDL 5.0 such that class procedures can have name conflicts
; with IDL procedures of the same name. This is the case with the IDL
; STOP procedure. This routine may be renamed if this problem is fixed.
;
; EXAMPLE:
; scaler = obj_new('epics_scaler', '13IDC:scaler1')
; scaler->START ; Start counting
; scaler->STOP ; Stop immediately
; counts = scaler->READ() ; Read the counts on all of the channels
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
; 18-SEP-1998 MLR Added /WAIT to caput call, since this is not the
; default in ezcaIDL any more, and it is required
; for the scaler wait to work correctly.
;-
; This immediately stops scaler
t = caput(self.record_name +'.CNT', 0, /WAIT) ; Stop counting
end
;*****************************************************************************
function epics_scaler::get_title, channel
;+
; NAME:
; EPICS_SCALER::GET_TITLE
;
; PURPOSE:
; This function returns the .NMx field of the EPICS scaler record. This
; is typically a short description of the scaler input.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; Result = scaler->GET_TITLE(Channel)
;
; INPUTS:
; None:
;
; OPTIONAL INPUTS:
; Channel: If a channel is specified then only the title of this
; scaler channel is returned. By default the titles of all
; scaler channels are returned. On the Joerger scaler this is
; either 8 or 16 channels, depending upon the model.
;
; OUTPUTS:
; This function returns the titles of the scaler channels.
;
; EXAMPLE:
; scaler = obj_new('epics_scaler', '13IDC:scaler1')
; print, scaler->get_title(1)
; Photodiode
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
if (n_elements(channel) ne 0) then begin
field = '.NM' + strtrim(channel+1,2)
t = caget(self.record_name + field, title)
endif else begin
title = strarr(self.nchans)
for i=1,self.nchans do begin
field = '.NM' + strtrim(i,2)
t = caget(self.record_name + field, temp)
title[i-1]=temp
endfor
endelse
return, title
end
;*****************************************************************************
pro epics_scaler::set_title, channel, title
;+
; NAME:
; EPICS_SCALER::SET_TITLE
;
; PURPOSE:
; This procedure sets the .NMx field of the EPICS scaler record. This
; is typically a short description of the scaler input.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
;
; scaler->SET_TITLE, Channel, Title
;
; INPUTS:
; Channel: The scaler channel whose title is to be set. This is a
; number in the range 0-7 or 0-15 depending upon the model.
; Title: The title string.
;
; OUTPUTS:
; None
;
; EXAMPLE:
; scaler = obj_new('epics_scaler', '13IDC:scaler1')
; scaler->set_title, 1, 'Photodiode'
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
field = '.NM' + strtrim(channel+1,2)
t = caput(self.record_name + field, title)
end
;*****************************************************************************
function epics_scaler::init, record_name
;+
; NAME:
; EPICS_SCALER::INIT
;
; PURPOSE:
; This is the initialization code which is invoked when a new object of
; type EPICS_SCALER is created. It cannot be called directly, but only
; indirectly by the IDL OBJ_NEW() function.
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
; Result = OBJ_NEW('epics_scaler', Record_Name)
;
; INPUTS:
; Record_Name: The name of the EPICS scaler record for the scaler object
; being created. This record name can include a field
; name which will be stripped off. For example,
; '13IDC:scaler1' and '13IDC:scaler1.S2' are both
; valid. This makes it convenient when dragging process
; variable names from MEDM windows to IDL windows.
;
; OUTPUTS:
; This function returns a status to indicate whether it was able to
; establish channel access communication with the specified EPICS scaler
; record. This status is 1 for success, 0 for failure. This status is
; passed back indirectly to the routine which calls OBJ_NEW(). OBJ_NEW
; will return a valid object pointer if this routine succeeds, and will
; return a NULL object pointer if this routine fails. The user should
; test the return value of OBJ_NEW() with the IDL function OBJ_VALID().
;
; SIDE EFFECTS:
; The routine establishes channel access monitors on all of the fields
; in the scaler record which the methods in this class will read. This
; greatly improves the speed and efficiency.
;
; RESTRICTIONS:
; This routine cannot be called directly. It is called indirectly when
; creating a new object of class EPICS_SCALER by the IDL OBJ_NEW()
; function.
;
; EXAMPLE:
; scaler = obj_new('epics_scaler', '13IDC:scaler1')
; if (OBJ_VALID(scaler)) then print, 'It worked!'
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
parse_record_name, record_name, record_name
self.record_name = record_name
status = caget( self.record_name+'.NCH', nchans) ; see if it exists
if status ne 0 then return, 0 ; it does not exist
self.nchans = nchans
; Set channel access monitors on all fields we will be reading
caStartGroup
t = casetmonitor(self.record_name + '.FREQ')
t = casetmonitor(self.record_name + '.CNT')
for i=1,self.nchans do begin
num = strtrim(string(i), 2)
t = casetmonitor(self.record_name + '.PR' + num)
t = casetmonitor(self.record_name + '.S' + num)
t = casetmonitor(self.record_name + '.NM' + num)
endfor
t = caEndGroup()
return, 1
end
;*****************************************************************************
pro epics_scaler__define
;+
; NAME:
; EPICS_SCALER__DEFINE
;
; PURPOSE:
; This is the definition code which is invoked when a new object of
; type EPICS_SCALER is created. It cannot be called directly, but only
; indirectly by the IDL OBJ_NEW() function,
;
; CATEGORY:
; EPICS device class library.
;
; CALLING SEQUENCE:
; Result = OBJ_NEW('epics_scaler', Record_Name)
;
; INPUTS:
; Record_Name: The name of the EPICS scaler record for the scaler object
; being created. This record name can include a field
; name which will be stripped off. For example,
; '13IDC:scaler1' and '13IDC:scaler1.S2' are both
; valid. This makes it convenient when dragging process
; variable names from MEDM windows to IDL windows. This
; name is passed to EPICS_SCALER::INIT().
;
; OUTPUTS:
; None (but see EPICS_SCALER::INIT)
;
; RESTRICTIONS:
; This routine cannot be called directly. It is called indirectly when
; creating a new object of class EPICS_SCALER by the IDL OBJ_NEW()
; function.
;
; EXAMPLE:
; scaler = obj_new('epics_scaler', '13IDC:scaler1')
; if (OBJ_VALID(scaler)) then print, 'It worked!'
;
; MODIFICATION HISTORY:
; Written by: Mark Rivers, October 1, 1997
;-
epics_scaler = { epics_scaler, record_name: '', nchans: 0}
end
focus_scan_common.pro 0100644 0000621 0000620 00000000353 06462243636 014267 0 ustar epics epics ;-
; focus_scan_common.pro
; store common data for focus_scan
;-
common FOCUS_SCAN, $
f1_motor_name, f2_motor_name, edge_motor_name, mcs_pv, dwell_time, $
sum_start, sum_stop, diff_start, diff_stop, diff_step, sum_step, filename
focus_scan_diag.pro 0100644 0000621 0000620 00000016134 06462264707 013711 0 ustar epics epics pro focus_scan_diag
; make 2-D grid of mirror forces to see focal spot.
;
; focus on a 2-D grid
; This program moves a motor back and forth, usually over an edge, and
; collects MCS data on the counts. It displays the derivative of the
; counts in another window.
; It assumes that the user has set ROI around the position of the edge
@bsif_common
@focus_scan_common.pro
print, '>> Focus scan program <<'
;
; initialize common block on first entrance
if (n_elements(sum_step) eq 0) then begin
print, ' setting initial values'
f1_motor_name = '13IDC:HforceU'
f2_motor_name = '13IDC:HforceD'
edge_motor_name= '13IDC:Stage_X'
mcs_pv = '13IDC:aim_mcs1'
dwell_time = 0.1
sum_start = 400.
sum_stop = 500.
sum_step = 10.
diff_start = -50.
diff_stop = 50.
diff_step = 10.
filename = 'focus.001'
endif
;
; calculate real starting values for f1 and f2
;
; get motor names
edge_motor_name = get_string('PV name of motor for edge scan:', $
edge_motor_name)
edge_motor = obj_new('epics_motor', edge_motor_name)
pos = edge_motor->get_position()
print, 'Current position = ', pos
edge_start = get_float('Start position for edge motor', pos)
edge_stop = get_float('Stop position for edge motor', pos+.1)
scan_speed = get_float('Scan speed for edge motor', .1)
flyback_speed = edge_motor->get_slew_speed()
flyback_speed = get_float('Flyback speed for edge motor', flyback_speed)
dwell_time = get_float('Dwell time of MCS (sec):', dwell_time)
edge_step = 1000.* scan_speed * dwell_time ; Step size in microns
f1_motor_name = get_string('PV name of F1 motor', f1_motor_name)
f1_motor = obj_new('epics_motor', f1_motor_name)
f2_motor_name = get_string('PV name of F2 motor', f2_motor_name)
f2_motor = obj_new('epics_motor', f2_motor_name)
f1_pos = f1_motor->get_position()
f2_pos = f2_motor->get_position()
print, 'Current positions of F1 and F2 = ', f1_pos, f2_pos
sum_start = get_float('Start position for Sum ', sum_start)
sum_stop = get_float('Stop position for Sum ', sum_stop)
sum_step = get_float('Step size for Sum ', sum_step)
diff_start = get_float('Start position for Diff ', diff_start)
diff_stop = get_float('Stop position for Diff ', diff_stop)
diff_step = get_float('Step size for Diff ', diff_step)
;sum_start = ave_start * 2.
;sum_stop = ave_stop * 2.
;sum_step = ave_step
;diff_start = diff_start * 2.
;diff_stop = diff_stop * 2.
f1_start = (sum_start + diff_start )
f2_start = (sum_start - diff_start )
; calculate number of scan points and create the image_data array
n_sum = (abs(sum_start - sum_stop )/ sum_step ) + 1
n_diff = (abs(diff_start - diff_stop )/ diff_step ) + 1
print,' allocating ', n_sum, n_diff, ' for image_data '
image_data = fltarr(n_sum, n_diff, 2)
filename = get_string('Enter filename to save data', filename)
mcs_pv = get_string('PV name of MCS:', mcs_pv)
mcs = obj_new('epics_mca', mcs_pv)
;
; Do an edge scan so user can set ROI
; Set speed of drive
edge_motor->set_slew_speed, flyback_speed
; Drive to low position
edge_motor->move, edge_start
edge_motor->wait
mcs->erase
mcs->acquire_on
edge_motor->set_slew_speed, scan_speed
edge_motor->move, edge_stop
edge_motor->wait
mcs->acquire_off
reply = get_string('Define an ROI around the edge, hit Return when ready', '')
roi = mcs->get_rois()
low_chan = roi[0].left
high_chan = roi[0].right
if (low_chan le 0 or high_chan le 0) then message, $
'You must define ROI 0 around the edge position to use this routine'
npoints = high_chan - low_chan + 1
magic = 2.*sqrt(2.*alog(2.))
; increment over diff and ave
for isum=0, n_sum-1 do begin
sum = sum_start + isum * sum_step
for idiff=0, n_diff-1 do begin
diff = diff_start + idiff * diff_step
f1_pos = (sum - diff ) /2.
f2_pos = (sum + diff ) /2.
print, 'moving to -> ' , sum, diff, f1_pos, f2_pos
f1_motor->move, f1_pos
f1_motor->wait
f2_motor->move, f2_pos
f2_motor->wait
; Set speed of drive
edge_motor->set_slew_speed, flyback_speed
; Drive to low position
edge_motor->move, edge_start
edge_motor->wait
mcs->erase
edge_motor->set_slew_speed, scan_speed
mcs->acquire_on
edge_motor->move, edge_stop
edge_motor->wait
mcs->acquire_off
data = mcs->get_data()
; Limit data to that in the ROI
data = data(low_chan:high_chan)
; Compute the derivative
deriv = float(data - shift(data, 1))
; Throw out first and last point
deriv = deriv(1:npoints-2)
; Flip sign if the scan started in air
np = n_elements(deriv)
if (data(0) gt data(np-1)) then deriv = -deriv
; Display the derivative
plot, deriv
; Compute array of motor positions with arbitrary origin
x = findgen(np) * edge_step
sm = smooth(deriv, 3)
max = max(sm, max_index)
thresh = .05 * max
left = max_index
while ((left gt 1) and (sm(left) gt thresh)) $
do left = left-1
right = max_index
while ((right lt np-1) and (sm(right) gt thresh)) $
do right = right+1
good = left + indgen(right-left+1)
;Compute FWHM
norm = total(deriv(good)) > 1.
m1 = total(deriv(good) * x(good)) / norm
m2 = sqrt( total(deriv(good) * (x(good)-m1)^2) / norm )
fwhm = magic * m2
image_data(isum, idiff, 0) = fwhm
image_data(isum, idiff, 1) = m1
oplot, x(good), deriv(good), psym=1
; print, format='(f9.4,f9.4,f12.4,f12.4 )', sum, diff, m1, fwhm
print, 'point [', strtrim(string(isum),2), ', ', $
strtrim(string(idiff),2), '] of [', $
strtrim(string(fix(n_sum)),2), ',', $
strtrim(string(fix(n_diff)),2), ']', sum, diff, f1_pos, f2_pos, m1, fwhm
; See if the user has typed ^P on the keyboard. If so, pause. Empty typeahead
; buffer checking each character for ^P.
c = get_kbrd(0)
if (c eq string(16B)) then begin
print, "Scanning interrupted by keyboard input"
print, " To plot data:"
print, " PLOT, IMAGE_DATA()"
print, " To look at numbers:"
print, " PRINT, IMAGE_DATA()"
print, " To abort scan:"
print, " ABORT_SCAN"
print, " .CON"
print, " To continue scan"
print, " .CON "
stop
endif
endfor
endfor
; exit for control-p mechanism
done_scan:
; Define BSIF variables
x_start = sum_start
x_stop = sum_stop
x_dist = sum_start + findgen(n_sum)*sum_step
x_title = 'Sum : (' + f1_motor_name + ' + ' + f2_motor_name+ ') / 2'
x_normal = 1
y_start = diff_start
y_stop = diff_stop
y_dist = diff_start + findgen(n_diff)*diff_step
y_title = 'Diff: (' + f2_motor_name + ' - ' + f1_motor_name+ ')'
y_normal = 1
rotated = 0
data_title = ['FWHM', 'Centroid']
image_title = 'Focus scan using ' + edge_motor_name
write_bsif, filename
;
; Move motors back
edge_motor->move, edge_start
f1_motor->move, f1_start
f2_motor->move, f2_start
edge_motor->set_slew_speed, flyback_speed
end
focus_scan_diag_save.pro 0100644 0000621 0000620 00000016142 06462265257 014727 0 ustar epics epics pro focus_scan_diag
; make 2-D grid of mirror forces to see focal spot.
;
; focus on a 2-D grid
; This program moves a motor back and forth, usually over an edge, and
; collects MCS data on the counts. It displays the derivative of the
; counts in another window.
; It assumes that the user has set ROI around the position of the edge
@bsif_common
@focus_scan_common.pro
print, '>> Focus scan program <<'
;
; initialize common block on first entrance
if (n_elements(sum_step) eq 0) then begin
print, ' setting initial values'
f1_motor_name = '13IDC:HforceU'
f2_motor_name = '13IDC:HforceD'
edge_motor_name= '13IDC:Stage_X'
mcs_pv = '13IDC:aim_mcs1'
dwell_time = 0.1
sum_start = 400.
sum_stop = 500.
sum_step = 10.
diff_start = -50.
diff_stop = 50.
diff_step = 10.
filename = 'focus.001'
endif
;
; calculate real starting values for f1 and f2
;
; get motor names
edge_motor_name = get_string('PV name of motor for edge scan:', $
edge_motor_name)
edge_motor = obj_new('epics_motor', edge_motor_name)
pos = edge_motor->get_position()
print, 'Current position = ', pos
edge_start = get_float('Start position for edge motor', pos)
edge_stop = get_float('Stop position for edge motor', pos+.1)
scan_speed = get_float('Scan speed for edge motor', .1)
flyback_speed = edge_motor->get_slew_speed()
flyback_speed = get_float('Flyback speed for edge motor', flyback_speed)
dwell_time = get_float('Dwell time of MCS (sec):', dwell_time)
edge_step = 1000.* scan_speed * dwell_time ; Step size in microns
f1_motor_name = get_string('PV name of F1 motor', f1_motor_name)
f1_motor = obj_new('epics_motor', f1_motor_name)
f2_motor_name = get_string('PV name of F2 motor', f2_motor_name)
f2_motor = obj_new('epics_motor', f2_motor_name)
f1_pos = f1_motor->get_position()
f2_pos = f2_motor->get_position()
print, 'Current positions of F1 and F2 = ', f1_pos, f2_pos
sum_start = get_float('Start position for Sum ', sum_start)
sum_stop = get_float('Stop position for Sum ', sum_stop)
sum_step = get_float('Step size for Sum ', sum_step)
diff_start = get_float('Start position for Diff ', diff_start)
diff_stop = get_float('Stop position for Diff ', diff_stop)
diff_step = get_float('Step size for Diff ', diff_step)
;sum_start = ave_start * 2.
;sum_stop = ave_stop * 2.
;sum_step = ave_step
;diff_start = diff_start * 2.
;diff_stop = diff_stop * 2.
f1_start = (sum_start + diff_start )/2.
f2_start = (sum_start - diff_start )/2.
; calculate number of scan points and create the image_data array
n_sum = (abs(sum_start - sum_stop )/ sum_step ) + 1
n_diff = (abs(diff_start - diff_stop )/ diff_step ) + 1
print,' allocating ', n_sum, n_diff, ' for image_data '
image_data = fltarr(n_sum, n_diff, 2)
filename = get_string('Enter filename to save data', filename)
mcs_pv = get_string('PV name of MCS:', mcs_pv)
mcs = obj_new('epics_mca', mcs_pv)
;
; Do an edge scan so user can set ROI
; Set speed of drive
edge_motor->set_slew_speed, flyback_speed
; Drive to low position
edge_motor->move, edge_start
edge_motor->wait
mcs->erase
mcs->acquire_on
edge_motor->set_slew_speed, scan_speed
edge_motor->move, edge_stop
edge_motor->wait
mcs->acquire_off
reply = get_string('Define an ROI around the edge, hit Return when ready', '')
roi = mcs->get_rois()
low_chan = roi[0].left
high_chan = roi[0].right
if (low_chan le 0 or high_chan le 0) then message, $
'You must define ROI 0 around the edge position to use this routine'
npoints = high_chan - low_chan + 1
magic = 2.*sqrt(2.*alog(2.))
; increment over diff and ave
for isum=0, n_sum-1 do begin
sum = sum_start + isum * sum_step
for idiff=0, n_diff-1 do begin
diff = diff_start + idiff * diff_step
f1_pos = (sum - diff ) /2.
f2_pos = (sum + diff ) /2.
print, 'moving to -> ' , sum, diff, f1_pos, f2_pos
f1_motor->move, f1_pos
f1_motor->wait
f2_motor->move, f2_pos
f2_motor->wait
; Set speed of drive
edge_motor->set_slew_speed, flyback_speed
; Drive to low position
edge_motor->move, edge_start
edge_motor->wait
mcs->erase
edge_motor->set_slew_speed, scan_speed
mcs->acquire_on
edge_motor->move, edge_stop
edge_motor->wait
mcs->acquire_off
data = mcs->get_data()
; Limit data to that in the ROI
data = data(low_chan:high_chan)
; Compute the derivative
deriv = float(data - shift(data, 1))
; Throw out first and last point
deriv = deriv(1:npoints-2)
; Flip sign if the scan started in air
np = n_elements(deriv)
if (data(0) gt data(np-1)) then deriv = -deriv
; Display the derivative
plot, deriv
; Compute array of motor positions with arbitrary origin
x = findgen(np) * edge_step
sm = smooth(deriv, 3)
max = max(sm, max_index)
thresh = .05 * max
left = max_index
while ((left gt 1) and (sm(left) gt thresh)) $
do left = left-1
right = max_index
while ((right lt np-1) and (sm(right) gt thresh)) $
do right = right+1
good = left + indgen(right-left+1)
;Compute FWHM
norm = total(deriv(good)) > 1.
m1 = total(deriv(good) * x(good)) / norm
m2 = sqrt( total(deriv(good) * (x(good)-m1)^2) / norm )
fwhm = magic * m2
image_data(isum, idiff, 0) = fwhm
image_data(isum, idiff, 1) = m1
oplot, x(good), deriv(good), psym=1
; print, format='(f9.4,f9.4,f12.4,f12.4 )', sum, diff, m1, fwhm
print, 'point [', strtrim(string(isum),2), ', ', $
strtrim(string(idiff),2), '] of [', $
strtrim(string(fix(n_sum)),2), ',', $
strtrim(string(fix(n_diff)),2), ']', sum, diff, f1_pos, f2_pos, m1, fwhm
; See if the user has typed ^P on the keyboard. If so, pause. Empty typeahead
; buffer checking each character for ^P.
c = get_kbrd(0)
if (c eq string(16B)) then begin
print, "Scanning interrupted by keyboard input"
print, " To plot data:"
print, " PLOT, IMAGE_DATA()"
print, " To look at numbers:"
print, " PRINT, IMAGE_DATA()"
print, " To abort scan:"
print, " ABORT_SCAN"
print, " .CON"
print, " To continue scan"
print, " .CON "
stop
endif
endfor
endfor
; exit for control-p mechanism
done_scan:
; Define BSIF variables
x_start = sum_start
x_stop = sum_stop
x_dist = sum_start + findgen(n_sum)*sum_step
x_title = 'Sum : (' + f1_motor_name + ' + ' + f2_motor_name+ ') / 2'
x_normal = 1
y_start = diff_start
y_stop = diff_stop
y_dist = diff_start + findgen(n_diff)*diff_step
y_title = 'Diff: (' + f2_motor_name + ' - ' + f1_motor_name+ ')'
y_normal = 1
rotated = 0
data_title = ['FWHM', 'Centroid']
image_title = 'Focus scan using ' + edge_motor_name
write_bsif, filename
;
; Move motors back
edge_motor->move, edge_start
f1_motor->move, f1_start
f2_motor->move, f2_start
edge_motor->set_slew_speed, flyback_speed
end
focus_scan.pro 0100755 0000621 0000620 00000013355 06462236566 012734 0 ustar epics epics pro focus_scan
; This routine adjusts the forces on the mirrors to
; and find the optimum
; focus on a 2-D grid
; This program moves a motor back and forth, usually over an edge, and
; collects MCS data on the counts. It displays the derivative of the
; counts in another window.
; It assumes that the user has set ROI around the position of the edge
@bsif_common
f1_motor_name = ' '
f2_motor_name = ' '
edge_motor_name = '13IDC:Stage_X'
mcs_pv = '13IDC:aim_mcs1'
print, '$Focus scan program'
edge_motor_name = get_string('PV name of motor for edge scan:', $
edge_motor_name)
edge_motor = obj_new('epics_motor', edge_motor_name)
pos = edge_motor->get_position()
print, 'Curent position = ', pos
edge_start = get_float('Start position for edge motor', pos)
edge_stop = get_float('Stop position for edge motor', pos+.1)
scan_speed = get_float('Scan speed for edge motor', .1)
flyback_speed = edge_motor->get_slew_speed()
flyback_speed = get_float('Flyback speed for edge motor', flyback_speed)
dwell_time = get_float('Dwell time of MCS (sec):', .01)
edge_step = 1000.* scan_speed * dwell_time ; Step size in microns
f1_motor_name = get_string('PV name of F1 motor', f1_motor_name)
f1_motor = obj_new('epics_motor', f1_motor_name)
pos = f1_motor->get_position()
print, 'Curent position = ', pos
f1_start = get_float('Start position for F1 motor', pos)
f1_stop = get_float('Stop position for F1 motor', pos+100.)
f1_step = get_float('Step size for F1 motor', 10.)
f2_motor_name = get_string('PV name of F2 motor', f2_motor_name)
f2_motor = obj_new('epics_motor', f2_motor_name)
pos = f2_motor->get_position()
print, 'Curent position = ', pos
f2_start = get_float('Start position for F2 motor', pos)
f2_stop = get_float('Stop position for F2 motor', pos+100.)
f2_step = get_float('Step size for F2 motor', 10.)
filename = get_string('Enter filename to save data', 'focus.001')
nx = (f1_stop-f1_start)/f1_step + 1
ny = (f2_stop-f2_start)/f2_step + 1
image_data = fltarr(nx, ny, 2)
mcs_pv = get_string('PV name of MCS:', mcs_pv)
mcs = obj_new('epics_mca', mcs_pv)
; Do an edge scan so user can set ROI
; Set speed of drive
edge_motor->set_slew_speed, flyback_speed
; Drive to low position
edge_motor->move, edge_start
edge_motor->wait
mcs->erase
mcs->acquire_on
edge_motor->set_slew_speed, scan_speed
edge_motor->move, edge_stop
edge_motor->wait
mcs->acquire_off
reply = get_string('Define an ROI around the edge, hit Return when ready', '')
roi = mcs->get_rois()
low_chan = roi[0].left
high_chan = roi[0].right
if (low_chan le 0 or high_chan le 0) then message, $
'You must define ROI 0 around the edge position to use this routine'
npoints = high_chan - low_chan + 1
f1_pos = f1_start
for ix=0, nx-1 do begin
f2_pos = f2_start
f1_motor->move, f1_pos
f1_motor->wait
for iy=0, ny-1 do begin
f2_motor->move, f2_pos
f2_motor->wait
; Set speed of drive
edge_motor->set_slew_speed, flyback_speed
; Drive to low position
edge_motor->move, edge_start
edge_motor->wait
mcs->erase
edge_motor->set_slew_speed, scan_speed
mcs->acquire_on
edge_motor->move, edge_stop
edge_motor->wait
mcs->acquire_off
data = mcs->get_data()
; Limit data to that in the ROI
data = data(low_chan:high_chan)
; Compute the derivative
deriv = float(data - shift(data, 1))
; Throw out first and last point
deriv = deriv(1:npoints-2)
; Flip sign if the scan started in air
np = n_elements(deriv)
if (data(0) gt data(np-1)) then deriv = -deriv
; Display the derivative
plot, deriv
; Compute array of motor positions with arbitrary origin
x = findgen(np) * edge_step
sm = smooth(deriv, 3)
max = max(sm, max_index)
thresh = .05 * max
left = max_index
while ((left gt 1) and (sm(left) gt thresh)) $
do left = left-1
right = max_index
while ((right lt np-1) and (sm(right) gt thresh)) $
do right = right+1
good = left + indgen(right-left+1)
;Compute FWHM
norm = total(deriv(good)) > 1.
m1 = total(deriv(good) * x(good)) / norm
m2 = total(deriv(good) * (x(good)-m1)^2) / norm
fwhm = 2.*sqrt(2.*alog(2.)) * sqrt(m2)
image_data(ix, iy, 0) = fwhm
image_data(ix, iy, 1) = m1
oplot, x(good), deriv(good), psym=1
;
print, 'point [', strtrim(string(ix),2), ', ', $
strtrim(string(iy),2), '] of [', $
strtrim(string(fix(nx)),2), ',', $
strtrim(string(fix(ny)),2), ']'
print, format='(4f12.3)', $
f1_pos, f2_pos, m1, fwhm
f2_pos = f2_pos + f2_step
endfor
f1_pos = f1_pos + f1_step
endfor
; Define BSIF variables
x_start = f1_start
x_stop = f1_stop
x_dist = f1_start + findgen(nx)*f1_step
x_title = 'F1 (' + f1_motor_name + ')'
x_normal = 1
y_start = f2_start
y_stop = f2_stop
y_dist = f2_start + findgen(ny)*f2_step
y_title = 'F2 (' + f2_motor_name + ')'
y_normal = 1
rotated = 0
data_title = ['FWHM', 'Centroid']
image_title = 'Focus scan using ' + edge_motor_name
write_bsif, filename
; Move motors back
edge_motor->move, edge_start
f1_motor->move, f1_start
f2_motor->move, f2_start
edge_motor->set_slew_speed, flyback_speed
end
get_choice.pro 0100755 0000621 0000620 00000005052 06413015652 012660 0 ustar epics epics function get_choice, prompt, choices, current
;+
; NAME:
; GET_CHOICE.PRO
; PURPOSE:
; To input a character string from a list of possible choices
; with prompting, a default value, and error handling.
; CALLING SEQUENCE:
; selection = GET_CHOICE(prompt, choices, default)
; INPUTS:
; PROMPT
; A prompt string, typically informing the user what value is required.
; CHOICES
; A character array, containing the list of possible choices for the user
; to select from
; DEFAULT
; The default choice. The is a number from 0 to n_elements(CHOICES)-1,
; i.e. it is the index in the CHOICES array of the default choice.
; If the user only types then this value will be returned.
; OPTIONAL INPUT PARAMETERS:
; None
; KEYWORD PARAMETERS:
; None
; OUTPUTS:
; SELECTION
; The function returns the index number of the selected choice in the
; CHOICES array, or the the default choice if the user did not enter
; a choice.
; OPTIONAL OUTPUT PARAMETERS:
; None
; COMMON BLOCKS:
; None
; SIDE EFFECTS:
; None
; RESTRICTIONS:
; The procedure does not detect ambiguous responses. For example,
; if CHOICES=["ORANGE", "APPLE", "ASPARAGUS"] and the user types
; "A" then APPLE will be selected and GET_CHOICE will return 1.
; PROCEDURE:
; Prints out the prompt string followed by the default choice
; in square brackets. Reads an input string from the user. If the
; input string is null then the default choice index is returned.
; If the string is not null it is checked to see if it matches one of the
; choices. The matching is case insensitive and only checks up to the
; number of characters which the user typed, so abbreviation is allowed.
; If a match is found the index number of that choice is returned.
; If the input is not a valid choice the list of valid choices is
; printed and the user is prompted again.
; MODIFICATION HISTORY:
; Created November, 1990 by Mark Rivers
; Added error checking October 23, 1991 - Mark Rivers
;-
on_ioerror, try_again
try_again:
print, prompt+' ['+choices(current)+']', format="(a,$)"
string = ' '
read, format='(q,a)', nc, string
if nc eq 0 then return, current
; The user entered a value, see if it is a valid option
n_choice = n_elements(choices)
for i=0, n_choice-1 do begin
if (strupcase(string) eq strupcase(strmid(choices(i),0,nc))) then return, i
endfor
print, 'Valid choices are:'
for i=0, n_choice-1 do print, choices(i)
goto, try_again
end
get_dist.pro 0100755 0000621 0000620 00000001166 06413015652 012373 0 ustar epics epics pro get_dist
; Temporary kludge to to get x_dist, y_dist from BSIF files with multiple
; scanning regions. Assumes READ_BSIF has already been called.
@bsif_common
if n_elements( user_buffer) gt 1 then begin
nbytes = 4 * (n_rows + n_cols)
if (user_buffer(0) eq 87) and (user_buffer(1) eq 25) and $
(n_elements(user_buffer) eq 2) then goto, over
if n_elements( user_buffer) ne nbytes then message, 'User buffer is wrong size
new_buffer = fltarr( n_rows + n_cols)
copy_bytes, nbytes, user_buffer, new_buffer
x_dist = double (new_buffer(0 : n_cols-1))
y_dist = double (new_buffer(n_cols : *))
endif
over:
end
get_float.pro 0100755 0000621 0000620 00000004463 06413015652 012540 0 ustar epics epics function get_float, prompt, value, min = min, max = max
;+
; NAME:
; GET_FLOAT.PRO
; PURPOSE:
; To input a floating point number, with prompting, a default value,
; optional bounds checking, and error handling.
; CALLING SEQUENCE:
; result = GET_FLOAT(prompt, default, min=min, max=max)
; INPUTS:
; PROMPT
; A prompt string, typically informing the user what value is required.
; DEFAULT
; The default value of the number to be input. If the user just types
; then this value will be returned.
; OPTIONAL INPUT PARAMETERS:
; None
; KEYWORD PARAMETERS:
; min and max are the smallest and largest allowed values. If either
; keyword is present and the user tries to enter a value outside the
; range, the default is changed to min or max and the user is presented
; with the prompt string and new default again.
; OUTPUTS:
; RESULT
; The function returns the floating point number which the user entered,
; or the default value if the user did not enter a value.
; OPTIONAL OUTPUT PARAMETERS:
; None
; COMMON BLOCKS:
; None
; SIDE EFFECTS:
; None
; RESTRICTIONS:
; None
; PROCEDURE:
; Prints out the prompt string followed by the default value for the
; number in square brackets. Reads an input string from the user. If the
; input string is null then the default value is returned. If the string
; is not null it is converted to a float and that is returned. If an
; invalid floating point number is entered the user is prompted again.
; MODIFICATION HISTORY:
; Created November, 1990 by Mark Rivers
; Added error checking October 23, 1991 - Mark Rivers
; Added min and max check September 4, 1992 - Harvey Rarback
;-
deflt = float(value)
on_ioerror, try_again
ok = 1
try_again:
if not ok then print, string( 7B)
print, prompt + ' [', deflt, ']', format='(a,g0.0,a,$)'
ok = 0
string = ' '
read, format='(q,a)', nc, string
if nc gt 0 then begin
temp = float(string)
if n_elements( min) ne 0 then begin
if temp lt min then begin
deflt = min
goto, try_again
endif
endif
if n_elements( max) ne 0 then begin
if temp gt max then begin
deflt = max
goto, try_again
endif
endif
return, temp
endif else begin
return, deflt
endelse
end
get_int.pro 0100755 0000621 0000620 00000004443 06413015652 012223 0 ustar epics epics function get_int, prompt, value, min = min, max = max
;+
; NAME:
; GET_INT.PRO
; PURPOSE:
; To input a short integer value number, with prompting, a default value,
; optional bounds checking, and error handling.
; CALLING SEQUENCE:
; result = GET_INT(prompt, default, min = min, max = max)
; INPUTS:
; PROMPT
; A prompt string, typically informing the user what value is required.
; DEFAULT
; The default value of the number to be input. If the user just types
; then this value will be returned.
; OPTIONAL INPUT PARAMETERS:
; None
; KEYWORD PARAMETERS:
; min and max are the smallest and largest allowed values. If either
; keyword is present and the user tries to enter a value outside the
; range, the default is changed to min or max and the user is presented
; with the prompt string and new default again.
; OUTPUTS:
; RESULT
; The function returns the short integer number which the user entered,
; or the default value if the user did not enter a value.
; OPTIONAL OUTPUT PARAMETERS:
; None
; COMMON BLOCKS:
; None
; SIDE EFFECTS:
; None
; RESTRICTIONS:
; None
; PROCEDURE:
; Prints out the prompt string followed by the default value for the
; number in square brackets. Reads an input string from the user. If the
; input string is null then the default value is returned. If the string
; is not null it is converted to an integer and that is returned. If an
; invalid number is entered the user is prompted again.
; MODIFICATION HISTORY:
; Created November, 1990 by Mark Rivers
; Added error checking October 23, 1991 - Mark Rivers
; Added min and max check September 4, 1992 - Harvey Rarback
;-
deflt = fix(value)
on_ioerror, try_again
ok = 1
try_again:
if not ok then print, string( 7B)
print, prompt + ' [', deflt, ']', format='(a,i0,a,$)'
ok = 0
string = ' '
read, format='(q,a)', nc, string
if nc gt 0 then begin
temp = fix(string)
if n_elements( min) ne 0 then begin
if temp lt min then begin
deflt = min
goto, try_again
endif
endif
if n_elements( max) ne 0 then begin
if temp gt max then begin
deflt = max
goto, try_again
endif
endif
return, temp
endif else begin
return, deflt
endelse
end
get_string.pro 0100755 0000621 0000620 00000003206 06413015653 012734 0 ustar epics epics function get_string, prompt, value
;+
; NAME:
; GET_STRING.PRO
; PURPOSE:
; To input a character string with prompting, a default value,
; and error handling.
; CALLING SEQUENCE:
; result = GET_STRING(prompt, default)
; INPUTS:
; PROMPT
; A prompt string, typically informing the user what value is required.
; DEFAULT
; The default value of the string to be input. If the user just types
; then this value will be returned.
; OPTIONAL INPUT PARAMETERS:
; None
; KEYWORD PARAMETERS:
; None
; OUTPUTS:
; RESULT
; The function returns the character string which the user entered,
; or the default string if the user did not enter one.
; OPTIONAL OUTPUT PARAMETERS:
; None
; COMMON BLOCKS:
; None
; SIDE EFFECTS:
; None
; RESTRICTIONS:
; None
; PROCEDURE:
; Prints out the prompt string followed by the default value for the
; input string in square brackets. Reads an input string from the user.
; If the input string is null then the default string is returned.
; If an I/O error occurs the the user is prompted again.
; MODIFICATION HISTORY:
; Created November, 1990 by Mark Rivers
; Added error checking October 23, 1991 - Mark Rivers
; Made input on a new line if the default string is >20 characters
;-
on_ioerror, try_again
try_again:
if strlen(value) le 20 then begin
print, prompt+' ['+value+']', format="(a,$)"
endif else begin
print, prompt+' ['+value+']', format="(a)"
endelse
string = ''
read, format='(q,a)', nc, string
if nc gt 0 then begin
return, string
endif else begin
return, value
endelse
end
init_scan_sd.pro 0100755 0000621 0000620 00000006457 07250007113 013227 0 ustar epics epics pro init_scan_sd
;+
; NAME:
; INIT_SCAN_SD
; PURPOSE:
; To initialize the scan descriptor structure. It needs to be called once
; in each IDL session in which scanning is done. It does nothing
; on second and subsequent calls.
; CALLING SEQUENCE:
; INIT_SCAN_SD
; INPUTS:
; None
; OUTPUTS:
; None
; COMMON BLOCKS:
; SCAN_COMMON, which contains the scan descriptor (SD) and motor
; descriptor (MD) structures.
; SIDE EFFECTS:
; Defines a number of new structure types, ROI, SCALER, SD, MD.
; PROCEDURE:
; Just defines SD and MD structures and puts them in common block
; SCAN_COMMON.
; MODIFICATION HISTORY:
; Created Dec. 1991 by Mark Rivers
; Modifications:
; Mar. 1995 by Harvey Rarback to allow piecewise linear md's
; March 2, 2001 MLR Added "gated" field to sd for gating scaler with MCA
;
;-
@scan_common
if (n_elements(sd) ne 0) then return
roi = {roi, $
name: " ", $ ; Name of roi
left_chan: 0, $ ; Left channel
right_chan: 0, $ ; Right channel
bgd_width: 0, $ ; Background width
plot: 1 $ ; Plot flag
}
scalers = {scalers, $
title: " ", $ ; Title of scaler
plot: 1 $ ; Plot flag
}
sd = {sd, $
file_name: "test.dat", $; File name
scan_type: 0, $; Scan type (scaler, ROI, spectrum, MCS, GE13)
title: " ", $; Scan title
mca: obj_new(), $ ; EPICS MCA object
mca_pvname: " ",$; EPICS MCA record name
n_chans: 0, $ ; Number of channels
eoffset: 0., $ ; Calibration offset
eslope: 0., $ ; Calibration slope
equad: 0., $ ; Calibration quadratic term
n_rois: 0, $ ; Number of ROIs
roi: replicate(roi, MAX_ROIS), $ ; ROI structures
scaler: obj_new(), $ ; EPICS scaler object
scaler_pvname: " ",$ ; EPICS scaler record name
n_scalers: 1, $ ; Number of scaler channels
scalers: replicate(scalers, MAX_SCALERS), $
gated: 0, $ ; Is scaler gated by MCA? 0=No, 1=Yes
n_dims: 1, $ ; Number of scan dimensions = 1 or 2
dims: make_array(MAX_SCAN_DIMS, value=10), $
; Scan dimensions
n_motors: 1, $ ; Number of motors
motors: objarr(MAX_MOTORS), $; Maximum number of motors
dwell_time: 1., $ ; Dwell time (seconds)
timing_mode: LIVE_TIME_MODE, $; LIVE_TIME(1) or REAL_TIME (2)
plot: make_array(MAX_SCALERS, /INT, value=-1), $
; Scalers or ROIs to plot
abort_scan_widget: 0L, $
abort_scan: 0L $
}
md = {md, $
name: " ", $ ; Motor name
n_parts: 1, $ ; Number of piecewise linear scan regions
start: replicate( NEW_START, MAX_PARTS), $ ; Region start positions
stop: replicate( 1., MAX_PARTS), $ ; Region stop positions
inc: replicate( .1, MAX_PARTS), $ ; Region step sizes
home: 0. $ ; Home position
}
md = replicate(md, MAX_MOTORS)
sd.plot(0)=0
end
make_help_files.pro 0100755 0000621 0000620 00000000434 07073712726 013706 0 ustar epics epics dest = '/net/cars1/usr/local/etc/httpd/htdocs/software/'
mk_html_help, 'epics_motor__define.pro', dest+'epics_motor_class.html', $
title = 'EPICS Motor Class'
mk_html_help, 'epics_scaler__define.pro', dest+'epics_scaler_class.html', $
title = 'EPICS Scaler Class'
end
parse_file_name.pro 0100755 0000621 0000620 00000001753 06413015653 013705 0 ustar epics epics pro parse_file_name, file, path, name, extension, version
if (!version.os_family eq 'VMS') then begin
full_name = findfile(file)
full_name = full_name(0)
start = 0
stop = strpos(full_name, ']', start)
n = stop - start + 1
path = strmid(full_name, start, n)
start = stop + 1
stop = strpos(full_name, '.', start) - 1
n = stop - start + 1
name = strmid(full_name, start, n)
start = stop + 1
stop = strpos(full_name, ';', start) - 1
n = stop - start + 1
extension = strmid(full_name, start, n)
start = stop + 1
stop = strlen(full_name)
n = stop - start + 1
version = strmid(full_name, start, n)
endif else begin
; Find the last "/" in the file name
path = ""
extension= ""
name = file
pos = strpos(name, '/')
if (pos gt 0) then begin
path = strmid(name, 0, pos)
name = strmid(name, pos+1, 100)
endif
pos = strpos(name, '.')
if (pos gt 0) then begin
name = strmid(name, 0, pos)
ext = strmid(name, pos+1, 100)
endif
endelse
end
parse_record_name.pro 0100755 0000621 0000620 00000000503 06413015653 014234 0 ustar epics epics pro parse_record_name, name, record, field
; This routine accepts a PV name and returns the name of the record and the
; field if there was one.
pos = strpos(name, '.')
if (pos eq -1) then begin
record = name
field = ''
endif else begin
record = strmid(name, 0, pos)
field = strmid(name, pos, 100)
endelse
end
read_bsif.pro 0100664 0000621 0000620 00000013220 07231343275 012504 0 ustar epics epics pro READ_BSIF, file, xdr=xdr, user=user, header_only=header_only, $
get_dist=get_dist
;+
; NAME:
; READ_BSIF.PRO
; PURPOSE:
; Reads a Brookhaven Standard Image Format file.
; The default on all systems except VMS is to read an XDR format file which is
; computer independent. On VMS only the default is to read the old-style
; non-XDR file format written on a VAX/VMS system.
; CALLING SEQUENCE:
; READ_BSIF, filename
; INPUTS:
; filename; The name of the file to read
; KEYWORD PARAMETERS:
; XDR
; Set this keyword to specify that the file is in XDR, a portable binary
; format. This keyword is only necessary on VMS.
; USER
; Returns the user_buffer
; HEADER_ONLY
; Set this keyword to only read the image header stuff and the user_buffer.
; GET_DIST
; Set this keyword to get x_dist and y_dist arrays for multiple scan regions
; OUTPUTS:
; The image data and parameters are read into common block BSIF_COMMON.
; All of the values in this common block are modified. See the file
; BSIF_COMMON.PRO for a description of each of the variables in this
; common block.
; COMMON BLOCKS:
; BSIF_COMMON, defined in BSIF_COMMON.PRO.
; SIDE EFFECTS:
; Modifies the variables in common block BSIF_COMMON.
; RESTRICTIONS:
; All of the data values at each pixel must be of the same data type,
; since the data are read into a 3-dimensional array.
;
; Calling READ_BSIF again overwrites any existing data, since the same
; common block is used. What we really need is the ability to read
; images into structures.
; PROCEDURE:
; For XDR files READ_BSIF opens the file and reads the data.
; For VMS BSIF files READ_BSIF.PRO simply calls READ_BSIF_I, which is
; a procedure which is written in C. It must be made known via the
; LINKIMAGE command. This is normally done in the startup file.
; MODIFICATION HISTORY
; Written in 1990 by Mark Rivers
; September 1996 Harvey Rarback. Added get_dist keyword.
; January 2001 Mark Rivers. Made XDR the default on non-VMS systems.
; Merged BNL version (with get_dist) with the APS version.
;-
@bsif_common
on_error, 2
if n_elements(file) eq 0 then message, 'Must specify a file name'
file = string(file)
if (keyword_set(xdr) or (!version.os ne 'vms')) then begin
get_lun, lun
openr, lun, file, /xdr
n_rows = 0L
n_cols = 0L
n_data = 0L
x_normal = 0L
y_normal = 0L
rotated = 0L
x_start = 0.
x_stop = 0.
y_start = 0.
y_stop = 0.
image_title = ' '
x_title = ' '
y_title = ' '
readu, lun, n_rows, n_cols, n_data, x_normal, $
y_normal, rotated, x_start, x_stop, y_start, y_stop, $
image_title, x_title, y_title
data_title = strarr(n_data)
data_type = 0L
ub_len = 0L
readu, lun, data_title, data_type, ub_len
nregions = keyword_set( get_dist) and ub_len ge 8
if keyword_set(header_only) then begin
image_data=0
case data_type of
0: image_data_bytes = 1 * n_cols * n_rows * n_data
1: image_data_bytes = 1 * n_cols * n_rows * n_data
2: image_data_bytes = 2 * n_cols * n_rows * n_data
3: image_data_bytes = 2 * n_cols * n_rows * n_data
4: image_data_bytes = 4 * n_cols * n_rows * n_data
5: image_data_bytes = 4 * n_cols * n_rows * n_data
6: image_data_bytes = 4 * n_cols * n_rows * n_data
7: image_data_bytes = 8 * n_cols * n_rows * n_data
endcase
tmp=fstat(lun)
offset=image_data_bytes+tmp.cur_ptr
point_lun,lun,offset
endif else begin
case data_type of
0: image_data = bytarr(n_cols, n_rows, n_data)
1: image_data = bytarr(n_cols, n_rows, n_data)
2: image_data = intarr(n_cols, n_rows, n_data)
3: image_data = intarr(n_cols, n_rows, n_data)
4: image_data = lonarr(n_cols, n_rows, n_data)
5: image_data = lonarr(n_cols, n_rows, n_data)
6: image_data = fltarr(n_cols, n_rows, n_data)
7: image_data = dblarr(n_cols, n_rows, n_data)
endcase
readu, lun, image_data
endelse
if n_elements(user) ne 0 then begin
readu, lun, user
user_buffer = user
endif else if nregions then begin
temp = fltarr( n_rows + n_cols)
readu, lun, temp
user_buffer = temp
endif else begin
user_buffer = bytarr(ub_len)
readu, lun, user_buffer
endelse
if nregions then begin
x_dist = user_buffer(0 : n_cols-1)
y_dist = user_buffer(n_cols : *)
endif else begin
x_dist = findgen(n_cols)/((n_cols-1)>1)*(x_stop-x_start) + x_start
y_dist = findgen(n_rows)/((n_rows-1)>1)*(y_stop-y_start) + y_start
endelse
close, lun
free_lun, lun
endif else begin
if keyword_set(header_only) then begin
read_bsif_h_i, file, n_rows, n_cols, n_data, x_normal, $
y_normal, rotated, x_start, x_stop, y_start, y_stop, $
image_title, x_title, y_title, data_title, data_type, $
compression_type, user_buffer, image_data
endif else begin
read_bsif_i, file, n_rows, n_cols, n_data, x_normal, $
y_normal, rotated, x_start, x_stop, y_start, y_stop, $
image_title, x_title, y_title, data_title, data_type, $
compression_type, user_buffer, image_data
endelse
if keyword_set( get_dist) and n_elements( user_buffer) ge 8 then begin
new_buffer = fltarr( n_rows + n_cols)
copy_bytes, nbytes, user_buffer, new_buffer
x_dist = double (new_buffer(0 : n_cols-1))
y_dist = double (new_buffer(n_cols : *))
endif else begin
x_dist = findgen(n_cols)/((n_cols-1)>1)*(x_stop-x_start) + x_start
y_dist = findgen(n_rows)/((n_rows-1)>1)*(y_stop-y_start) + y_start
endelse
endelse
return
end
scan_common.pro 0100755 0000621 0000620 00000000522 06413015654 013062 0 ustar epics epics MAX_SCAN_DIMS = 2
LIVE_TIME_MODE = 0
REAL_TIME_MODE = 1
MAX_ROIS = 10
MAX_SCALERS = 32
MAX_MOTORS = 32
MAX_PARTS = 10
NEW_START = 123456789.
SCALER_SCAN = 0
ROI_SCAN = 1
SPECTRUM_SCAN = 2
MCS_SCAN = 3
GE13_SCAN = 4
SCAN_TYPES = ['Scaler', 'ROI', 'Spectrum', 'MCS', 'Ge 13 Spectra']
common scan_common, sd, md
scan.pro 0100755 0000621 0000620 00000025566 07324661565 011543 0 ustar epics epics ; ************************************************************
pro abort_scan, event
; This routine gets called when the ABORT_SCAN button is pressed
; It sets the abort_scan flag in the scan descriptor, which the scan
; routines look at after each point and abort the scan
@scan_common
sd.abort_scan = 1
end
; ************************************************************
pro scan, setup=setup, $
file=file, $
time=time, $
motor=motor, $
start=start, $
stop=stop, $
step=step, $
title=title, $
plot=plot, $
confirm=confirm, $
relative=relative
;+
; NAME:
; SCAN.PRO
; PURPOSE:
; To scan motors and collect data.
; CALLING SEQUENCE:
; SCAN, [keywords]
; INPUTS:
; None
; KEYWORD PARAMETERS:
; FILE=filename
; Used to specify the name of a file in which to save the scan data.
; Data are saved in Brookhaven Standard Image Format (BSIF).
; If the file name extension is numeric (e.g. MY_SCAN.001) then the
; extension number will be automatically incremented after the file is
; written, so the next scan will be MY_SCAN.002, etc.
; TIME=time
; Used to specify the collection time per point in seconds.
; MOTOR=[motor1, motor2, ...]
; Used to specify the name(s) of the motors to be scanned.
; START=start
; START=[start1, start2, ...]
; The start position(s) of the motor(s) being scanned.
; The order of the elements is the same as the scanning regions of each
; of the motors.
; STOP=stop
; STOP=[stop1, stop2, ...]
; The stop positions(s) of the motor(s) being scanned.
; The order of the elements is the same as the scanning regions of each
; of the motors.
; STEP=step
; STEP=[step1, step2, ...]
; The step size(s) of the motor(s) being scanned.
; The order of the elements is the same as the scanning regions of each
; of the motors.
; /RELATIVE
; If /RELATIVE is specified then the START and STOP positions are
; positions relative to the current motor position(s). If /RELATIVE
; is not specified then the START and STOP position(s) are absolute
; motor position(s).
; TITLE=title
; A string containing the title of the scan.
; PLOT=plot_values
; A vector of data values to be plotted in real time as data are
; collected. The default is not to plot any values on the first scan
; after entering IDL. Subsequent scans will plot the same data as
; the previous scan so the PLOT keyword need only be given once.
; Examples:
;
; Assume a scaler scan with data being collected from 3 scalers:
; PLOT=[0,2] ; will plot the first and third scalers as data are
; ; collected.
; Assume an ROI scan with data being collected from 2 ROIs and 2 scalers:
; PLOT=[0,1,2] ; will plot both ROIs and the first scaler.
;
; Use PLOT=-1 to turn off real-time plotting.
; /SETUP
; If set then routine SETUP_SCAN is called before beginning the scan.
; This allows the user to modify scan parameters with prompting.
; /CONFIRM
; If set then routine CONFIRM_SCAN is called before beginning the scan.
; This echoes the scan parameters and allows the user to abort if they
; are not acceptable.
; OUTPUTS:
; None
; COMMON BLOCKS:
; BSIF_COMMON The variables in this common block are modified to reflect
; the scan parameters.
; SCAN_COMMON The scan descriptor structure (SD) is used to control
; the scan. It is modified by the keywords passed to this routine and
; by SETUP_SCAN.
; SIDE EFFECTS:
; Modifies values in above common blocks.
; Moves motors, reads CAMAC scalers, reads Nuclear Data configruations,
; etc.
; RESTRICTIONS:
; The keyword parameters scan only be used to control a subset of the
; scan parameters. Other parameters can only be modified by calling
; SETUP_SCAN.
; PROCEDURE:
; This routine calls SETUP_SCAN and CONFIRM_SCAN if the appropriate
; keywords are specified. It then does some bookeeping and calls the
; appropriate scan routine (SCAN_SCALER, SCAN_ROI, SCAN_SPECTRUM,
; SCAN_MCS, SCAN_GE13).
; MODIFICATION HISTORY:
; Created January 1992 by Mark Rivers
; Feb. 22, 1995. Made routine check that scan increment was an integral
; number of motor steps. Mark Rivers
; March 1995 Modified for piecewise linear scans. Harvey Rarback
; October 1997 Mark Rivers Converted to IDL objects
; November 1997 Mark Rivers Added ABORT_SCAN
; January 16, 2001 Mark Rivers Added code (from BNL version) to save
; positions in piecewise linear scans
;-
@bsif_common
@scan_common
;on_error, 2
if (n_elements(sd) eq 0) or (keyword_set(setup)) then begin
setup_scan
confirm = 1
endif
if keyword_set(file) then sd.file_name = file
if keyword_set(time) then sd.dwell_time = time
if n_elements(motor) ne 0 then begin
for i=0, n_elements(motor)-1 do begin
m = obj_new('epics_motor', motor)
if (not obj_valid(m)) then message, 'Unknown motor= ' + motor
sd.motors(i) = m
md(i).name = sd.motors(i)->get_name()
endfor
endif
; Get the current (home) positions of each motor
for i=0, sd.n_motors-1 do begin
md(i).home = sd.motors(i)->get_position()
endfor
if n_elements(start) ne 0 then begin
n = -1
for i=0, sd.n_motors-1 do begin
for j=0, md(i).n_parts-1 do begin
n = n + 1
if n lt n_elements(start) then begin
if keyword_set(relative) then begin
md(i).start(j) = md(i).home + start(n)
endif else begin
md(i).start(j) = start(n)
endelse
endif
endfor
endfor
endif
if n_elements(stop) ne 0 then begin
n = -1
for i=0, sd.n_motors-1 do begin
for j=0, md(i).n_parts-1 do begin
n = n + 1
if n lt n_elements(stop) then begin
if keyword_set(relative) then begin
md(i).stop(j) = md(i).home + stop(n)
endif else begin
md(i).stop(j) = stop(n)
endelse
endif
endfor
endfor
endif
if n_elements(step) ne 0 then begin
n = -1
for i=0, sd.n_motors-1 do begin
for j=0, md(i).n_parts-1 do begin
n = n + 1
if n lt n_elements(step) then md(i).inc(j) = step(n)
endfor
endfor
endif
; Make sure the motor increments are an integral nonzero number of motor steps
for i=0, sd.n_motors-1 do begin
scale = sd.motors(i)->get_scale()
for j=0, md(i).n_parts-1 do begin
t = round(md(i).inc(j) * scale) / scale
if t eq 0. then t = 1. / scale
if (abs(t) ne abs(md(i).inc(j))) then begin
message, string('Step size of motor ' + md(i).name +' changed from ', $
md(i).inc(j), ' to ', t, format = '(a,g0.0,a,g0.0)'), $
/continue
md(i).inc(j) = t
endif
endfor
endfor
; Correct the sign of the motor increments if necessary
for i=0, sd.n_motors-1 do begin
for j=0, md(i).n_parts-1 do begin
if (md(i).stop(j) gt md(i).start(j)) then begin
md(i).inc(j) = abs(md(i).inc(j))
endif else begin
md(i).inc(j) = -abs(md(i).inc(j))
endelse
endfor
endfor
if n_elements(plot) ne 0 then begin
sd.plot=-1
for i=0, n_elements(plot)-1 do sd.plot(plot(i)) = 1
endif
if n_elements(title) ne 0 then sd.title = title
; Compute number of points and target locations in scan
x_dist = [0.]
sd.dims(0) = 0
for l = 0, md(0).n_parts-1 do begin
xstart = md(0).start(l)
xstop = md(0).stop(l)
xstep = md(0).inc(l)
; Underestimate number of scanning steps to minimize chance of "backtracking"
; for multiple region scans
nx = fix( abs( (xstart - xstop) / xstep)) + 1
sd.dims(0) = sd.dims(0) + nx
x_dist = [x_dist, xstart + findgen( nx) * xstep]
endfor
x_dist = x_dist(1 : *)
if (sd.n_dims eq 2) then begin ; 2-D scan
y_dist = [0.]
sd.dims(1) = 0
for l = 0, md(1).n_parts-1 do begin
ystart = md(1).start(l)
ystop = md(1).stop(l)
ystep = md(1).inc(l)
ny = fix( abs( (ystart - ystop) / ystep)) + 1
sd.dims(1) = sd.dims(1) + ny
y_dist = [y_dist, ystart + findgen( ny) * ystep]
endfor
y_dist = y_dist(1 : *)
endif else begin
sd.dims(1) = 1
y_dist = [0.]
endelse
if keyword_set(confirm) then confirm_scan
if sd.n_dims eq 1 then begin
n_cols = sd.dims(0)
n_rows = 1
endif else begin
n_cols = sd.dims(0)
n_rows = sd.dims(1)
endelse
case sd.scan_type of
SCALER_SCAN: begin
; The number of data at each pixel is the number of scalers
n_data = sd.n_scalers
for i=0, sd.n_scalers-1 do data_title(i) = sd.scalers[i].title
end
ROI_SCAN: begin
; The number of data at each pixel is the number of ROIs plus the number of
; scalers plus 2, for live time and real time.
n_data = sd.n_rois + sd.n_scalers + 2
for i=0, sd.n_rois-1 do data_title(i) = sd.roi(i).name
for i=0, sd.n_scalers-1 do data_title(sd.n_rois+i) = sd.scalers[i].title
data_title(sd.n_rois + sd.n_scalers) = 'Real time (msec)'
data_title(sd.n_rois + sd.n_scalers + 1) = 'Live time (msec)'
end
SPECTRUM_SCAN: begin
; Dummy value for n_data
n_data = 1
end
MCS_SCAN: message, 'scan_mcs is not supported now.'
endcase
if (md(0).inc(0) gt 0.) then x_normal = 1 else x_normal = 0
if (md(1).inc(0) gt 0.) then y_normal = 1 else y_normal = 0
rotated = 0
x_start = md(0).start(0)
x_stop = md(0).stop(md(0).n_parts-1)
y_start = md(1).start(0)
y_stop = md(1).stop(md(1).n_parts-1)
image_title = sd.title
x_title = md(0).name
y_title = md(1).name
data_title = strarr(n_data)
image_data = lonarr(n_cols, n_rows, n_data)
user_buffer = [0B]
; Tell user how to abort scan
print, 'Type ^P to pause scan after next pixel'
; Move motors to beginning of scan
for i=0, sd.n_motors-1 do sd.motors(i)->move, md(i).start(0)
for i=0, sd.n_motors-1 do sd.motors(i)->wait
; Reset abort scan flag
sd.abort_scan=0
; Now call the appropriate scan routine
case sd.scan_type of
SCALER_SCAN: scan_scaler
ROI_SCAN: scan_roi
SPECTRUM_SCAN: scan_spectrum
MCS_SCAN: message, 'scan_mcs is not supported now.'
endcase
; Reset abort scan flag in case scan was aborted
sd.abort_scan=0
; Move all of the motors back to the start of the scan
for i=0, sd.n_motors-1 do sd.motors(i)->move, md(i).home
for i=0, sd.n_motors-1 do sd.motors(i)->wait
if ((md(0).n_parts gt 1) or (md(1).n_parts gt 1)) then begin
nbytes = 4 * (n_rows + n_cols)
user_buffer = bytarr(nbytes)
copy_bytes, nbytes, float( [x_dist, y_dist]), user_buffer
endif
; All done, save the data
if (sd.scan_type ne SPECTRUM_SCAN) then begin
write_bsif, sd.file_name
print, 'Data saved in file ', sd.file_name
endif
; Increment the file extension number if it is numeric
sd.file_name = increment_filename(sd.file_name)
; Set X and Y back to autorange (they are reset in plot routine)
!x.range=0
!y.range=0
end
scan_roi.pro 0100755 0000621 0000620 00000006466 07251027335 012400 0 ustar epics epics pro scan_roi
; Modified:
; March 2, 2001 MLR Added support for "gated" mode in which EPICS scaler is gated
; by EPICS MCA
; March 5, 2001 MLR Fixed bugs in "gated" mode. Added 0.1 second delays in 2
; places.
@bsif_common
@scan_common
line_scan = (sd.n_dims eq 1)
; Set the preset live or real time on the MCA
presets = sd.mca->get_presets()
old_presets = presets
if (sd.timing_mode eq REAL_TIME_MODE) then begin
presets.real_time = sd.dwell_time
presets.live_time = 0.
endif else begin
presets.real_time = 0.
presets.live_time = sd.dwell_time
endelse
sd.mca->set_presets, presets
for row=0, n_rows-1 do begin
for col=0, n_cols-1 do begin
; The motors are in the correct position.
; Clear data, begin acquisition
; For now we assume that all scalers are on one module
; and that there is only one MCA record involved
; Erase MCA
sd.mca->erase
; Start MCA. It will not actually start counting until the scaler is
; started, since it is gated by the scaler (not true with EPICS)
; Erase and start scaler.
if (sd.gated) then begin
; If we are gated then the scaler should count for as long as possible
sd.scaler->start, sd.dwell_time*10
; Wait 0.1 seconds so that we can be sure the scaler has
; actually started counting before turning on MCA
wait, 0.1
endif else begin
sd.scaler->start, sd.dwell_time
endelse
sd.mca->acquire_on
; Wait for MCA to complete. Wait 0.1 seconds so that we can be sure the MCA has
; actually started before we test if it is done.
wait, 0.1
sd.mca->acquire_wait, sd.dwell_time
; If in gated mode then stop the scaler
; If not in gated mode then wait for the scaler
if (sd.gated) then begin
sd.scaler->scaler_stop
endif else begin
sd.scaler->wait
endelse
; Save ROI counts
sd.mca->get_roi_counts, total, net
for i=0, sd.n_rois-1 do begin
image_data(col, row, i) = net[i]
endfor
; Save scaler counts
counts = sd.scaler->read()
for i=0, sd.n_scalers-1 do begin
j = i + sd.n_rois
image_data(col, row, j) = counts[i]
endfor
elapsed = sd.mca->get_elapsed()
offset = sd.n_rois + sd.n_scalers
image_data(col, row, offset) = elapsed.real_time*1000.
image_data(col, row, offset+1) =elapsed.live_time*1000.
; Call the routine to display this pixel
display_point, row, col
; The scan could have been aborted at this point
if (sd.abort_scan ne 0) then goto, done
; Move to next point - skip if last point
if (col ne n_cols-1) then begin
sd.motors(0)->move, x_dist(col+1)
; If this is line scan move any other motors
if line_scan then $
for i=1, sd.n_motors-1 do sd.motors(i)->move, /relative, $
md(i).inc(0)
for i=0, sd.n_motors-1 do sd.motors(i)->wait
endif
endfor ; Fast motor loop
; Move slow axis, skip if last point or if line scan
if (row ne n_rows-1) and (not line_scan) then begin
sd.motors(1)->move, y_dist(row+1)
sd.motors(1)->wait
; Move fast motor back to beginning of scan
sd.motors(0)->move, md(0).start(0)
sd.motors(0)->wait
endif
endfor ; Slow scan loop
done:
sd.mca->set_presets, old_presets
return
end
scan_roi_vax.pro 0100775 0000621 0000620 00000010567 07231362675 013264 0 ustar epics epics pro scan_roi
@bsif_common
@scan_common
@camdef
sd.config_chan = cam_open(sd.config_name)
real_time_buff = [0L, 0L]
live_time_buff = [0L, 0L]
if (sd.timing_mode eq LIVE_TIME_MODE) then begin
live_time_buff = secs_to_delta(sd.dwell_time)
endif else begin
real_time_buff = secs_to_delta(sd.dwell_time)
endelse
cam_putp, sd.config_chan, CAM_X_PREAL, real_time_buff
cam_putp, sd.config_chan, CAM_X_PLIVE, live_time_buff
k = sd.active_motors ; Shorthand
line_scan = (sd.n_dims eq 1)
real_time = 0.
live_time = 0.
time_buff=lonarr(2)
if (sd.n_rois gt 0) then background = lonarr(sd.n_rois)
spect_data = lonarr(sd.n_chans)
print_time = 0.
decay=1.0
for row=0, n_rows-1 do begin
for col=0, n_cols-1 do begin
; The motors are in the correct position. Tell the ND9900 to
; clear data, begin acquisition
; THE FOLLOWING PRINT STATEMENT IS NECESSARY TO SOLVE A TIMING BUG WHICH HAS
; SURFACED EITHER IN THE NEW VERSION OF THE NUCLEAR DATA SOFTWARE OR THE NEW
; VERSION OF MOTOR_WAIT. IT NEEDS TO BE FIXED
wait_for_beam:
print, 'Erasing ND9900'
status = cam_command(sd.config_chan, 'ERASE')
for i=0, sd.n_scalers-1 do clear_scaler, sd.scaler(i).sys_number
status = cam_command(sd.config_chan, 'ON')
; Wait for ND9900 acquisition to complete.
nd_wait, sd.config_chan
if (sd.beam_scaler ge 0) then begin ; check beam dump
beam_check = read_scaler(sd.scaler(sd.beam_scaler).sys_number)
; Get real time
cam_getp, sd.config_chan, CAM_X_EREAL, time_buff
real_time = delta_to_secs(time_buff)
; Get live time
cam_getp, sd.config_chan, CAM_X_ELIVE, time_buff
live_time = delta_to_secs(time_buff)
if (real_time GT 0.) then beam_check = beam_check / real_time
print, beam_check
; If this is the first measurement then save this initial value
if (col eq 0) and (row eq 0) then begin
initial_beam_check = beam_check
if (initial_beam_check EQ 0.) then message, 'Zero beam check counts'
endif
decay = beam_check / initial_beam_check
; If beam check is <10% of initial value, beam has dumped
if (decay lt 0.1) then begin
if systime(1) - print_time ge 900. then begin
print, 'Beam has dumped, waiting at ' + strmid( systime(), 11,5) + '.'
print_time = systime(1)
endif
wait, 5
goto, wait_for_beam
endif else if print_time ne 0. then begin
print_time = 0.
print, 'Beam restored at ' + strmid( systime(), 11, 5) + '.'
endif
endif
; Read spectrum from ND9900
cam_read, sd.config_chan, spect_data, 1, 1, sd.n_chans
for i=0, sd.n_rois-1 do begin
background(i) = 0
l = sd.roi(i).left_chan
r = sd.roi(i).right_chan
w = sd.roi(i).bgd_width
if (w GT 0) then begin
background(i) = (r-l+1) * $
(total(spect_data((l-w):(l-1))) + $
total(spect_data((r+1):(r+w)))) / (2.*w)
endif
image_data(col, row, i) = total(spect_data(l:r)) - background(i)
endfor
; Save scaler counts
offset = sd.n_rois
for i=0, sd.n_scalers-1 do begin
image_data(col, row, offset+i) = read_scaler(sd.scaler(i).sys_number)
endfor
; Save elapsed live and real time in msec
offset = sd.n_rois + sd.n_scalers
image_data(col, row, offset) = real_time*1000.
image_data(col, row, offset+1) = live_time*1000.
; Call the routine to display this pixel
display_point, row, col, decay, background
; Move to next point - skip if last point
if (col ne n_cols-1) then begin
move_motor_to, k(0), x_dist(col+1)
; If this is line scan move any other motors
if line_scan then $
for i=1, sd.n_motors-1 do move_motor_by, k(i), md(k(i)).inc(0)
for i=0, sd.n_motors-1 do motor_wait, k(i)
endif
endfor ; Fast motor loop
; Move slow axis, skip if last point or if line scan
if (row ne n_rows-1) and (not line_scan) then begin
move_motor_to, k(1), y_dist(row+1)
motor_wait, k(1)
; Move fast motor back to beginning of scan
move_motor_to, k(0), md(k(0)).start(0)
motor_wait, k(0)
endif
endfor ; Slow motor loop
; Set preset live and real times back to 0 so we can collect by hand
cam_putp, sd.config_chan, CAM_X_PREAL, [0L, 0L]
cam_putp, sd.config_chan, CAM_X_PLIVE, [0L, 0L]
; Close the ND configuration so other processes can access it
cam_close
return
end
scan_scaler.pro 0100755 0000621 0000620 00000002641 06430410563 013044 0 ustar epics epics pro scan_scaler
@bsif_common
@scan_common
line_scan = (sd.n_dims eq 1)
for row=0, n_rows-1 do begin
for col=0, n_cols-1 do begin
; The motors are in the correct position.
; Clear data, begin acquisition
; For now we assume that all scalers are on one module
sd.scaler->start, sd.dwell_time
; Wait for scaler to complete.
sd.scaler->wait
; Save scaler counts
counts = sd.scaler->read()
for i=0, sd.n_scalers-1 do begin
image_data(col, row, i) = counts[i]
endfor
; Call the routine to display this pixel
display_point, row, col
; The scan could have been aborted at this point
if (sd.abort_scan ne 0) then return
; Move to next point - skip if last point
if (col ne n_cols-1) then begin
sd.motors(0)->move, x_dist(col+1)
; If this is line scan move any other motors
if line_scan then $
for i=1, sd.n_motors-1 do sd.motors(i)->move, /relative, $
md(i).inc(0)
for i=0, sd.n_motors-1 do sd.motors(i)->wait
endif
endfor ; Fast motor loop
; Move slow axis, skip if last point or if line scan
if (row ne n_rows-1) and (not line_scan) then begin
sd.motors(1)->move, y_dist(row+1)
sd.motors(1)->wait
; Move fast motor back to beginning of scan
sd.motors(0)->move, md(0).start(0)
sd.motors(0)->wait
endif
endfor ; Slow scan loop
return
end
scan_spectrum.pro 0100755 0000621 0000620 00000005563 07320426021 013436 0 ustar epics epics pro scan_spectrum, file_name
; Modified:
; July 3, 2001 MLR Converted from old VAX version to new EPICS version.
@bsif_common
@scan_common
line_scan = (sd.n_dims eq 1)
; Set the preset live or real time on the MCA
presets = sd.mca->get_presets()
old_presets = presets
if (sd.timing_mode eq REAL_TIME_MODE) then begin
presets.real_time = sd.dwell_time
presets.live_time = 0.
endif else begin
presets.real_time = 0.
presets.live_time = sd.dwell_time
endelse
sd.mca->set_presets, presets
for row=0, n_rows-1 do begin
for col=0, n_cols-1 do begin
; The motors are in the correct position.
; Clear data, begin acquisition
; For now we assume that all scalers are on one module
; and that there is only one MCA record involved
; Erase MCA
sd.mca->erase
; Start MCA. It will not actually start counting until the scaler is
; started, since it is gated by the scaler (not true with EPICS)
; Erase and start scaler.
if (sd.gated) then begin
; If we are gated then the scaler should count for as long as possible
sd.scaler->start, sd.dwell_time*10
; Wait 0.1 seconds so that we can be sure the scaler has
; actually started counting before turning on MCA
wait, 0.1
endif else begin
sd.scaler->start, sd.dwell_time
endelse
sd.mca->acquire_on
; Wait for MCA to complete. Wait 0.1 seconds so that we can be sure the MCA has
; actually started before we test if it is done.
wait, 0.1
sd.mca->acquire_wait, sd.dwell_time
; If in gated mode then stop the scaler
; If not in gated mode then wait for the scaler
if (sd.gated) then begin
sd.scaler->scaler_stop
endif else begin
sd.scaler->wait
endelse
; Save spectrum
sd.mca->write_file, sd.file_name
; Print out info
print, 'Column, row = [',col, row,'], total=[',n_cols-1, n_rows-1,'] file=', $
sd.file_name, format='(a,i4,i4,a,i4,i4,a,a)'
sd.file_name = increment_filename(sd.file_name)
; The scan could have been aborted at this point
if (sd.abort_scan ne 0) then goto, done
; Move to next point - skip if last point
if (col ne n_cols-1) then begin
sd.motors(0)->move, x_dist(col+1)
; If this is line scan move any other motors
if line_scan then $
for i=1, sd.n_motors-1 do sd.motors(i)->move, /relative, $
md(i).inc(0)
for i=0, sd.n_motors-1 do sd.motors(i)->wait
endif
endfor ; Fast motor loop
; Move slow axis, skip if last point or if line scan
if (row ne n_rows-1) and (not line_scan) then begin
sd.motors(1)->move, y_dist(row+1)
sd.motors(1)->wait
; Move fast motor back to beginning of scan
sd.motors(0)->move, md(0).start(0)
sd.motors(0)->wait
endif
endfor ; Slow scan loop
done:
sd.mca->set_presets, old_presets
return
end
scan_spectrum_vax.pro 0100755 0000621 0000620 00000011535 07320422616 014316 0 ustar epics epics pro scan_spectrum, file_name
@bsif_common
@scan_common
@camdef
sd.config_chan = cam_open(sd.config_name)
real_time_buff = [0L, 0L]
live_time_buff = [0L, 0L]
if (sd.timing_mode eq LIVE_TIME_MODE) then begin
live_time_buff = secs_to_delta(sd.dwell_time)
endif else begin
real_time_buff = secs_to_delta(sd.dwell_time)
endelse
cam_putp, sd.config_chan, CAM_X_PREAL, real_time_buff
cam_putp, sd.config_chan, CAM_X_PLIVE, live_time_buff
k = sd.active_motors ; Shorthand
n_cols = sd.roi(0).right_chan - sd.roi(0).left_chan + 1
n_rows = sd.dims(0)
; The number of data at each pixel is always 1 for now
n_data = sd.dims(1)
image_data = lonarr(n_cols, n_rows, n_data)
y_start = x_start
y_stop = x_stop
y_dist = x_dist
x_start = sd.eoffset + sd.roi(0).left_chan*sd.eslope
x_stop = sd.eoffset + sd.roi(0).right_chan*sd.eslope
x_dist = findgen(n_cols)/((n_cols-1)>1)*(x_stop-x_start) + x_start
x_title = 'Energy'
y_title = md(k(0)).name
data_title = strarr(n_data)
data_title(0) = string(sd.n_scalers)+ $
' Scalers; Real time; Live time; Spectral counts('+ $
string(n_cols)+' channels)'
for i=1, n_data-1 do data_title(i) = 'Row '+string(i)
image_data = lonarr(n_cols, n_rows, n_data)
line_scan = (sd.n_dims eq 1)
real_time = 0.
live_time = 0.
time_buff=lonarr(2)
spect_data = lonarr(n_cols)
decay = 1.
print_time = 0.
for row=0, n_data-1 do begin
for col=0, n_rows-1 do begin
; The motors are in the correct position. Tell the ND9900 to
; clear data, begin acquisition
; THE FOLLOWING PRINT STATEMENT IS NECESSARY TO SOLVE A TIMING BUG WHICH HAS
; SURFACED EITHER IN THE NEW VERSION OF THE NUCLEAR DATA SOFTWARE OR THE NEW
; VERSION OF MOTOR_WAIT. IT NEEDS TO BE FIXED
print, 'Erasing ND9900'
wait_for_beam:
status = cam_command(sd.config_chan, 'ERASE')
for i=0, sd.n_scalers-1 do clear_scaler, sd.scaler(i).sys_number
status = cam_command(sd.config_chan, 'ON')
; Wait for ND9900 acquisition to complete.
nd_wait, sd.config_chan
if (sd.beam_scaler ge 0) then begin ; check beam dump
beam_check = read_scaler(sd.scaler(sd.beam_scaler).sys_number)
; Get real time
cam_getp, sd.config_chan, CAM_X_EREAL, time_buff
real_time = delta_to_secs(time_buff)
; Get live time
cam_getp, sd.config_chan, CAM_X_ELIVE, time_buff
live_time = delta_to_secs(time_buff)
if (real_time GT 0.) then beam_check = beam_check / real_time
; If this is the first measurement then save this initial value
if (col eq 0) and (row eq 0) then begin
initial_beam_check = beam_check
if (initial_beam_check EQ 0.) then message, 'Zero beam check counts'
endif
decay = beam_check / initial_beam_check
; If beam check is <10% of initial value, beam has dumped
if (decay lt 0.1) then begin
if systime(1) - print_time ge 900. then begin
print, 'Beam has dumped, waiting at ' + strmid( systime(), 11,5) + '.'
print_time = systime(1)
endif
wait, 5
goto, wait_for_beam
endif else if print_time ne 0. then begin
print_time = 0.
print, 'Beam restored at ' + strmid( systime(), 11, 5) + '.'
endif
endif
; Read spectrum from ND9900
cam_read, sd.config_chan, spect_data, sd.roi(0).left_chan, 1, n_cols
image_data(0, col, row) = spect_data
; Save scaler counts
offset = 0
for i=0, sd.n_scalers-1 do begin
image_data(offset+i, col, row) = read_scaler(sd.scaler(i).sys_number)
endfor
; Save elapsed live and real time in msec
offset = sd.n_scalers
image_data(offset, col, row) = real_time*1000.
image_data(offset+1, col, row) = live_time*1000.
; Call the routine to display this pixel
display_point, row, col, decay, background
; The scan could have been aborted at this point
if (sd.abort_scan ne 0) then return
; Move to next point - skip if last point
if (col ne n_rows-1) then begin
move_motor_to, k(0), y_dist(col+1)
; If this is line scan move any other motors
if line_scan then $
for i=1, sd.n_motors-1 do move_motor, /relative, k(i), md(k(i)).inc(0)
for i=0, sd.n_motors-1 do motor_wait, k(i)
endif
endfor ; Fast motor loop
; Move slow axis, skip if last point or if line scan
if (row ne n_data-1) and (not line_scan) then begin
move_motor, /relative, k(1), md(k(1)).inc(0) ; no piecewise linear available here
motor_wait, k(1)
; Move fast motor back to beginning of scan
move_motor_to, k(0), md(k(0)).start(0)
motor_wait, k(0)
endif
endfor ; Slow motor loop
; Set preset live and real times back to 0 so we can collect by hand
cam_putp, sd.config_chan, CAM_X_PREAL, [0L, 0L]
cam_putp, sd.config_chan, CAM_X_PLIVE, [0L, 0L]
; Close the ND configuration so other processes can access it
cam_close
; Close the Fortran output lun if open
if (n_elements(fortran_lun) ne 0) then close, fortran_lun
return
end
scan_vax.pro 0100775 0000621 0000620 00000024666 07231362675 012420 0 ustar epics epics pro scan, setup=setup, $
file=file, $
time=time, $
motor=motor, $
start=start, $
stop=stop, $
step=step, $
title=title, $
plot=plot, $
confirm=confirm, $
relative=relative
;+
; NAME:
; SCAN.PRO
; PURPOSE:
; To scan motors and collect data.
; CALLING SEQUENCE:
; SCAN, [keywords]
; INPUTS:
; None
; KEYWORD PARAMETERS:
; FILE=filename
; Used to specify the name of a file in which to save the scan data.
; Data are saved in Brookhaven Standard Image Format (BSIF).
; If the file name extension is numeric (e.g. MY_SCAN.001) then the
; extension number will be automatically incremented after the file is
; written, so the next scan will be MY_SCAN.002, etc.
; TIME=time
; Used to specify the collection time per point in seconds.
; MOTOR=[motor1, motor2, ...]
; Used to specify the name(s) of the motors to be scanned.
; START=start
; START=[start1, start2, ...]
; The start position(s) of the motor(s) being scanned.
; The order of the elements is the same as the scanning regions of each
; of the motors.
; STOP=stop
; STOP=[stop1, stop2, ...]
; The stop positions(s) of the motor(s) being scanned.
; The order of the elements is the same as the scanning regions of each
; of the motors.
; STEP=step
; STEP=[step1, step2, ...]
; The step size(s) of the motor(s) being scanned.
; The order of the elements is the same as the scanning regions of each
; of the motors.
; /RELATIVE
; If /RELATIVE is specified then the START and STOP positions are
; positions relative to the current motor position(s). If /RELATIVE
; is not specified then the START and STOP position(s) are absolute
; motor position(s).
; TITLE=title
; A string containing the title of the scan.
; PLOT=plot_values
; A vector of data values to be plotted in real time as data are
; collected. The default is not to plot any values on the first scan
; after entering IDL. Subsequent scans will plot the same data as
; the previous scan so the PLOT keyword need only be given once.
; Examples:
;
; Assume a scaler scan with data being collected from 3 scalers:
; PLOT=[0,2] ; will plot the first and third scalers as data are
; ; collected.
; Assume an ROI scan with data being collected from 2 ROIs and 2 scalers:
; PLOT=[0,1,2] ; will plot both ROIs and the first scaler.
;
; Use PLOT=-1 to turn off real-time plotting.
; /SETUP
; If set then routine SETUP_SCAN is called before beginning the scan.
; This allows the user to modify scan parameters with prompting.
; /CONFIRM
; If set then routine CONFIRM_SCAN is called before beginning the scan.
; This echoes the scan parameters and allows the user to abort if they
; are not acceptable.
; OUTPUTS:
; None
; COMMON BLOCKS:
; BSIF_COMMON The variables in this common block are modified to reflect
; the scan parameters.
; SCAN_COMMON The scan descriptor structure (SD) is used to control
; the scan. It is modified by the keywords passed to this routine and
; by SETUP_SCAN.
; SIDE EFFECTS:
; Modifies values in above common blocks.
; Moves motors, reads CAMAC scalers, reads Nuclear Data configruations,
; etc.
; RESTRICTIONS:
; The keyword parameters scan only be used to control a subset of the
; scan parameters. Other parameters can only be modified by calling
; SETUP_SCAN.
; PROCEDURE:
; This routine calls SETUP_SCAN and CONFIRM_SCAN if the appropriate
; keywords are specified. It then does some bookeeping and calls the
; appropriate scan routine (SCAN_SCALER, SCAN_ROI, SCAN_SPECTRUM,
; SCAN_MCS, SCAN_GE13).
; MODIFICATION HISTORY:
; Created January 1992 by Mark Rivers
; Feb. 22, 1995. Made routine check that scan increment was an integral
; number of motor steps. Mark Rivers
; March 1995 Modified for piecewise linear scans. Harvey Rarback
;-
@bsif_common
@scan_common
on_error, 2
camac_open
if (n_elements(sd) eq 0) or (keyword_set(setup)) then begin
setup_scan
confirm = 1
endif
if keyword_set(file) then sd.file_name = file
if keyword_set(time) then sd.dwell_time = time
if n_elements(motor) ne 0 then begin
for i=0, n_elements(motor)-1 do begin
k = lookup_motor(motor(i))
if k eq 0 then message, 'Unknown motor= '+motor(i)
md(k).name = motor(i)
sd.active_motors(i) = k
endfor
endif
k = sd.active_motors ; Shorthand
; Get the current (home) positions of each motor
for i=0, sd.n_motors-1 do begin
get_mot_pos, k(i), temp
md(k(i)).home = temp
endfor
if n_elements(start) ne 0 then begin
n = -1
for i=0, sd.n_motors-1 do begin
for j=0, md(k(i)).n_parts-1 do begin
n = n + 1
if n lt n_elements(start) then begin
if keyword_set(relative) then begin
md(k(i)).start(j) = md(k(i)).home + start(n)
endif else begin
md(k(i)).start(j) = start(n)
endelse
endif
endfor
endfor
endif
if n_elements(stop) ne 0 then begin
n = -1
for i=0, sd.n_motors-1 do begin
for j=0, md(k(i)).n_parts-1 do begin
n = n + 1
if n lt n_elements(stop) then begin
if keyword_set(relative) then begin
md(k(i)).stop(j) = md(k(i)).home + stop(n)
endif else begin
md(k(i)).stop(j) = stop(n)
endelse
endif
endfor
endfor
endif
if n_elements(step) ne 0 then begin
n = -1
for i=0, sd.n_motors-1 do begin
for j=0, md(k(i)).n_parts-1 do begin
n = n + 1
if n lt n_elements(step) then md(k(i)).inc(j) = step(n)
endfor
endfor
endif
; Make sure the motor increments are an integral nonzero number of motor steps
for i=0, sd.n_motors-1 do begin
get_motor_info, k(i), scale=scale
for j=0, md(k(i)).n_parts-1 do begin
t = round(md(k(i)).inc(j) * scale) / scale
if t eq 0. then t = 1. / scale
if (abs(t) ne abs(md(k(i)).inc(j))) then begin
message, string('Step size of motor ' + md(k(i)).name +' changed from ', $
md(k(i)).inc(j), ' to ', t, format = '(a,g0.0,a,g0.0)'), $
/continue
md(k(i)).inc(j) = t
endif
endfor
endfor
; Correct the sign of the motor increments if necessary
for i=0, sd.n_motors-1 do begin
for j=0, md(k(i)).n_parts-1 do begin
if (md(k(i)).stop(j) gt md(k(i)).start(j)) then begin
md(k(i)).inc(j) = abs(md(k(i)).inc(j))
endif else begin
md(k(i)).inc(j) = -abs(md(k(i)).inc(j))
endelse
endfor
endfor
if n_elements(plot) ne 0 then begin
sd.plot=-1
for i=0, n_elements(plot)-1 do sd.plot(i) = plot(i)
endif
if n_elements(title) ne 0 then sd.title = title
; Compute number of points and target locations in scan
x_dist = [0.]
sd.dims(0) = 0
for l = 0, md(k(0)).n_parts-1 do begin
xstart = md(k(0)).start(l)
xstop = md(k(0)).stop(l)
xstep = md(k(0)).inc(l)
; Underestimate number of scanning steps to minimize chance of "backtracking"
; for multiple region scans
nx = fix( abs( (xstart - xstop) / xstep)) + 1
sd.dims(0) = sd.dims(0) + nx
x_dist = [x_dist, xstart + findgen( nx) * xstep]
endfor
x_dist = x_dist(1 : *)
if (sd.n_dims eq 2) then begin ; 2-D scan
y_dist = [0.]
sd.dims(1) = 0
for l = 0, md(k(1)).n_parts-1 do begin
ystart = md(k(1)).start(l)
ystop = md(k(1)).stop(l)
ystep = md(k(1)).inc(l)
ny = fix( abs( (ystart - ystop) / ystep)) + 1
sd.dims(1) = sd.dims(1) + ny
y_dist = [y_dist, ystart + findgen( ny) * ystep]
endfor
y_dist = y_dist(1 : *)
endif else begin
sd.dims(1) = 1
y_dist = [0.]
endelse
if keyword_set(confirm) then confirm_scan
; Copy scan parameters to BSIF common block variables
if sd.n_dims eq 1 then begin
n_cols = sd.dims(0)
n_rows = 1
endif else begin
n_cols = sd.dims(0)
n_rows = sd.dims(1)
endelse
if sd.scan_type eq ROI_SCAN then begin
; The number of data at each pixel is the number of ROIs plus the number of
; scalers plus 2, for live time and real time.
n_data = sd.n_rois + sd.n_scalers + 2
endif
if (sd.scan_type eq SCALER_SCAN) then begin
; The number of data at each pixel is the number of scalers
n_data = sd.n_scalers
endif
if (md(k(0)).inc(0) gt 0.) then x_normal = 1 else x_normal = 0
if (md(k(1)).inc(0) gt 0.) then y_normal = 1 else y_normal = 0
rotated = 0
x_start = md(k(0)).start(0)
x_stop = md(k(0)).stop(md(k(0)).n_parts-1)
y_start = md(k(1)).start(0)
y_stop = md(k(1)).stop(md(k(1)).n_parts-1)
image_title = sd.title
x_title = md(k(0)).name
y_title = md(k(1)).name
data_title = strarr(n_data)
if (sd.scan_type eq ROI_SCAN) then begin
for i=0, sd.n_rois-1 do data_title(i) = sd.roi(i).name
for i=0, sd.n_scalers-1 do data_title(sd.n_rois+i) = sd.scaler(i).name
data_title(sd.n_rois + sd.n_scalers) = 'Real time (msec)'
data_title(sd.n_rois + sd.n_scalers + 1) = 'Live time (msec)'
endif
if (sd.scan_type eq SCALER_SCAN) then begin
for i=0, sd.n_scalers-1 do data_title(i) = sd.scaler(i).name
endif
image_data = lonarr(n_cols, n_rows, n_data)
USER_BUFFER = [0B]
; Tell user how to abort scan
print, 'Type ^P to pause scan after next pixel'
; Move motors to beginning of scan
for i=0, sd.n_motors-1 do move_motor_to, k(i), md(k(i)).start(0)
for i=0, sd.n_motors-1 do motor_wait, k(i)
; Now call the appropriate scan routine
case sd.scan_type of
SCALER_SCAN: scan_scaler
ROI_SCAN: scan_roi
SPECTRUM_SCAN: scan_spectrum
MCS_SCAN: message, 'scan_mcs is not supported now.'
GE13_SCAN: scan_ge13
endcase
; Move all of the motors back to the start of the scan
for i=0, sd.n_motors-1 do move_motor_to, k(i), md(k(i)).home
for i=0, sd.n_motors-1 do motor_wait, k(i)
; Temporary kludge to save x_, y_dist
IF MD(K(0)).N_PARTS GT 1 OR MD(K(1)).N_PARTS GT 1 THEN BEGIN
NBYTES = 4 * (N_ROWS + N_COLS)
USER_BUFFER = BYTARR(NBYTES)
COPY_BYTES, NBYTES, FLOAT( [X_DIST, Y_DIST]), USER_BUFFER
ENDIF
; All done, save the data
write_bsif, sd.file_name
print, 'Data saved in file ', sd.file_name
; Increment the file extension number if it is numeric
file_parse, sd.file_name, disk, dir, file, ext, version
on_ioerror, not_numeric
nc = strlen(ext) - 1
ext = strmid(ext, 1, nc) ; Peel off the period
ext = fix(ext)+1 ; Convert to number, add one, jump on error
nc = strtrim(string(nc),2)
ext = string(ext, format='(i'+nc+'.'+nc+')')
sd.file_name = file + '.' + ext
not_numeric:
end
setup_scan.pro 0100755 0000621 0000620 00000011167 06423757746 012761 0 ustar epics epics pro setup_scan
; This routine gets the information for the scan descriptor (sd) and motor
; descriptor (md) for a scan
; Define constants
@scan_common
init_scan_sd
sd.file_name = get_string('File name', sd.file_name)
sd.title = get_string('Scan title', sd.title)
sd.scan_type = get_choice('Scan type (Scaler, ROI, Spectrum, MCS)', $
scan_types, sd.scan_type)
sd.n_dims = $
get_choice('Scan dimensions (1D or 2D)', ['1D', '2D'], sd.n_dims-1) + 1
if (sd.n_dims eq 1) then begin
sd.n_motors = get_int('Number of motors to scan', sd.n_motors)
endif else begin
sd.n_motors = 2
endelse
for i=0, sd.n_motors-1 do begin
print, ' '
name = get_string(string('Name of motor ',i, format='(a, i0)'), md(i).name)
m = obj_new('epics_motor', name)
if (not obj_valid(m)) then message, "Motor does not exist!!!"
sd.motors(i)=m
md(i).name = name
msg1 = ' for motor ' + name
md(i).start(0) = sd.motors(i)->get_position()
get_step = 1
if sd.n_dims eq 1 and sd.n_motors gt 1 then begin
md(i).n_parts = 1
if i gt 0 then get_step = 0
endif else if sd.scan_type eq SPECTRUM_SCAN and i gt 0 then begin
md(i).n_parts = 1
endif else begin
md(i).n_parts = get_int( 'Number of piecewise linear scanning regions' + $
msg1, md(i).n_parts, min = 1, max = MAX_PARTS)
endelse
for l = 0, md(i).n_parts-1 do begin
msg2 = msg1
if md(i).n_parts gt 1 then msg2 = msg1 + string( ' in region ', l+1, $
format = '(a, i0)')
if md(i).start(l) eq NEW_START then md(i).start(l) = md(i).stop(l-1)
md(i).start(l) = get_float( 'Start position' + msg2, md(i).start(l))
md(i).stop(l) = get_float( 'Stop position' + msg2, md(i).stop(l))
if get_step then begin
md(i).inc(l) = get_float( 'Step size' + msg2, md(i).inc(l))
endif else begin ; other than first motor in 1-D scan
md(i).inc(l) = md(0).inc(0) * (md(i).stop(l) - md(i).start(l)) / $
(md(0).stop(0) - md(0).start(0))
print, 'Step size' + msg2 + ' = ', md(i).inc(l), format = '(a, g0.0)'
endelse
endfor
endfor
if (sd.scan_type eq ROI_SCAN) or $
(sd.scan_type eq SPECTRUM_SCAN) then begin
; Find out what MCA record the user wants
print, ' '
sd.mca_pvname = get_string('MCA record', sd.mca_pvname)
; Extract just the record name
sd.mca = obj_new('epics_mca', sd.mca_pvname)
if (not obj_valid(sd.mca)) then message, $
"MCA record does not exist or is not correct version!!!"
sd.n_chans = sd.mca->get_nchans()
calibration = sd.mca->get_calibration()
sd.eoffset = calibration.offset
sd.eslope = calibration.slope
sd.equad = calibration.quad
sd.timing_mode = get_choice('Timing mode (Live or Real)', $
['Live', 'Real'], sd.timing_mode)
if (sd.timing_mode eq LIVE_TIME_MODE) then begin
sd.dwell_time = get_float('Live time per pixel ', sd.dwell_time)
endif else begin
sd.dwell_time = get_float('Real time per pixel ', sd.dwell_time)
endelse
if (sd.scan_type eq ROI_SCAN) then begin
roi = sd.mca->get_rois()
sd.n_rois = n_elements(roi)
for i=0, sd.n_rois-1 do begin
roi(i).label = $
get_string('Title for ROI'+string(i), roi(i).label)
sd.roi(i).name = roi(i).label
roi(i).bgd_width = $
get_int('Number of channels for background window', $
roi(i).bgd_width)
sd.roi(i).bgd_width = roi(i).bgd_width
endfor
sd.mca->set_rois, roi
endif
if sd.scan_type eq SPECTRUM_SCAN then begin
sd.roi(0).left_chan = get_int('First channel to store', 1)
sd.roi(0).right_chan = get_int('Last channel to store', sd.n_chans)
endif
endif
if (sd.scan_type eq SCALER_SCAN) or $
(sd.scan_type eq MCS_SCAN) then begin
sd.dwell_time = get_float('Time per point', sd.dwell_time)
endif
if (sd.scan_type eq ROI_SCAN) or $
(sd.scan_type eq SPECTRUM_SCAN) or $
(sd.scan_type eq SCALER_SCAN) then begin
sd.scaler_pvname = get_string('PV name for scaler ', sd.scaler_pvname)
scaler = obj_new('epics_scaler', sd.scaler_pvname)
if (not obj_valid(scaler)) then message, $
"MCA record does not exist or is not correct version!!!"
sd.scaler = scaler
sd.n_scalers = get_int('Number of EPICS scalers to use', sd.n_scalers)
for i=0, sd.n_scalers-1 do begin
sd.scalers[i].title = sd.scaler->get_title(i)
sd.scalers[i].title = get_string( string( 'Title for scaler ', i+1, $
format = '(a,i0)'), sd.scalers[i].title)
sd.scaler->set_title, i, sd.scalers[i].title
endfor
endif
end
test1.pro 0100755 0000621 0000620 00000000730 06457421525 011635 0 ustar epics epics pro test1_event, event
end
pro test1
n = 25
widgets={base: 0L, base1: 0L, text: lonarr(n)}
widgets.base = widget_base(/column)
widgets.base1 = widget_base(widgets.base, /column)
widget_control, widgets.base1, update=0
for i=0, n-1 do begin
widgets.text[i] = widget_text(widgets.base1, value=string(i))
endfor
widget_control, widgets.base1, update=1
widget_control, widgets.base, /realize
xmanager, 'test1', widgets.base
end
test2.pro 0100755 0000621 0000620 00000001463 06457422655 011647 0 ustar epics epics pro test2_event, event
common test2_common, widgets, seed
widget_control, widgets.base, update=0
widget_control, widgets.base1, /destroy
widgets.base1 = widget_base(widgets.base, /column)
n = randomu(seed) * 10
for i=0, n-1 do begin
widgets.text[i] = widget_text(widgets.base1, value=string(i))
endfor
widget_control, widgets.base, update=1
end
pro test2
common test2_common, widgets, seed
n = 10
widgets={base: 0L, base1: 0L, update: 0L, text: lonarr(n)}
widgets.base = widget_base(/column)
widgets.update = widget_button(widgets.base, value='Update')
widgets.base1 = widget_base(widgets.base, /column)
for i=0, n-1 do begin
widgets.text[i] = widget_text(widgets.base1, value=string(i))
endfor
widget_control, widgets.base, /realize
xmanager, 'test2', widgets.base
end
widget_scan.pro 0100644 0000621 0000620 00000070776 06470166600 013075 0 ustar epics epics ; ************************************************************
pro widget_scan_print
common widget_scan_print_common, print
@scan_common
@bsif_common
if (n_elements(print) eq 0) then begin
print = { $
xsize: 6., $
ysize: 4., $
orientation: 0, $
thick: 1.0, $
charthick: 1.0, $
charsize: 1.0, $
xtitle: '', $
ytitle: '', $
title: '', $
font: 0, $
command: 'lpr -Pgse_floor' $
}
endif
print.title = sd.file_name
print.xtitle = x_title
desc = [ $
'1, BASE, ,COLUMN, FRAME', $
'1, BASE, ,ROW, FRAME', $
'0, FLOAT, '+ string(print.xsize) + $
',TAG =xsize, LABEL_TOP =X size (inches), WIDTH=12', $
'0, FLOAT, '+ string(print.ysize) + $
',TAG =ysize, LABEL_TOP =Y size (inches), WIDTH =12', $
'2, BUTTON, Portrait|Landscape, EXCLUSIVE,' + $
'LABEL_TOP =Orientation, TAG =orientation,' + $
'SET_VALUE ='+string(print.orientation), $
'1, BASE, ,ROW, FRAME', $
'0, FLOAT, '+ string(print.charsize) + $
',TAG =charsize, LABEL_TOP =Character size, WIDTH =12', $
'0, FLOAT, '+ string(print.thick) + $
',TAG =thick, LABEL_TOP =Line thickness , WIDTH =12', $
'0, FLOAT, '+ string(print.charthick) + $
',TAG =charthick, LABEL_TOP =Character thickness,' + $
'WIDTH =12', $
'2, BUTTON, Postscript|Vector, EXCLUSIVE,' + $
'LABEL_TOP =Font, TAG =font,' + $
'SET_VALUE ='+ string(print.font), $
'1, BASE, ,ROW, FRAME', $
'2, TEXT, ' + print.xtitle + $
',TAG =xtitle, LABEL_LEFT =X title: , WIDTH =30', $
'1, BASE, ,ROW, FRAME', $
'2, TEXT, ' + print.ytitle + $
',TAG =ytitle, LABEL_LEFT =Y title: , WIDTH =30', $
'1, BASE, ,ROW, FRAME', $
'2, TEXT, ' + print.title + $
',TAG =title, LABEL_LEFT =Plot title: , WIDTH =30', $
'1, BASE, ,ROW, FRAME', $
'2, TEXT, ' + print.command + $
',TAG =command, LABEL_LEFT =Print command: , WIDTH =30', $
'1, BASE, ,ROW, FRAME', $
'0, BUTTON, Print, QUIT, TAG =print', $
'2, BUTTON, Cancel, QUIT, TAG =cancel']
k = where(sd.plot gt 0, nplot)
if (nplot eq 0) then return
form = cw_form( /column, title='Scan Print', desc)
if (form.cancel) then return
old_device = !d.name
set_plot, 'ps'
if (form.orientation) eq 1 then landscape=1 else landscape=0
if (form.font) eq 1 then font=-1 else font=0
device, xsize=form.xsize, ysize=form.ysize, /inch, landscape=landscape, $
file='idl.ps'
big = max(image_data(*, 0, k))
small = min(image_data(*, 0, k))
plot, x_dist, image_data(*, 0, k(0)), psym=-1, $
yrange = [small - 0.2*abs(small), big + 0.2*abs(big)], $
charsize = form.charsize, $
thick = form.thick, $
charthick = form.charthick, $
xtitle = form.xtitle, $
ytitle = form.ytitle, $
title = form.title, $
font = font
for i=1, n_elements(k)-1 do begin
oplot, x_dist, image_data(*, 0, k(i)), psym=-(i+1), $
thick = form.thick
endfor
device, /close
set_plot, old_device
command = form.command + ' idl.ps'
spawn, command
print.xsize = form.xsize
print.ysize = form.ysize
print.orientation = form.orientation
print.charsize = form.charsize
print.thick = form.thick
print.charthick = form.charthick
print.font = form.font
print.xtitle = form.xtitle
print.ytitle = form.ytitle
print.title = form.title
print.command = form.command
end
; ************************************************************
pro set_plot_values
@scan_common
sd.plot=-1
j=0
if (sd.scan_type eq ROI_SCAN) then begin
for i=0, sd.n_rois-1 do begin
sd.plot[j] = sd.roi[i].plot
j=j+1
endfor
endif
for i=0, sd.n_scalers-1 do begin
sd.plot[j] = sd.scalers[i].plot
j=j+1
endfor
end
; ************************************************************
pro draw_scaler_widgets, widgets
@scan_common
widget_control, widgets.base, /hourglass
if obj_valid(sd.scaler) then begin
titles = sd.scaler->get_title()
for i=0, sd.n_scalers-1 do begin
sd.scalers[i].title = titles[i]
endfor
endif
if (widget_info(widgets.base, /realized)) then begin
if (!version.os eq 'Win32') then begin
widget_control, widgets.base, map=0
endif else begin
widget_control, widgets.scaler_base2, update=0
endelse
endif
widget_control, widgets.scaler_base2, /destroy
widgets.scaler_base2 = widget_base(widgets.scaler_base1, /row)
row = widgets.scaler_base2
widgets.scaler_name = cw_field(row, title='Scaler PVname', $
value=sd.scaler_pvname, $
/return_events, /column, /string, xsize=20)
widgets.n_scalers = cw_field(row, title='# scalers', value=sd.n_scalers, $
/return_events, /column, /integer, xsize=10)
col = widget_base(row, /column)
t = widget_label(col, value='Title')
for i=0, sd.n_scalers-1 do begin
widgets.scalers[i].title = widget_text(col, /edit, $
value=sd.scalers[i].title, xsize=20)
endfor
c = widget_base(row, /column)
geometry = widget_info(widgets.scalers[0].title, /geometry)
ysize = geometry.scr_ysize
t = widget_label(c, value='Plot')
col = widget_base(c, /column, /nonexclusive)
for i=0, sd.n_scalers-1 do begin
widgets.scalers[i].plot = widget_button(col, value="", ysize=ysize)
widget_control, widgets.scalers[i].plot, set_button=sd.scalers[i].plot
endfor
set_plot_values
if (widget_info(widgets.base, /realized)) then begin
if (!version.os eq 'Win32') then begin
widget_control, widgets.base, map=1
endif else begin
widget_control, widgets.scaler_base2, update=1
endelse
endif
end
; ************************************************************
pro draw_roi_widgets, widgets
@scan_common
widget_control, widgets.base, /hourglass
if obj_valid(sd.mca) then begin
roi = sd.mca->get_rois()
sd.n_rois = n_elements(roi)
for i=0, sd.n_rois-1 do begin
sd.roi(i).name = roi(i).label
sd.roi(i).bgd_width = roi(i).bgd_width
sd.roi(i).left_chan = roi(i).left
sd.roi(i).right_chan = roi(i).right
endfor
endif else begin
sd.n_rois = 0
endelse
if (widget_info(widgets.base, /realized)) then begin
if (!version.os eq 'Win32') then begin
widget_control, widgets.base, map=0
endif else begin
widget_control, widgets.roi_base2, update=0
endelse
endif
widget_control, widgets.roi_base2, /destroy
widgets.roi_base2 = widget_base(widgets.roi_base1, /row)
row = widgets.roi_base2
col = widget_base(row, /column)
widgets.mca_name = cw_field(col, title='MCA PVname', value=sd.mca_pvname, $
/return_events, /column, /string, xsize=20)
col = widget_base(col, /column)
widgets.timing_base = col
t = widget_label(col, value='Timing mode')
widgets.timing_mode = widget_droplist(col, value=['Live', 'Real'])
widget_control, widgets.timing_mode, set_droplist_select=sd.timing_mode
col = widget_base(row, /column)
t = widget_label(col, value='Title')
for i=0, sd.n_rois-1 do begin
widgets.rois(i).title = widget_text(col, /edit, $
value=sd.roi(i).name, xsize=10)
endfor
col = widget_base(row, /column)
t = widget_label(col, value='Left channel')
for i=0, sd.n_rois-1 do begin
widgets.rois(i).left = widget_text(col, /edit, $
value=string(sd.roi(i).left_chan), xsize=10)
endfor
col = widget_base(row, /column)
t = widget_label(col, value='Right channel')
for i=0, sd.n_rois-1 do begin
widgets.rois(i).right = widget_text(col, /edit, $
value=string(sd.roi(i).right_chan), xsize=10)
endfor
col = widget_base(row, /column)
t = widget_label(col, value='Back. width')
for i=0, sd.n_rois-1 do begin
widgets.rois(i).bgd_width = widget_text(col, /edit, $
value=string(sd.roi(i).bgd_width), xsize=10)
endfor
c = widget_base(row, /column)
geometry = widget_info(widgets.scalers[0].title, /geometry)
ysize = geometry.scr_ysize
t = widget_label(c, value='Plot')
col = widget_base(c, /column, /nonexclusive)
for i=0, sd.n_rois-1 do begin
widgets.rois[i].plot = widget_button(col, value="", ysize=ysize)
widget_control, widgets.rois[i].plot, set_button=sd.roi[i].plot
endfor
set_plot_values
if (widget_info(widgets.base, /realized)) then begin
if (!version.os eq 'Win32') then begin
widget_control, widgets.base, map=1
endif else begin
widget_control, widgets.roi_base2, update=1
endelse
endif
end
; ************************************************************
pro widget_scan_sens, widgets
@scan_common
if (sd.n_dims eq 1) then sens=1 else sens=0
widget_control, widgets.n_motors_base, sensitive=sens
if (sd.scan_type eq SCALER_SCAN) then sens=0 else sens=1
widget_control, widgets.roi_base1, sensitive=sens
if (sd.n_dims eq 2) then sd.n_motors = 2
widget_control, widgets.n_motors, set_droplist_select=sd.n_motors-1
if (sd.n_motors eq 1) then sens=0 else sens=1
widget_control, widgets.mp(1).base, sensitive=sens
for i=0,1 do begin
if obj_valid(sd.motors(i)) then sens=1 else sens=0
widget_control, widgets.mp(i).abs_start, sensitive=sens
widget_control, widgets.mp(i).abs_stop, sensitive=sens
widget_control, widgets.mp(i).rel_start, sensitive=sens
widget_control, widgets.mp(i).rel_stop, sensitive=sens
widget_control, widgets.mp(i).step, sensitive=sens
widget_control, widgets.mp(i).npoints, sensitive=sens
widget_control, widgets.mp(i).position, sensitive=sens
endfor
end
; ************************************************************
pro new_scan_params, index, widgets
@scan_common
; This routine computes and displays scan parameters
; It must make sure that:
; start, stop, and step are integral number of motor steps
; start, stop, step, and npoints are internally consistent
; scan range is within soft limits
; Updates estimated scan time
if (not obj_valid(sd.motors(index))) then return
mot = md(index)
; Make sure start, stop, and step are all integer # of motor steps
scale = sd.motors(index)->get_scale()
position = sd.motors(index)->get_position()
mot.start[0] = round(mot.start[0]*scale) / scale
mot.stop[0] = round(mot.stop[0]*scale) / scale
mot.inc[0] = round(mot.inc[0]*scale) / scale
; Correct sign of step size if necessary
if (mot.stop[0] gt mot.start[0]) then mot.inc[0] = abs(mot.inc[0]) $
else mot.inc[0] = -abs(mot.inc[0])
sd.dims(index) = (mot.stop[0]-mot.start[0])/mot.inc[0] + 1
widget_control, widgets.mp(index).abs_start, set_value=mot.start[0]
widget_control, widgets.mp(index).abs_stop, set_value=mot.stop[0]
widget_control, widgets.mp(index).rel_start, set_value=(mot.start[0]-position)
widget_control, widgets.mp(index).rel_stop, set_value=(mot.stop[0]-position)
widget_control, widgets.mp(index).step, set_value=mot.inc[0]
widget_control, widgets.mp(index).npoints, set_value = sd.dims(index)
widget_control, widgets.mp(index).position, set_value = position
widget_control, widgets.mp(index).name, set_value=mot.name
md(index) = mot
; Compute estimated scan time
points = sd.dims(0)
if (sd.n_dims eq 2) then points= points * sd.dims(1)
time = sd.dwell_time * points
widget_control, widgets.total_time, set_value=time
; Update scan dimensions, scan type, etc. in case we were called
; because of restore scan params from file
widget_control, widgets.scan_mode, set_droplist_select=sd.scan_type
widget_control, widgets.scan_dims, set_droplist_select=sd.n_dims-1
widget_control, widgets.n_motors, set_droplist_select=sd.n_motors-1
widget_control, widgets.dwell_time, set_value=sd.dwell_time
; Check for soft-limit violations
high_limit = sd.motors[index]->get_high_limit()
low_limit = sd.motors[index]->get_low_limit()
if (mot.start[0] gt high_limit) or (mot.start[0] lt low_limit) then $
t = dialog_message(/error, "Start position is beyond soft limits", $
dialog_parent=widgets.base)
if (mot.stop[0] gt high_limit) or (mot.stop[0] lt low_limit) then $
t = dialog_message(/error, "Stop position is beyond soft limits", $
dialog_parent=widgets.base)
end
; ************************************************************
pro widget_scan_event, event
@scan_common
@bsif_common
widget_control, event.top, get_uvalue=widgets, /no_copy
if n_elements(widgets) eq 0 then begin
; This is an event during a scan (when xmanager is inactive)
; Ignore it.
print, 'got event, id = ', event.id
return
endif
case event.id of
widgets.timer: begin
; Read the current motor position, store it, and display it.
for i=0,1 do begin
if obj_valid(sd.motors(i)) then begin
pos = sd.motors(i)->get_position()
widget_control, widgets.mp(i).position, set_value=pos
endif
endfor
widget_control, widgets.timer, timer=1.0
end
widgets.scan_mode: begin
sd.scan_type = event.index
widget_scan_sens, widgets
end
widgets.scan_dims: begin
sd.n_dims = event.index + 1
widget_scan_sens, widgets
end
widgets.n_motors: begin
sd.n_motors = event.index + 1
widget_scan_sens, widgets
end
widgets.dwell_time: begin
sd.dwell_time = event.value
new_scan_params, 0, widgets
end
widgets.scan_file: begin
widget_control, event.id, get_value=scan_file
sd.file_name = scan_file[0]
end
widgets.scan_title: begin
widget_control, event.id, get_value=scan_title
sd.title = scan_title[0]
end
widgets.start_scan: begin
widget_control, widgets.start_scan, sensitive=0
widget_control, widgets.exit, sensitive=0
widget_control, widgets.print, sensitive=0
set_plot_values
catch, error
if (error eq 0) then begin
sd.abort_scan_widget = widgets.abort_scan
scan
endif else begin ; An error occured during the scan
t = dialog_message(/error, !ERR_STRING, dialog_parent=widgets.base)
endelse
widget_control, widgets.start_scan, sensitive=1
widget_control, widgets.exit, sensitive=1
widget_control, widgets.print, sensitive=1
; Update scan file name
widget_control, widgets.scan_file, set_value=sd.file_name
end
widgets.print: begin
widget_scan_print
end
widgets.save_params: begin
file = dialog_pickfile( title = 'Save scan parameters')
if (file ne "") then save, /xdr, sd, md, filename=file
end
widgets.read_file: begin
file = dialog_pickfile( title = 'Read data file', /must_exist)
if (file ne "") then begin
read_bsif, file
set_plot_values
display_point, n_elements(image_data(0,*,0))-1, $
n_elements(image_data(*,0,0))-1, /rescale
endif
end
widgets.replot: begin
set_plot_values
display_point, n_elements(image_data(0,*,0))-1, $
n_elements(image_data(*,0,0))-1, /rescale
end
widgets.restore_params: begin
file = dialog_pickfile( title = 'Restore scan parameters', /must_exist)
if (file ne "") then begin
restore, file
for i=0, 1 do new_scan_params, i, widgets
draw_scaler_widgets, widgets
draw_roi_widgets, widgets
widget_scan_sens, widgets
endif
end
widgets.exit: begin
widget_control, event.top, /destroy
return
end
endcase
widget_control, event.top, set_uvalue=widgets, /no_copy
end
; ************************************************************
pro widget_scan_motor_event, event
@scan_common
widget_control, event.top, get_uvalue=widgets, /no_copy
for i=0, 1 do begin
if (event.id eq widgets.mp[i].name) then begin
widget_control, widgets.base, /hourglass
widget_control, event.id, get_value=motor_name
motor_name = motor_name[0]
m = obj_new('epics_motor', motor_name)
if (not obj_valid(m)) then begin
t = dialog_message(/error, 'Invalid motor name', $
dialog_parent=widgets.base)
goto, done
endif
obj_destroy, sd.motors(i)
sd.motors(i) = m
md(i).name = sd.motors(i)->get_name()
position = sd.motors(i)->get_position()
; Use the same values of relative start and stop positions and step
widget_control, widgets.mp(i).rel_start, get_value=rel_start
widget_control, widgets.mp(i).rel_stop, get_value=rel_stop
md(i).start[0] = position + rel_start
md(i).stop[0] = position + rel_stop
widget_control, event.id, set_value=md(i).name
widget_scan_sens, widgets
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).abs_start) then begin
md(i).start[0] = event.value
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).abs_stop) then begin
md(i).stop[0] = event.value
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).rel_start) then begin
position = sd.motors(i)->get_position()
md(i).start[0] = position + event.value
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).rel_stop) then begin
position = sd.motors(i)->get_position()
md(i).stop[0] = position + event.value
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).step) then begin
md(i).inc[0] = event.value
new_scan_params, i, widgets
endif
endfor
done:
widget_control, event.top, set_uvalue=widgets, /no_copy
end
; ************************************************************
pro widget_scan_scaler_event, event
@scan_common
widget_control, event.top, get_uvalue=widgets, /no_copy
case event.id of
widgets.scaler_name: begin
widget_control, widgets.base, /hourglass
widget_control, event.id, get_value=scaler_name
scaler_name = scaler_name[0]
scaler = obj_new('epics_scaler', scaler_name)
if obj_valid(scaler) then begin
obj_destroy, sd.scaler
sd.scaler = scaler
sd.scaler_pvname = scaler_name
draw_scaler_widgets, widgets
endif else begin
t = dialog_message(/error, 'Scaler not found', $
dialog_parent=widgets.base)
endelse
end
widgets.n_scalers: begin
widget_control, event.id, get_value=n_scalers
sd.n_scalers = n_scalers > 1
draw_scaler_widgets, widgets
end
else: begin
for i=0, sd.n_scalers-1 do begin
if (event.id eq widgets.scalers[i].title) then begin
widget_control, event.id, get_value=title
title = title[0]
sd.scalers[i].title = title
sd.scaler->set_title, i, title
endif else if (event.id eq widgets.scalers[i].plot) then begin
sd.scalers[i].plot = event.select
set_plot_values
endif
endfor
end
endcase
widget_control, event.top, set_uvalue=widgets, /no_copy
end
; ************************************************************
pro widget_scan_roi_event, event
@scan_common
widget_control, event.top, get_uvalue=widgets, /no_copy
case event.id of
widgets.timing_mode: begin
sd.timing_mode = event.index ; This assumes index=0 is mode=0
widget_scan_sens, widgets
end
widgets.mca_name: begin
widget_control, widgets.base, /hourglass
widget_control, event.id, get_value=mca_name
mca_name = mca_name[0]
m = obj_new('epics_mca', mca_name)
if obj_valid(m) then begin
obj_destroy, sd.mca
sd.mca = m
sd.mca_pvname = mca_name
draw_roi_widgets, widgets
endif else begin
t = dialog_message(/error, 'MCA not found', dialog_parent=widgets.base)
endelse
end
else: begin
for i=0, sd.n_rois-1 do begin
if (event.id eq widgets.rois(i).title) then begin
widget_control, event.id, get_value=title
title = title[0]
rois = sd.mca->get_rois()
rois[i].label = title
sd.mca->set_rois, rois
endif else if (event.id eq widgets.rois(i).left) then begin
widget_control, event.id, get_value=left
left = long(left[0])
rois = sd.mca->get_rois()
rois[i].left = left
sd.mca->set_rois, rois
endif else if (event.id eq widgets.rois(i).right) then begin
widget_control, event.id, get_value=right
right = long(right[0])
rois = sd.mca->get_rois()
rois[i].right = right
sd.mca->set_rois, rois
endif else if (event.id eq widgets.rois(i).bgd_width) then begin
widget_control, event.id, get_value=bgd_width
bgd_width = long(bgd_width[0])
rois = sd.mca->get_rois()
rois[i].bgd_width = bgd_width
sd.mca->set_rois, rois
endif else if (event.id eq widgets.rois[i].plot) then begin
sd.roi[i].plot = event.select
set_plot_values
endif
endfor
end
endcase
widget_control, event.top, set_uvalue=widgets, /no_copy
end
; ************************************************************
pro widget_scan, group=group
@scan_common
init_scan_sd
; Resolve object routines, since restore scan params might happen first
resolve_routine, 'epics_motor__define'
resolve_routine, 'epics_scaler__define'
resolve_routine, 'epics_mca__define'
resolve_routine, 'mca__define'
mp = {base: 0L, name: 0L, $
abs_start: 0L, abs_stop: 0L, rel_start: 0L, rel_stop: 0L, $
step: 0L, npoints: 0L, position: 0L}
rois = {title: 0L, left: 0L, right:0L, bgd_width: 0L, plot: 0L}
scalers = {title: 0L, plot: 0L}
widgets = { base: 0L, $
scan_mode: 0L, $
scan_dims: 0L, $
n_motors_base: 0L, $
n_motors: 0L, $
mp: replicate(mp, 2), $
n_scalers: 0L, $
scaler_base1: 0L, $
scaler_base2: 0L, $
scaler_name: 0L, $
scalers: replicate(scalers, MAX_SCALERS), $
mca_name: 0L, $
roi_base1: 0L, $
roi_base2: 0L, $
rois: replicate(rois, MAX_ROIS), $
timing_base: 0L, $
timing_mode: 0L, $
dwell_time: 0L, $
total_time: 0L, $
timer: 0L, $
start_scan: 0L, $
abort_scan: 0L, $
replot: 0L, $
print: 0L, $
save_params: 0L, $
restore_params: 0L, $
read_file: 0L, $
scan_title: 0L, $
scan_file: 0L, $
exit: 0L }
default_font = get_font_name(/small)
label_font = get_font_name(/bold)
widgets.base = widget_base(title="Scan Setup", /column, mbar=mbar)
widget_control, widgets.base, default_font=default_font
widgets.timer = widgets.base
file = widget_button( mbar, /menu, value = 'File ', font=label_font)
widgets.print = widget_button( file, value = 'Print . . .')
widgets.save_params = widget_button( file, $
value = 'Save scan parameters. . .')
widgets.restore_params = widget_button( file, $
value = 'Restore scan parameters. . .')
widgets.read_file = widget_button( file, $
value = 'Read data file. . .')
widgets.exit = widget_button( file, value = 'Exit')
row = widget_base(widgets.base, /row, /frame)
col = widget_base(row, /column)
t = widget_label(col, value='Scan type')
widgets.scan_mode = widget_droplist(col, $
value= ['Scaler', 'ROI', 'Spectrum', 'MCS'])
widget_control, widgets.scan_mode, set_droplist_select=sd.scan_type
col = widget_base(row, /column)
t = widget_label(col, value='Scan dims.')
widgets.scan_dims = widget_droplist(col, value=['1-D', '2-D'])
widget_control, widgets.scan_dims, set_droplist_select=sd.n_dims-1
col = widget_base(row, /column)
widgets.n_motors_base = col
t = widget_label(col, value='# motors')
widgets.n_motors = widget_droplist(col, value=['1', '2'])
col = widget_base(row, /column)
widgets.dwell_time = cw_field(row, title='Count time (sec)', /return_events, $
value=sd.dwell_time, /column, /float, xsize=10)
widgets.total_time = cw_field(row, title='Total time (sec)', /noedit, $
value=0.0, /column, /float, xsize=10)
r = widget_base(widgets.base, /row, event_pro='widget_scan_motor_event')
for i=0, 1 do begin
col = widget_base(r, /column, /frame)
widgets.mp(i).base = col
t = widget_label(col, value='Motor '+strtrim(i+1,2), font=label_font)
row = widget_base(col, /row)
widgets.mp(i).name = cw_field(row, title='Motor name', value=md(i).name, $
/return_events, /column, /string, xsize=20)
width=10
widgets.mp(i).position = cw_field(row, title='Current position', value=0.0, $
/return_events, /column, /float, xsize=width)
row = widget_base(col, /row)
widgets.mp(i).abs_start = cw_field(row, title='Start (abs)', $
value=md(i).start[0], $
/return_events, /column, /float, xsize=width)
widgets.mp(i).abs_stop = cw_field(row, title='Stop (abs)', $
value=md(i).stop[0], $
/return_events, /column, /float, xsize=width)
widgets.mp(i).step = cw_field(row, title='Step', value=md[i].inc[0], $
/return_events, /column, /float, xsize=width)
row = widget_base(col, /row)
widgets.mp(i).rel_start = cw_field(row, title='Start (rel)', value=-1.0, $
/return_events, /column, /float, xsize=width)
widgets.mp(i).rel_stop = cw_field(row, title='Stop (rel)', value=1.0, $
/return_events, /column, /float, xsize=width)
widgets.mp(i).npoints = cw_field(row, title='# points', value=0, $
/noedit, /column, /integer, xsize=width)
endfor
widgets.scaler_base1 = widget_base(widgets.base, /column, /frame, $
event_pro='widget_scan_scaler_event')
t = widget_label(widgets.scaler_base1, value='Scalers', font=label_font)
widgets.scaler_base2 = widget_base(widgets.scaler_base1, /row, /frame)
draw_scaler_widgets, widgets
widgets.roi_base1 = widget_base(widgets.base, /column, /frame, $
event_pro='widget_scan_roi_event')
t = widget_label(widgets.roi_base1, value='Regions of Interest', $
font=label_font)
widgets.roi_base2 = widget_base(widgets.roi_base1, /row, /frame)
draw_roi_widgets, widgets
row = widget_base(widgets.base, /row, /frame)
col = widget_base(row, /column)
t = widget_label(col, value='Scan file name')
widgets.scan_file = widget_text(col, value=sd.file_name, /edit, $
xsize=20)
col = widget_base(row, /column)
t = widget_label(col, value='Scan title')
widgets.scan_title = widget_text(col, value=sd.title, /edit, $
xsize=60)
row = widget_base(widgets.base, /row)
widgets.start_scan = widget_button(row, value='Start scan', font=label_font)
widgets.abort_scan = widget_button(row, value='Abort scan', font=label_font, $
event_pro = 'abort_scan')
widgets.replot = widget_button(row, value='Replot', font=label_font)
for i=0, 1 do new_scan_params, i, widgets
widget_scan_sens, widgets
widget_control, widgets.base, set_uvalue=widgets
widget_control, widgets.base, /realize
widget_control, widgets.timer, timer=1.0
xmanager, 'widget_scan', widgets.base, group_leader=group, /no_block
end
widget_scan_test.pro 0100644 0000621 0000620 00000050553 06464452242 014126 0 ustar epics epics ; ************************************************************
pro set_plot_values
@scan_common
sd.plot=-1
j=0
if (sd.scan_type eq ROI_SCAN) then begin
for i=0, sd.n_rois-1 do begin
sd.plot[j] = sd.roi[i].plot
j=j+1
endfor
endif
for i=0, sd.n_scalers-1 do begin
sd.plot[j] = sd.scalers[i].plot
j=j+1
endfor
end
; ************************************************************
pro draw_scaler_widgets, widgets
@scan_common
widget_control, widgets.base, /hourglass
if obj_valid(sd.scaler) then begin
titles = sd.scaler->get_title()
for i=0, sd.n_scalers-1 do begin
sd.scalers[i].title = titles[i]
endfor
endif
if (widget_info(widgets.base, /realized)) then $
widget_control, widgets.base, map=0
widget_control, widgets.scaler_base2, /destroy
widgets.scaler_base2 = widget_base(widgets.scaler_base1, /row)
row = widgets.scaler_base2
widgets.scaler_name = cw_field(row, title='Scaler PVname', $
value=sd.scaler_pvname, $
/return_events, /column, /string, xsize=20)
widgets.n_scalers = cw_field(row, title='# scalers', value=sd.n_scalers, $
/return_events, /column, /integer, xsize=10)
col = widget_base(row, /column)
t = widget_label(col, value='Title')
for i=0, sd.n_scalers-1 do begin
widgets.scalers[i].title = widget_text(col, /edit, $
value=sd.scalers[i].title, xsize=20)
endfor
c = widget_base(row, /column)
geometry = widget_info(widgets.scalers[0].title, /geometry)
ysize = geometry.scr_ysize
t = widget_label(c, value='Plot')
col = widget_base(c, /column, /nonexclusive)
for i=0, sd.n_scalers-1 do begin
widgets.scalers[i].plot = widget_button(col, value="", ysize=ysize)
widget_control, widgets.scalers[i].plot, set_button=sd.scalers[i].plot
endfor
set_plot_values
if (widget_info(widgets.base, /realized)) then $
widget_control, widgets.base, map=1
end
; ************************************************************
pro draw_roi_widgets, widgets
@scan_common
widget_control, widgets.base, /hourglass
if obj_valid(sd.mca) then begin
roi = sd.mca->get_rois()
sd.n_rois = n_elements(roi)
for i=0, sd.n_rois-1 do begin
sd.roi(i).name = roi(i).label
sd.roi(i).bgd_width = roi(i).bgd_width
sd.roi(i).left_chan = roi(i).left
sd.roi(i).right_chan = roi(i).right
endfor
endif else begin
sd.n_rois = 0
endelse
if (widget_info(widgets.base, /realized)) then $
widget_control, widgets.base, map=0
widget_control, widgets.roi_base2, /destroy
widgets.roi_base2 = widget_base(widgets.roi_base1, /row)
row = widgets.roi_base2
col = widget_base(row, /column)
widgets.mca_name = cw_field(col, title='MCA PVname', value=sd.mca_pvname, $
/return_events, /column, /string, xsize=20)
col = widget_base(col, /column)
widgets.timing_base = col
t = widget_label(col, value='Timing mode')
widgets.timing_mode = widget_droplist(col, value=['Live', 'Real'])
widget_control, widgets.timing_mode, set_droplist_select=sd.timing_mode
col = widget_base(row, /column)
t = widget_label(col, value='Title')
for i=0, sd.n_rois-1 do begin
widgets.rois(i).title = widget_text(col, /edit, $
value=sd.roi(i).name, xsize=10)
endfor
col = widget_base(row, /column)
t = widget_label(col, value='Left channel')
for i=0, sd.n_rois-1 do begin
widgets.rois(i).left = widget_text(col, /edit, $
value=string(sd.roi(i).left_chan), xsize=10)
endfor
col = widget_base(row, /column)
t = widget_label(col, value='Right channel')
for i=0, sd.n_rois-1 do begin
widgets.rois(i).right = widget_text(col, /edit, $
value=string(sd.roi(i).right_chan), xsize=10)
endfor
col = widget_base(row, /column)
t = widget_label(col, value='Back. width')
for i=0, sd.n_rois-1 do begin
widgets.rois(i).bgd_width = widget_text(col, /edit, $
value=string(sd.roi(i).bgd_width), xsize=10)
endfor
c = widget_base(row, /column)
geometry = widget_info(widgets.scalers[0].title, /geometry)
ysize = geometry.scr_ysize
t = widget_label(c, value='Plot')
col = widget_base(c, /column, /nonexclusive)
for i=0, sd.n_rois-1 do begin
widgets.rois[i].plot = widget_button(col, value="", ysize=ysize)
widget_control, widgets.rois[i].plot, set_button=sd.roi[i].plot
endfor
set_plot_values
if (widget_info(widgets.base, /realized)) then $
widget_control, widgets.base, map=1
end
; ************************************************************
pro widget_scan_sens, widgets
@scan_common
if (sd.n_dims eq 1) then sens=1 else sens=0
widget_control, widgets.n_motors_base, sensitive=sens
if (sd.scan_type eq SCALER_SCAN) then sens=0 else sens=1
widget_control, widgets.roi_base1, sensitive=sens
if (sd.n_dims eq 2) then sd.n_motors = 2
widget_control, widgets.n_motors, set_droplist_select=sd.n_motors-1
if (sd.n_motors eq 1) then sens=0 else sens=1
widget_control, widgets.mp(1).base, sensitive=sens
for i=0,1 do begin
if obj_valid(sd.motors(i)) then sens=1 else sens=0
widget_control, widgets.mp(i).abs_start, sensitive=sens
widget_control, widgets.mp(i).abs_stop, sensitive=sens
widget_control, widgets.mp(i).rel_start, sensitive=sens
widget_control, widgets.mp(i).rel_stop, sensitive=sens
widget_control, widgets.mp(i).step, sensitive=sens
widget_control, widgets.mp(i).npoints, sensitive=sens
widget_control, widgets.mp(i).position, sensitive=sens
endfor
end
; ************************************************************
pro new_scan_params, index, widgets
@scan_common
; This routine computes and displays scan parameters
; It must make sure that:
; start, stop, and step are integral number of motor steps
; start, stop, step, and npoints are internally consistent
; scan range is within soft limits
; Updates estimated scan time
if (not obj_valid(sd.motors(index))) then return
mot = md(index)
; Make sure start, stop, and step are all integer # of motor steps
scale = sd.motors(index)->get_scale()
position = sd.motors(index)->get_position()
mot.start[0] = round(mot.start[0]*scale) / scale
mot.stop[0] = round(mot.stop[0]*scale) / scale
mot.inc[0] = round(mot.inc[0]*scale) / scale
; Correct sign of step size if necessary
if (mot.stop[0] gt mot.start[0]) then mot.inc[0] = abs(mot.inc[0]) $
else mot.inc[0] = -abs(mot.inc[0])
sd.dims(index) = (mot.stop[0]-mot.start[0])/mot.inc[0] + 1
widget_control, widgets.mp(index).abs_start, set_value=mot.start[0]
widget_control, widgets.mp(index).abs_stop, set_value=mot.stop[0]
widget_control, widgets.mp(index).rel_start, set_value=(mot.start[0]-position)
widget_control, widgets.mp(index).rel_stop, set_value=(mot.stop[0]-position)
widget_control, widgets.mp(index).step, set_value=mot.inc[0]
widget_control, widgets.mp(index).npoints, set_value = sd.dims(index)
md(index) = mot
; Compute estimated scan time
points = sd.dims(0)
if (sd.n_dims eq 2) then points= points * sd.dims(1)
time = sd.dwell_time * points
widget_control, widgets.total_time, set_value=time
; Check for soft-limit violations
high_limit = sd.motors[index]->get_high_limit()
low_limit = sd.motors[index]->get_low_limit()
if (mot.start[0] gt high_limit) or (mot.start[0] lt low_limit) then $
t = dialog_message(/error, "Start position is beyond soft limits", $
dialog_parent=widgets.base)
if (mot.stop[0] gt high_limit) or (mot.stop[0] lt low_limit) then $
t = dialog_message(/error, "Stop position is beyond soft limits", $
dialog_parent=widgets.base)
end
; ************************************************************
pro widget_scan_event, event
@scan_common
widget_control, event.top, get_uvalue=widgets, /no_copy
if n_elements(widgets) eq 0 then begin
; This is an event during a scan (when xmanager is inactive)
; Ignore it.
print, 'got event, id = ', event.id
return
endif
case event.id of
widgets.timer: begin
; Read the current motor position, store it, and display it.
for i=0,1 do begin
if obj_valid(sd.motors(j)) then begin
pos = sd.motors(i)->get_position()
widget_control, widgets.mp(i).position, set_value=pos
endif
endfor
widget_control, widgets.timer, timer=1.0
end
widgets.scan_mode: begin
sd.scan_type = event.index
widget_scan_sens, widgets
end
widgets.scan_dims: begin
sd.n_dims = event.index + 1
widget_scan_sens, widgets
end
widgets.n_motors: begin
sd.n_motors = event.index + 1
widget_scan_sens, widgets
end
widgets.dwell_time: begin
sd.dwell_time = event.value
new_scan_params, 0, widgets
end
widgets.scan_file: begin
widget_control, event.id, get_value=scan_file
sd.file_name = scan_file[0]
end
widgets.scan_title: begin
widget_control, event.id, get_value=scan_title
sd.title = scan_title[0]
end
widgets.start_scan: begin
widget_control, widgets.start_scan, sensitive=0
widget_control, widgets.exit, sensitive=0
set_plot_values
catch, error
if (error eq 0) then begin
sd.abort_scan_widget = widgets.abort_scan
scan
endif else begin ; An error occured during the scan
t = dialog_message(/error, !ERR_STRING, dialog_parent=widgets.base)
endelse
widget_control, widgets.start_scan, sensitive=1
widget_control, widgets.exit, sensitive=1
; Update scan file name
widget_control, widgets.scan_file, set_value=sd.file_name
end
widgets.exit: begin
widget_control, event.top, /destroy
return
end
endcase
widget_control, event.top, set_uvalue=widgets, /no_copy
end
; ************************************************************
pro widget_scan_motor_event, event
@scan_common
widget_control, event.top, get_uvalue=widgets, /no_copy
for i=0, 1 do begin
if (event.id eq widgets.mp[i].name) then begin
widget_control, widgets.base, /hourglass
widget_control, event.id, get_value=motor_name
motor_name = motor_name[0]
m = obj_new('epics_motor', motor_name)
if (not obj_valid(m)) then begin
t = dialog_message(/error, 'Invalid motor name', $
dialog_parent=widgets.base)
goto, done
endif
obj_destroy, sd.motors(i)
sd.motors(i) = m
md(i).name = sd.motors(i)->get_name()
position = sd.motors(i)->get_position()
; Use the same values of relative start and stop positions and step
widget_control, widgets.mp(i).rel_start, get_value=rel_start
widget_control, widgets.mp(i).rel_stop, get_value=rel_stop
md(i).start[0] = position + rel_start
md(i).stop[0] = position + rel_stop
widget_control, event.id, set_value=md(i).name
widget_scan_sens, widgets
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).abs_start) then begin
md(i).start[0] = event.value
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).abs_stop) then begin
md(i).stop[0] = event.value
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).rel_start) then begin
position = sd.motors(i)->get_position()
md(i).start[0] = position + event.value
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).rel_stop) then begin
position = sd.motors(i)->get_position()
md(i).stop[0] = position + event.value
new_scan_params, i, widgets
endif else if (event.id eq widgets.mp(i).step) then begin
md(i).inc[0] = event.value
new_scan_params, i, widgets
endif
endfor
done:
widget_control, event.top, set_uvalue=widgets, /no_copy
end
; ************************************************************
pro widget_scan_scaler_event, event
@scan_common
widget_control, event.top, get_uvalue=widgets, /no_copy
case event.id of
widgets.scaler_name: begin
widget_control, widgets.base, /hourglass
widget_control, event.id, get_value=scaler_name
scaler_name = scaler_name[0]
scaler = obj_new('epics_scaler', scaler_name)
if obj_valid(scaler) then begin
obj_destroy, sd.scaler
sd.scaler = scaler
sd.scaler_pvname = scaler_name
draw_scaler_widgets, widgets
endif else begin
t = dialog_message(/error, 'Scaler not found', $
dialog_parent=widgets.base)
endelse
end
widgets.n_scalers: begin
widget_control, event.id, get_value=n_scalers
sd.n_scalers = n_scalers > 1
draw_scaler_widgets, widgets
end
else: begin
for i=0, sd.n_scalers-1 do begin
if (event.id eq widgets.scalers[i].title) then begin
widget_control, event.id, get_value=title
title = title[0]
sd.scalers[i].title = title
sd.scaler->set_title, i, title
endif else if (event.id eq widgets.scalers[i].plot) then begin
sd.scalers[i].plot = event.select
set_plot_values
endif
endfor
end
endcase
widget_control, event.top, set_uvalue=widgets, /no_copy
end
; ************************************************************
pro widget_scan_roi_event, event
@scan_common
widget_control, event.top, get_uvalue=widgets, /no_copy
case event.id of
widgets.timing_mode: begin
sd.timing_mode = event.index ; This assumes index=0 is mode=0
widget_scan_sens, widgets
end
widgets.mca_name: begin
widget_control, widgets.base, /hourglass
widget_control, event.id, get_value=mca_name
mca_name = mca_name[0]
m = obj_new('epics_mca', mca_name)
if obj_valid(m) then begin
obj_destroy, sd.mca
sd.mca = m
sd.mca_pvname = mca_name
draw_roi_widgets, widgets
endif else begin
t = dialog_message(/error, 'MCA not found', dialog_parent=widgets.base)
endelse
end
else: begin
for i=0, sd.n_rois-1 do begin
if (event.id eq widgets.rois(i).title) then begin
widget_control, event.id, get_value=title
title = title[0]
rois = sd.mca->get_rois()
rois[i].label = title
sd.mca->set_rois, rois
endif else if (event.id eq widgets.rois(i).left) then begin
widget_control, event.id, get_value=left
left = long(left[0])
rois = sd.mca->get_rois()
rois[i].left = left
sd.mca->set_rois, rois
endif else if (event.id eq widgets.rois(i).right) then begin
widget_control, event.id, get_value=right
right = long(right[0])
rois = sd.mca->get_rois()
rois[i].right = right
sd.mca->set_rois, rois
endif else if (event.id eq widgets.rois(i).bgd_width) then begin
widget_control, event.id, get_value=bgd_width
bgd_width = long(bgd_width[0])
rois = sd.mca->get_rois()
rois[i].bgd_width = bgd_width
sd.mca->set_rois, rois
endif else if (event.id eq widgets.rois[i].plot) then begin
sd.roi[i].plot = event.select
set_plot_values
endif
endfor
end
endcase
widget_control, event.top, set_uvalue=widgets, /no_copy
end
; ************************************************************
pro widget_scan, group=group
@scan_common
init_scan_sd
mp = {base: 0L, name: '', $
abs_start: 0L, abs_stop: 0L, rel_start: 0L, rel_stop: 0L, $
step: 0L, npoints: 0L, position: 0L}
rois = {title: 0L, left: 0L, right:0L, bgd_width: 0L, plot: 0L}
scalers = {title: 0L, plot: 0L}
widgets = { base: 0L, $
scan_mode: 0L, $
scan_dims: 0L, $
n_motors_base: 0L, $
n_motors: 0L, $
mp: replicate(mp, 2), $
n_scalers: 0L, $
scaler_base1: 0L, $
scaler_base2: 0L, $
scaler_name: 0L, $
scalers: replicate(scalers, MAX_SCALERS), $
mca_name: 0L, $
roi_base1: 0L, $
roi_base2: 0L, $
rois: replicate(rois, MAX_ROIS), $
timing_base: 0L, $
timing_mode: 0L, $
dwell_time: 0L, $
total_time: 0L, $
timer: 0L, $
start_scan: 0L, $
abort_scan: 0L, $
scan_title: 0L, $
scan_file: 0L, $
exit: 0L }
default_font = get_font_name(/small)
label_font = get_font_name(/bold)
widgets.base = widget_base(title="Scan Setup", /column)
widget_control, widgets.base, default_font=default_font
widgets.timer = widgets.base
row = widget_base(widgets.base, /row, /frame)
col = widget_base(row, /column)
t = widget_label(col, value='Scan type')
widgets.scan_mode = widget_droplist(col, $
value= ['Scaler', 'ROI', 'Spectrum', 'MCS'])
widget_control, widgets.scan_mode, set_droplist_select=sd.scan_type
col = widget_base(row, /column)
t = widget_label(col, value='Scan dims.')
widgets.scan_dims = widget_droplist(col, value=['1-D', '2-D'])
widget_control, widgets.scan_dims, set_droplist_select=sd.n_dims-1
col = widget_base(row, /column)
widgets.n_motors_base = col
t = widget_label(col, value='# motors')
widgets.n_motors = widget_droplist(col, value=['1', '2'])
col = widget_base(row, /column)
widgets.dwell_time = cw_field(row, title='Count time (sec)', /return_events, $
value=sd.dwell_time, /column, /float, xsize=10)
widgets.total_time = cw_field(row, title='Total time (sec)', /noedit, $
value=0.0, /column, /float, xsize=10)
r = widget_base(widgets.base, /row, event_pro='widget_scan_motor_event')
for i=0, 1 do begin
col = widget_base(r, /column, /frame)
widgets.mp(i).base = col
t = widget_label(col, value='Motor '+strtrim(i+1,2), font=label_font)
row = widget_base(col, /row)
widgets.mp(i).name = cw_field(row, title='Motor name', value=md(i).name, $
/return_events, /column, /string, xsize=20)
width=10
widgets.mp(i).position = cw_field(row, title='Current position', value=0.0, $
/return_events, /column, /float, xsize=width)
row = widget_base(col, /row)
widgets.mp(i).abs_start = cw_field(row, title='Start (abs)', $
value=md(i).start[0], $
/return_events, /column, /float, xsize=width)
widgets.mp(i).abs_stop = cw_field(row, title='Stop (abs)', $
value=md(i).stop[0], $
/return_events, /column, /float, xsize=width)
widgets.mp(i).step = cw_field(row, title='Step', value=md[i].inc[0], $
/return_events, /column, /float, xsize=width)
row = widget_base(col, /row)
widgets.mp(i).rel_start = cw_field(row, title='Start (rel)', value=-1.0, $
/return_events, /column, /float, xsize=width)
widgets.mp(i).rel_stop = cw_field(row, title='Stop (rel)', value=1.0, $
/return_events, /column, /float, xsize=width)
widgets.mp(i).npoints = cw_field(row, title='# points', value=0, $
/noedit, /column, /integer, xsize=width)
endfor
widgets.scaler_base1 = widget_base(widgets.base, /column, /frame, $
event_pro='widget_scan_scaler_event')
t = widget_label(widgets.scaler_base1, value='Scalers', font=label_font)
widgets.scaler_base2 = widget_base(widgets.scaler_base1, /row, /frame)
draw_scaler_widgets, widgets
widgets.roi_base1 = widget_base(widgets.base, /column, /frame, $
event_pro='widget_scan_roi_event')
t = widget_label(widgets.roi_base1, value='Regions of Interest', $
font=label_font)
widgets.roi_base2 = widget_base(widgets.roi_base1, /row, /frame)
draw_roi_widgets, widgets
row = widget_base(widgets.base, /row, /frame)
col = widget_base(row, /column)
t = widget_label(col, value='Scan file name')
widgets.scan_file = widget_text(col, value=sd.file_name, /edit, $
xsize=20)
col = widget_base(row, /column)
t = widget_label(col, value='Scan title')
widgets.scan_title = widget_text(col, value=sd.title, /edit, $
xsize=60)
row = widget_base(widgets.base, /row)
widgets.start_scan = widget_button(row, value='Start scan', font=label_font)
widgets.abort_scan = widget_button(row, value='Abort scan', font=label_font, $
event_pro = 'abort_scan')
widgets.exit = widget_button(row, value='Exit', font=label_font)
for i=0, 1 do new_scan_params, i, widgets
widget_scan_sens, widgets
widget_control, widgets.base, set_uvalue=widgets
widget_control, widgets.base, /realize
widget_control, widgets.timer, timer=1.0
xmanager, 'widget_scan', widgets.base, group_leader=group
end
write_bsif.pro 0100664 0000621 0000620 00000006761 07231345476 012744 0 ustar epics epics pro WRITE_BSIF, file, xdr=xdr
;+
; NAME:
; WRITE_BSIF.PRO
; PURPOSE:
; Writes a Brookhaven Standard Image Format file.
; The default on all systems except VMS is to write an XDR format file which is
; computer independent. On VMS only the default is to write the old-style
; non-XDR file format.
; CALLING SEQUENCE:
; WRITE_BSIF, filename
; INPUTS:
; filename; The name of the file to write
; KEYWORD PARAMETERS:
; XDR
; Set this keyword to specify that the file is to be written in XDR,
; a portable binary format. This keyword is only necessary on VMS.
; OUTPUTS:
; None
; COMMON BLOCKS:
; BSIF_COMMON, defined in BSIF_COMMON.PRO.
; SIDE EFFECTS:
; Writes the data and parameters stored in common block BSIF_COMMON to
; the specified file.
; RESTRICTIONS:
;
; PROCEDURE:
; For XDR files WRITE_BSIF opens the file and writes out the data.
; For VMS BSIF files WRITE_BSIF.PRO simply calls WRITE_BSIF_I, which is
; a procedure which is written in C. It must be made known via the
; LINKIMAGE command. This is normally done in the startup file.
; MODIFICATION HISTORY
; Written in 1990 by Mark Rivers
; Modified October 1991 to ensure that DATA_TITLE is a string array.
; 4/21/94 MLR Create user_buffer if it doesn't exist. Was crashing in
; write_bsif_i.c if it was not defined.
; Modified September 1996 by Harvey Rarback to use user_buffer for
; [x_dist,y_dist] for XDR files
; Jan 17, 2001 MLR Made XDR the default for non-VMS systems. Merged BNL and
; APS versions.
;-
;
@bsif_common
n_cols = n_elements(image_data(*, 0, 0))
n_rows = n_elements(image_data(0, *, 0))
n_data = n_elements(image_data(0, 0, *))
data_min = dblarr(n_data)
data_max = dblarr(n_data)
temp = strarr(n_data)
for i=0, n_data-1 do begin
mn = min(image_data(*,*,i), max=mx)
data_min(i) = mn
data_max(i) = mx
temp(i) = data_title(i)
endfor
data_title = temp
; Make sure the user buffer exists. write_bsif_i crashes if it doesn't.
ub_len = n_elements(user_buffer)
if (ub_len eq 0) then begin
ub_len = 1
user_buffer = bytarr(ub_len)
endif
if (keyword_set(xdr) or (!version.os ne 'vms')) then begin
get_lun, lun
openw, lun, file, /xdr
ub_len = n_elements(user_buffer)
if (ub_len eq 0) then begin
ub_len = 1
user_buffer = bytarr(ub_len)
endif else if ub_len eq 4*(n_rows+n_cols) then begin ; multiple scan regions
new_buffer = fltarr( n_rows + n_cols)
copy_bytes, ub_len, user_buffer, new_buffer
user_buffer = new_buffer
endif
type = size(image_data)
type = type(type(0)+1)
; Convert from IDL data types to BSIF data types
case type of
1: data_type = 1
2: data_type = 3
3: data_type = 5
4: data_type = 6
5: data_type = 7
endcase
writeu, lun, long(n_rows), long(n_cols), long(n_data), long(x_normal), $
long(y_normal), long(rotated), float(x_start), float(x_stop), $
float(y_start), float(y_stop), $
string(image_title), string(x_title), string(y_title), $
data_title, long(data_type), long(ub_len),$
image_data, user_buffer
close, lun
free_lun, lun
endif else begin
write_bsif_i, file, n_rows, n_cols, n_data, x_normal, $
y_normal, rotated, x_start, x_stop, y_start, y_stop, $
image_title, x_title, y_title, data_title, data_type, $
compression_type, data_min, data_max, user_buffer, image_data
endelse
return
end
escan/a2f.pro 0100644 0000621 0000620 00000000123 07237637100 012322 0 ustar epics epics function a2f, x
; string to floating point
y = double(strtrim(x,2))
return, y
end
escan/collect_offsets.pro 0100644 0000621 0000620 00000007224 07316236570 015045 0 ustar epics epics pro collect_offsets_event, event
Widget_Control, event.top, get_uvalue = p
Widget_Control, event.id, get_uvalue = uval
case uval of
'exit': begin
obj_destroy, (*p).scaler_obj
Widget_Control, event.top, /destroy
end
'collect': begin
sc = (*p).scaler_pv
ctime= (*p).ctime
t = ca_put((*p).sh_clos,1)
t = caget((*p).shutter, sh_status)
wait, 0.5
t = caget(sc + '.CONT', save_mode)
t = caget(sc + '.TP' , save_time)
t = ca_put(sc + '.TP' , ctime)
(*p).scaler_obj->start, ctime
(*p).scaler_obj->wait
counts = (*p).scaler_obj->read()
;
sx = size(counts)
tx = strtrim(string(counts[0],format='(i11)'))
for i = 1, sx[1]-1 do begin
ax = string(byte(i+65))
ix = strtrim(string(i+1,format='(i1.1)'))
cx = strtrim(string(counts[i],format='(i10)'))
cpv = sc + '_calc' + ix + '.CALC'
; print, i, ' ', ax, cx, ix, tx
calc = ax + '-' + cx + '*(A/' + tx + ')'
calc = strcompress(calc,/remove_all)
j = ca_put(cpv, calc)
endfor
Widget_Control, event.top, /destroy
;done: return scaler mode, count time, and re-open shutter
t = ca_put(sc + '.CONT', save_mode)
t = ca_put(sc + '.TP' , save_time)
t = ca_put((*p).sh_open, 1)
(*p).scaler_obj->start, 1
(*p).scaler_obj->wait
obj_destroy, (*p).scaler_obj
end
'ctime': begin
Widget_Control, (*p).form.ctime, get_value=s
x = a2f(s)
if (x le 0) then x = 10.0
(*p).ctime = x
Widget_Control, (*p).form.ctime, set_value=f2a(x)
end
endcase
return
end
function collect_offsets, p
;
; gui for selecting detectors
mine = Widget_Base(TITLE = 'Collect Scaler Offsets', /COLUMN, APP_MBAR = menubar)
fileMenu = Widget_Button(menubar, value = 'File')
exitMB = Widget_Button(fileMenu, value = 'Exit', uvalue = 'exit', /sep)
mainFRAME = Widget_Base(mine, /COLUMN)
; gather all valid detector names (why not??)
;
dgrp = (*p).es->get_param('detgroups')
scanPV = (*p).es->get_scan_param(0,scanPV)
prefix = (*p).es->get_param('prefix')
sh_clos= (*p).es->get_param('shutter_clos')
sh_open= (*p).es->get_param('shutter_open')
shutter= (*p).es->get_param('shutter_pv')
collect_time= 10.0
MAX_DTY = n_elements(dgrp.name)
for i = 0,MAX_DTY-1 do begin
pr = dgrp.prefix[i]
if ((dgrp.use_det[i] eq 1) and (dgrp.is_mca[i] eq 0)) then begin
scaler_pv = pr
endif
endfor
so = obj_new('EPICS_SCALER',scaler_pv)
form = {ctime:0L, scan_pv:0L,dialog:0L}
info = {es:(*p).es, form:form,ctime:collect_time, $
shutter:shutter, sh_open:sh_open, sh_clos:sh_clos, $
prefix:prefix, scaler_pv:scaler_pv, scaler_obj:so}
base = Widget_Base(mainFrame,/col)
base2 = Widget_Base(base,/row)
str = 'Collect Offsets for ' + scaler_pv
x = Widget_Label(base2, value =str)
base2 = Widget_Base(base,/row)
info.form.ctime = CW_FIELD(base2, /FLOAT, /ROW, XSIZE =7, $
title = 'Collection Time', UVALUE = 'ctime', $
VALUE = f2a(info.ctime), $
/return_events)
x = Widget_Label(base2, value = 's')
base2 = Widget_Base(base,/row)
X = Widget_Button(base2, value = 'Collect Offsets', uval='collect')
X = Widget_Button(base2, value = 'Quit', uval='exit')
Widget_Control, mine, /update
p_info = ptr_new(info,/NO_COPY)
Widget_Control, mine, set_uvalue=p_info
Widget_Control, mine, /REALIZE
xmanager, 'collect_offsets', mine, /NO_BLOCK
return, 0
end
escan/data_viewer.pro 0100644 0000621 0000620 00000010017 07335357540 014155 0 ustar epics epics pro data_viewer_event, event
@scan_dims
Widget_Control, event.top, get_uval = p
widget_control, event.id, get_uval = uval
ErrorNo = 0
Catch, ErrorNo
if (ErrorNo ne 0) then begin
Catch, /CANCEL
ErrA = ['Error!', 'Number' + strtrim(!error, 2), !Err_String]
a = Dialog_Message(ErrA, /ERROR)
return
endif
print, 'data viewer event, uval = ', uval, event.id
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'read_file': begin
s_file = dialog_pickfile(filter='*.*', get_path=path, $
/must_exist, /read, file = s_file)
if (s_file ne '') then begin
tmp_o = read_scan(s_file)
help, tmp_o
endif
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
print, ' data file : ', t
end
'usertext': begin
end
'colors': begin
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
return
end
pro data_viewer, file=file, use_dialog=use_dialog
;
; gui for selecting detectors
;
@scan_dims
print, 'Data Viewer version 1.0'
;
if (keyword_set (use_dialog)) then begin
file = dialog_pickfile(filter='*.*', get_path=path, $
/write, file = init_file)
endif
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
da = fltarr(5,4)
xsize = 800
ysize = 495
cpt2d = 0
cpt1d = 0
;
datafile=''
px = ptr_new()
data = {files:px,da:da}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'black', $
'yellow', 'red', 'cyan', 'blue']
!p.background = set_color('white')
!p.color = set_color('black')
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',$
ylab:'', title:'', charsize:1.3}
info = {data:data, form:form, plot:plot}
main = Widget_Base(title = 'Data Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Read Scan File ...', uval = 'read_file')
x = Widget_Button(menu, value = 'Export to ASCII ', uval = 'ascii_export')
x = Widget_Button(menu, value = 'Print', uval = 'print')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /sep)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = Widget_Base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
info.form.timer = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
; Widget_Control, info.form.draw, get_value=d
; info.form.draw_id = d
; wset, info.form.draw_id
; device, retain=2
Widget_Control, main, /realize
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'data_viewer', main, /no_block
return
end
escan/define_detectors_group.pro 0100664 0000621 0000620 00000022153 07237637100 016405 0 ustar epics epics pro define_detectors_event, event
Widget_Control, event.top, get_uvalue = p
Widget_Control, event.id, get_uvalue = uval
if (uval eq 'cancel') then begin
x = (*p).es->set_param('detectors',(*p).det_save)
endif
if ((uval eq 'save') or (uval eq 'exit')) then begin
; print, ' info.group = ', (*p).group
dgrp = (*p).es->get_param('detgroups')
;print, ' Saving Detectors '
M_DET = n_elements( (*p).det.countPV )
for i = 0, M_DET - 1 do begin
j = Widget_Info( (*p).form.det_elem[i], /droplist_select)
net = Widget_Info( (*p).form.use_net[i], /droplist_select)
if (j gt 0) then begin
k = Widget_Info( (*p).form.det_desc[i], /droplist_select)
(*p).det.countPV[i] = ''
igr = (*p).group[j] - 1
pr = dgrp.prefix[igr]
if (igr eq 0) then begin
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=k,net=net)
(*p).det.countPV[i] = x.countPV
(*p).det.desc[i] = x.full_desc
endif else if (igr eq 1) then begin
x = get_detnam(prefix=pr,type='med:mca',elem=j-1,roi=k,net=net)
(*p).det.countPV[i] = x.countPV
(*p).det.desc[i] = x.full_desc
endif
endif else begin
(*p).det.countPV[i] = ''
endelse
; print, i, ' PV = ', (*p).det.countPV[i]
endfor
x = (*p).es->set_param('detectors',(*p).det)
endif
iu = strpos(uval,'_')
if ((uval eq 'cancel') or (uval eq 'exit')) then begin
caSetTimeout, (*p).timeout
caSetRetryCount, (*p).retry
Widget_Control, event.top, /DESTROY
endif else if (uval ne 'save') then begin
thing = strmid(uval,0,iu)
_elem_ = fix(strmid(uval,iu+1,strlen(uval)))-1
;; print, ' uval = ', thing, _elem_, event.index
if (thing eq 'elem') then begin
; print, ' event_index = ', event.index
Widget_Control, (*p).form.det_desc[_elem_], $
set_value = (*p).elem_list[event.index,*]
Widget_Control, (*p).form.det_desc[_elem_], set_droplist_select = 0
; if (_elem_ eq 1) then $
; Widget_Control, (*p).form.use_net[_elem_], set_droplist_select = 1
endif
endif
return
end
function define_detectors, p
;
; gui for selecting detectors
;
N_MCAS = 30
N_ROIS = 10
ret = (*p).es->lookup_detectors()
det = (*p).es->get_param('detectors')
det_save = det
MAX_DET = n_elements( det.countPV)
;
mine = Widget_Base(TITLE = 'Define Detectors', /COLUMN, APP_MBAR = menubar)
fileMenu = Widget_Button(menubar, value = 'File')
saveMB = Widget_Button(fileMenu, value = 'Save', uvalue = 'save' )
exitMB = Widget_Button(fileMenu, value = 'Exit', uvalue = 'exit', /sep)
mainFRAME = Widget_Base(mine, /COLUMN)
TMP = Widget_Base(mainFRAME, /ROW)
tx1 = Widget_Label(TMP, value = ' Looking up available detectors ... ')
Widget_Control, mine, /REALIZE
Widget_Control, mine, update = 0
;
; gather all valid detector names (why not??)
;
dgrp = (*p).es->get_param('detgroups')
scanPV = (*p).es->get_scan_param(0,scanPV)
prefix = (*p).es->get_param('prefix')
;
MAX_DTY = n_elements(dgrp.name)
elem_list = strarr(N_MCAS, N_ROIS)
group = intarr(N_MCAS + N_ROIS)
elemx = strarr(N_MCAS + N_ROIS )
elems = ['None' ]
groupx = [0]
form = {det_choice:0, det_elem:lonarr(MAX_DET), $
det_desc:lonarr(MAX_DET) , use_net: lonarr(MAX_DET) }
info = {es:(*p).es, form:form, det_save:det_save, $
det:det, elems:elemx, elem_list: elem_list, group:group, $
timeout:0.001, retry:50 }
print, ' a'
info.timeout = caGetTimeout()
info.retry = caGetRetryCount()
t0 = (info.timeout/ 10.) > 0.001
caSetTimeout, t0
caSetRetryCount, 25
print, ' ----------- DEFINE DETECTORS ----------------', info.timeout
i_elems = 0
for i = 0,MAX_DTY-1 do begin
pr = dgrp.prefix[i]
print, ' ' , i, ' ', pr
if (dgrp.use_det[i] eq 1) then begin
; print, ' using ' , dgrp.name[i], ' is mca? = ', $
; dgrp.is_mca[i], ' # elems = ',dgrp.max_elems[i] , pr
if (dgrp.is_mca[i] eq 0) then begin
groupx = [groupx, i+1]
elems = [elems, dgrp.name[i]]
i_elems = i_elems + 1
for n = 0, dgrp.max_elems[i]-1 do begin
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=n,net=0)
;print, ' n, ielems, x = ', n, i_elems, x.desc
elem_list[i_elems,n] = x.desc
endfor
endif else begin
for j = 0, dgrp.max_elems[i] - 1 do begin
groupx = [groupx, i+1]
elems = [elems, dgrp.name[i]+' MCA' + strtrim(string(j+1),2)]
i_elems = i_elems + 1
for n = 0, N_ROIS-1 do begin
x = get_detnam(prefix=pr,type='med:mca',elem=j,roi=n,$
net=0)
elem_list[i_elems,n] = x.desc
;print, ' n, ielems, x = ', n, i_elems, x.desc
endfor
endfor
endelse
endif
endfor
; info.group = group
info.group = groupx
info.elems = elems
info.elem_list = elem_list
print, ' info.elems = ', info.elems
print, ' info.group = ', info.group
Widget_Control, TMP, /destroy
base2 = Widget_Base(mainFrame,/row)
X = Widget_Button(base2, value = 'Save Changes', uval='save')
X = Widget_Button(base2, value = 'Cancel', uval='cancel')
X = Widget_Button(base2, value = 'Done', uval='exit')
M_COLS = 4
M_ROWS = (MAX_DET/M_COLS) + 1
net_choices = ['Sum' , 'Net']
i = -1
Grid = Widget_Base(mainFRAME, /ROW)
tcol = lonarr(M_COLS+1)
for icol = 1, M_COLS do begin
tcol[icol] = Widget_Base(Grid, /col)
tc = Widget_Base(tcol[icol], /row)
X = Widget_Label(TC, XSIZE=80, value = ' Detector ')
X = Widget_Label(TC, XSIZE=80, value = ' Sum / Net')
X = Widget_Label(TC, XSIZE=80, value = ' Element ')
X = Widget_Label(TC, XSIZE=80, value = ' Selection ')
for irow = 0, M_ROWS-1 do begin
i = i + 1
if (i ge MAX_DET) then goto, form_end
index = strtrim(string(i+1,format='(i2.2)'),2)
T = Widget_Base(tcol[icol], /row)
uvalu = 'elem_' + index
T1 = Widget_Label(T, XSIZE=40, value = index )
uvalu = 'net_' + index
info.form.use_net[i] = Widget_DROPLIST(T, value = net_choices, $
uvalue = uvalu, /dynamic_resize)
uvalu = 'elem_' + index
info.form.det_elem[i] = Widget_DROPLIST(T, value = elems, uvalue = uvalu, /dynamic_resize)
Widget_Control, info.form.det_elem[i], set_droplist_SELECT = 0
uvalu = 'desc_' + index
info.form.det_desc[i] = Widget_DROPLIST(T, value = elem_list[1,*], uvalue = uvalu, /dynamic_resize)
elem_choice = 03
ending = ''
print, ' I = ' , i, uvalu, det.countPV[i]
if (det.countPV[i] ne '') then begin
igr = det.group[i]
gr = dgrp.prefix[igr]
ending = strmid(det.countPV[i], strlen(dgrp.prefix[igr]), strlen(det.countPV[i]))
x = split_det_name(gr, ending, dgrp.is_mca[igr])
print, i, ' ', det.countPV[i], ' | ', gr, ' | ', det.desc[i], ' | ', ending
Widget_Control, info.form.use_net[i], set_droplist_select = det.use_net[i]
roi = ''
if (dgrp.is_mca[igr] eq 1) then begin
i_elem = strmid(ending,3,strpos(ending,'.')-3)
elem = 'MCA ' + strtrim(i_elem,2)
i_elem = fix(i_elem) + 1
roi = strmid(ending, strpos(ending,'.R')+2)
if (strmid(roi,strlen(roi)-1) eq 'N') then roi = strmid(roi,0,strlen(roi)-1)
i_roi = fix(roi)
; print, ' MCA ', i_elem, i_roi, ' from ' , ending
Widget_Control, info.form.det_elem[i], set_droplist_select = i_elem
Widget_Control, info.form.det_desc[i], set_value = elem_list[i_elem,*]
Widget_Control, info.form.det_desc[i], set_droplist_select = i_roi
endif else begin
i_elem = 1
if (strmid(ending,0,5) eq '_calc') then begin
roi = strmid(ending, 5, strpos(ending,'.')-5)
endif else if (strmid(ending,0,2) eq '.S') then begin
roi = strmid(ending,2)
endif
i_roi = fix(roi)-1
Widget_Control, info.form.det_elem[i], set_droplist_select = i_elem
Widget_Control, info.form.det_desc[i], set_value = elem_list[i_elem,*]
Widget_Control, info.form.det_desc[i], set_droplist_select = i_roi
endelse
endif else begin
Widget_Control, info.form.det_elem[i], set_droplist_select = 0
Widget_Control, info.form.det_desc[i], set_value = elem_list[elem_choice,*]
Widget_Control, info.form.det_desc[i], set_value = elem_list[0,*]
endelse
endfor
endfor
form_end:
Widget_Control, mine, /update
p_info = ptr_new(info,/NO_COPY)
Widget_Control, mine, set_uvalue=p_info
Widget_Control, mine, /REALIZE
xmanager, 'define_detectors', mine, /NO_BLOCK
return, 0
end
escan/define_detectors.pro 0100644 0000621 0000620 00000025722 07317660752 015204 0 ustar epics epics pro define_detectors_event, event
MAX_SCA = 10
MAX_MED = 16
MAX_ROI = 10
Widget_Control, event.top, get_uvalue = p
Widget_Control, event.id, get_uvalue = uval
mca = '-1'
elem = '-1'
i = strpos(uval, '.')
if (i gt 1) then begin
elem = strmid(uval,i+1,strlen(uval))
uval = strmid(uval,0,i)
j = strpos(elem,',')
if (j ge 1) then begin
mca = strmid(elem,j+1, strlen(elem))
elem = strmid(elem,0,j)
endif
endif
print, 'def det uval = ', uval, ' | mca ', mca, ' | elem ', elem
case uval of
'exit': begin
caSetTimeout, (*p).timeout
caSetRetryCount, (*p).retry
Widget_Control, event.top, /destroy
end
'sca_use_net': (*p).data.sca_use_net = event.index
'med_use_net': (*p).data.med_use_net = event.index
'save': begin
; print, ' saving results: '
widget_control, (*p).form.med_tot, get_value = s_med_tot
widget_control, (*p).form.sca_tot, get_value = s_sca_tot
med_tot = a2f(s_med_tot)
sca_tot = a2f(s_sca_tot)
tot = med_tot + sca_tot
if (tot gt 70) then begin
mes = [' Too Many Detectors Defined. ', ' ', $
' Up to 70 Detectors can be used', ' ', $
' The detector settings have not been saved yet.']
ret = dialog_message(mes)
endif else begin
; scalars
in_use = (*p).data.sca_use
pr = (*p).dgrp.prefix[0]
net = Widget_Info( (*p).form.sca_use_net, /droplist_select)
idet = -1
for is = 0, MAX_SCA - 1 do begin
if (in_use[is] eq 1) then begin
idet = idet + 1
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=is,net=net)
(*p).det.countPV[idet] = x.countPV
(*p).det.desc[idet] = x.full_desc
; print, 'det ', idet, ' is scalar: ' , x.full_desc, ' == ', x.countPV
endif
endfor
; med
in_use = (*p).data.med_use
pr = (*p).dgrp.prefix[1]
net = Widget_Info( (*p).form.med_use_net, /droplist_select)
for ir = 0, MAX_ROI - 1 do begin
for id = 0, MAX_MED - 1 do begin
if (in_use[ir,id] eq 1) then begin
idet = idet + 1
nd = id+1
x = get_detnam(prefix=pr,type='med:mca',elem=nd,roi=ir,net=net)
(*p).det.countPV[idet] = x.countPV
(*p).det.desc[idet] = x.full_desc
; print, 'det ', idet, ' is mca: ' , x.full_desc, ' == ', x.countPV
endif
endfor
endfor
; print, ' set ', idet , ' detectors.'
for ir = idet+1, 69 do begin
(*p).det.countPV[ir] = ''
(*p).det.desc[ir] = ''
endfor
x = (*p).es->set_param('detectors',(*p).det)
endelse
end
'roi_use_all': begin
widget_control, (*p).form.med_tot, get_value = s_med_tot
med_tot = a2f(s_med_tot)
print, ' roi use all ', elem, ' currently ', med_tot , ' in use '
for i = 0, MAX_MED -1 do begin
Widget_Control, (*p).form.med_use[elem,i], get_value=t
in_use = (*p).data.med_use[elem, i]
if (in_use eq 0) then begin
Widget_Control, (*p).form.med_use[elem,i], set_button=1
(*p).data.med_use[elem,i] = 1
med_tot = med_tot + 1
endif
s_med_tot = strtrim(fix(med_tot),2)
widget_control, (*p).form.med_tot, set_value = s_med_tot
endfor
end
'roi_clr_all': begin
widget_control, (*p).form.med_tot, get_value = s_med_tot
med_tot = a2f(s_med_tot)
print, ' roi clear all ', elem, ' currently ', med_tot , ' in use '
for i = 0, MAX_MED -1 do begin
Widget_Control, (*p).form.med_use[elem,i], get_value=t
in_use = (*p).data.med_use[elem, i]
if (in_use eq 1) then begin
Widget_Control, (*p).form.med_use[elem,i], set_button=0
(*p).data.med_use[elem,i] = 0
med_tot = med_tot - 1
endif
s_med_tot = strtrim(fix(med_tot),2)
widget_control, (*p).form.med_tot, set_value = s_med_tot
endfor
end
'sca': begin
(*p).data.sca_use[elem] = event.select
Widget_Control, (*p).form.sca_tot, get_value=t
ns = a2f(t)
ns = fix(ns + event.select*2 - 1)
Widget_Control, (*p).form.sca_tot, set_value=string(ns)
end
'med': begin
(*p).data.med_use[elem,mca-1] = event.select
Widget_Control, (*p).form.med_tot, get_value=t
ns = a2f(t)
ns = fix(ns + event.select*2 - 1)
Widget_Control, (*p).form.med_tot, set_value=string(ns)
end
else: print, ' unknown event ', uval
endcase
; event.select
return
end
function define_detectors, p
;
; GUI for selecting detectors by ROI
;
print, ' This is define_detectors v 1.0'
N_MCAS = 30
MAX_SCA = 10
MAX_MED = 16
MAX_ROI = 10
ret = (*p).es->lookup_detectors()
det = (*p).es->get_param('detectors')
det_save = det
MAX_DET = n_elements( det.countPV)
;
mine = Widget_Base(TITLE = 'Define Detectors', /COLUMN, APP_MBAR = menubar)
fileMenu = Widget_Button(menubar, value = 'File')
saveMB = Widget_Button(fileMenu, value = 'Save', uvalue = 'save' )
exitMB = Widget_Button(fileMenu, value = 'Exit', uvalue = 'exit', /sep)
main = Widget_Base(mine, /COLUMN)
TMP = Widget_Base(main, /ROW)
;
; gather all valid detector names (why not??)
;
dgrp = (*p).es->get_param('detgroups')
scanPV = (*p).es->get_scan_param(0,scanPV)
prefix = (*p).es->get_param('prefix')
;
MAX_DTY = n_elements(dgrp.name)
form = {det_choice:0, det_elem:lonarr(MAX_DET), $
det_desc:lonarr(MAX_DET) , use_net: lonarr(MAX_DET), $
sca_tot:0L, sca_use_net:1L, $
med_tot:0L, med_use_net:0L, $
med_use:lonarr(MAX_ROI,MAX_MED), $
sca_use:lonarr(MAX_SCA), $
med_use_all:lonarr(MAX_ROI), $
med_clr_all:lonarr(MAX_ROI) }
data = {med_use:lonarr(MAX_ROI, MAX_MED), sca_use:lonarr(MAX_SCA) , $
med_use_net:0, sca_use_net:1 , med_proto:7}
info = {es:(*p).es, form:form, $
det:det, dgrp:dgrp, data:data, $
timeout:0.01, retry:100 ,$
snames:strarr(MAX_SCA) }
info.timeout = caGetTimeout()
info.retry = caGetRetryCount()
t0 = (info.timeout/ 20.) > 0.001
caSetTimeout, t0
caSetRetryCount, 300
net_choices = ['Sum' , 'Net']
Widget_Control, default_font='Fixedsys'
;
; Scalers
sframe = Widget_Base(main, /col, /frame)
lf = Widget_Base(sframe, /row)
x = Widget_label(lf, value = ' Scalars: Use ')
info.form.sca_use_net = Widget_DROPLIST(lf, value = net_choices, $
uvalue = 'sca_use_net', /dynamic_resize)
x = Widget_label(lf, value = ' Counts ')
x = Widget_label(lf, value = ' Total Number Used ')
info.form.sca_tot = Widget_Label(lf, value = ' ')
fr0 = Widget_Base(sframe, /row, /nonexclusive)
if ((dgrp.use_det[0] eq 1) and (dgrp.is_mca[0] eq 0)) then begin
pr = dgrp.prefix[0]
for n = 0, MAX_SCA - 1 do begin
uvs = 'sca.' + strtrim(string(n),2)
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=n,net=0)
t = x.desc
if (x.desc eq '') then t = 'UNUSED'
info.form.sca_use[n] = Widget_Button(fr0, Value = t, uvalue = uvs)
info.snames[n] = x.desc
endfor
endif
;
; MCA
sframe = Widget_Base(main, /col, /frame)
lf = Widget_Base(sframe, /row)
x = Widget_label(lf, value = ' MED Detector: Use ')
info.form.med_use_net = Widget_DROPLIST(lf, value = net_choices, $
uvalue = 'med_use_net', /dynamic_resize)
x = Widget_label(lf, value = ' Counts ')
x = Widget_label(lf, value = ' Total Number Used ')
info.form.med_tot = Widget_Label(lf, value = ' ')
fr1 = Widget_Base(sframe, /col)
if ((dgrp.use_det[1] eq 1) and (dgrp.is_mca[1] eq 1)) then begin
mp = info.data.med_proto
; print, ' using MCA ', mp, ' as the master '
for nr = 0, MAX_ROI - 1 do begin
fr0 = Widget_Base(fr1, /row)
uvs = 'roi_use_all.' + strtrim(string(nr),2)
pr = dgrp.prefix[1]
x = get_detnam(prefix=pr,type='mca',elem=mp,roi=nr,net=0)
t = x.desc
if (x.desc eq '') then t = 'UNUSED'
x = Widget_Label(fr0, xsize=60, Value = t)
info.form.med_use_all[nr] = Widget_Button(fr0, value = 'Use All', uvalue = uvs)
fr00 = Widget_Base(fr0, /row, /nonexclusive)
for nm = 0, MAX_MED-1 do begin
xim = strtrim(string(nm+1),2)
uvs = 'med.' + strtrim(string(nr),2) + ',' + xim
info.form.med_use[nr,nm] = Widget_Button(fr00, value = xim, uvalue= uvs)
endfor
uvs = 'roi_clr_all.' + strtrim(string(nr),2)
info.form.med_clr_all[nr] = Widget_Button(fr0, value = 'Clear All', uvalue = uvs)
endfor
endif
;
; set defaults by what is actually in use
ns_x = 0
nm_x = 0
medpr = dgrp.prefix[1]
scapr = dgrp.prefix[0]
for i = 0, MAX_DET -1 do begin
if ( det.countPV[i] ne '') then begin
if (strpos(det.countPV[i],'scaler') ge 1) then begin
for n = 0, MAX_SCA -1 do begin
if (det.desc[i] eq info.snames[n]) then begin
ns_x = ns_x + 1
info.data.sca_use[n] = 1
Widget_Control, info.form.sca_use[n] , set_button=1
endif
endfor
endif else if (strpos(det.countPV[i],'mca') ge 1) then begin
for nm = 0, MAX_MED -1 do begin
xdet = medpr + 'mca' + strtrim(string(nm+1),2) + '.R'
for nr = 0, MAX_ROI -1 do begin
d = xdet + strtrim(string(nr),2)
if (det.countPV[i] eq d) then begin
nm_x = nm_x + 1
info.data.med_use[nr,nm] = 1
Widget_Control, info.form.med_use[nr,nm] , set_button=1
endif
endfor
endfor
endif
endif
endfor
widget_control, info.form.sca_tot, set_value = string(ns_x)
widget_control, info.form.med_tot, set_value = string(nm_x)
base2 = Widget_Base(main,/row)
X = Widget_Button(base2, value = 'Save Changes', uval='save')
X = Widget_Button(base2, value = 'Exit', uval='exit')
M_COLS = 4
M_ROWS = (MAX_DET/M_COLS) + 1
net_choices = ['Sum' , 'Net']
Widget_Control, info.form.sca_use_net, set_droplist_select=info.data.sca_use_net
Widget_Control, info.form.med_use_net, set_droplist_select=info.data.med_use_net
i = -1
Grid = Widget_Base(main, /ROW)
tcol = lonarr(M_COLS+1)
form_end:
Widget_Control, mine, /update
p_info = ptr_new(info,/NO_COPY)
Widget_Control, mine, set_uvalue=p_info
Widget_Control, mine, /REALIZE
xmanager, 'define_detectors', mine, /NO_BLOCK
return, 0
end
escan/define_meta_detectors.pro 0100664 0000621 0000620 00000016407 07237637100 016204 0 ustar epics epics pro meta_detectors_event, event
Widget_Control, event.top, get_uvalue = p
Widget_Control, event.id, get_uvalue = uval
mca = '-1'
elem = '-1'
i = strpos(uval, '.')
if (i gt 1) then begin
elem = strmid(uval,i+1,strlen(uval))
uval = strmid(uval,0,i)
j = strpos(elem,',')
if (j ge 1) then begin
mca = strmid(elem,j+1, strlen(elem))
elem = strmid(elem,0,j)
endif
endif
print, uval, ' , ', elem, ' , ', mca
case uval of
'save': begin
print, ' save results'
end
'exit': begin
print, ' exit '
end
'sca_use_net': begin
print, ' sca_use_net '
end
'med_use_net': begin
print, ' med_use_net '
end
'sca_use': begin
print, ' sca_use element: ', elem
end
'roi_use_all': begin
print, ' roi use all ', elem
end
'med': begin
print, ' sca_use element: ', elem
end
else: print, ' unknown event ', uval
endcase
; event.select
return
end
function meta_detectors, p
;
; GUI for selecting detectors by ROI
;
N_MCAS = 30
MAX_SCA = 10
MAX_MED = 16
MAX_ROI = 10
print, ' define_meta_detectors '
ret = (*p).es->lookup_detectors()
det = (*p).es->get_param('detectors')
det_save = det
MAX_DET = n_elements( det.countPV)
;
mine = Widget_Base(TITLE = 'Define Detectors', /COLUMN, APP_MBAR = menubar)
fileMenu = Widget_Button(menubar, value = 'File')
saveMB = Widget_Button(fileMenu, value = 'Save', uvalue = 'save' )
exitMB = Widget_Button(fileMenu, value = 'Exit', uvalue = 'exit', /sep)
main = Widget_Base(mine, /COLUMN)
TMP = Widget_Base(main, /ROW)
;
; gather all valid detector names (why not??)
;
dgrp = (*p).es->get_param('detgroups')
scanPV = (*p).es->get_scan_param(0,scanPV)
prefix = (*p).es->get_param('prefix')
;
MAX_DTY = n_elements(dgrp.name)
form = {det_choice:0, det_elem:lonarr(MAX_DET), $
det_desc:lonarr(MAX_DET) , use_net: lonarr(MAX_DET), $
sca_used:0L, sca_use_net:0L, $
med_used:0L, med_use_net:0L, $
med_use_mca:lonarr(MAX_ROI,MAX_MED) }
info = {es:(*p).es, form:form, det_save:det_save, $
det:det, $
timeout:0.001, retry:50 ,$
sbutton:lonarr(MAX_SCA), s_use_net:1L, snames:strarr(MAX_SCA) , $
sca_inuse:0 , med_inuse:0 , $
mbutton:lonarr(MAX_ROI), m_use_all:lonarr(MAX_ROI), $
m_use_net:1L, mnames:strarr(MAX_ROI) }
info.timeout = caGetTimeout()
info.retry = caGetRetryCount()
t0 = (info.timeout/ 10.) > 0.001
caSetTimeout, t0
caSetRetryCount, 25
net_choices = ['Sum' , 'Net']
; Widget_Control, default_font='Fixedsys'
;
; Scalars
sframe = Widget_Base(main, /col,/frame)
lf = Widget_Base(sframe, /row)
x = Widget_label(lf, value = ' Scalars: Use ')
info.form.sca_use_net = Widget_DROPLIST(lf, value = net_choices, $
uvalue = 'sca_use_net', /dynamic_resize)
x = Widget_label(lf, value = ' Counts ')
x = Widget_label(lf, value = ' Total Number Used ')
info.form.sca_used = Widget_Label(lf, value = ' ')
fr0 = Widget_Base(sframe, /row, /nonexclusive)
if ((dgrp.use_det[0] eq 1) and (dgrp.is_mca[0] eq 0)) then begin
pr = dgrp.prefix[0]
for n = 0, MAX_SCA - 1 do begin
uvs = 'sca.' + strtrim(string(n),2)
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=n,net=0)
t = x.desc
if (x.desc eq '') then t = 'UNUSED'
info.sbutton[n] = Widget_Button(fr0, xsize=60, Value = t, uvalue = uvs)
info.snames[n] = x.desc
endfor
endif
;
; MCA
sframe = Widget_Base(main, /col,/frame)
lf = Widget_Base(sframe, /row)
x = Widget_label(lf, value = ' MED Detector: Use ')
info.form.med_use_net = Widget_DROPLIST(lf, value = net_choices, $
uvalue = 'med_use_net', /dynamic_resize)
x = Widget_label(lf, value = ' Counts ')
x = Widget_label(lf, value = ' Total Number Used ')
info.form.med_used = Widget_Label(lf, value = ' ')
fr1 = Widget_Base(sframe, /col)
if ((dgrp.use_det[1] eq 1) and (dgrp.is_mca[1] eq 1)) then begin
for nr = 0, MAX_ROI - 1 do begin
fr0 = Widget_Base(fr1, /row)
uvs = 'roi_use_all.' + strtrim(string(nr),2)
pr = dgrp.prefix[1]
x = get_detnam(prefix=pr,type='mca',elem=1,roi=nr,net=0)
t = x.desc
if (x.desc eq '') then t = 'UNUSED'
info.mbutton[nr] = Widget_Label(fr0, xsize=60, Value = t)
info.mnames[nr] = x.desc
info.m_use_all[nr] = Widget_Button(fr0, value = 'Use All', uvalue = uvs)
fr00 = Widget_Base(fr0, /row, /nonexclusive)
for nm = 0, MAX_MED-1 do begin
xim = strtrim(string(nm+1),2)
uvs = 'med.' + strtrim(string(nr),2) + ',' + xim
info.form.med_use_mca[nr,nm] = Widget_Button(fr00, value = xim, uvalue= uvs)
endfor
endfor
endif
;
; set defaults by what is actually in use
ns_x = 0
nm_x = 0
medpr = dgrp.prefix[1]
print, ' prefix = ', medpr
for i = 0, MAX_DET -1 do begin
if ( det.countPV[i] ne '') then begin
; look for 'scaler' if (det.counPV[i]
; print , i , ' -> ', det.desc[i]
if (strpos(det.countPV[i],'scaler') ge 1) then begin
for n = 0, MAX_SCA -1 do begin
if (det.desc[i] eq info.snames[n]) then begin
ns_x = ns_x + 1
Widget_Control, info.sbutton[n] , set_button=1
endif
endfor
endif else if (strpos(det.countPV[i],'mca') ge 1) then begin
for nm = 0, MAX_MED -1 do begin
xdet = medpr + 'mca' + strtrim(string(nm+1),2) + '.R'
for nr = 0, MAX_ROI -1 do begin
d = xdet + strtrim(string(nr),2)
if (det.countPV[i] eq d) then begin
; print, 'det ', d, ' is seen ! '
nm_x = nm_x + 1
Widget_Control, info.form.med_use_mca[nr,nm] , set_button=1
endif
endfor
endfor
endif
; else look for med
endif
endfor
info.sca_inuse = ns_x
info.med_inuse = nm_x
print, ' ', ns_x, nm_x
widget_control, info.form.sca_used, set_value = string(info.sca_inuse)
widget_control, info.form.med_used, set_value = string(info.med_inuse)
; endif else begin
; ; look up proto-typical detector (#7)
; groupx = [groupx, i+1]
; for n = 0, N_ROIS-1 do begin
; x = get_detnam(prefix=pr,type='med:mca',elem=7,roi=n,$
; net=0)
; print, ' MCA: n, ielems, x = ', n, i_elems, x.desc
; endfor
; endelse
; endif
; endfor
; Widget_Control, TMP, /destroy
base2 = Widget_Base(main,/row)
X = Widget_Button(base2, value = 'Save Changes', uval='save')
X = Widget_Button(base2, value = 'Cancel', uval='cancel')
X = Widget_Button(base2, value = 'Done', uval='exit')
M_COLS = 4
M_ROWS = (MAX_DET/M_COLS) + 1
net_choices = ['Sum' , 'Net']
i = -1
Grid = Widget_Base(main, /ROW)
tcol = lonarr(M_COLS+1)
form_end:
Widget_Control, mine, /update
p_info = ptr_new(info,/NO_COPY)
Widget_Control, mine, set_uvalue=p_info
Widget_Control, mine, /REALIZE
xmanager, 'define_meta_detectors', mine, /NO_BLOCK
return, 0
end
escan/define_raw_detectors.pro 0100644 0000621 0000620 00000022053 07312216160 016030 0 ustar epics epics pro define_raw_detectors_event, event
Widget_Control, event.top, get_uvalue = p
Widget_Control, event.id, get_uvalue = uval
if (uval eq 'cancel') then begin
x = (*p).es->set_param('detectors',(*p).det_save)
endif
if ((uval eq 'save') or (uval eq 'exit')) then begin
; print, ' info.group = ', (*p).group
dgrp = (*p).es->get_param('detgroups')
;print, ' Saving Detectors '
M_DET = n_elements( (*p).det.countPV )
for i = 0, M_DET - 1 do begin
j = Widget_Info( (*p).form.det_elem[i], /droplist_select)
net = Widget_Info( (*p).form.use_net[i], /droplist_select)
if (j gt 0) then begin
k = Widget_Info( (*p).form.det_desc[i], /droplist_select)
(*p).det.countPV[i] = ''
igr = (*p).group[j] - 1
pr = dgrp.prefix[igr]
if (igr eq 0) then begin
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=k,net=net)
(*p).det.countPV[i] = x.countPV
(*p).det.desc[i] = x.full_desc
endif else if (igr eq 1) then begin
x = get_detnam(prefix=pr,type='med:mca',elem=j-1,roi=k,net=net)
(*p).det.countPV[i] = x.countPV
(*p).det.desc[i] = x.full_desc
endif
endif else begin
(*p).det.countPV[i] = ''
endelse
; print, i, ' PV = ', (*p).det.countPV[i]
endfor
x = (*p).es->set_param('detectors',(*p).det)
endif
iu = strpos(uval,'_')
if ((uval eq 'cancel') or (uval eq 'exit')) then begin
caSetTimeout, (*p).timeout
caSetRetryCount, (*p).retry
Widget_Control, event.top, /DESTROY
endif else if (uval ne 'save') then begin
thing = strmid(uval,0,iu)
_elem_ = fix(strmid(uval,iu+1,strlen(uval)))-1
;; print, ' uval = ', thing, _elem_, event.index
if (thing eq 'elem') then begin
; print, ' event_index = ', event.index
Widget_Control, (*p).form.det_desc[_elem_], $
set_value = (*p).elem_list[event.index,*]
Widget_Control, (*p).form.det_desc[_elem_], set_droplist_select = 0
; if (_elem_ eq 1) then $
; Widget_Control, (*p).form.use_net[_elem_], set_droplist_select = 1
endif
endif
return
end
function define_raw_detectors, p
;
; primitive gui for selecting detectors:
;
N_MCAS = 30
N_ROIS = 10
ret = (*p).es->lookup_detectors()
det = (*p).es->get_param('detectors')
det_save = det
MAX_DET = n_elements( det.countPV)
;
mine = Widget_Base(TITLE = 'Define Detectors', /COLUMN, APP_MBAR = menubar)
fileMenu = Widget_Button(menubar, value = 'File')
saveMB = Widget_Button(fileMenu, value = 'Save', uvalue = 'save' )
exitMB = Widget_Button(fileMenu, value = 'Exit', uvalue = 'exit', /sep)
mainFRAME = Widget_Base(mine, /COLUMN)
TMP = Widget_Base(mainFRAME, /ROW)
tx1 = Widget_Label(TMP, value = ' Looking up available detectors ... ')
Widget_Control, mine, /REALIZE
; gather all valid detector names (why not??)
;
dgrp = (*p).es->get_param('detgroups')
scanPV = (*p).es->get_scan_param(0,scanPV)
prefix = (*p).es->get_param('prefix')
;
MAX_DTY = n_elements(dgrp.name)
elem_list = strarr(N_MCAS, N_ROIS)
group = intarr(N_MCAS + N_ROIS)
elemx = strarr(N_MCAS + N_ROIS )
elems = ['None' ]
groupx = [0]
form = {det_choice:0, det_elem:lonarr(MAX_DET), $
det_desc:lonarr(MAX_DET) , use_net: lonarr(MAX_DET) }
info = {es:(*p).es, form:form, det_save:det_save, $
det:det, elems:elemx, elem_list: elem_list, group:group, $
timeout:0.001, retry:50 }
info.timeout = caGetTimeout()
info.retry = caGetRetryCount()
t0 = (info.timeout/ 10.) > 0.001
caSetTimeout, t0
caSetRetryCount, 25
print, ' ----------- DEFINE DETECTORS ----------------', info.timeout
i_elems = 0
for i = 0,MAX_DTY-1 do begin
pr = dgrp.prefix[i]
if (dgrp.use_det[i] eq 1) then begin
; print, ' using ' , dgrp.name[i], ' is mca? = ', $
; dgrp.is_mca[i], ' # elems = ',dgrp.max_elems[i] , pr
if (dgrp.is_mca[i] eq 0) then begin
groupx = [groupx, i+1]
elems = [elems, dgrp.name[i]]
i_elems = i_elems + 1
for n = 0, dgrp.max_elems[i]-1 do begin
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=n,net=0)
;print, ' n, ielems, x = ', n, i_elems, x.desc
elem_list[i_elems,n] = x.desc
endfor
endif else begin
for j = 0, dgrp.max_elems[i] - 1 do begin
groupx = [groupx, i+1]
elems = [elems, dgrp.name[i]+' MCA' + strtrim(string(j+1),2)]
i_elems = i_elems + 1
for n = 0, N_ROIS-1 do begin
x = get_detnam(prefix=pr,type='med:mca',elem=j,roi=n,$
net=0)
elem_list[i_elems,n] = x.desc
;print, ' n, ielems, x = ', n, i_elems, x.desc
endfor
endfor
endelse
endif
endfor
; info.group = group
info.group = groupx
info.elems = elems
info.elem_list = elem_list
Widget_Control, TMP, /destroy
base2 = Widget_Base(mainFrame,/row)
X = Widget_Button(base2, value = 'Save Changes', uval='save')
X = Widget_Button(base2, value = 'Cancel', uval='cancel')
X = Widget_Button(base2, value = 'Done', uval='exit')
M_COLS = 4
M_ROWS = (MAX_DET/M_COLS) + 1
net_choices = ['Sum' , 'Net']
i = -1
Grid = Widget_Base(mainFRAME, /ROW)
Widget_Control, Grid, update = 0
tcol = lonarr(M_COLS+1)
for icol = 1, M_COLS do begin
tcol[icol] = Widget_Base(Grid, /col)
tc = Widget_Base(tcol[icol], /row)
X = Widget_Label(TC, XSIZE=80, value = ' Detector ')
X = Widget_Label(TC, XSIZE=80, value = ' Sum / Net')
X = Widget_Label(TC, XSIZE=80, value = ' Element ')
X = Widget_Label(TC, XSIZE=80, value = ' Selection ')
for irow = 0, M_ROWS-1 do begin
i = i + 1
if (i ge MAX_DET) then goto, form_end
index = strtrim(string(i+1,format='(i2.2)'),2)
T = Widget_Base(tcol[icol], /row)
uvalu = 'elem_' + index
T1 = Widget_Label(T, XSIZE=40, value = index )
uvalu = 'net_' + index
info.form.use_net[i] = Widget_DROPLIST(T, value = net_choices, $
uvalue = uvalu, /dynamic_resize)
uvalu = 'elem_' + index
info.form.det_elem[i] = Widget_DROPLIST(T, value = elems, uvalue = uvalu, /dynamic_resize)
Widget_Control, info.form.det_elem[i], set_droplist_SELECT = 0
uvalu = 'desc_' + index
info.form.det_desc[i] = Widget_DROPLIST(T, value = elem_list[1,*], uvalue = uvalu, /dynamic_resize)
elem_choice = 03
ending = ''
; print, ' I = ' , i, uvalu, det.countPV[i]
if (det.countPV[i] ne '') then begin
igr = det.group[i]
gr = dgrp.prefix[igr]
ending = strmid(det.countPV[i], strlen(dgrp.prefix[igr]), strlen(det.countPV[i]))
x = split_det_name(gr, ending, dgrp.is_mca[igr])
print, i, ' ', det.countPV[i], ' | ', gr, ' | ', det.desc[i], ' | ', ending
Widget_Control, info.form.use_net[i], set_droplist_select = det.use_net[i]
roi = ''
if (dgrp.is_mca[igr] eq 1) then begin
i_elem = strmid(ending,3,strpos(ending,'.')-3)
elem = 'MCA ' + strtrim(i_elem,2)
i_elem = fix(i_elem) + 1
roi = strmid(ending, strpos(ending,'.R')+2)
if (strmid(roi,strlen(roi)-1) eq 'N') then roi = strmid(roi,0,strlen(roi)-1)
i_roi = fix(roi)
; print, ' MCA ', i_elem, i_roi, ' from ' , ending
Widget_Control, info.form.det_elem[i], set_droplist_select = i_elem
Widget_Control, info.form.det_desc[i], set_value = elem_list[i_elem,*]
Widget_Control, info.form.det_desc[i], set_droplist_select = i_roi
endif else begin
i_elem = 1
if (strmid(ending,0,5) eq '_calc') then begin
roi = strmid(ending, 5, strpos(ending,'.')-5)
endif else if (strmid(ending,0,2) eq '.S') then begin
roi = strmid(ending,2)
endif
i_roi = fix(roi)-1
Widget_Control, info.form.det_elem[i], set_droplist_select = i_elem
Widget_Control, info.form.det_desc[i], set_value = elem_list[i_elem,*]
Widget_Control, info.form.det_desc[i], set_droplist_select = i_roi
endelse
endif else begin
Widget_Control, info.form.det_elem[i], set_droplist_select = 0
Widget_Control, info.form.det_desc[i], set_value = elem_list[elem_choice,*]
Widget_Control, info.form.det_desc[i], set_value = elem_list[0,*]
endelse
endfor
endfor
form_end:
Widget_Control, Grid, /update
Widget_Control, mine, /update
p_info = ptr_new(info,/NO_COPY)
Widget_Control, mine, set_uvalue=p_info
Widget_Control, mine, /REALIZE
xmanager, 'define_raw_detectors', mine, /NO_BLOCK
return, 0
end
escan/define_scan.pro 0100644 0000621 0000620 00000015030 07335600264 014113 0 ustar epics epics pro define_scan_event, event
@scan_include
Widget_Control, event.id, get_uval = uval
;
dgr = (*p).es->get_param('detgroups')
;
sc1 = (*p).es->get_param('scan1')
uva = strmid(uval, 0, strlen(uval)-1)
dnum = 0
if ((uva eq 'name') or (uva eq 'trig') or (uva eq 'count') or $
(uva eq 'prefix') or (uva eq 'use') or (uva eq 'mca')) then begin
dnum = fix(strmid(uval, strlen(uval)-1, strlen(uval)))
uval = uva
endif
case uval of
'exit': begin
dgr = (*p).es->get_param('detgroups')
Widget_Control, event.top, /DESTROY
end
'save': begin
end
'exit': begin
dgr = (*p).es->get_param('detgroups')
Widget_Control, event.top, /DESTROY
end
'scan_prefix': begin
Widget_Control, (*p).wid.pref, get_value=t
x = (*p).es->set_param('prefix', strtrim(t,2))
end
'pdly': begin
Widget_Control, (*p).wid.pdly, get_value=t
sc1.pdly = double(strtrim(t,2))
end
'ddly': begin
Widget_Control, (*p).wid.ddly, get_value=t
sc1.ddly = double(strtrim(t,2))
end
'mfile': begin
Widget_Control, (*p).wid.mfile, get_value=t
x = (*p).es->set_param('monitorfile', strtrim(t,2) )
end
'sh_pv': begin
Widget_Control, (*p).wid.sh_pv, get_value=t
x = (*p).es->set_param('shutter_pv', strtrim(t,2) )
end
'name': begin
Widget_Control, (*p).wid.dname[dnum], get_value=t
dgr.name[dnum] = strtrim(t,2)
end
'trig': begin
Widget_Control, (*p).wid.dtrig[dnum], get_value=t
dgr.triggerpv[dnum] = strtrim(t,2)
end
'nelems': begin
Widget_Control, (*p).wid.delems[dnum], get_value=t
dgr.max_elems[dnum] = strtrim(t,2)
end
'count': begin
Widget_Control, (*p).wid.dcount[dnum], get_value=t
dgr.counterpv[dnum] = strtrim(t,2)
end
'prefix': begin
Widget_Control, (*p).wid.dpref[dnum], get_value=t
dgr.prefix[dnum] = strtrim(t,2)
end
'mca': begin
dgr.is_mca[dnum] = event.select
end
'use': begin
dgr.use_det[dnum] = event.select
end
endcase
u = (*p).es->set_param('scan1', sc1)
u = (*p).es->set_param('detgroups', dgr)
return
end
function define_scan, p
;
; gui for defining 'other' scan parameters
;
MAX_DET = 10
main = Widget_Base(TITLE = 'Scan Parameters', /COLUMN, APP_MBAR = menubar)
fMenu = Widget_Button(menubar, value = 'File')
exitMB = Widget_Button(fMenu, value = 'Exit', uvalue = 'exit', /sep)
mFRAME = Widget_Base(main, /COLUMN)
sc1 = (*p).es->get_param('scan1')
ddly = sc1.ddly
pdly = sc1.pdly
dgr = (*p).es->get_param('detgroups')
mfile = (*p).es->get_param('monitorfile')
sh_pv = (*p).es->get_param('shutter_pv')
prefix = (*p).es->get_param('prefix')
n_dgr = n_elements(dgr.name)
nzero = lonarr(n_dgr)
wid = {det_choice:0L, pref:0L,mfile:0L, sh_pv:0L, $
det_elem:lonarr(MAX_DET), det_desc:lonarr(MAX_DET), $
ddly:0L, pdly:0L, dtrig:nzero, dname:nzero, delems:nzero, $
dcount:nzero,dpref:nzero,duse:nzero, dmca:nzero }
info = {es:(*p).es, wid:wid}
base = Widget_Base(mFrame, /row)
tt = Widget_Base(base,/row)
info.wid.pref = CW_FIELD(tt, title= 'Scan Prefix:', uvalue = 'scan_prefix',$
value = prefix, xsize=13,$
/return_events)
info.wid.mfile = CW_FIELD(tt, title= 'PV Save List:', $
uvalue = 'mfile',$
value = strtrim(string(mfile),2), xsize=20,$
/return_events)
info.wid.sh_pv = CW_FIELD(tt, title= 'Shutter PV:', $
uvalue = 'sh_pv',$
value = strtrim(string(sh_pv),2), xsize=20,$
/return_events)
base = Widget_Base(mFrame, /row)
tt = Widget_Base(base,/row,/frame)
info.wid.pdly = CW_FIELD(tt, title= 'Positioner Settling Time', uvalue = 'pdly',$
value = strtrim(string(pdly),2), xsize=13,$
/return_events, /floating)
info.wid.ddly = CW_FIELD(tt, title= 'Detector Settling Time', uvalue = 'ddly',$
value = strtrim(string(ddly),2), xsize=13,$
/return_events, /floating)
base = Widget_Base(mFrame, /row)
col = Widget_Base(base,/col,/frame)
tt = Widget_Base(col,/row)
xx = Widget_Label(tt, xsize = 130, value = 'Detector Group')
x = Widget_Label(tt, xsize = 130, value = 'Prefix')
x = Widget_Label(tt, xsize = 130, value = 'Trigger')
x = Widget_Label(tt, xsize = 130, value = 'Counter')
x = Widget_Label(tt, xsize = 80, value = '# Elements')
x = Widget_Label(tt, xsize = 50, value = 'MCA?')
x = Widget_Label(tt, xsize = 50, value = 'Use?')
uva = ['name', 'prefix', 'trig', 'count', 'nelems', 'mca', 'use']
for i = 0, n_elements(dgr.name)-1 do begin
f = Widget_Base(col, /row)
uvs = uva + strtrim(string(i),2)
info.wid.dname[i] = CW_FIELD(f, title= ' ', XSIZE = 18, uvalue = uvs[0], $
value = strtrim(dgr.name[i],2), $
/return_events)
info.wid.dpref[i] = CW_FIELD(f, title= ' ', XSIZE = 18, uvalue = uvs[1], $
value = strtrim(dgr.prefix[i],2), $
/return_events)
info.wid.dtrig[i] = CW_FIELD(f, title= ' ', XSIZE = 12, uvalue = uvs[2], $
value = strtrim(dgr.triggerpv[i],2), $
/return_events)
info.wid.dcount[i] = CW_FIELD(f, title= ' ', XSIZE =12, uvalue = uvs[3], $
value = strtrim(dgr.counterpv[i],2), $
/return_events)
info.wid.delems[i] = CW_FIELD(f, title= ' ', XSIZE =12, uvalue = uvs[4], $
value = strtrim(dgr.max_elems[i],2), $
/return_events)
bbase = Widget_Base(f, /row,/nonexclusive)
info.wid.dmca[i] = Widget_Button(bbase, xsize=60, Value = ' ', uvalue = uvs[5])
info.wid.duse[i] = Widget_Button(bbase, xsize=60, Value = ' ', uvalue = uvs[6])
Widget_Control, info.wid.dmca[i] , SET_BUTTON = dgr.is_mca[i]
Widget_Control, info.wid.duse[i] , SET_BUTTON = dgr.use_det[i]
endfor
base2 = Widget_Base(mFrame,/row)
X = Widget_Button(base2, value = 'Save', uval='save')
X = Widget_Button(base2, value = 'Exit', uval='exit')
p_info = ptr_new(info,/NO_COPY)
Widget_Control, main, set_uvalue=p_info, /REALIZE
xmanager, 'define_scan', main, /NO_BLOCK
return, 0
end
escan/define_scanx.pro 0100644 0000621 0000620 00000015165 07314501700 014304 0 ustar epics epics pro define_scan_event, event
@scan_include
Widget_Control, event.id, get_uval = uval
;
dgr = (*p).es->get_param('detgroups')
;
sc = (*p).es->get_param('scan1')
uva = strmid(uval, 0, strlen(uval)-1)
dnum = 0
if ((uva eq 'name') or (uva eq 'trig') or (uva eq 'count') or $
(uva eq 'prefix') or (uva eq 'use') or (uva eq 'mca')) then begin
dnum = fix(strmid(uval, strlen(uval)-1, strlen(uval)))
uval = uva
endif
case uval of
'exit': begin
dgr = (*p).es->get_param('detgroups')
Widget_Control, event.top, /DESTROY
end
'save': begin
end
'exit': begin
dgr = (*p).es->get_param('detgroups')
Widget_Control, event.top, /DESTROY
end
'scan_prefix': begin
Widget_Control, (*p).wid.pref, get_value=t
x = (*p).es->set_param('prefix', strtrim(t,2))
end
'pdly': begin
Widget_Control, (*p).wid.pdly, get_value=t
sc.pdly = double(strtrim(t,2))
end
'ddly': begin
Widget_Control, (*p).wid.ddly, get_value=t
sc.ddly = double(strtrim(t,2))
end
'mfile': begin
Widget_Control, (*p).wid.mfile, get_value=t
x = (*p).es->set_param('monitorfile', strtrim(t,2) )
end
'sh_pv': begin
Widget_Control, (*p).wid.sh_pv, get_value=t
x = (*p).es->set_param('shutter_pv', strtrim(t,2) )
end
'name': begin
Widget_Control, (*p).wid.dname[dnum], get_value=t
dgr.name[dnum] = strtrim(t,2)
end
'trig': begin
Widget_Control, (*p).wid.dtrig[dnum], get_value=t
dgr.triggerpv[dnum] = strtrim(t,2)
end
'nelems': begin
Widget_Control, (*p).wid.delems[dnum], get_value=t
dgr.max_elems[dnum] = strtrim(t,2)
end
'count': begin
Widget_Control, (*p).wid.dcount[dnum], get_value=t
dgr.counterpv[dnum] = strtrim(t,2)
end
'prefix': begin
Widget_Control, (*p).wid.dpref[dnum], get_value=t
dgr.prefix[dnum] = strtrim(t,2)
end
'mca': begin
dgr.is_mca[dnum] = event.select
end
'use': begin
dgr.use_det[dnum] = event.select
end
endcase
u = (*p).es->set_param(_scan, sc)
u = (*p).es->set_param('detgroups', dgr)
return
end
function define_scan, p
;
; gui for defining 'other' scan parameters
;
MAX_DET = 10
main = Widget_Base(TITLE = 'Scan Parameters', /COLUMN, APP_MBAR = menubar)
fMenu = Widget_Button(menubar, value = 'File')
exitMB = Widget_Button(fMenu, value = 'Exit', uvalue = 'exit', /sep)
mFRAME = Widget_Base(main, /COLUMN)
current_scan = (*p).es->get_param('current_scan')
_scan = 'scan' + string(strtrim(current_scan, 2))
sc = (*p).es->get_param(_scan)
ddly = sc.ddly
pdly = sc.pdly
dgr = (*p).es->get_param('detgroups')
mfile = (*p).es->get_param('monitorfile')
sh_pv = (*p).es->get_param('shutter_pv')
prefix = (*p).es->get_param('prefix')
n_dgr = n_elements(dgr.name)
nzero = lonarr(n_dgr)
wid = {det_choice:0L, pref:0L,mfile:0L, sh_pv:0L, $
det_elem:lonarr(MAX_DET), det_desc:lonarr(MAX_DET), $
ddly:0L, pdly:0L, dtrig:nzero, dname:nzero, delems:nzero, $
dcount:nzero,dpref:nzero,duse:nzero, dmca:nzero }
info = {es:(*p).es, wid:wid}
base = Widget_Base(mFrame, /row)
tt = Widget_Base(base,/row)
info.wid.pref = CW_FIELD(tt, title= 'Scan Prefix:', uvalue = 'scan_prefix',$
value = prefix, xsize=13,$
/return_events)
info.wid.mfile = CW_FIELD(tt, title= 'PV Save List:', $
uvalue = 'mfile',$
value = strtrim(string(mfile),2), xsize=20,$
/return_events)
info.wid.sh_pv = CW_FIELD(tt, title= 'Shutter PV:', $
uvalue = 'sh_pv',$
value = strtrim(string(sh_pv),2), xsize=20,$
/return_events)
base = Widget_Base(mFrame, /row)
tt = Widget_Base(base,/row,/frame)
info.wid.pdly = CW_FIELD(tt, title= 'Positioner Settling Time', uvalue = 'pdly',$
value = strtrim(string(pdly),2), xsize=13,$
/return_events, /floating)
info.wid.ddly = CW_FIELD(tt, title= 'Detector Settling Time', uvalue = 'ddly',$
value = strtrim(string(ddly),2), xsize=13,$
/return_events, /floating)
base = Widget_Base(mFrame, /row)
col = Widget_Base(base,/col,/frame)
tt = Widget_Base(col,/row)
xx = Widget_Label(tt, xsize = 130, value = 'Detector Group')
x = Widget_Label(tt, xsize = 130, value = 'Prefix')
x = Widget_Label(tt, xsize = 130, value = 'Trigger')
x = Widget_Label(tt, xsize = 130, value = 'Counter')
x = Widget_Label(tt, xsize = 80, value = '# Elements')
x = Widget_Label(tt, xsize = 50, value = 'MCA?')
x = Widget_Label(tt, xsize = 50, value = 'Use?')
uva = ['name', 'prefix', 'trig', 'count', 'nelems', 'mca', 'use']
for i = 0, n_elements(dgr.name)-1 do begin
f = Widget_Base(col, /row)
uvs = uva + strtrim(string(i),2)
info.wid.dname[i] = CW_FIELD(f, title= ' ', XSIZE = 18, uvalue = uvs[0], $
value = strtrim(dgr.name[i],2), $
/return_events)
info.wid.dpref[i] = CW_FIELD(f, title= ' ', XSIZE = 18, uvalue = uvs[1], $
value = strtrim(dgr.prefix[i],2), $
/return_events)
info.wid.dtrig[i] = CW_FIELD(f, title= ' ', XSIZE = 12, uvalue = uvs[2], $
value = strtrim(dgr.triggerpv[i],2), $
/return_events)
info.wid.dcount[i] = CW_FIELD(f, title= ' ', XSIZE =12, uvalue = uvs[3], $
value = strtrim(dgr.counterpv[i],2), $
/return_events)
info.wid.delems[i] = CW_FIELD(f, title= ' ', XSIZE =12, uvalue = uvs[4], $
value = strtrim(dgr.max_elems[i],2), $
/return_events)
bbase = Widget_Base(f, /row,/nonexclusive)
info.wid.dmca[i] = Widget_Button(bbase, xsize=60, Value = ' ', uvalue = uvs[5])
info.wid.duse[i] = Widget_Button(bbase, xsize=60, Value = ' ', uvalue = uvs[6])
Widget_Control, info.wid.dmca[i] , SET_BUTTON = dgr.is_mca[i]
Widget_Control, info.wid.duse[i] , SET_BUTTON = dgr.use_det[i]
endfor
base2 = Widget_Base(mFrame,/row)
X = Widget_Button(base2, value = 'Save', uval='save')
X = Widget_Button(base2, value = 'Exit', uval='exit')
p_info = ptr_new(info,/NO_COPY)
Widget_Control, main, set_uvalue=p_info, /REALIZE
xmanager, 'define_scan', main, /NO_BLOCK
return, 0
end
escan/dump_pvs.pro 0100664 0000621 0000620 00000001271 07241032016 013504 0 ustar epics epics pro dump_pvs , input=input, output=output
;
; simple dump of PV list (as in scan_pvs.dat) to a file
;
if (n_elements(output) eq 0) then output = 'pv_values.out'
if (n_elements(input) eq 0) then begin
input = 'scan_pvs.dat'
endif
; on_ioerror, no_file:
; if (keyword_set (use_dialog)) then begin
; file = dialog_pickfile(filter='*.scn', get_path=path, $
; /write, file = init_file)
; endif
; file = strtrim(file,2)
; if (file eq '') then return, -1
e = obj_new('EPICS_SCAN')
x = e->set_param('monitorfile', input)
openw, lun, output, /get_lun
x = e->write_pv_list(lun=lun)
close, lun
free_lun, lun
print, 'wrote PVS to ', output
obj_destroy, e
return
end
escan/epics_scan__define.pro 0100644 0000621 0000620 00000121365 07335065220 015443 0 ustar epics epics ; Mark Rivers, 12/7/00, added PREFIX keyword to INIT
; Mark Rivers, 12/8/00, only read positioner and detector arrays if they are valid,
; and only read "npts" values
function ca_put, pv, val
;
x = 0
x = caput(pv,val)
; print, ' CA_PUT ', pv
return, x
end
function epics_scan::write_pv_list, lun=lun
;
; this reads the list of PVs in self.monitorfile and writes them out.
; if lun is specified, it writes to this unit (assumed opened for write)
; otherwise it writes to standard output
l_out = -999
if (keyword_set(lun) ne 0) then l_out = lun
ret = -1
tab = string(9B)
if (self.paramfile ne ' ') then begin
on_ioerror, badfile
ret = 0
str = ' '
openr, inp, self.monitorfile, /get_lun
while not (eof(inp)) do begin
readf, inp, str
str = strtrim(str,2)
s = strcompress(str)
if (s eq ' ') then goto, loop_end
ismc = strpos(str, ';')
ihash = strpos(str, '#')
if ((ismc lt 0) and (ihash lt 0)) then begin
sx = str_sep(strcompress(str), ' ')
if (n_elements(sx) lt 1) then goto, loop_end
pv = sx[0]
ti = pv
il = strlen(pv)
if (il le 3) then goto, loop_end
if (n_elements(sx) gt 1) then begin
tx = strtrim(strmid(str,strlen(sx[0]),strlen(str)),2)
ti = tx + " ("+ pv+ ')'
endif else if (strupcase(strmid(pv,il-4,4)) eq '.VAL') then begin
dv = strmid(pv,0,il-4) + '.DESC'
stat = caget(dv, tn)
if (stat eq 0) then ti = tn + " ("+ pv+ ')'
endif
stat = caget(pv, val)
if (stat ne 0) then begin
output = '; ' + ti + tab + " not connected "
endif else begin
output = '; ' + ti + tab + " = " + string(val)
endelse
if (l_out ge 0) then begin
printf, l_out, output
endif else begin
print, output
endelse
endif
loop_end:
endwhile
close, inp
free_lun, inp
badfile: ret = -2
endif
return, ret
end
function epics_scan::close_scanfile
close, self.lun
free_lun, self.lun
self.lun = -3
return, 0
end
function epics_scan::open_scanfile, append=append
if (self.datafile eq ' ') then self.datafile = 'scan_001.dat'
app = 1
if (n_elements(append) ne 0) then app = append
openw, lun, self.datafile, /get_lun, append=app
self.lun = lun
return, self.lun
end
function epics_scan::write_scan_data, short_labels=short_labels
;
; this reads the scan1 data from the crate, and writes the results
; out to self.lun (presumably, the already open scanfile)
;
ret = 0
SPV = self.scan[0].scanPV
write_labels = 1
if (n_elements(short_labels) ne 0) then write_labels = short_labels
; print, ' write_scan_data, labels = ' , write_labels
dat = self->read_data_from_crate()
lun = self.lun
mpos = n_elements(dat.p_used)
mdet = n_elements(dat.d_used)
npts = dat.npts
printf, lun, '; scan ended at time: ' , systime(0)
if (write_labels eq 1) then begin
printf, lun, '; n_points = ', npts
printf, lun, '; column labels:'
endif
n = 0
label = '; '
for i = 0,mpos-1 do begin
if (dat.p_used(i) eq 1) then begin
n = n + 1
sn = strtrim(string(n,format='(i1.1)'),2)
if (write_labels eq 1) then begin
com = '; P' + sn + ' = {'
desc = self.scan[0].pos_names[i]
printf, lun, com, desc , '} --> ', self.scan[0].posPVs[i]
endif
label = label + ' P' + sn
endif
endfor
n = 0
for i = 0, mdet-1 do begin
if (dat.d_used(i) eq 1) then begin
n = n + 1
sn = strtrim(string(n),2)
if (write_labels eq 1) then begin
com = '; D' + sn + ' = {'
desc = self.detectors.desc[i]
printf, lun, com, desc , '} --> ', self.detectors.countPV[i]
endif
label = label + ' D' + sn
endif
endfor
if (write_labels eq 1) then begin
printf, lun, ';--------------------------------------------'
printf, lun, label
endif else begin
printf, lun, ';----------------'
printf, lun, '; '
endelse
for i = 0, npts-1 do begin
printf, lun, format='(1x,g14.7,$)', dat.pa[ 0,i]
for j = 1, mpos -1 do begin
if (dat.p_used(j) eq 1) then printf, lun, format='(1x,g14.7,$)', dat.pa[ j,i]
endfor
for j = 0, mdet-1 do begin
if (dat.d_used(j) eq 1) then printf, lun, format='(1x,g14.7,$)', dat.da[ j,i]
endfor
printf, lun, ' '
endfor
; flush file buffer for sure
flush, lun
return, ret
end
function epics_scan::start_scan1d, no_file=no_file, no_pv_list=no_pv_list,$
user_titles=user_titles, no_header=no_header
; begin scan1d (this __only__ does a 1d scan!!)
stime = systime(0)
;
;
; check shutter status: if closed, then do NOT scan
; and return -1
; print, ' In start_scan1d'
result = caget(self.shutter_pv, shutter)
;
; if ((shutter ne 1) or (result ne 0)) then return, -1
;
; print, ' starting ', self.scan[0].scanPV
result = ca_put(self.scan[0].scanPV + '.EXSC', 1)
if (self.lun lt -2) then begin
x = self->open_scanfile(/append)
endif
lun = self.lun
if (result ne 0) then return, result
write_file = 1
if (keyword_set(no_file)) then write_file = 0
write_pvlist = 1
if (keyword_set(no_pv_list)) then write_pvlist= 0
write_header = 1
if (keyword_set(no_header)) then write_header= 0
if (write_file) then begin
if (write_header eq 1) then begin
printf, lun, '; current scan = ', f2a(self.current_scan)
printf, lun, '; scan dimension= ', f2a(self.dimension)
printf, lun, '; scan prefix = ', self.prefix
if (keyword_set(user_titles)) then begin
printf, lun, '; User titles:'
for i = 0, n_elements(user_titles) - 1 do begin
s = strcompress(strtrim(user_titles[i],2))
if (s ne ' ') then printf, lun, '; ' + user_titles[i]
endfor
endif
if (write_pvlist) then begin
printf, lun, '; PV list:'
x = self->write_pv_list(lun=lun)
endif
printf, lun, '; scan began at time: ', stime
printf, lun, ';====================================================='
endif
self.lun = lun
endif
; print, ' start_scan1d result = ', result, lun
flush, lun
return, result
end
function epics_scan::check_scan_limits
; check scan limits
y = self.scan[self.current_scan-1].scanPV
print, 'checking scan limits for scan ',y
x1 = ca_put(y + '.CMND', 1)
wait, 0.25
x = caget(y + '.ALRT', ret)
if (x ne 0) then begin
wait, 0.5
x = caget(y + '.ALRT', ret)
if (x ne 0) then ret = x
endif
return, ret
end
function epics_scan::get_npts
; get total number of points in scan
n = 1
for is = 0, self.dimension-1 do n = n * self.scan[is].npts_total
return, n
end
function epics_scan::generate_scan_table, iscan, arr
n = 0
; print, ' < Generating Scan Table ', iscan
sc = self.scan[iscan]
nregs = sc.n_regions
is_rel = sc.is_rel
time_est = 0.0000
delays = sc.ddly + sc.pdly
ETOK = 0.2624682917
ref = 0
e0 = sc.params[0]
if (sc.is_rel eq 1) then begin
ref = sc.params[0]
if (strupcase(sc.type) eq 'MOTOR') then begin
mot = self->get_motor(sc.drives[0])
ref = mot.curpos
endif
endif
;
; print, ' gen_scan: is_rel, ref = ', sc.is_rel, ref, sc.type
; positioner #1 is the primary drive
arr = fltarr(4,self.max_scan_points)
ip = -1
for j = 0, nregs-1 do begin
; print, ' reg ', j, ' of ', nregs
; print, 'start/stop/step/npts/time '
; print, sc.start[j], sc.stop[j], sc.step[j], sc.npts[j], sc.time[j]
for i = 0, sc.npts[j]-1 do begin
ip = ip + 1
arr[0,ip] = ref + sc.start[j] + sc.step[j]*i
if (sc.is_kspace[j] eq 1) then begin
; note that the k-space values are _always_ relative,
; so need to use e0, not ref. tricky, huh?
arr[0,ip] = e0 + (sc.start[j] + sc.step[j]*i)^2 / ETOK
endif
arr[1,ip] = sc.time[j]
time_est = time_est + sc.time[j] + delays
endfor
; fix scan region boundaries from repeating points:
; remove the last point of the earlier region
if (ip ge 0) and (j lt nregs-1) then begin
ip = ip - 1
time_est = time_est - ( sc.time[j] + delays )
endif
endfor
n = ip + 1
; print, ' Npts = ' , n, ' time = ', time_est, ' s'
; for i = 0, n-1 do begin
; print, ' > ', i, arr[0,i], ' : ', arr[1,i]
; endfor
self.scan[iscan].time_est = time_est
return, n
end
function epics_scan::read_data_from_crate
;
; upload 1d scan results from crate
; returns structure with members
; npts number of points collected
; p_used integer array for positioners used
; d_used integer array for detectors used
; npos number of positions used
; pa (npts,npos)
; da (npts,ndet)
; pauses scan while reading!
SPV = self.scan[0].scanPV
; Pause Scan for read
x = caget(self.prefix + 'scanPause.VAL', pause_val)
x = ca_put(self.prefix + 'scanPause.VAL', 1)
;
M_DET = n_elements(self.detectors.countPV)
M_POS = n_elements(self.scan[0].drives)
p_used = intarr(M_POS)
d_used = intarr(M_DET)
s = caget(SPV+'.NPTS', npts)
; print, ' scan: npts = ', npts
ret = {npts:0, p_used:p_used, d_used:d_used, $
pa:fltarr(M_POS,npts), da:fltarr(M_DET,npts)}
;
; gather scan data
for i = 0, M_POS-1 do begin
d = string(i+1,format='(i1.1)')
s = caget(SPV + '.P' + d + 'NV', ix)
if (ix eq 0) then begin
ret.p_used(i) = 1
s = caget(SPV + '.P' + d + 'RA', p, max=npts)
for j=0, npts-1 do ret.pa[i, j] = p[j]
endif
endfor
for i = 0, M_DET-1 do begin
; d = string(i+1,format='(i1.1)')
; if (i ge 9) then d = string(byte(i + 56))
; Matt 26-Sept-2000 switch to 70 detector scan record
d = string(i+1,format='(i2.2)')
s = caget(SPV + '.D' + d + 'NV', ix)
if (ix eq 0) then begin
ret.d_used(i) = 1
x = caget( SPV + '.D' + d + 'DA', p, max=npts)
for j=0, npts-1 do ret.da[i, j] = p[j]
endif
endfor
ret.npts = npts
; Un-Pause Scan before return
x = ca_put(self.prefix + 'scanPause.VAL', pause_val)
return, ret
end
function epics_scan::load_to_crate
;
; load a motor scan record to the crate
;
; print, 'LOAD: current_scan ', self.current_scan, ' dim: ', self.dimension
time_est = 0.000
for is = 0, self.dimension-1 do begin
;print, ' >> scan ', is, ' << '
imot = self.scan[is].drives[0]
SPV = self.scan[is].scanPV
type = self.scan[is].type
if (strupcase(self.scan[is].type) eq 'EXAFS') then imot = self.motors.e_drive
x = ca_put( SPV + '.PASM', self.scan[is].pasm) ; 'Prior Pos' after scan
; [stay, start, prior, peak, valley, +edge, -edge]
; print, ' delays= ', self.scan[is].pdly, self.scan[is].ddly
x = ca_put( SPV + '.PDLY', self.scan[is].pdly)
x = ca_put( SPV + '.DDLY', self.scan[is].ddly)
x = ca_put( SPV + '.P1AR', 0) ; always use 'Absolute mode'
x = ca_put( SPV + '.P1SM', 1) ; always use table mode
nx = self->generate_scan_table(is, pos)
self.scan[is].npts_total = nx
; help, pos
; print, " nx = ", nx, ' table 0, table 1'
; print, pos[0:1,0:nx-1]
; print, " scan ", is+1, ' npts = ', nx, ' estimated time = ', self.scan[is].time_est
;print, self.motors.pv[imot], " > ", self.motors.rbv[imot]
x = ca_put( SPV + '.P1PV', self.motors.pv[imot]) ;
x = ca_put( SPV + '.R1PV', self.motors.rbv[imot]) ;
x = ca_put( SPV + '.P1PA', pos[0,0:nx-1]) ;
x = ca_put( SPV + '.NPTS', nx) ;
self.scan[is].pos_names[0] = self.motors.name[imot]
;
; for scan1 (is = 0):
; setup the detector triggers, pos2 and pos3 arrays for count times
;
if (is eq 0) then begin
;
; detector triggers:
;
itrig = 0
scaler_set = 0
med_set = 0
x = ca_put(SPV + '.T1PV', '')
x = ca_put(SPV + '.T2PV', '')
self.scan[is].pos_names[1] = ''
self.scan[is].pos_names[2] = ''
self.scan[is].pos_names[3] = ''
for i = 0, n_elements(self.detgroups.name) - 1 do begin
prex = self.detgroups.prefix[i]
usex = self.detgroups.use_det[i]
coux = prex + self.detgroups.counterpv[i]
rbvx = coux
trix = prex + self.detgroups.triggerpv[i]
; print, ' detector: ', i, ' ', prex, usex, trix
if (usex eq 1) then begin
itrig = itrig + 1
st_t = string(itrig,format='(i1.1)')
; print, ' TRIGGER ', itrig, trix
SPV_t = SPV + '.T' + st_t + 'PV'
x = ca_put(SPV_t, trix)
if ((scaler_set eq 0) and (strpos(trix,'scaler') ne -1)) then begin
;print , ' SCALER '
rbvx = strmid(coux,0, strlen(coux)-1)
x = ca_put( prex + '.CONT', 0) ; put scaler in one-shot mode
x = ca_put( SPV + '.P2PV', coux)
x = ca_put( SPV + '.R2PV', rbvx)
x = ca_put( SPV + '.P2PA', pos[1,0:nx-1])
x = ca_put( SPV + '.P2AR', 0) ; always use 'Absolute mode'
x = ca_put( SPV + '.P2SM', 1) ; always use table mode
scaler_set = 1
self.scan[is].pos_names[1] = 'Scaler Count Time'
endif else if ((med_set eq 0) and (strpos(trix,'med') ne -1)) then begin
;print , ' MED '
x = ca_put( prex + 'ReadSeq.SCAN', 0) ; set med to 'passive read rate'
x = ca_put( prex + 'StatusSeq.SCAN', 8) ; set med status rate to 0.2s
x = ca_put( prex + 'PresetReal', count_time) ; set med count time
x = ca_put( SPV + '.P3PV', coux)
x = ca_put( SPV + '.R3PV', rbvx)
x = ca_put( SPV + '.P3PA', pos[1,0:nx-1])
x = ca_put( SPV + '.P3AR', 0) ; always use 'Absolute mode'
x = ca_put( SPV + '.P3SM', 1) ; always use table mode
self.scan[is].pos_names[2] = 'MCA Count Time'
med_set = 1
endif
endif
endfor
endif else begin
x = ca_put( SPV + '.T1PV', self.scan[is-1].scanPV + '.EXSC')
endelse
endfor
result = self->check_scan_limits()
message = ' Ready to scan '
if (result ne 0) then begin
message = ' Problem with Scan Definition: Check Limits '
print , ' SPV = ', SPV
print , ' is = ', is
print , ' scan 2 = ', self.scan[1].scanPV
print , ' scan 1 = ', self.scan[0].scanPV
endif
print, format='(1x,a,$)', message
return, result
end
function epics_scan::save_paramfile, use_dialog=use_dialog
init_file = self.paramfile
file = init_file
; empirically determine ranges of data structures
MAX_DET = n_elements(self.detectors.countPV)
MAX_MOT = n_elements(self.motors.pv)
xs = size(self.scan[0].start)
MAX_REG = xs[1]
MAX_POS = xs[2]
MAX_PAR = n_elements(self.scan[0].params)
frm_s0 = '(a,' +strtrim(string(MAX_REG),2) + 'f10.3)'
frm_s1 = '(a,' +strtrim(string(MAX_REG),2) + 'g13.7)'
frm_s2 = '(a,' +strtrim(string(MAX_PAR),2) + 'g13.7)'
if (keyword_set (use_dialog)) then begin
file = dialog_pickfile(filter='*.scn', get_path=path, $
/write, file = init_file)
endif
file = strtrim(file,2)
if (file eq '') then return, -1
self.paramfile = file
openw, lun, file, /get_lun
printf, lun, ';Scan Parameters% v1.1'
printf, lun, ' prefix% ', self.prefix
printf, lun, ' shutter_pv% ', self.shutter_pv
printf, lun, ' shutter_open% ', self.shutter_open
printf, lun, ' shutter_clos% ', self.shutter_clos
printf, lun, ' datafile% ', self.datafile
printf, lun, ' monitorfile% ', self.monitorfile
printf, lun, ' dimension% ', self.dimension
printf, lun, ' current_scan% ', self.current_scan
for iscan = 0, 2 do begin
scanname = 'scan ' + string(iscan+1, format='(i1.1)')
printf, lun, format='(";",a," %")', scanname
printf, lun, format='(" scanPV% ",a)', self.scan[iscan].scanPV
printf, lun, ' type% ', self.scan[iscan].type
printf, lun, ' drives% ', string(self.scan[iscan].drives) + ' '
printf, lun, ' n_regions%', self.scan[iscan].n_regions
printf, lun, ' is_rel% ', self.scan[iscan].is_rel
printf, lun, ' delays% ', self.scan[iscan].pdly, self.scan[iscan].ddly
printf, lun, format=frm_s0, " is_kspace%" , self.scan[iscan].is_kspace
printf, lun, format=frm_s2, " params% ", self.scan[iscan].params
printf, lun, format=frm_s0, " time% ", self.scan[iscan].time
printf, lun, format=frm_s0, " npts% ", self.scan[iscan].npts
for i = 0, MAX_POS-1 do begin
printf, lun, ' pos% ', string(i, format='(i1.1)'), ' '
printf, lun, format=frm_s1, " start% ", self.scan[iscan].start(*,i)
printf, lun, format=frm_s1, " stop% ", self.scan[iscan].stop(*,i)
printf, lun, format=frm_s1, " step% ", self.scan[iscan].step(*,i)
endfor
endfor
; write Motor PVs and Names (but not anything else from motor struct!)
printf, lun, ';motors% ', MAX_MOT
for i = 1, MAX_MOT-1 do begin
if (self.motors.name[i] ne '') then begin
printf, lun, ' ', self.motors.pv[i], ' | ', $
self.motors.name[i]
endif
endfor
; write detector groups
printf, lun, ';detgroups%' , (n_elements(self.detgroups.name))
for i = 0, n_elements(self.detgroups.name)-1 do begin
if (self.detgroups.name[i] ne '') then begin
s = self.detgroups.name[i] + ' | ' $
+ self.detgroups.prefix[i] + ' | ' $
+ self.detgroups.triggerpv[i] + ' | ' $
+ self.detgroups.counterpv[i] + ' | ' $
+ f2a(self.detgroups.max_elems[i]) + ' | ' $
+ f2a(self.detgroups.is_mca[i]) + ' | ' $
+ f2a(self.detgroups.use_det[i] )
printf, lun, ' ', s
endif
endfor
; write detector Count and Name PVs
printf, lun, ';detectors%' , (MAX_DET< self.detectors.ndetectors)
for i = 0, MAX_DET-1 do begin
if (self.detectors.countPV[i] ne '') then begin
printf, lun, ' ', self.detectors.countPV[i]
endif
endfor
close, lun
free_lun, lun
print, ' wrote file = ', file
return, 0
end
function epics_scan::read_paramfile, use_dialog=use_dialog, file=file
;
; read scan file to (re)initialize epics_scan object
; returns 0 for apparent succees, <0 for bad or unfound files
;
s_file = self.paramfile
if (keyword_set(file) ne 0) then s_file = file
if (keyword_set (use_dialog)) then begin
s_file = dialog_pickfile(filter='*.scn', get_path=path, $
/must_exist, /read, file = s_file)
endif
retval = -3
s_file = strtrim(s_file,2)
if (s_file eq '') then return, -2
self.paramfile = s_file
on_ioerror, bad_file
openr, lun, s_file, /get_lun
retval = 0
read_det= 0
nline = 0
ipos = 0
str = ' '
mode = 'null'
n_det = -1
n_dgrp = -1
n_mot = 0
for i = 0, n_elements(self.motors.name)-1 do begin
self.motors.pv[i] = ''
self.motors.name[i] = ''
endfor
self.motors.name[0] = 'None'
;
line1 = 1
while not (eof(lun)) do begin
readf, lun, str
str = strtrim(str,2)
if ((str eq '') or (strmid(str, 0, 1) eq '#')) then goto, loop_end
if (line1 eq 1) then begin
line1 = 0
s = strmid(str, 0, 17)
t = strmid(str, 18, strlen(str))
if (s ne ';Scan Parameters%') then begin
print, ' File ', s_file, ' is not a valid scan file'
retval = -1
goto, ret
endif
version = t
endif
iperc = strpos(str, '%')
ismc = strpos(str, ';')
if ((ismc eq 0) and (iperc ge 0)) then begin
s = strmid(str,ismc+1, iperc-1)
mode = s
iscan= 0
ipos = 0
stmp = strmid(s,0,4)
if (stmp eq 'scan') then begin
stmp = strcompress(s)
sx = str_sep(stmp,' ')
mode = 'scan'
iscan = fix(strtrim(sx[1],2)) - 1
ipos = 0
endif
endif else begin
key = strmid(str,0, iperc)
val = strtrim(strmid(str,iperc+1, strlen(str)), 2)
case mode of
'Scan Parameters': begin
case key of
'prefix': self.prefix = val
'datafile': self.datafile = val
'shutter_pv': self.shutter_pv = val
'shutter_clos': self.shutter_clos= val
'shutter_open': self.shutter_open= val
'monitorfile': self.monitorfile = val
'current_scan': self.current_scan= val
'dimension': self.dimension = val
'total_time': self.total_time = val
else: print, ' unknown key for Main: ', key
endcase
end
'scan': begin
case key of
'scanPV': self.scan[iscan].scanPV = val
'type': self.scan[iscan].type = val
'n_regions': self.scan[iscan].n_regions = val
'is_rel': self.scan[iscan].is_rel = val
'pos': ipos = fix(val)
'delays': begin
n = string_array(val,arr)
self.scan[iscan].pdly = arr[0]
self.scan[iscan].ddly = arr[1]
end
'drives': begin
n = string_array(val,arr)
for i = 0, n-1 do $
self.scan[iscan].drives[i] = arr[i]
end
'params': begin
n = string_array(val,arr)
for i = 0, n-1 do $
self.scan[iscan].params[i] = arr[i]
end
'is_kspace': begin
n = string_array(val,arr)
for i = 0, n-1 do $
self.scan[iscan].is_kspace[i] = arr[i]
end
'time': begin
n = string_array(val,arr)
for i = 0, n-1 do $
self.scan[iscan].time[i] = arr[i]
end
'npts': begin
n = string_array(val,arr)
for i = 0, n-1 do $
self.scan[iscan].npts[i] = arr[i]
end
'start': begin
n = string_array(val,arr)
for i = 0, n-1 do $
self.scan[iscan].start[i,ipos] = arr[i]
end
'stop': begin
n = string_array(val,arr)
for i = 0, n-1 do $
self.scan[iscan].stop[i,ipos] = arr[i]
end
'step': begin
n = string_array(val,arr)
for i = 0, n-1 do $
self.scan[iscan].step[i,ipos] = arr[i]
end
else: print, ' unknown key for scan: ', key
endcase
end
'detgroups': begin
n_dgrp = n_dgrp + 1
stmp = strcompress(val)
sx = str_sep(stmp,'|')
self.detgroups.name[n_dgrp] = strtrim(sx[0],2)
self.detgroups.prefix[n_dgrp] = strtrim(sx[1],2)
self.detgroups.triggerpv[n_dgrp] = strtrim(sx[2],2)
self.detgroups.counterpv[n_dgrp] = strtrim(sx[3],2)
self.detgroups.max_elems[n_dgrp] = strtrim(sx[4],2)
self.detgroups.is_mca[n_dgrp] = a2f(sx[5])
self.detgroups.use_det[n_dgrp] = a2f(sx[6])
end
'detectors': begin
read_det = 1
n_det = n_det + 1
self.detectors.countPV[n_det] = val
end
'motors': begin
n_mot = n_mot + 1
stmp = strcompress(val)
sx = str_sep(stmp,'|')
self.motors.pv[n_mot] = strtrim(sx[0],2)
if (n_elements(sx) ge 2) then begin
self.motors.name[n_mot] = strtrim(sx[1],2)
endif else begin
il = strlen(self.motors.pv[n_mot])
dv = strmid(self.motors.pv[n_mot],0,il-4) + '.DESC'
stat = caget(dv, tn)
if (stat eq 0) then self.motors.name[n_mot] = tn
endelse
end
else: begin
print, ' unknown mode ', mode
end
endcase
endelse
loop_end:
endwhile
ret:
if (read_det eq 1) then x = self->set_param('detectors',self.detectors)
close, lun
free_lun, lun
return, retval
bad_file:
print, ' '
print, ' Warning: scan parameter file ', s_file, ' could not be loaded.'
return, retval
end
function epics_scan::lookup_detectors
;
; get detector settings from currently defined scan
; used for initializing detector structure
;
scan_pv = self.scan[0].scanPV
ndet = 0
; print, ' IN look up detectors: ', n_elements(self.detectors.countPV)
for i = 0, n_elements(self.detectors.countPV)-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
; Matt 26-Sept-2000 switch to 70 detector scan record
det = string(i+1,format='(i2.2)')
x = caget(scan_pv + '.D' + det + 'PV', str)
if ((x eq 0) and (str ne '')) then begin
ndet = ndet + 1
; print, 'str =', str
kk = self->fill_in_detector_settings(i,str)
endif
endfor
self.detectors.ndetectors = ndet
return, ndet
end
function epics_scan::fill_in_detector_settings, ndet, str
;
str = strtrim(str,2)
if (str eq '') then return, -1
i = ndet
self.detectors.countPV[i] = str
; decide which detector group this belongs to
igroup = 0
dgrp = self.detgroups
ending = ''
for ig = 0, n_elements(dgrp.prefix)-1 do begin
if (dgrp.use_det[ig] eq 1) then begin
l = strlen(dgrp.prefix[ig])
if (strmid(str,0,l) eq dgrp.prefix[ig]) then begin
igroup = ig
ending = strmid(str,l,strlen(str))
endif
endif
endfor
is_mca = dgrp.is_mca[igroup]
gr = strtrim(dgrp.prefix[igroup],2)
lgr = strlen(gr)
en = strtrim(ending,2)
len = strlen(en)
dv = gr + en
elem = 'None'
use_net = 0
if (gr ne '') and (en eq '') then begin
elem = 'OK'
if (strupcase(strmid(gr,lgr-4,4)) eq '.VAL') then begin
dv = strmid(gr,0,lgr-4) + '.DESC'
endif
endif else if ( (gr ne '') and (en ne '')) then begin
if (is_mca eq 1) then begin
elem = 'OK'
dv = gr + en + 'NM'
if (strmid(en,len,1) eq 'N') then begin
use_net = 1
dv = gr + en + 'M'
endif
endif else begin
if (strmid(en,0,2) eq '.S') then begin
elem = strmid(en,2,len)
dv = gr + '.NM' + elem
endif else if (strmid(en,0,5) eq '_calc') then begin
use_net = 1
en = strmid(en,5,len)
len = strlen(en)
elem = strmid(en,0,len)
if (strupcase(strmid(en,len-4,4)) eq '.VAL') then begin
elem = strmid(en,0,len-4)
endif
endif
if (elem ne 'None') then dv = gr + '.NM' + elem
endelse
endif
desc = dv
if (elem ne 'None') then stat = caget(dv, desc)
self.detectors.group[i] = igroup
self.detectors.use_net[i] = use_net
self.detectors.desc[i] = desc
; print, ' Fill in Detector: ', i, ' ' , str, igroup, use_net, ' => ', desc
return,0
end
function epics_scan::lookup_positioners
;
; get positioner PVs
;
scan_pv = self.scan[0].scanPV
for i = 0, n_elements(self.scan[0].drives)-1 do begin
pos = string(i+1,format='(i1.1)')
x = caget(scan_pv + '.P' + pos + 'PV', str)
if ((x eq 0) and (str ne '')) then begin
self.scan[0].posPVs[i] = str
endif
endfor
return, 0
end
function epics_scan::lookup_motors
;
; get motor settings for all defined motors
;
for i = 1, n_elements(self.motors.name)-1 do x = self->lookup_motor(i)
return, 0
end
function epics_scan::lookup_motor, i
;
; get motor settings for a particular motor (by index),
; and put them in the proper motor structure members
; returns:
; 0 complete success
; -1 some caget failed
; -2 null motor specified
; -4 motor index out of range
if ((i le 0) or (i ge n_elements(self.motors.name))) then return, -4
pv = strtrim(self.motors.pv[i],2 )
if (pv eq '' ) then return, -3
il = strlen(pv)
if (strupcase(strmid(pv,il-4,4)) eq '.VAL') then pv = strmid(pv,0,il-4)
;; print, ' lookup_motor ', i, ' = ', pv
;
; pv and rbv's
self.motors.pv[i] = pv + '.VAL'
self.motors.rbv[i] = pv + '.RBV'
; current position
s = caget(pv + '.RBV', x)
if (s ne 0 ) then return, -1
self.motors.curpos[i] = x
; name (if not pre-defined)
if (self.motors.name[i] eq '') then begin
s = caget(pv + '.DESC', x)
if (s ne 0 ) then return, -1
self.motors.name[i] = x
endif
; units
s = caget(pv + '.EGU', x)
if (s ne 0 ) then return, -1
self.motors.units[i] = x
; limits
if (strpos(pv,'Energy') ne -1) then begin
pvx = self.motors.rbv[i]
n = strpos(pvx,'Energy')
self.motors.rbv[i] = self.motors.pv[i]
self.motors.hlim[i] = 35000.00
self.motors.llim[i] = 4000.00
endif else begin
s = caget(pv + '.LLM', x)
if (s ne 0 ) then return, -1
self.motors.llim[i] = x
s = caget(pv + '.HLM', x)
if (s ne 0 ) then return, -1
self.motors.hlim[i] = x
endelse
; done
return,0
end
function epics_scan::get_motor, imotor
;
; returns a simple motor struct for a specified motor
;
mot = {name: ' ', pv: ' ', rbv: ' ', units:' ', $
curpos:0., llim:0., hlim:0.}
;---------
im = 1
if (keyword_set(imotor) ne 0) then im = imotor
mot.name = self.motors.name[im]
mot.pv = self.motors.pv[im]
mot.rbv = self.motors.rbv[im]
mot.units = self.motors.units[im]
mot.curpos= self.motors.curpos[im]
mot.llim = self.motors.llim[im]
mot.hlim = self.motors.hlim[im]
;print, ' { get_motor: ', im
;help, mot, /struct
;print, ' } '
return, mot
end
function epics_scan::get_motor_position, imotor
;
; returns and updates current motor position
im = 1
if (keyword_set(imotor) ne 0) then im = imotor
res = caget(self.motors.rbv[im], xx)
self.motors.curpos[im] = xx
return, xx
end
function epics_scan::set_motor, imotor, mot
;
; sets a motor struct for a specified motor
;
;----
retval = -1
if (keyword_set(imotor) ne 0) then begin
retval = 0
self.motors.name[imotor] = mot.name
self.motors.pv[imotor] = mot.pv
self.motors.rbv[imotor] = mot.rbv
self.motors.units[imotor] = mot.units
self.motors.curpos[imotor] = mot.curpos
self.motors.llim[imotor] = mot.llim
self.motors.hlim[imotor] = mot.hlim
endif
return, retval
end
function epics_scan::get_scan_param, iscan, par
;
; returns a single attribute of a particular scan
;
retval = 0
is = 0
if (keyword_set(iscan) ne 0) then is = iscan
if (keyword_set(par) ne 0) then begin
case par of
'scanPV': retval = self.scan[is].scanPV
'type': retval = self.scan[is].type
'max_points': retval = self.scan[is].max_points
'n_regions': retval = self.scan[is].n_regions
'drives': retval = self.scan[is].drives
'pos_names': retval = self.scan[is].pos_names
'start': retval = self.scan[is].start
'stop': retval = self.scan[is].stop
'step': retval = self.scan[is].step
'npts': retval = self.scan[is].npts
'time': retval = self.scan[is].time
'params': retval = self.scan[is].params
'is_rel': retval = self.scan[is].is_rel
'is_kspace': retval = self.scan[is].is_kspace
endcase
endif
return, retval
end
function epics_scan::get_param, par
;
; return a copy of an object member structure
; for outside manipulation and later 'set_param'ing
val = 0
if (keyword_set(par) ne 0) then begin
case par of
'prefix': val = self.prefix
'lun': val = self.lun
'dimension': val = self.dimension
'total_time': val = self.total_time
'paramfile': val = self.paramfile
'detgroups': val = self.detgroups
'datafile': val = self.datafile
'shutter_pv': val = self.shutter_pv
'shutter_clos': val = self.shutter_clos
'shutter_open': val = self.shutter_open
'monitorfile': val = self.monitorfile
'detectors': val = self.detectors
'current_scan': val = self.current_scan
'motors': val = self.motors
'scan1': val = self.scan[0]
'scan2': val = self.scan[1]
'scan3': val = self.scan[2]
'npts_total': val = self->get_npts()
'med_obj': val = self.med_obj
endcase
endif
return, val
end
function epics_scan::set_param, par, val
retval = 0
if (keyword_set(par) ne 0) then begin
retval = 1
case par of
'prefix': self.prefix = val
'lun': self.lun = val
'dimension': self.dimension = val
'total_time': self.total_time = val
'paramfile': self.paramfile = val
'datafile': self.datafile = val
'monitorfile': self.monitorfile = val
'shutter_pv': self.shutter_pv = val
'shutter_clos': self.shutter_clos = val
'shutter_open': self.shutter_open = val
'detgroups': self.detgroups = val
'current_scan': self.current_scan = val
'motors': self.motors = val
'scan1': self.scan[0] = val
'scan2': self.scan[1] = val
'scan3': self.scan[2] = val
'detectors': begin
self.detectors = val
SPV = self.scan[0].scanPV
for i = 0, n_elements(self.detectors.countPV) - 1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
; Matt 26-Sept-2000 switch to 70 detector scan record
det = string(i+1,format='(i2.2)')
x = ca_put( SPV + '.D' + det + 'PV', self.detectors.countPV[i])
; print, ' det ', det , ' --> ', self.detectors.countPV[i]
endfor
end
else: retval = 0
endcase
endif
return, retval
end
function epics_scan::init, prefix=prefix, scan_file=scan_file, use_dialog=use_dialog
;
@scan_dims
;
caSetTimeout, 0.005
caSetRetryCount, 200
if (n_elements(prefix) eq 0) then prefix='13IDC:'
self.prefix = prefix
self.paramfile = 'default.scn'
self.datafile = 'scan_001.dat'
self.monitorfile = 'scan_pvs.dat'
self.shutter_pv = '13IDA:eps_mbbi4'
self.shutter_clos = '13IDA:eps_bo4'
self.shutter_open = '13IDA:eps_bo3'
self.user_comments = ''
self.current_scan = 1
self.dimension = 1
self.max_scan_points = MAX_SCAN_POINTS
self.detgroups.name[0] = 'Scaler'
self.detgroups.use_det[0] = 1
self.detgroups.prefix[0] = '13IDC:scaler1.'
self.detgroups.max_elems[0] = 8
self.detgroups.is_mca[0] = 0
self.detgroups.triggerpv[0] = 'CNT'
self.detgroups.counterpv[0] = 'TP'
self.detgroups.name[1] = 'Ge16 med'
self.detgroups.use_det[1] = 0
self.detgroups.prefix[1] = '13GE1:med:'
self.detgroups.max_elems[1] = 16
self.detgroups.is_mca[1] = 1
self.detgroups.triggerpv[1] = 'EraseStart'
self.detgroups.counterpv[1] = 'PresetReal'
self.scan[0].scanPV = self.prefix + 'scan1'
self.scan[1].scanPV = self.prefix + 'scan2'
self.scan[2].scanPV = self.prefix + 'scan3'
for i = 0, 2 do begin
self.scan[i].type = 'motor'
self.scan[i].is_rel = 1
self.scan[i].start[0] = 0.
self.scan[i].stop[0] = 1.
self.scan[i].n_regions = 1
self.scan[i].time[0] = 1
self.scan[i].pasm = 2
self.scan[i].pdly = 0.50
self.scan[i].ddly = 0.25
self.scan[i].params[0] = 8980.
endfor
if (keyword_set(scan_file) ne 0) then begin
print, ' Reading scan parameters from ', scan_file
u = self->read_paramfile(file=scan_file,use_dialog=0)
if (u lt 0) then begin
self.paramfile = ' '
u = self->read_paramfile(use_dialog=1)
endif
print, format='(1x,a,$)', ' Getting current motor settings ... '
u = self->lookup_motors()
print, format='(1x,a,$)', ' detector settings ... '
u = self->lookup_detectors()
print, ' '
for i = 0, n_elements(self.motors.name)-1 do begin
if (strupcase(strtrim(self.motors.name[i],2)) eq 'ENERGY') then self.motors.e_drive = i
endfor
endif
return, 1
end
pro epics_scan__define
;+
; NAME:
; EPICS_SCAN__DEFINE
;
; PURPOSE:
; Defines an EPICS scan object.
;
; CATEGORY:
; EPICS class library.
;
; CALLING SEQUENCE:
; my_scan = obj_new('EPICS_SCAN')
;
;
; INPUTS:
; None.
;
; OPTIONAL INPUTS:
; None.
;
; KEYWORD PARAMETERS:
; None.
;
;
; OUTPUTS:
; Return value will contain the object reference.
;
;
; OPTIONAL OUTPUTS:
; None.
;
;
; COMMON BLOCKS:
; None.
;
;
; SIDE EFFECTS:
; EPICS_Scan object is created.
;
;
; RESTRICTIONS:
; This routine is not called directly, but by IDL's own obj_new()
;
; PROCEDURE:
;
;
; EXAMPLE:
; scan = obj_new('EPICS_SCAN')
; x = scan->set_param('prefix', '13LAB:')
;
;
; MODIFICATION HISTORY:
; May 30 2000: M Newville
;-
@scan_dims
MAX_MOT = 36 ; number of motors
MAX_SCA = 8 ; number of scalar channels
MAX_REG = 4 ; number of regions in segmented scan
MAX_PAR = 11 ; number of 'extra parameters' in scan:
; currently params[0] = E0 for EXAFS scan
; params 1..10 are used for scanning
; specified points
MAX_DTY = 3 ; number of types of detectors
; detectors are the values read during a scan
detectors = { detectors, ndetectors: 0, $
group: intarr(MAX_DET), $
use_net: intarr(MAX_DET), $
in_use: intarr(MAX_DET), $
countPV: strarr(MAX_DET), $
desc: strarr(MAX_DET) }
; detgroups are the detector objects (Scaler, MED, etc)
detgroups = { detgroups, $
name: strarr(MAX_DTY), $
prefix: strarr(MAX_DTY), $
triggerpv: strarr(MAX_DTY), $
counterpv: strarr(MAX_DTY), $
max_elems: intarr(MAX_DTY), $
is_mca: intarr(MAX_DTY), $
use_det: intarr(MAX_DTY) }
motors = { motors, name: strarr(MAX_MOT), e_drive:0L,$
pv: strarr(MAX_MOT), rbv: strarr(MAX_MOT), $
curpos: fltarr(MAX_MOT), units: strarr(MAX_MOT), $
llim: fltarr(MAX_MOT), hlim: fltarr(MAX_MOT) }
scan1 = { scan, scanPV: 'scan1', type : 'Motor', $
drives: intarr(MAX_POS), $
pos_names: strarr(MAX_POS), $
posPVs: strarr(MAX_POS), $
start: fltarr(MAX_REG, MAX_POS), $
stop: fltarr(MAX_REG, MAX_POS), $
step: fltarr(MAX_REG, MAX_POS), $
npts: intarr(MAX_REG), npts_total: 1, $
time: fltarr(MAX_REG), $
params: fltarr(MAX_PAR), $
is_kspace: intarr(MAX_REG), $
is_rel: 1, n_regions: 1, $
pasm: 2, ddly: 0.25, pdly:0.5 , time_est:0.000}
scan2 = scan1
scan3 = scan1
scan2.scanPV = 'scan2'
scan3.scanPV = 'scan3'
epics_scan= { epics_scan, $
prefix: ' ', $
paramfile: ' ', $
monitorfile: ' ', $ ; file of PVs to write down at start of scan
datafile: ' ', $
user_comments:' ', $
med_obj:0L, $
lun: -3, $
dimension: 1, $
total_time: 1.00000000, $
current_scan: 1, $
shutter_pv: ' ',$
shutter_clos: ' ',$
shutter_open: ' ',$
max_scan_points: MAX_SCAN_POINTS, $
detgroups: detgroups, $
detectors: detectors, $
motors: motors, $
scan: [scan1, scan2, scan3] }
end
escan/escan.pro 0100755 0000621 0000620 00000102341 07317216671 012760 0 ustar epics epics
function update_scan_settings, w, sc, i
; update the start, stop, step, npts settings for a scan segments
;
sc.npts[i] = npts_calc(sc.start[i],sc.stop[i],sc.step[i],step_out)
sc.step[i] = step_out
Widget_Control, w.start[i], set_value = f2a(sc.start[i])
Widget_Control, w.stop[i], set_value = f2a(sc.stop[i] )
Widget_Control, w.step[i], set_value = f2a(sc.step[i] )
Widget_Control, w.npts[i], set_value = f2a(sc.npts[i] )
return, sc
end
function set_sensitive_regions, w, nregs
;
; set sensitivity of scan segment regions
;
; print, ' Set Sensitive Regions ', w, nregs
if (nregs gt 1) then begin
for i = 0, nregs-1 do begin
Widget_Control, w.start[i], SENSITIVE = 1
Widget_Control, w.stop[i], SENSITIVE = 1
Widget_Control, w.step[i], SENSITIVE = 1
Widget_Control, w.npts[i], SENSITIVE = 1
Widget_Control, w.time[i], SENSITIVE = 1
Widget_Control, w.units[i], SENSITIVE = 1
endfor
endif
for i = nregs, 2 do begin
Widget_Control, w.start[i], SENSITIVE = 0
Widget_Control, w.stop[i], SENSITIVE = 0
Widget_Control, w.step[i], SENSITIVE = 0
Widget_Control, w.npts[i], SENSITIVE = 0
Widget_Control, w.time[i], SENSITIVE = 0
Widget_Control, w.units[i], SENSITIVE = 0
endfor
return,0
end
function check_motor_limits, pos, is_rel, motor
;
; check that a motor position is within motor limits,
; includes 'relative position'
;
; returns a value for the position that is within motor limits
out = pos
abs = out
if (is_rel) then abs = abs + motor.curpos
if ((abs < motor.llim) or (abs > motor.hlim)) then begin
out = abs > motor.llim < motor.hlim
if (is_rel) then out = out - motor.curpos
endif
return, out
end
;
pro exafs_event, event
@scan_include
Widget_Control, event.id, get_uval = uval
; print, ' exafs_event: scan = <',_scan,'> uval = ', uval
wid = (*p).escan
case uval of
'e0': begin
Widget_Control, wid.e0, get_value = t
sc.params[0] = strtrim(t,2)
end
'nregs': begin
Widget_Control, wid.nregs, get_value = t
nregs = ((fix(strtrim(t[0],2)) > 1) < 3)
Widget_Control, wid.nregs, set_value = f2a(nregs)
sc.n_regions = nregs
u = (*p).es->set_param(_scan, sc)
u = set_sensitive_regions(wid,nregs)
end
'use_rel': begin
do_change = 0
dx = sc.params[0]
if ((event.index eq 1) and (sc.is_rel eq 0)) then begin ;
do_change = 1
sc.is_rel = 1
dx = -dx
endif else if ((event.index eq 0) and (sc.is_rel eq 1)) then begin
do_change = 1
sc.is_rel = 0
endif
if (do_change eq 1) then begin
for i = 0, 2 do begin
if (sc.is_kspace[i] eq 0) then begin
sc.start[i] = sc.start[i] + dx
sc.stop[i] = sc.stop[i] + dx
sc = update_scan_settings(wid, sc, i)
endif
endfor
endif
end
'cur_pos': begin
end
'start0': begin
Widget_Control, wid.start[0], get_value = t
sc.start[0] = a2f(t)
sc = update_scan_settings( wid, sc, 0)
end
'stop0': begin
Widget_Control, wid.stop[0], get_value = t
sc.stop[0] = a2f(t)
sc = update_scan_settings(wid, sc, 0)
sc.start[1] = sc.stop[0]
sc = update_scan_settings(wid, sc, 1)
end
'step0': begin
Widget_Control, wid.step[0], get_value = t
sc.step[0] = a2f(t)
sc = update_scan_settings(wid, sc, 0)
end
'start1': begin
Widget_Control, wid.start[1], get_value = t
sc.start[1] = a2f(t)
sc = update_scan_settings(wid, sc, 1)
sc.stop[0] = sc.start[1]
sc = update_scan_settings(wid, sc, 0)
end
'stop1': begin
Widget_Control, wid.stop[1], get_value = t
sc.stop[1] = a2f(t)
sc = update_scan_settings(wid, sc, 1)
sc.start[2] = sc.stop[1]
; print, ' is_kspace, is_rel = ', sc.is_kspace[2], sc.is_rel
if (sc.is_kspace[2] eq 1) then begin
if (sc.is_rel eq 0) then sc.start[2] = (sc.start[2] - sc.params[0])>0
sc.start[2] = sqrt(sc.start[2] * ETOK)
endif
; print, ' sc.start[2]= ', sc.start[2]
sc = update_scan_settings(wid, sc, 2)
end
'step1': begin
Widget_Control, wid.step[1], get_value = t
sc.step[1] = a2f(t)
sc = update_scan_settings(wid, sc, 1)
end
'start2': begin
Widget_Control, wid.start[2], get_value = t
sc.start[2] = a2f(t)
sc = update_scan_settings(wid, sc, 2)
sc.stop[1] = sc.start[2]
if (sc.is_kspace[2] eq 1) then begin
if (sc.is_rel eq 0) then sc.stop[2] = (sc.stop[2] - sc.params[0])>0
sc.stop[1] = sc.stop[1] * sc.stop[1] / ETOK
endif
sc = update_scan_settings(wid, sc, 1)
end
'stop2': begin
Widget_Control, wid.stop[2], get_value = t
sc.stop[2] = a2f(t)
sc = update_scan_settings(wid, sc, 2)
end
'step2': begin
Widget_Control, wid.step[2], get_value = t
sc.step[2] = a2f(t)
sc = update_scan_settings(wid, sc, 2)
end
'npts0': begin
Widget_Control, wid.npts[0], get_value = t
sc.npts[0] = ((fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[0] = (sc.start[0] - sc.stop[0])/(sc.npts[0]-1)
sc = update_scan_settings(wid, sc, 0)
end
'npts1': begin
Widget_Control, wid.npts[1], get_value = t
sc.npts[1] = ((fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[1] = (sc.start[1] - sc.stop[1])/(sc.npts[1]-1)
sc = update_scan_settings(wid, sc, 1)
end
'npts2': begin
Widget_Control, wid.npts[2], get_value = t
sc.npts[2] = ((fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[2] = (sc.start[2] - sc.stop[2])/(sc.npts[2]-1)
sc = update_scan_settings(wid, sc, 2)
end
'time0': begin
Widget_Control, wid.time[0], get_value = t
sc.time[0] = a2f(t)
end
'time1': begin
Widget_Control, wid.time[1], get_value = t
sc.time[1] = a2f(t)
end
'time2': begin
Widget_Control, wid.time[2], get_value = t
sc.time[2] = a2f(t)
end
'units0': print, " K steps ?? No WAY! "
'units1': print, " K steps ?? No WAY! "
'units2': begin
; print, "kspace: ", event.index
if (event.index eq 1) then begin ; choose 'Ang^-1'
if (sc.is_kspace[2] eq 0) then begin ; switching from E to k space
sc.is_kspace[2] = 1
d = sc.start[2]
if (sc.is_rel eq 0) then d = d - sc.params[0]
sc.start[2] = sqrt(d * ETOK)
d = sc.stop[2]
if (sc.is_rel eq 0) then d = d - sc.params[0]
sc.stop[2] = sqrt(d * ETOK)
sc.step[2] = 0.05
endif
endif else begin; choose 'eV'
if (sc.is_kspace[2] eq 1) then begin ; switching from k to E space
sc.is_kspace[2] = 0
d = sc.start[2] * sc.start[2] / ETOK
if (sc.is_rel eq 0) then d = d + sc.params[0]
sc.start[2] = d
d = sc.stop[2] * sc.stop[2] / ETOK
if (sc.is_rel eq 0) then d = d + sc.params[0]
sc.stop[2] = d
sc.step[2] = 2.0
endif
endelse
sc = update_scan_settings(wid, sc, 2)
end
else: print, 'exafs_event: unknown!', uval
endcase
u = (*p).es->set_param(_scan, sc)
return
end
pro motor_event, event
@scan_include
Widget_Control, event.id, get_uval = uval
wid = (*p).mscan
case uval of
'use_rel': begin
do_change = 0
dx = motor.curpos
if ((event.index eq 1) and (sc.is_rel eq 0)) then begin ;
sc.is_rel = 1
do_change = 1
dx = -dx
endif else if ((event.index eq 0) and (sc.is_rel eq 1)) then begin
do_change = 1
sc.is_rel = 0
endif
if (do_change eq 1) then begin
for i = 0, 2 do begin
sc.start[i] = sc.start[i] + dx
sc.stop[i] = sc.stop[i] + dx
sc = update_scan_settings(wid, sc, i)
endfor
endif
end
'nregs': begin
Widget_Control, wid.nregs, get_value = t
nregs = ((fix(strtrim(t[0],2)) > 1) < 3)
Widget_Control, wid.nregs, set_value = f2a(nregs)
sc.n_regions = nregs
u = (*p).es->set_param(_scan, sc)
u = set_sensitive_regions(wid,nregs)
end
'motor_name': begin
motor = (*p).es->get_motor(event.index)
sc.drives[0] = event.index
sc.start[0] = check_motor_limits(sc.start[0],sc.is_rel,motor)
sc.stop[0] = check_motor_limits(sc.stop[0], sc.is_rel,motor)
sc = update_scan_settings(wid, sc, 0)
Widget_Control, wid.llim, set_value = f2a(motor.llim)
Widget_Control, wid.hlim, set_value = f2a(motor.hlim)
Widget_Control, wid.cur_pos, set_value = f2a(motor.curpos)
end
'cur_pos': begin
Widget_Control, wid.cur_pos, get_value = cur
val = a2f(cur)
rbv = motor.rbv
pv = strtrim(motor.pv,2)
ilen = strlen(pv)
if (strupcase(strmid(pv,ilen-4,4)) eq '.VAL') then pv = strmid(pv,0,ilen-4)
if ((val le motor.hlim) and (val ge motor.llim)) then begin
s = caput(pv + '.VAL', val)
dmov = 0
while (dmov eq 0) do begin
s = caget(pv + '.DMOV', dmov)
s = caget(rbv, val)
Widget_Control, wid.cur_pos, set_value = f2a(val)
endwhile
motor.curpos = val
u = (*p).es->set_motor(imotor, motor)
endif else begin
print, ' requested position is outside limits'
endelse
end
'time0': begin
Widget_Control, wid.time[0], get_value = t
sc.time[0] = a2f(t)
end
'start0': begin
Widget_Control, wid.start[0], get_value = t
start = a2f(t)
sc.start[0] = check_motor_limits(start,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 0)
end
'stop0': begin
Widget_Control, wid.stop[0], get_value = t
stop = a2f(t)
sc.stop[0] = check_motor_limits(stop,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 0)
sc.start[1] = sc.stop[0]
sc = update_scan_settings(wid, sc, 1)
end
'step0': begin
Widget_Control, wid.step[0], get_value = t
sc.step[0] = a2f(t)
sc = update_scan_settings( wid, sc, 0)
end
'npts0': begin
Widget_Control, wid.npts[0], get_value = t
sc.npts[0] = (( fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[0] = (sc.start[0] - sc.stop[0])/(sc.npts[0] - 1)
sc = update_scan_settings( wid, sc, 0)
end
;
'time1': begin
Widget_Control, wid.time[1], get_value = t
sc.time[1] = a2f(t)
end
'start1': begin
Widget_Control, wid.start[1], get_value = t
start = a2f(t)
sc.start[1] = check_motor_limits(start,sc.is_rel,motor)
sc = update_scan_settings(wid, sc, 1)
sc.stop[0] = sc.start[1]
sc = update_scan_settings(wid, sc, 0)
end
'stop1': begin
Widget_Control, wid.stop[1], get_value = t
stop = a2f(t)
sc.stop[1] = check_motor_limits(stop,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 1)
sc.start[2] = sc.stop[1]
sc = update_scan_settings(wid, sc, 2)
end
'step1': begin
Widget_Control, wid.step[1], get_value = t
sc.step[1] = a2f(t)
sc = update_scan_settings( wid, sc, 1)
end
'npts1': begin
Widget_Control, wid.npts[1], get_value = t
sc.npts[1] = (( fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[1] = (sc.start[1] - sc.stop[1])/(sc.npts[1] - 1)
sc = update_scan_settings( wid, sc, 1)
end
;
'time2': begin
Widget_Control, wid.time[2], get_value = t
sc.time[2] = a2f(t)
end
'start2': begin
Widget_Control, wid.start[2], get_value = t
start = a2f(t)
sc.start[2] = check_motor_limits(start,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 2)
sc.stop[1] = sc.start[2]
sc = update_scan_settings(wid, sc, 1)
end
'stop2': begin
Widget_Control, wid.stop[2], get_value = t
stop = a2f(t)
sc.stop[2] = check_motor_limits(stop,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 2)
end
'step2': begin
Widget_Control, wid.step[2], get_value = t
sc.step[2] = a2f(t)
sc = update_scan_settings( wid, sc, 2)
; print, ' motor step2 == ', sc.step[2], sc.npts[2]
end
'npts2': begin
Widget_Control, wid.npts[2], get_value = t
sc.npts[2] = (( fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[2] = (sc.start[2] - sc.stop[2])/(sc.npts[2] - 1.00)
sc = update_scan_settings( wid, sc, 2)
end
'units': x = 1
'llim': x = 1
'hlim': x = 1
else: print, 'motor_event: unknown!'
endcase
u = (*p).es->set_param(_scan, sc)
return
end
pro escan_fill_screen, p
;
; fill in escan screens from data structure
;
print, 'escan_fill '
cur_dim = (*p).es->get_param('dimension')
cur_scan = (*p).es->get_param('current_scan')
allmotors = (*p).es->get_param('motors')
_scan = 'scan' + string(strtrim(cur_scan, 2))
sc = (*p).es->get_param(_scan)
imotor = sc.drives[0]
motor = (*p).es->get_motor(imotor)
cur_type = 0
wid = (*p).mscan
if (strlowcase(sc.type) eq 'exafs') then begin
wid = (*p).escan
cur_type = 1
endif
cur_scan = cur_scan-1
Widget_Control, (*p).form.scan_num, set_droplist_select = cur_scan
Widget_Control, (*p).form.scan_dim, set_droplist_select = cur_dim-1
Widget_Control, (*p).form.scan_type, set_droplist_select = cur_type
; print, ' cur_scan = ', cur_scan
x_start = (*p).es->get_scan_param(cur_scan, 'start')
x_stop = (*p).es->get_scan_param(cur_scan, 'stop')
x_step = (*p).es->get_scan_param(cur_scan, 'step')
x_npts = (*p).es->get_scan_param(cur_scan, 'npts')
x_time = (*p).es->get_scan_param(cur_scan, 'time')
x_isk = (*p).es->get_scan_param(cur_scan, 'is_kspace')
; for i = 0, 2 do begin
; x_ = (*p).es->get_scan_param(i, 'is_kspace')
; print, ' IS K-SPACE ', i, x_
; endfor
Widget_Control, wid.nregs, set_value = f2a(sc.n_regions)
Widget_Control, wid.is_rel, set_DROPLIST_SELECT = sc.is_rel
m_names = allmotors.name
Widget_Control, (*p).mscan.motor, set_value =m_names
for i = 0, 2 do begin
Widget_Control, wid.start[i], set_value=f2a(x_start[i,0])
Widget_Control, wid.stop[i], set_value=f2a(x_stop[i,0])
Widget_Control, wid.step[i], set_value=f2a(x_step[i,0])
Widget_Control, wid.npts[i], set_value=f2a(x_npts[i,0])
Widget_Control, wid.time[i], set_value=f2a(x_time[i,0])
endfor
if (cur_type eq 0) then begin
Widget_Control, (*p).mscan.motor, set_DROPLIST_SELECT= sc.drives[0]
Widget_Control, (*p).mscan.is_rel, set_DROPLIST_SELECT= sc.is_rel
Widget_Control, (*p).mscan.cur_pos, set_value= f2a(motor.curpos)
Widget_Control, (*p).mscan.hlim, set_value= f2a(motor.hlim)
Widget_Control, (*p).mscan.llim, set_value= f2a(motor.llim)
Widget_Control, (*p).form.nb[1], map=0
Widget_Control, (*p).form.nb[0], map=1
endif else begin
Widget_Control, (*p).escan.e0, set_value = f2a(sc.params[0])
Widget_Control, (*p).form.nb[0], map=0
Widget_Control, (*p).form.nb[1], map=1
Widget_Control, (*p).escan.units[2], SET_DROPLIST_SELECT = x_isk[2]
endelse
for i = 0, 2 do sc = update_scan_settings(wid, sc, i)
u = (*p).es->set_param(_scan, sc)
u = set_sensitive_regions(wid, sc.n_regions)
return
end
;
pro escan_event, event
;
@scan_include
Widget_Control, event.id, get_uval = uval
if (strupcase(strtrim(sc.type,2)) eq 'EXAFS') then begin
scan_type = 1
wid = (*p).escan
endif else begin
scan_type = 0
wid = (*p).mscan
endelse
; print, 'escan_event uval = ', uval
case uval of
'exit': Widget_Control, event.top, /destroy
'save_params': retval = (*p).es->save_paramfile(/use_dialog)
'saveas_params': retval = (*p).es->save_paramfile(/use_dialog)
'read_params': begin
retval = (*p).es->read_paramfile(/use_dialog)
escan_fill_screen, p
end
'data_file_name': begin
Widget_Control, (*p).form.data_file_name, get_value = t
t = strtrim(t[0],2)
x = (*p).es->set_param('datafile',t)
end
'raw_dets': begin
r = define_raw_detectors(p)
d = (*p).es->get_param('detectors')
t = ['','']
for i = 0, n_elements(d.countPV)- 1 do begin
if (strpos(d.countPV[i],'scaler') ne -1) then t[0]= 'scaler1.CNT'
if (strpos(d.countPV[i],'med') ne -1) then t[1]= 'med:Start.VAL'
endfor
x = (*p).es->set_param('triggers',t)
end
'set_dets': begin
r = define_detectors(p)
d = (*p).es->get_param('detectors')
t = ['','']
for i = 0, n_elements(d.countPV)- 1 do begin
if (strpos(d.countPV[i],'scaler') ne -1) then t[0]= 'scaler1.CNT'
if (strpos(d.countPV[i],'med') ne -1) then t[1]= 'med:Start.VAL'
endfor
x = (*p).es->set_param('triggers',t)
end
'collect_offs': begin
r = collect_offsets(p)
end
'define_mots': begin
motor = (*p).es->get_param('motors')
end
'setup': begin
; print , ' setup '
r = define_scan(p)
end
'scan_type': begin
if (event.index eq 0) then begin
Widget_Control, (*p).form.nb[1], map=0
Widget_Control, (*p).form.nb[0], map=1
Widget_Control, (*p).mscan.motor, set_DROPLIST_SELECT = sc.drives[0]
wid = (*p).mscan
sc.type = 'Motor'
endif else begin
Widget_Control, (*p).form.nb[0], map=0
Widget_Control, (*p).form.nb[1], map=1
Widget_Control, (*p).escan.e0, set_value = f2a(sc.params[0])
wid = (*p).escan
sc.type = 'EXAFS'
endelse
u = set_sensitive_regions(wid, sc.n_regions)
Widget_Control, wid.nregs, set_value = f2a(sc.n_regions)
Widget_Control, wid.is_rel, set_DROPLIST_SELECT = sc.is_rel
u = (*p).es->set_param(_scan, sc)
for i = 0, 2 do begin
sc = update_scan_settings(wid, sc, i)
endfor
end
'scan_dim': begin
; print, " SCAN_DIM event: ", event.index + 1
u = (*p).es->set_param('dimension', event.index+1)
end
'scan_num': begin
current_scan = event.index + 1
x = (*p).es->set_param('current_scan', current_scan)
_scan = 'scan' + string(strtrim(current_scan,2))
sc = (*p).es->get_param(_scan)
motor = (*p).es->get_motor(sc.drives[0])
motor.curpos = (*p).es->get_motor_position(sc.drives[0])
pv = motor.pv
il = strlen(pv)
if (strupcase(strmid(pv,il-4,4)) eq '.VAL') then pv = strmid(pv,0,il-4)
scan_type = 0
wid = (*p).mscan
if (strupcase(strtrim(sc.type,2)) eq 'EXAFS') then begin
scan_type = 1
wid = (*p).escan
endif
Widget_Control, (*p).form.nb[0], map=0
Widget_Control, (*p).form.nb[1], map=0
Widget_Control, (*p).form.nb[scan_type], map=1
Widget_Control, (*p).form.scan_type, set_DROPLIST_SELECT = scan_type
Widget_Control, wid.nregs, set_value = f2a(sc.n_regions)
Widget_Control, wid.is_rel, set_DROPLIST_SELECT = sc.is_rel
for i = 0, 2 do begin
sc = update_scan_settings(wid, sc, i)
endfor
if (scan_type eq 0) then begin
Widget_Control, wid.motor, set_DROPLIST_SELECT= sc.drives[0]
Widget_Control, wid.is_rel, set_DROPLIST_SELECT= sc.is_rel
Widget_Control, wid.cur_pos, set_value= f2a(motor.curpos)
Widget_Control, wid.hlim, set_value= f2a(motor.hlim)
Widget_Control, wid.llim, set_value= f2a(motor.llim)
endif else begin
Widget_Control, wid.e0, set_value = f2a(sc.params[0])
endelse
u = set_sensitive_regions(wid, sc.n_regions)
end
'load': begin
x = (*p).es->load_to_crate()
sc = (*p).es->get_param(_scan)
dim = (*p).es->get_param('dimension')
tx = fltarr(3)
np = intarr(3)+1
for i = 0, dim-1 do begin
x = (*p).es->get_param('scan'+string(i+1,format='(i1.1)'))
tx(i) = x.time_est
np(i) = x.npts_total
endfor
total_time = tx(2) + np(2) * ( tx(1) + np(1) * tx(0) )
tm1 = sec2hms(total_time)
print, 'time estimate: ', tm1
widget_control, (*p).form.time_est, set_value = tm1
x = (*p).es->set_param('total_time',total_time)
end
'scan_view': begin
x = scan_viewer( (*p).es )
end
else: print , ' unknown event ', uval
endcase
return
end
;
;------------------------------------------------------------------
pro escan, scan_file=scan_file
;
;
print, ' This is escan v 1.0'
N_SCAN_TYPES = 2
N_REG = 5
scan_types = ['Motor', 'EXAFS']
scan_nums = ['Scan 1', 'Scan 2', 'Scan 3']
rel_choices = ['Absolute', 'Relative']
scan_dims = ['1', '2', '3']
cur_dim = 0
;
; define and setup epics_scan object
s_file = 'default.scn'
if (keyword_set(scan_file) ne 0 ) then s_file = scan_file
es = obj_new('epics_scan', scan_file = s_file, /use_dialog)
datafile = es->get_param('datafile')
motor = es->get_param('motors')
det = es->get_param('detectors')
cur_scan = es->get_param('current_scan')
sc = es->get_param('scan' + string(strtrim(cur_scan, 2)))
cur_scan = cur_scan - 1
m_names = motor.name
drives = es->get_scan_param(cur_scan, 'drives')
imot = drives[0]
_motor = es->get_motor(imot)
; if (imot eq motor.e_drive) then print, " driving Energy!!"
_energy = es->get_motor(motor.e_drive)
cur_type = 0
cx_type = es->get_scan_param(0, 'type')
if (cx_type eq scan_types[1]) then cur_type = 1
; print, ' scan type: ', cx_type , ' scan_types[1] = ', scan_types[1], cur_type
;--------------------------------------------------------------------------------
; nbframe holds the frame ids for the 2 'notebook frames'
nb = lonarr(N_SCAN_TYPES)
arr0 = lonarr(N_REG)
form = {scan_num:scan_nums[0], data_file_name:0L, time_est:0L, $
scan_type:scan_types[0], scan_dim:scan_dims[0], $
cur_dim:1L, nb:nb}
mscan = {motor:m_names[0], cur_pos:0L, llim:0L, hlim:0L, e0:0L,$
nregs:1L, is_rel:rel_choices[1], units:arr0, $
start:arr0, stop:arr0, step:arr0, npts:arr0, time:arr0}
escan = {e0:0L, cur_pos:0L, motor:0L, llim:0L, hlim:0L, $
nregs:3L, is_rel:rel_choices[1], units:arr0, $
start:arr0, stop:arr0, step:arr0, npts:arr0, time:arr0 }
info = {es:es, form:form, mscan:mscan, escan:escan}
;-----------------------
; menus
main = Widget_Base(title = 'Epics Scan Setup', /col, app_mbar = mbar)
; Widget_Control, default_font='Fixedsys'
menu = Widget_Button(mbar, value= 'File')
x = Widget_Button(menu, value= 'Read Scan File ...', uval= 'read_params')
x = Widget_Button(menu, value= 'Save Scan File ...', uval= 'save_params')
x = Widget_Button(menu, value= 'Save As ...', uval= 'saveas_params')
x = Widget_Button(menu, value= 'Exit', uval= 'exit', /sep)
menu = Widget_Button(mbar, value= 'Setup')
x = Widget_Button(menu, value= 'General Setup ...', uval= 'setup')
x = Widget_Button(menu, value= 'Select Detectors ...', uval= 'set_dets')
x = Widget_Button(menu, value= 'Define Motors ...', uval= 'define_mots')
x = Widget_Button(menu, value= 'Collect Offsets ...', uval= 'collect_offs')
; x = Widget_Button(menu, value= 'Set Raw Detectors ...',uval= 'raw_dets')
menu = Widget_Button(mbar, value= 'Help', /menu, /help)
x = Widget_Button(menu, value= 'Help on EPICS SCAN', uval= 'escan_help')
x = Widget_Button(menu, value= 'Help on IDL', uval= 'IDLhelp')
;-----------------------
mframe = Widget_Base(main, /col)
fr0 = Widget_Base(mframe, /row, /frame)
info.form.scan_num = Widget_Droplist(fr0, value= scan_nums, uval= 'scan_num', $
title = ' ')
info.form.scan_dim = Widget_Droplist(fr0, value= scan_dims, uval= 'scan_dim', $
title = ' of dimension ')
info.form.scan_type= Widget_Droplist(fr0, value= scan_types, uval= 'scan_type', $
title = ' Type ')
Widget_Control, info.form.scan_num, set_Droplist_SELECT = cur_scan
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
Widget_Control, info.form.scan_type, set_Droplist_SELECT = cur_type
x_start = info.es->get_scan_param(0, 'start')
x_stop = info.es->get_scan_param(0, 'stop')
x_step = info.es->get_scan_param(0, 'step')
x_npts = info.es->get_scan_param(0, 'npts')
x_time = info.es->get_scan_param(0, 'time')
info.escan.nregs = info.es->get_scan_param(0, 'n_regions')
;
OptBase = Widget_Base(mframe, /frame)
;-----------------------
; Motor Scan Frame:
info.form.nb[0] = Widget_Base(OptBase, /col, MAP = 0,event_pro='motor_event')
fr01 = Widget_Base(info.form.nb[0], /row)
x = Widget_Label(fr01, value = 'Motor')
info.mscan.motor = Widget_Droplist(fr01, value= m_names, uval= 'motor_name', $
title = ' ')
Widget_Control, info.mscan.motor, set_Droplist_SELECT = imot
info.mscan.nregs = CW_FIELD(fr01, /INTEGER, /ROW, xsize=4, $
title = 'Number of Scan Regions', UVALUE = 'nregs', $
VALUE = f2a(info.mscan.nregs), $
/return_events)
info.mscan.is_rel = Widget_Droplist(fr01, value= rel_choices, uval= 'use_rel', $
title = 'use ')
Widget_Control, info.mscan.is_rel, set_Droplist_SELECT = 1
x = Widget_Label(fr01, value = 'Positions')
fr02 = Widget_Base(info.form.nb[0], /row )
info.mscan.cur_pos = CW_Field(fr02, title = 'Current Position', $
xsize=11, uval = 'cur_pos', $
value = f2a(_motor.curpos), $
/return_events, /floating)
info.mscan.llim = CW_Field(fr02, title = 'Limits : Low ', $
xsize = 11, uval = 'llim', /noedit, $
value = f2a(_motor.llim), $
/return_events, /floating)
info.mscan.hlim = CW_Field(fr02, title = ' : High ', $
xsize = 11, uval = 'hlim', /noedit, $
value = f2a(_motor.hlim), $
/return_events, /floating)
fr03 = Widget_Base(info.form.nb[0], /col,/frame)
fr04 = Widget_Base(fr03, /row)
X = Widget_Label(fr04, XSIZE= 85, VALUE = 'Region ' )
X = Widget_Label(fr04, XSIZE= 100, VALUE = ' Start ' )
X = Widget_Label(fr04, XSIZE= 100, VALUE = ' Stop ' )
X = Widget_Label(fr04, XSIZE= 100, VALUE = ' Step ' )
X = Widget_Label(fr04, XSIZE= 100, VALUE = ' Npts ' )
X = Widget_Label(fr04, XSIZE= 100, VALUE = ' Time (s)')
X = Widget_Label(fr04, XSIZE= 100, VALUE = ' Units ' )
reg_title = ['1', '2', '3', '4']
uv_ = ['start', 'stop', 'step', 'npts', 'time']
for i = 0, 2 do begin
fr05 = Widget_Base(fr03, /row)
X = Widget_Label(fr05, XSIZE=80, VALUE = reg_title[i], /ALIGN_LEFT)
uvs = uv_ + strtrim(string(i),2)
info.mscan.start[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[0], $
value = f2a(x_start[i,0]), $
/return_events, /floating)
info.mscan.stop[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[1], $
value = f2a(x_stop[i,0]), $
/return_events, /floating)
info.mscan.step[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[2], $
value = f2a(x_step[i,0]), $
/return_events, /floating)
info.mscan.npts[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[3], $
value = f2a(x_npts[i]), $
/return_events, /floating)
info.mscan.time[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[4], $
value = f2a(x_time[i]), $
/return_events, /floating)
info.mscan.units[i] = Widget_Label(fr05, uval = 'units', $
value= strtrim(_motor.units,2) )
endfor
;
;-----------------------
; EXAFS Scan Frame:
info.form.nb[1] = Widget_Base(OptBase, /col, MAP = 0,event_pro='exafs_event')
fr11 = Widget_Base(info.form.nb[1], /row)
x = Widget_Label(fr11, value = ' EXAFS ')
info.escan.e0 = CW_FIELD(fr11, /FLOATING, /ROW, XSIZE = 9, $
TITLE = ' E0', UVALUE = 'e0', $
VALUE = f2a(info.escan.e0), $
/return_events)
info.escan.nregs = CW_FIELD(fr11, /INTEGER, /ROW, XSIZE = 5, $
TITLE = ' Number of Scan Regions', UVALUE = 'nregs', $
VALUE = f2a(info.escan.nregs), $
/return_events)
info.escan.is_rel = Widget_Droplist(fr11, title = 'use ', $
value = Rel_choices, uval = 'use_rel')
Widget_Control, info.escan.is_rel, set_Droplist_SELECT = 1
x = Widget_Label(fr11, value = 'Energies')
fr12 = Widget_Base(info.form.nb[1], /row )
; info.escan.cur_pos = CW_Field(fr12, title = 'Current Energy', $
; xsize = 12, uval = 'cur_pos', $
; value = f2a(_energy.curpos), $
; /return_events, /floating)
fr12 = Widget_Base(info.form.nb[1], /row)
fr13 = Widget_Base(info.form.nb[1], /col,/frame)
fr14 = Widget_Base(fr13, /row)
X = Widget_Label(fr14, XSIZE= 85, VALUE = 'Region ' )
X = Widget_Label(fr14, XSIZE= 100, VALUE = ' Start ' )
X = Widget_Label(fr14, XSIZE= 100, VALUE = ' Stop ' )
X = Widget_Label(fr14, XSIZE= 100, VALUE = ' Step ' )
X = Widget_Label(fr14, XSIZE= 100, VALUE = ' Npts ' )
X = Widget_Label(fr14, XSIZE= 100, VALUE = ' Time (s)')
X = Widget_Label(fr14, XSIZE= 100, VALUE = ' Units ' )
etitle = ['Pre-Edge', 'XANES', 'EXAFS', 'EXTRA']
k_spaces = ['eV', STRING(197B)+'^(-1)']
uv_ = ['start', 'stop', 'step', 'npts', 'time','units']
for i = 0, 2 do begin
fr15 = Widget_Base(fr13, /row)
X = Widget_Label(fr15, XSIZE= 80, VALUE = etitle[i], /ALIGN_LEFT)
uvs = uv_ + strtrim(string(i),2)
info.escan.start[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[0], $
value = f2a(x_start[i,0]), $
/return_events, /floating)
info.escan.stop[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[1], $
value = f2a(x_stop[i,0]), $
/return_events, /floating)
info.escan.step[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[2], $
value = f2a(x_step[i,0]), $
/return_events, /floating)
info.escan.npts[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[3], $
value = f2a(x_npts[i]), $
/return_events, /floating)
info.escan.time[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[4], $
value = f2a(x_time[i]), $
/return_events, /floating)
if (i le 1) then begin
X = Widget_Label(fr15, XSIZE= 30, VALUE = 'eV', /ALIGN_LEFT)
info.escan.units[i] = Widget_Base(fr15, /row, Map = 0)
endif else begin
info.escan.units[i] = Widget_Droplist(fr15, value = k_spaces, $
uvalue = uvs[5], title = ' ')
ch = es->get_scan_param(0, 'is_kspace')
Widget_Control, info.escan.units[i], SET_DROPLIST_SELECT = ch[i]
endelse
endfor
; map the current scan type!
Widget_Control, info.form.nb[cur_type], map=1
Widget_Control, info.escan.e0, set_value = f2a(sc.params[0])
u = set_sensitive_regions(info.mscan,sc.n_regions)
u = set_sensitive_regions(info.escan,sc.n_regions)
;-----------------------
; Bottom Frame:
base1 = Widget_Base(mframe, /col, /frame)
base2 = Widget_Base(base1,/row)
X = Widget_Button(base2, value = 'Load Scan', uval='load')
X = Widget_Button(base2, value = 'Scan Viewer', uval='scan_view')
X = Widget_Button(base2, value = 'EXIT ', uval='exit')
X = Widget_Label(base2, value = 'Estimated time:')
info.form.time_est = Widget_Label(base2, xsize=190,value = ' ')
; render widgets, load info structure into main
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uval=p_info
Widget_Control, main, /realize
xmanager, 'escan', main, /no_block
return
end
escan/escan_x.pro 0100664 0000621 0000620 00000103176 07237637100 013310 0 ustar epics epics function npts_calc, start_in, stop_in, step_in, step
MAX_SCAN_POINTS = 2000 ; maximum number of points in scan record
ETOK = 0.2624682917
step = step_in
start = start_in
stop = stop_in
if (abs(step) le 1.d-8) then step = (stop - start)/20.0
if (abs(step) le 1.d-8) then begin
step = 1.
npts = 3
endif else begin
npts = 1 + round((abs(stop - start) )/abs(step))
npts = fix ( (npts > 2) < MAX_SCAN_POINTS)
step = (stop - start) / (npts-1)
endelse
return, npts
end
function f2a, x
; floating point to string
y = strtrim(string(x),2)
return, y
end
function a2f, x
; string to floating point
y = double(strtrim(x,2))
return, y
end
function sec2hms, x
; convert time in seconds to hhh:mm:ss.dd string
rem = x
hh = fix(rem) / 3600
rem = rem - hh * 3600
mm = fix(rem) / 60
rem = rem - mm * 60
ss = fix(rem)
dd = fix((rem - ss)*100)
ff = '(i2.2)'
s = strtrim(string(hh),2) + ':' + string(mm,format=ff) + ':' + $
string(ss,format=ff) + '.' + string(dd,format=ff)
return, s
end
function update_scan_settings, w, sc, i
; update the start, stop, step, npts settings for a scan segments
;
sc.npts[i] = npts_calc(sc.start[i],sc.stop[i],sc.step[i],step_out)
sc.step[i] = step_out
Widget_Control, w.start[i], set_value = f2a(sc.start[i])
Widget_Control, w.stop[i], set_value = f2a(sc.stop[i] )
Widget_Control, w.step[i], set_value = f2a(sc.step[i] )
Widget_Control, w.npts[i], set_value = f2a(sc.npts[i] )
return, sc
end
function set_sensitive_regions, w, nregs
;
; set sensitivity of scan segment regions
;
; print, ' Set Sensitive Regions ', w, nregs
if (nregs gt 1) then begin
for i = 0, nregs-1 do begin
Widget_Control, w.start[i], SENSITIVE = 1
Widget_Control, w.stop[i], SENSITIVE = 1
Widget_Control, w.step[i], SENSITIVE = 1
Widget_Control, w.npts[i], SENSITIVE = 1
Widget_Control, w.time[i], SENSITIVE = 1
Widget_Control, w.units[i], SENSITIVE = 1
endfor
endif
for i = nregs, 2 do begin
Widget_Control, w.start[i], SENSITIVE = 0
Widget_Control, w.stop[i], SENSITIVE = 0
Widget_Control, w.step[i], SENSITIVE = 0
Widget_Control, w.npts[i], SENSITIVE = 0
Widget_Control, w.time[i], SENSITIVE = 0
Widget_Control, w.units[i], SENSITIVE = 0
endfor
return,0
end
function check_motor_limits, pos, is_rel, motor
;
; check that a motor position is within motor limits,
; includes 'relative position'
;
; returns a value for the position that is within motor limits
out = pos
abs = out
if (is_rel) then abs = abs + motor.curpos
if ((abs < motor.llim) or (abs > motor.hlim)) then begin
out = abs > motor.llim < motor.hlim
if (is_rel) then out = out - motor.curpos
endif
return, out
end
;
pro exafs_event, event
@scan_include
Widget_Control, event.id, get_uval = uval
; print, ' exafs_event: scan = <',_scan,'> uval = ', uval
wid = (*p).escan
case uval of
'e0': begin
Widget_Control, wid.e0, get_value = t
sc.params[0] = strtrim(t,2)
end
'nregs': begin
Widget_Control, wid.nregs, get_value = t
nregs = ((fix(strtrim(t[0],2)) > 1) < 3)
Widget_Control, wid.nregs, set_value = f2a(nregs)
sc.n_regions = nregs
u = (*p).es->set_param(_scan, sc)
u = set_sensitive_regions(wid,nregs)
end
'use_rel': begin
do_change = 0
dx = sc.params[0]
if ((event.index eq 1) and (sc.is_rel eq 0)) then begin ;
do_change = 1
sc.is_rel = 1
dx = -dx
endif else if ((event.index eq 0) and (sc.is_rel eq 1)) then begin
do_change = 1
sc.is_rel = 0
endif
if (do_change eq 1) then begin
for i = 0, 2 do begin
if (sc.is_kspace[i] eq 0) then begin
sc.start[i] = sc.start[i] + dx
sc.stop[i] = sc.stop[i] + dx
sc = update_scan_settings(wid, sc, i)
endif
endfor
endif
end
'cur_pos': begin
end
'start0': begin
Widget_Control, wid.start[0], get_value = t
sc.start[0] = a2f(t)
sc = update_scan_settings( wid, sc, 0)
end
'stop0': begin
Widget_Control, wid.stop[0], get_value = t
sc.stop[0] = a2f(t)
sc = update_scan_settings(wid, sc, 0)
sc.start[1] = sc.stop[0]
sc = update_scan_settings(wid, sc, 1)
end
'step0': begin
Widget_Control, wid.step[0], get_value = t
sc.step[0] = a2f(t)
sc = update_scan_settings(wid, sc, 0)
end
'start1': begin
Widget_Control, wid.start[1], get_value = t
sc.start[1] = a2f(t)
sc = update_scan_settings(wid, sc, 1)
sc.stop[0] = sc.start[1]
sc = update_scan_settings(wid, sc, 0)
end
'stop1': begin
Widget_Control, wid.stop[1], get_value = t
sc.stop[1] = a2f(t)
sc = update_scan_settings(wid, sc, 1)
sc.start[2] = sc.stop[1]
; print, ' is_kspace, is_rel = ', sc.is_kspace[2], sc.is_rel
if (sc.is_kspace[2] eq 1) then begin
if (sc.is_rel eq 0) then sc.start[2] = (sc.start[2] - sc.params[0])>0
sc.start[2] = sqrt(sc.start[2] * ETOK)
endif
; print, ' sc.start[2]= ', sc.start[2]
sc = update_scan_settings(wid, sc, 2)
end
'step1': begin
Widget_Control, wid.step[1], get_value = t
sc.step[1] = a2f(t)
sc = update_scan_settings(wid, sc, 1)
end
'start2': begin
Widget_Control, wid.start[2], get_value = t
sc.start[2] = a2f(t)
sc = update_scan_settings(wid, sc, 2)
sc.stop[1] = sc.start[2]
if (sc.is_kspace[2] eq 1) then begin
if (sc.is_rel eq 0) then sc.stop[2] = (sc.stop[2] - sc.params[0])>0
sc.stop[1] = sc.stop[1] * sc.stop[1] / ETOK
endif
sc = update_scan_settings(wid, sc, 1)
end
'stop2': begin
Widget_Control, wid.stop[2], get_value = t
sc.stop[2] = a2f(t)
sc = update_scan_settings(wid, sc, 2)
end
'step2': begin
Widget_Control, wid.step[2], get_value = t
sc.step[2] = a2f(t)
sc = update_scan_settings(wid, sc, 2)
end
'npts0': begin
Widget_Control, wid.npts[0], get_value = t
sc.npts[0] = ((fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[0] = (sc.start[0] - sc.stop[0])/(sc.npts[0]-1)
sc = update_scan_settings(wid, sc, 0)
end
'npts1': begin
Widget_Control, wid.npts[1], get_value = t
sc.npts[1] = ((fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[1] = (sc.start[1] - sc.stop[1])/(sc.npts[1]-1)
sc = update_scan_settings(wid, sc, 1)
end
'npts2': begin
Widget_Control, wid.npts[2], get_value = t
sc.npts[2] = ((fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[2] = (sc.start[2] - sc.stop[2])/(sc.npts[2]-1)
sc = update_scan_settings(wid, sc, 2)
end
'time0': begin
Widget_Control, wid.time[0], get_value = t
sc.time[0] = a2f(t)
end
'time1': begin
Widget_Control, wid.time[1], get_value = t
sc.time[1] = a2f(t)
end
'time2': begin
Widget_Control, wid.time[2], get_value = t
sc.time[2] = a2f(t)
end
'units0': print, " K steps ?? No WAY! "
'units1': print, " K steps ?? No WAY! "
'units2': begin
; print, "kspace: ", event.index
if (event.index eq 1) then begin ; choose 'Ang^-1'
if (sc.is_kspace[2] eq 0) then begin ; switching from E to k space
sc.is_kspace[2] = 1
d = sc.start[2]
if (sc.is_rel eq 0) then d = d - sc.params[0]
sc.start[2] = sqrt(d * ETOK)
d = sc.stop[2]
if (sc.is_rel eq 0) then d = d - sc.params[0]
sc.stop[2] = sqrt(d * ETOK)
sc.step[2] = 0.05
endif
endif else begin; choose 'eV'
if (sc.is_kspace[2] eq 1) then begin ; switching from k to E space
sc.is_kspace[2] = 0
d = sc.start[2] * sc.start[2] / ETOK
if (sc.is_rel eq 0) then d = d + sc.params[0]
sc.start[2] = d
d = sc.stop[2] * sc.stop[2] / ETOK
if (sc.is_rel eq 0) then d = d + sc.params[0]
sc.stop[2] = d
sc.step[2] = 2.0
endif
endelse
sc = update_scan_settings(wid, sc, 2)
end
else: print, 'exafs_event: unknown!', uval
endcase
u = (*p).es->set_param(_scan, sc)
return
end
pro motor_event, event
@scan_include
Widget_Control, event.id, get_uval = uval
wid = (*p).mscan
case uval of
'use_rel': begin
do_change = 0
dx = motor.curpos
if ((event.index eq 1) and (sc.is_rel eq 0)) then begin ;
sc.is_rel = 1
do_change = 1
dx = -dx
endif else if ((event.index eq 0) and (sc.is_rel eq 1)) then begin
do_change = 1
sc.is_rel = 0
endif
if (do_change eq 1) then begin
for i = 0, 2 do begin
sc.start[i] = sc.start[i] + dx
sc.stop[i] = sc.stop[i] + dx
sc = update_scan_settings(wid, sc, i)
endfor
endif
end
'nregs': begin
Widget_Control, wid.nregs, get_value = t
nregs = ((fix(strtrim(t[0],2)) > 1) < 3)
Widget_Control, wid.nregs, set_value = f2a(nregs)
sc.n_regions = nregs
u = (*p).es->set_param(_scan, sc)
u = set_sensitive_regions(wid,nregs)
end
'motor_name': begin
motor = (*p).es->get_motor(event.index)
sc.drives[0] = event.index
sc.start[0] = check_motor_limits(sc.start[0],sc.is_rel,motor)
sc.stop[0] = check_motor_limits(sc.stop[0], sc.is_rel,motor)
sc = update_scan_settings(wid, sc, 0)
Widget_Control, wid.llim, set_value = f2a(motor.llim)
Widget_Control, wid.hlim, set_value = f2a(motor.hlim)
Widget_Control, wid.cur_pos, set_value = f2a(motor.curpos)
end
'cur_pos': begin
Widget_Control, wid.cur_pos, get_value = cur
val = a2f(cur)
rbv = motor.rbv
pv = strtrim(motor.pv,2)
ilen = strlen(pv)
if (strupcase(strmid(pv,ilen-4,4)) eq '.VAL') then pv = strmid(pv,0,ilen-4)
if ((val le motor.hlim) and (val ge motor.llim)) then begin
s = caput(pv + '.VAL', val)
dmov = 0
while (dmov eq 0) do begin
s = caget(pv + '.DMOV', dmov)
s = caget(rbv, val)
Widget_Control, wid.cur_pos, set_value = f2a(val)
endwhile
motor.curpos = val
u = (*p).es->set_motor(imotor, motor)
endif else begin
print, ' requested position is outside limits'
endelse
end
'time0': begin
Widget_Control, wid.time[0], get_value = t
sc.time[0] = a2f(t)
end
'start0': begin
Widget_Control, wid.start[0], get_value = t
start = a2f(t)
sc.start[0] = check_motor_limits(start,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 0)
end
'stop0': begin
Widget_Control, wid.stop[0], get_value = t
stop = a2f(t)
sc.stop[0] = check_motor_limits(stop,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 0)
sc.start[1] = sc.stop[0]
sc = update_scan_settings(wid, sc, 1)
end
'step0': begin
Widget_Control, wid.step[0], get_value = t
sc.step[0] = a2f(t)
sc = update_scan_settings( wid, sc, 0)
end
'npts0': begin
Widget_Control, wid.npts[0], get_value = t
sc.npts[0] = (( fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[0] = (sc.start[0] - sc.stop[0])/(sc.npts[0] - 1)
sc = update_scan_settings( wid, sc, 0)
end
;
'time1': begin
Widget_Control, wid.time[1], get_value = t
sc.time[1] = a2f(t)
end
'start1': begin
Widget_Control, wid.start[1], get_value = t
start = a2f(t)
sc.start[1] = check_motor_limits(start,sc.is_rel,motor)
sc = update_scan_settings(wid, sc, 1)
sc.stop[0] = sc.start[1]
sc = update_scan_settings(wid, sc, 0)
end
'stop1': begin
Widget_Control, wid.stop[1], get_value = t
stop = a2f(t)
sc.stop[1] = check_motor_limits(stop,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 1)
sc.start[2] = sc.stop[1]
sc = update_scan_settings(wid, sc, 2)
end
'step1': begin
Widget_Control, wid.step[1], get_value = t
sc.step[1] = a2f(t)
sc = update_scan_settings( wid, sc, 1)
end
'npts1': begin
Widget_Control, wid.npts[1], get_value = t
sc.npts[1] = (( fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[1] = (sc.start[1] - sc.stop[1])/(sc.npts[1] - 1)
sc = update_scan_settings( wid, sc, 1)
end
;
'time2': begin
Widget_Control, wid.time[2], get_value = t
sc.time[2] = a2f(t)
end
'start2': begin
Widget_Control, wid.start[2], get_value = t
start = a2f(t)
sc.start[2] = check_motor_limits(start,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 2)
sc.stop[1] = sc.start[2]
sc = update_scan_settings(wid, sc, 1)
end
'stop2': begin
Widget_Control, wid.stop[2], get_value = t
stop = a2f(t)
sc.stop[2] = check_motor_limits(stop,sc.is_rel,motor)
sc = update_scan_settings( wid, sc, 2)
end
'step2': begin
Widget_Control, wid.step[2], get_value = t
sc.step[2] = a2f(t)
sc = update_scan_settings( wid, sc, 2)
; print, ' motor step2 == ', sc.step[2], sc.npts[2]
end
'npts2': begin
Widget_Control, wid.npts[2], get_value = t
sc.npts[2] = (( fix(strtrim(t,2)) > 2) < MAX_SCAN_POINTS)
sc.step[2] = (sc.start[2] - sc.stop[2])/(sc.npts[2] - 1.00)
sc = update_scan_settings( wid, sc, 2)
end
'units': x = 1
'llim': x = 1
'hlim': x = 1
else: print, 'motor_event: unknown!'
endcase
u = (*p).es->set_param(_scan, sc)
return
end
pro escan_fill_screen, p
;
; fill in escan screens from data structure
;
print, 'escan_fill '
cur_dim = (*p).es->get_param('dimension')
cur_scan = (*p).es->get_param('current_scan')
allmotors = (*p).es->get_param('motors')
_scan = 'scan' + string(strtrim(cur_scan, 2))
sc = (*p).es->get_param(_scan)
imotor = sc.drives[0]
motor = (*p).es->get_motor(imotor)
cur_type = 0
wid = (*p).mscan
if (strlowcase(sc.type) eq 'exafs') then begin
wid = (*p).escan
cur_type = 1
endif
cur_scan = cur_scan-1
Widget_Control, (*p).form.scan_num, set_droplist_select = cur_scan
Widget_Control, (*p).form.scan_dim, set_droplist_select = cur_dim-1
Widget_Control, (*p).form.scan_type, set_droplist_select = cur_type
; print, ' cur_scan = ', cur_scan
x_start = (*p).es->get_scan_param(cur_scan, 'start')
x_stop = (*p).es->get_scan_param(cur_scan, 'stop')
x_step = (*p).es->get_scan_param(cur_scan, 'step')
x_npts = (*p).es->get_scan_param(cur_scan, 'npts')
x_time = (*p).es->get_scan_param(cur_scan, 'time')
x_isk = (*p).es->get_scan_param(cur_scan, 'is_kspace')
; for i = 0, 2 do begin
; x_ = (*p).es->get_scan_param(i, 'is_kspace')
; print, ' IS K-SPACE ', i, x_
; endfor
Widget_Control, wid.nregs, set_value = f2a(sc.n_regions)
Widget_Control, wid.is_rel, set_DROPLIST_SELECT = sc.is_rel
m_names = allmotors.name
Widget_Control, (*p).mscan.motor, set_value =m_names
for i = 0, 2 do begin
Widget_Control, wid.start[i], set_value=f2a(x_start[i,0])
Widget_Control, wid.stop[i], set_value=f2a(x_stop[i,0])
Widget_Control, wid.step[i], set_value=f2a(x_step[i,0])
Widget_Control, wid.npts[i], set_value=f2a(x_npts[i,0])
Widget_Control, wid.time[i], set_value=f2a(x_time[i,0])
endfor
if (cur_type eq 0) then begin
Widget_Control, (*p).mscan.motor, set_DROPLIST_SELECT= sc.drives[0]
Widget_Control, (*p).mscan.is_rel, set_DROPLIST_SELECT= sc.is_rel
Widget_Control, (*p).mscan.cur_pos, set_value= f2a(motor.curpos)
Widget_Control, (*p).mscan.hlim, set_value= f2a(motor.hlim)
Widget_Control, (*p).mscan.llim, set_value= f2a(motor.llim)
Widget_Control, (*p).form.nb[1], map=0
Widget_Control, (*p).form.nb[0], map=1
endif else begin
Widget_Control, (*p).escan.e0, set_value = f2a(sc.params[0])
Widget_Control, (*p).form.nb[0], map=0
Widget_Control, (*p).form.nb[1], map=1
Widget_Control, (*p).escan.units[2], SET_DROPLIST_SELECT = x_isk[2]
endelse
for i = 0, 2 do sc = update_scan_settings(wid, sc, i)
u = (*p).es->set_param(_scan, sc)
u = set_sensitive_regions(wid, sc.n_regions)
return
end
;
pro escan_event, event
;
@scan_include
Widget_Control, event.id, get_uval = uval
if (strupcase(strtrim(sc.type,2)) eq 'EXAFS') then begin
scan_type = 1
wid = (*p).escan
endif else begin
scan_type = 0
wid = (*p).mscan
endelse
print, 'escan_event uval = ', uval
case uval of
'exit': Widget_Control, event.top, /destroy
'save_params': retval = (*p).es->save_paramfile(/use_dialog)
'saveas_params': retval = (*p).es->save_paramfile(/use_dialog)
'read_params': begin
retval = (*p).es->read_paramfile(/use_dialog)
escan_fill_screen, p
end
'data_file_name': begin
Widget_Control, (*p).form.data_file_name, get_value = t
t = strtrim(t[0],2)
x = (*p).es->set_param('datafile',t)
end
'define_dets': begin
r = define_detectors(p)
d = (*p).es->get_param('detectors')
t = ['','']
for i = 0, n_elements(d.countPV)- 1 do begin
if (strpos(d.countPV[i],'scaler') ne -1) then t[0]= 'scaler1.CNT'
if (strpos(d.countPV[i],'med') ne -1) then t[1]= 'med:Start.VAL'
endfor
x = (*p).es->set_param('triggers',t)
end
'define_mots': begin
motor = (*p).es->get_param('motors')
end
'setup': begin
; print , ' setup '
r = define_scan(p)
end
'scan_type': begin
if (event.index eq 0) then begin
Widget_Control, (*p).form.nb[1], map=0
Widget_Control, (*p).form.nb[0], map=1
Widget_Control, (*p).mscan.motor, set_DROPLIST_SELECT = sc.drives[0]
wid = (*p).mscan
sc.type = 'Motor'
endif else begin
Widget_Control, (*p).form.nb[0], map=0
Widget_Control, (*p).form.nb[1], map=1
Widget_Control, (*p).escan.e0, set_value = f2a(sc.params[0])
wid = (*p).escan
sc.type = 'EXAFS'
endelse
u = set_sensitive_regions(wid, sc.n_regions)
Widget_Control, wid.nregs, set_value = f2a(sc.n_regions)
Widget_Control, wid.is_rel, set_DROPLIST_SELECT = sc.is_rel
u = (*p).es->set_param(_scan, sc)
for i = 0, 2 do begin
sc = update_scan_settings(wid, sc, i)
endfor
end
'scan_dim': begin
; print, " SCAN_DIM event: ", event.index + 1
u = (*p).es->set_param('dimension', event.index+1)
end
'scan_num': begin
current_scan = event.index + 1
x = (*p).es->set_param('current_scan', current_scan)
_scan = 'scan' + string(strtrim(current_scan,2))
sc = (*p).es->get_param(_scan)
motor = (*p).es->get_motor(sc.drives[0])
motor.curpos = (*p).es->get_motor_position(sc.drives[0])
pv = motor.pv
il = strlen(pv)
if (strupcase(strmid(pv,il-4,4)) eq '.VAL') then pv = strmid(pv,0,il-4)
scan_type = 0
wid = (*p).mscan
if (strupcase(strtrim(sc.type,2)) eq 'EXAFS') then begin
scan_type = 1
wid = (*p).escan
endif
Widget_Control, (*p).form.nb[0], map=0
Widget_Control, (*p).form.nb[1], map=0
Widget_Control, (*p).form.nb[scan_type], map=1
Widget_Control, (*p).form.scan_type, set_DROPLIST_SELECT = scan_type
Widget_Control, wid.nregs, set_value = f2a(sc.n_regions)
Widget_Control, wid.is_rel, set_DROPLIST_SELECT = sc.is_rel
for i = 0, 2 do begin
sc = update_scan_settings(wid, sc, i)
endfor
if (scan_type eq 0) then begin
Widget_Control, wid.motor, set_DROPLIST_SELECT= sc.drives[0]
Widget_Control, wid.is_rel, set_DROPLIST_SELECT= sc.is_rel
Widget_Control, wid.cur_pos, set_value= f2a(motor.curpos)
Widget_Control, wid.hlim, set_value= f2a(motor.hlim)
Widget_Control, wid.llim, set_value= f2a(motor.llim)
endif else begin
Widget_Control, wid.e0, set_value = f2a(sc.params[0])
endelse
u = set_sensitive_regions(wid, sc.n_regions)
end
'load': begin
x = (*p).es->load_to_crate()
sc = (*p).es->get_param(_scan)
dim = (*p).es->get_param('dimension')
tx = fltarr(3)
np = intarr(3)+1
for i = 0, dim-1 do begin
x = (*p).es->get_param('scan'+string(i+1,format='(i1.1)'))
tx(i) = x.time_est
np(i) = x.npts_total
endfor
total_time = tx(2) + np(2) * ( tx(1) + np(1) * tx(0) )
; print, ' total_time = ', total_time
widget_control, (*p).form.time_est, set_value = sec2hms(total_time)
x = (*p).es->set_param('total_time',total_time)
end
'scan_view': begin
x = scan_viewer( (*p).es )
end
else: print , ' unknown event ', uval
endcase
return
end
;
;------------------------------------------------------------------
pro escan, scan_file=scan_file
;
;
N_SCAN_TYPES = 2
N_REG = 5
scan_types = ['Motor', 'EXAFS']
scan_nums = ['Scan 1', 'Scan 2', 'Scan 3']
rel_choices = ['Absolute', 'Relative']
scan_dims = ['1', '2', '3']
cur_dim = 0
;
; define and setup epics_scan object
s_file = 'default.scn'
if (keyword_set(scan_file) ne 0 ) then s_file = scan_file
es = obj_new('epics_scan', scan_file = s_file)
datafile = es->get_param('datafile')
motor = es->get_param('motors')
det = es->get_param('detectors')
cur_scan = es->get_param('current_scan')
sc = es->get_param('scan' + string(strtrim(cur_scan, 2)))
cur_scan = cur_scan - 1
m_names = motor.name
drives = es->get_scan_param(cur_scan, 'drives')
imot = drives[0]
_motor = es->get_motor(imot)
; if (imot eq motor.e_drive) then print, " driving Energy!!"
_energy = es->get_motor(motor.e_drive)
cur_type = 0
cx_type = es->get_scan_param(0, 'type')
if (cx_type eq scan_types[1]) then cur_type = 1
; print, ' scan type: ', cx_type , ' scan_types[1] = ', scan_types[1], cur_type
;--------------------------------------------------------------------------------
; nbframe holds the frame ids for the 2 'notebook frames'
nb = lonarr(N_SCAN_TYPES)
arr0 = lonarr(N_REG)
form = {scan_num:scan_nums[0], data_file_name:0L, time_est:0L, $
scan_type:scan_types[0], scan_dim:scan_dims[0], $
cur_dim:1L, nb:nb}
mscan = {motor:m_names[0], cur_pos:0L, llim:0L, hlim:0L, e0:0L,$
nregs:1L, is_rel:rel_choices[1], units:arr0, $
start:arr0, stop:arr0, step:arr0, npts:arr0, time:arr0}
escan = {e0:0L, cur_pos:0L, motor:0L, llim:0L, hlim:0L, $
nregs:3L, is_rel:rel_choices[1], units:arr0, $
start:arr0, stop:arr0, step:arr0, npts:arr0, time:arr0 }
info = {es:es, form:form, mscan:mscan, escan:escan}
;-----------------------
; menus
main = Widget_Base(title = 'Epics Scan Setup', /col, app_mbar = mbar)
Widget_Control, default_font='Fixedsys'
menu = Widget_Button(mbar, value= 'File')
x = Widget_Button(menu, value= 'Read Scan File ...', uval= 'read_params')
x = Widget_Button(menu, value= 'Save Scan File ...', uval= 'save_params')
x = Widget_Button(menu, value= 'Save As ...', uval= 'saveas_params')
x = Widget_Button(menu, value= 'Exit', uval= 'exit', /sep)
menu = Widget_Button(mbar, value= 'Setup')
x = Widget_Button(menu, value= 'General Setup ...', uval= 'setup')
x = Widget_Button(menu, value= 'Define Detectors ...',uval= 'define_dets')
x = Widget_Button(menu, value= 'Define Motors ...', uval= 'define_mots')
menu = Widget_Button(mbar, value= 'Help', /menu, /help)
x = Widget_Button(menu, value= 'Help on EPICS SCAN', uval= 'escan_help')
x = Widget_Button(menu, value= 'Help on IDL', uval= 'IDLhelp')
;-----------------------
mframe = Widget_Base(main, /col)
fr0 = Widget_Base(mframe, /row, /frame)
info.form.scan_num = Widget_Droplist(fr0, value= scan_nums, uval= 'scan_num', $
title = ' ')
info.form.scan_dim = Widget_Droplist(fr0, value= scan_dims, uval= 'scan_dim', $
title = ' of ')
info.form.scan_type= Widget_Droplist(fr0, value= scan_types, uval= 'scan_type', $
title = ' Type ')
Widget_Control, info.form.scan_num, set_Droplist_SELECT = cur_scan
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
Widget_Control, info.form.scan_type, set_Droplist_SELECT = cur_type
x_start = info.es->get_scan_param(0, 'start')
x_stop = info.es->get_scan_param(0, 'stop')
x_step = info.es->get_scan_param(0, 'step')
x_npts = info.es->get_scan_param(0, 'npts')
x_time = info.es->get_scan_param(0, 'time')
info.escan.nregs = info.es->get_scan_param(0, 'n_regions')
;
OptBase = Widget_Base(mframe, /frame)
;-----------------------
; Motor Scan Frame:
info.form.nb[0] = Widget_Base(OptBase, /col, MAP = 0,event_pro='motor_event')
fr01 = Widget_Base(info.form.nb[0], /row)
x = Widget_Label(fr01,xsize=40, value = 'Motor')
info.mscan.motor = Widget_Droplist(fr01, value= m_names, uval= 'motor_name', $
title = ' ')
Widget_Control, info.mscan.motor, set_Droplist_SELECT = imot
info.mscan.nregs = CW_FIELD(fr01, /INTEGER, /ROW, XSIZE = 5, $
title = 'Number of Scan Regions', UVALUE = 'nregs', $
VALUE = f2a(info.mscan.nregs), $
/return_events)
info.mscan.is_rel = Widget_Droplist(fr01, value= rel_choices, uval= 'use_rel', $
title = 'use ')
Widget_Control, info.mscan.is_rel, set_Droplist_SELECT = 1
x = Widget_Label(fr01, xsize=60, value = 'Positions')
fr02 = Widget_Base(info.form.nb[0], /row )
info.mscan.cur_pos = CW_Field(fr02, title = 'Current Position', $
xsize = 11, uval = 'cur_pos', $
value = f2a(_motor.curpos), $
/return_events, /floating)
info.mscan.llim = CW_Field(fr02, title = 'Limits : Low ', $
xsize = 11, uval = 'llim', /noedit, $
value = f2a(_motor.llim), $
/return_events, /floating)
info.mscan.hlim = CW_Field(fr02, title = ' : High ', $
xsize = 11, uval = 'hlim', /noedit, $
value = f2a(_motor.hlim), $
/return_events, /floating)
fr03 = Widget_Base(info.form.nb[0], /col,/frame)
fr04 = Widget_Base(fr03, /row)
X = Widget_Label(fr04, xsize= 50, value = ' Region ' )
X = Widget_Label(fr04, xsize= 90, value = ' Start ' )
X = Widget_Label(fr04, xsize= 90, value = ' Stop ' )
X = Widget_Label(fr04, xsize= 90, value = ' Step ' )
X = Widget_Label(fr04, xsize= 90, value = ' Npts ' )
X = Widget_Label(fr04, xsize= 90, value = ' Time (s)' )
X = Widget_Label(fr04, XSIZE= 90, VALUE = ' Units ' )
reg_title = ['1', '2', '3', '4']
uv_ = ['start', 'stop', 'step', 'npts', 'time']
for i = 0, 2 do begin
fr05 = Widget_Base(fr03, /row)
X = Widget_Label(fr05, XSIZE= 60, VALUE = reg_title[i], /ALIGN_LEFT)
uvs = uv_ + strtrim(string(i),2)
info.mscan.start[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[0], $
value = f2a(x_start[i,0]), $
/return_events, /floating)
info.mscan.stop[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[1], $
value = f2a(x_stop[i,0]), $
/return_events, /floating)
info.mscan.step[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[2], $
value = f2a(x_step[i,0]), $
/return_events, /floating)
info.mscan.npts[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[3], $
value = f2a(x_npts[i]), $
/return_events, /floating)
info.mscan.time[i] = CW_FIELD(fr05, title= ' ', XSIZE = 9, uvalue = uvs[4], $
value = f2a(x_time[i]), $
/return_events, /floating)
info.mscan.units[i] = Widget_Label(fr05, xsize=80, uval = 'units', $
value= strtrim(_motor.units,2) )
endfor
;
;-----------------------
; EXAFS Scan Frame:
info.form.nb[1] = Widget_Base(OptBase, /col, MAP = 0,event_pro='exafs_event')
fr11 = Widget_Base(info.form.nb[1], /row)
x = Widget_Label(fr11, xsize=40, value = ' EXAFS ')
info.escan.e0 = CW_FIELD(fr11, /FLOATING, /ROW, XSIZE = 9, $
TITLE = ' E0', UVALUE = 'e0', $
VALUE = f2a(info.escan.e0), $
/return_events)
info.escan.nregs = CW_FIELD(fr11, /INTEGER, /ROW, XSIZE = 5, $
TITLE = ' Number of Scan Regions', UVALUE = 'nregs', $
VALUE = f2a(info.escan.nregs), $
/return_events)
info.escan.is_rel = Widget_Droplist(fr11, title = 'use ', $
value = Rel_choices, uval = 'use_rel')
Widget_Control, info.escan.is_rel, set_Droplist_SELECT = 1
x = Widget_Label(fr11, xsize=60, value = 'Energies')
fr12 = Widget_Base(info.form.nb[1], /row )
; info.escan.cur_pos = CW_Field(fr12, title = 'Current Energy', $
; xsize = 12, uval = 'cur_pos', $
; value = f2a(_energy.curpos), $
; /return_events, /floating)
fr12 = Widget_Base(info.form.nb[1], /row)
fr13 = Widget_Base(info.form.nb[1], /col,/frame)
fr14 = Widget_Base(fr13, /row)
X = Widget_Label(fr14, XSIZE= 50, VALUE = 'Region ' )
X = Widget_Label(fr14, XSIZE= 90, VALUE = ' Start ' )
X = Widget_Label(fr14, XSIZE= 90, VALUE = ' Stop ' )
X = Widget_Label(fr14, XSIZE= 90, VALUE = ' Step ' )
X = Widget_Label(fr14, XSIZE= 90, VALUE = ' Npts ' )
X = Widget_Label(fr14, XSIZE= 90, VALUE = ' Time (s)')
X = Widget_Label(fr14, XSIZE= 90, VALUE = ' Units ' )
etitle = ['Pre-Edge', 'XANES', 'EXAFS', 'EXTRA']
k_spaces = ['eV', STRING(197B)+'^(-1)']
uv_ = ['start', 'stop', 'step', 'npts', 'time','units']
for i = 0, 2 do begin
fr15 = Widget_Base(fr13, /row)
X = Widget_Label(fr15, XSIZE= 60, VALUE = etitle[i], /ALIGN_LEFT)
uvs = uv_ + strtrim(string(i),2)
info.escan.start[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[0], $
value = f2a(x_start[i,0]), $
/return_events, /floating)
info.escan.stop[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[1], $
value = f2a(x_stop[i,0]), $
/return_events, /floating)
info.escan.step[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[2], $
value = f2a(x_step[i,0]), $
/return_events, /floating)
info.escan.npts[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[3], $
value = f2a(x_npts[i]), $
/return_events, /floating)
info.escan.time[i] = CW_FIELD(fr15, title= ' ', XSIZE = 9, uvalue = uvs[4], $
value = f2a(x_time[i]), $
/return_events, /floating)
if (i le 1) then begin
X = Widget_Label(fr15, XSIZE= 30, VALUE = 'eV', /ALIGN_LEFT)
info.escan.units[i] = Widget_Base(fr15, /row, Map = 0)
endif else begin
info.escan.units[i] = Widget_Droplist(fr15, value = k_spaces, $
uvalue = uvs[5], title = ' ')
ch = es->get_scan_param(0, 'is_kspace')
Widget_Control, info.escan.units[i], SET_DROPLIST_SELECT = ch[i]
endelse
endfor
; map the current scan type!
Widget_Control, info.form.nb[cur_type], map=1
Widget_Control, info.escan.e0, set_value = f2a(x[0])
u = set_sensitive_regions(info.mscan,sc.n_regions)
u = set_sensitive_regions(info.escan,sc.n_regions)
;-----------------------
; Bottom Frame:
base1 = Widget_Base(mframe, /col, /frame)
base2 = Widget_Base(base1,/row)
X = Widget_Button(base2, value = 'Load Scan', uval='load')
X = Widget_Button(base2, value = 'Scan Viewer', uval='scan_view')
X = Widget_Button(base2, value = 'EXIT ', uval='exit')
X = Widget_Label(base2, value = 'Estimated time:')
info.form.time_est = Widget_Label(base2, xsize=190,value = ' ')
; render widgets, load info structure into main
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uval=p_info
Widget_Control, main, /realize
xmanager, 'escan', main, /no_block
return
end
escan/f2a.pro 0100644 0000621 0000620 00000000122 07237637100 012321 0 ustar epics epics function f2a, x
; floating point to string
y = strtrim(string(x),2)
return, y
end
escan/get_detnam.pro 0100644 0000621 0000620 00000005361 07237637100 013772 0 ustar epics epics function get_detnam, prefix=prefix, type=type, elem=elem,roi=roi,$
net=net
;
; given a detector type ('scaler', 'med:mca', or 'aim_adc'), an element #
; ( '1' for scaler1 or aim_adc1, or the med channel), and an roi (scaler
; channel or aim_adc or med ROI),
; return a structure with
; countPV: PV to count
; descPV: PV for description
; desc: brief description field 'Mn Ka'
; full_desc: full description field 'mca6: Mn Ka'
;
; notes:
; 1 for all detectors, rois start at 0, even though scaler PV
; names really start with 1. That is
; type= scaler, elem=1, roi=0
; will yield
; 13IDC:scaler1.S1
; 2 net will get the 'net' version of the detector:
; XXXyyy.R3N for aim_adc and med:mca (roi 3)
; XXXscaler1_calc3.VAL for scaler (elem 1, roi 2)
;---------------------------------------------------------------
pre_ = '13IDC:'
type_ = ''
elem_ = 1
roi_ = 0
net_ = 0
if (keyword_set(prefix) ne 0) then pre_ = prefix
if (keyword_set(type) ne 0) then type_ = type
if (keyword_set(elem) ne 0) then elem_ = elem
if (keyword_set(roi) ne 0) then roi_ = roi
if (keyword_set(net) ne 0) then net_ = net
out = {desc:'', full_desc:'', descPV:'', countPV:''}
s_elem = strtrim(string(elem_,format='(i1.1)'),2)
if (elem_ gt 9) then s_elem = strtrim(string(elem_,format='(i2.2)'),2)
pref = pre_
; pref = pre_ + type_ + s_elem
; _now_ (and only after pref is made!) rewrite type_ to make all mca-like
; detectors look the same
if ((type_ eq 'aim_adc') or (type_ eq 'med:mca')) then type_ = 'mca'
; print, ' GET_DETNAM: ', pre_ , ' :: ', type_ , '::', s_elem, roi, net_
case type_ of
'scaler': begin
s_roi = strtrim(string(roi_ + 1,format='(i1.1)'),2)
if (roi_ ge 9) then s_roi = strtrim(string(roi_+1 ,format='(i2.2)'),2)
out.descPV = pref + '.NM' + s_roi
out.countPV = pref + '.S' + s_roi
if (net_ eq 1) then out.countPV = pref + '_calc' + s_roi + '.VAL'
end
'mca': begin
s_roi = strtrim(string(roi_ ,format='(i1.1)'),2)
if (roi_ gt 9) then s_roi = strtrim(string(roi_ ,format='(i2.2)'),2)
out.descPV = pref + 'mca' + s_elem + '.R' + s_roi + 'NM'
out.countPV = pref + 'mca' + s_elem + '.R' + s_roi
if (net_ eq 1) then out.countPV = out.countPV + 'N'
end
endcase
; look up description
; print, ' OUT : ', out.descPV
if (out.descPV ne '') then begin
x = 'not available'
y = caget(out.descPV, x)
out.desc = x
endif
; full description
out.full_desc = out.desc
if (type_ eq 'mca') then out.full_desc = 'mca '+s_elem+': '+out.desc
; print, ' GETDETNAM : ', out.countPV, ' OUT : ', out.descPV, ' : ', out.desc
return, out
end
escan/increment_scanname.pro 0100644 0000621 0000620 00000003636 07237637100 015517 0 ustar epics epics function increment_scanname, inpfile
;
; increment a scan data file name
; strategy: uses getfilename()
; first see if a number is before '.'. if so, increment it.
; second look for number in the prefix. if so, increment it.
; lastly, insert a '_001' before the '.', preserving suffix.
;
; note: the numerical part of the file name will contain
; at least three digits.
; examples:
; increment_scanname('a.dat') -> 'a.dat.001'
; increment_scanname('a_001.dat') -> 'a_002.dat'
; increment_scanname('a.001') -> 'a.002'
; increment_scanname('a_102031.dat') -> 'a_103.dat' !!!
; increment_scanname('a_6.dat') -> 'a_007.dat'
; increment_scanname('a_001.002') -> 'a_001.003'
; increment_scanname('path/a.001') -> 'path/a.002'
; increment_scanname('/path/a.001') -> '/path/a.002'
;
; (note the fortran-ish and suffix-preserving behavior!)
;
; M Newville 24 Jan 2000 / 14 Jun 2000
;
outfile = ''
f = getfilename(inpfile)
x = strtrim(f.suffix, 2)
nsuffix = strpos(f.name, f.suffix)
prefix = strmid(f.name, 0, nsuffix-1)
; help, f, /struct
; print, " : ", x, nsuffix, " ", prefix
on_ioerror, non_numeric
i = fix(x) + 1
n = strlen(strtrim(string(i),2)) > 3
n = strtrim(string(n),2)
outfile = f.path + '/' + prefix + '.' + string(i,format='(i'+n+'.'+n+')')
goto, done
non_numeric:
if (outfile eq '') and (f.number ne -1) then begin
i = f.number + 1
n = strlen(strtrim(string(i),2)) > 3
n = strtrim(string(n),2)
m = string(i,format='(i'+n+'.'+n+')')
suffix = '.' + f.suffix
outfile = f.namestem + m + suffix
endif
if ((outfile eq '') or (strlen(f.namestem) lt strlen(f.path))) then begin
outfile = f.path + '/' + f.name + '.001'
endif
done:
; print, ' O2 = ' , outfile, ' n = ', n, i
; print, f
if ((strmid(outfile,0,1) eq '/') and $
(strmid(inpfile,0,1) ne '/') ) then outfile = strmid(outfile,1)
return, outfile
end
escan/list_detectors.pro 0100664 0000621 0000620 00000000426 07316224456 014715 0 ustar epics epics function list_detectors, d, M
;
l = strarr(M)
j = -1
for i = 0, n_elements(d.desc) - 1 do begin
if (d.desc[i] ne '') then begin
j = j + 1
l[j] = d.desc[i]
endif
endfor
out = strarr(j+1)
for i = 0, j do begin
out[i] = l[i]
endfor
return, out
end
escan/map_viewer.pro 0100644 0000621 0000620 00000007610 07332624552 014023 0 ustar epics epics pro v_map, file=file, da=da, x=x, y=y, npts=npts, npos=npos, $
ndet=ndet, nx=nx,ny=ny
@scan_dims
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
;
if (keyword_set(help) ne 0) then begin
print, 'Read_escan: Read data file from escan'
print, ' argument meaning '
print, ' file input file name '
print, ' x positioner array(s) for column fltarr(nx,npos)'
print, ' y positioner array for row'
print, ' da detector array [ fltarr([nx,ny,ndet)]'
print, ' npts number of data points in Scan'
print, ' npos number of positioners in Scan'
print, ' ndet number of detectors in Scan'
print, ' /help print this help message'
return
endif
;
if (n_elements(file) eq 0) then begin
print, 'read_sscan, file=file, da=da, pa=pa, npts=npts'
print, ' type read_sscan, /help for more details'
return
endif
str = '; '
print, format='(a,$)', 'opening file ...'
openr, lun, file, /get_lun
print, format='(a,$)', ' allocating memory ...'
MDIM = 500
tmp_x = fltarr(MDIM, MAX_POS)
tmp_det = fltarr(MDIM, MDIM, MAX_DET)
vars = fltarr(MAX_POS+MAX_DET)
tmp_y = fltarr(MDIM)
npts = -1
nrow = -1
npos = 4
ndet = MAX_DET
first_line = 1
ncols = 1
nline = 1
read_labels= 1
print, 'reading ...'
while not (eof(lun)) do begin
readf,lun,str
nline = nline + 1
string = strtrim(str,2)
if (strlen(string) gt 1) then begin
char1 = strmid(string, 0, 1)
if ((char1 ne ';') and (read_labels eq 0)) then begin
; read data
npts = npts + 1
reads, string, vars
if (nrow eq 0) then tmp_x[npts, 0:npos-1] = vars[0:npos-1]
tmp_det[npts, nrow, 0:ndet-1] = vars[npos:npos+ndet-1]
endif else begin
if (first_line eq 1) then begin
stmp = strmid(string, 0, 12)
s2 = strmid(string, 12, 13)
sx = str_sep(strtrim(s2,2), ' ')
if (((sx[0] ne '2') and (sx[0] ne '3')) or $
(stmp ne '; Epics Scan')) then begin
print, ' Not a 2d scan file! '
goto, endread
endif
first_line = 0
endif
char1 = strmid(string, 0, 1)
char3 = strmid(string, 0, 3)
char8 = strmid(strtrim(string,2) , 0,8)
if (char3 eq ';2D') then begin
nrow = nrow + 1
if ((nrow gt 5) and ( ((nrow) mod 10) eq 0)) then print, ";"
print, format='(a,i3,$)', ' ' , nrow
sc = strmid(string,3, strlen(string))
sx = str_sep(strtrim(sc,2), ' ' )
tmp_y[nrow] = sx[1]
npts_old = npts
npts = -1
endif else if ((read_labels eq 1) and (char8 eq ';-------')) then begin
read_labels = 0
readf,lun,string
label = strmid(strtrim(string,2) , 2,strlen(string))
nline = nline + 1
cols = str_sep(label, ' ')
npos = 0
ndet = 0
for k = 0, n_elements(cols)-1 do begin
if (strmid(strtrim(cols[k],2), 0,1) eq 'P') then npos = npos+1
if (strmid(strtrim(cols[k],2), 0,1) eq 'D') then ndet = ndet+1
endfor
vars = fltarr(npos+ndet)
endif
endelse
endif
endwhile
print, ""
nx = npts
if (nx eq -1) then nx = npts_old
ny = nrow
y = fltarr(ny+1)
da = fltarr(nx+1, ny+1, ndet)
x = fltarr(nx+1, npos)
for i = 0, nx do begin
for k = 0, npos-1 do x(i,k) = tmp_x(i,k)
for j = 0, ny do begin
for k = 0, ndet-1 do da(i,j,k) = tmp_det(i,j,k)
endfor
endfor
for j = 0, ny do y[j] = tmp_y[j]
endread:
close, lun
free_lun, lun
return
end
; ;
escan/meta_detectors.pro 0100644 0000621 0000620 00000023541 07243356626 014675 0 ustar epics epics pro meta_detectors_event, event
MAX_SCA = 10
MAX_MED = 16
MAX_ROI = 10
Widget_Control, event.top, get_uvalue = p
Widget_Control, event.id, get_uvalue = uval
mca = '-1'
elem = '-1'
i = strpos(uval, '.')
if (i gt 1) then begin
elem = strmid(uval,i+1,strlen(uval))
uval = strmid(uval,0,i)
j = strpos(elem,',')
if (j ge 1) then begin
mca = strmid(elem,j+1, strlen(elem))
elem = strmid(elem,0,j)
endif
endif
case uval of
'exit': begin
caSetTimeout, (*p).timeout
caSetRetryCount, (*p).retry
Widget_Control, event.top, /destroy
end
'sca_use_net': (*p).data.sca_use_net = event.index
'med_use_net': (*p).data.med_use_net = event.index
'save': begin
; print, ' saving results: '
widget_control, (*p).form.med_tot, get_value = s_med_tot
widget_control, (*p).form.sca_tot, get_value = s_sca_tot
med_tot = a2f(s_med_tot)
sca_tot = a2f(s_sca_tot)
tot = med_tot + sca_tot
if (tot gt 70) then begin
mes = [' Too Many Detectors Defined. ', ' ', $
' Up to 70 Detectors can be used', ' ', $
' The detector settings have not been saved yet.']
ret = dialog_message(mes)
endif else begin
; scalars
in_use = (*p).data.sca_use
pr = (*p).dgrp.prefix[0]
net = Widget_Info( (*p).form.sca_use_net, /droplist_select)
idet = -1
for is = 0, MAX_SCA - 1 do begin
if (in_use[is] eq 1) then begin
idet = idet + 1
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=is,net=net)
(*p).det.countPV[idet] = x.countPV
(*p).det.desc[idet] = x.full_desc
; print, 'det ', idet, ' is scalar: ' , x.full_desc, ' == ', x.countPV
endif
endfor
; med
in_use = (*p).data.med_use
pr = (*p).dgrp.prefix[1]
net = Widget_Info( (*p).form.med_use_net, /droplist_select)
for ir = 0, MAX_ROI - 1 do begin
for id = 0, MAX_MED - 1 do begin
if (in_use[ir,id] eq 1) then begin
idet = idet + 1
nd = id+1
x = get_detnam(prefix=pr,type='med:mca',elem=nd,roi=ir,net=net)
(*p).det.countPV[idet] = x.countPV
(*p).det.desc[idet] = x.full_desc
; print, 'det ', idet, ' is mca: ' , x.full_desc, ' == ', x.countPV
endif
endfor
endfor
x = (*p).es->set_param('detectors',(*p).det)
endelse
end
'roi_use_all': begin
widget_control, (*p).form.med_tot, get_value = s_med_tot
med_tot = a2f(s_med_tot)
; print, ' roi use all ', elem, ' currently ', med_tot , ' in use '
for i = 0, MAX_MED -1 do begin
Widget_Control, (*p).form.med_use[elem,i], get_value=t
in_use = (*p).data.med_use[elem, i]
if (in_use eq 0) then begin
Widget_Control, (*p).form.med_use[elem,i], set_button=1
med_tot = med_tot + 1
endif
s_med_tot = strtrim(fix(med_tot),2)
widget_control, (*p).form.med_tot, set_value = s_med_tot
endfor
end
'sca': begin
(*p).data.sca_use[elem] = event.select
Widget_Control, (*p).form.sca_tot, get_value=t
ns = a2f(t)
ns = fix(ns + event.select*2 - 1)
Widget_Control, (*p).form.sca_tot, set_value=string(ns)
end
'med': begin
(*p).data.med_use[elem,mca-1] = event.select
Widget_Control, (*p).form.med_tot, get_value=t
ns = a2f(t)
ns = fix(ns + event.select*2 - 1)
Widget_Control, (*p).form.med_tot, set_value=string(ns)
end
else: print, ' unknown event ', uval
endcase
; event.select
return
end
function meta_detectors, p
;
; GUI for selecting detectors by ROI
;
N_MCAS = 30
MAX_SCA = 10
MAX_MED = 16
MAX_ROI = 10
ret = (*p).es->lookup_detectors()
det = (*p).es->get_param('detectors')
det_save = det
MAX_DET = n_elements( det.countPV)
;
mine = Widget_Base(TITLE = 'Define Detectors', /COLUMN, APP_MBAR = menubar)
fileMenu = Widget_Button(menubar, value = 'File')
saveMB = Widget_Button(fileMenu, value = 'Save', uvalue = 'save' )
exitMB = Widget_Button(fileMenu, value = 'Exit', uvalue = 'exit', /sep)
main = Widget_Base(mine, /COLUMN)
TMP = Widget_Base(main, /ROW)
;
; gather all valid detector names (why not??)
;
dgrp = (*p).es->get_param('detgroups')
scanPV = (*p).es->get_scan_param(0,scanPV)
prefix = (*p).es->get_param('prefix')
;
MAX_DTY = n_elements(dgrp.name)
form = {det_choice:0, det_elem:lonarr(MAX_DET), $
det_desc:lonarr(MAX_DET) , use_net: lonarr(MAX_DET), $
sca_tot:0L, sca_use_net:1L, $
med_tot:0L, med_use_net:0L, $
med_use:lonarr(MAX_ROI,MAX_MED), $
sca_use:lonarr(MAX_SCA), $
med_use_all:lonarr(MAX_ROI) }
data = {med_use:lonarr(MAX_ROI, MAX_MED), sca_use:lonarr(MAX_SCA) , $
med_use_net:0, sca_use_net:1 , med_proto:7}
info = {es:(*p).es, form:form, $
det:det, dgrp:dgrp, data:data, $
timeout:0.01, retry:100 ,$
snames:strarr(MAX_SCA) }
info.timeout = caGetTimeout()
info.retry = caGetRetryCount()
t0 = (info.timeout/ 10.) > 0.001
caSetTimeout, t0
caSetRetryCount, 300
net_choices = ['Sum' , 'Net']
Widget_Control, default_font='Fixedsys'
print, ' Detectors: scalers'
;
; Scalers
sframe = Widget_Base(main, /col, /frame)
lf = Widget_Base(sframe, /row)
x = Widget_label(lf, value = ' Scalars: Use ')
info.form.sca_use_net = Widget_DROPLIST(lf, value = net_choices, $
uvalue = 'sca_use_net', /dynamic_resize)
x = Widget_label(lf, value = ' Counts ')
x = Widget_label(lf, value = ' Total Number Used ')
info.form.sca_tot = Widget_Label(lf, value = ' ')
fr0 = Widget_Base(sframe, /row, /nonexclusive)
if ((dgrp.use_det[0] eq 1) and (dgrp.is_mca[0] eq 0)) then begin
pr = dgrp.prefix[0]
for n = 0, MAX_SCA - 1 do begin
uvs = 'sca.' + strtrim(string(n),2)
x = get_detnam(prefix=pr,type='scaler',elem=1,roi=n,net=0)
t = x.desc
if (x.desc eq '') then t = 'UNUSED'
info.form.sca_use[n] = Widget_Button(fr0, Value = t, uvalue = uvs)
info.snames[n] = x.desc
endfor
endif
print, ' Detectors: MCA ' , MAX_ROI
;
; MCA
sframe = Widget_Base(main, /col, /frame)
lf = Widget_Base(sframe, /row)
x = Widget_label(lf, value = ' MED Detector: Use ')
info.form.med_use_net = Widget_DROPLIST(lf, value = net_choices, $
uvalue = 'med_use_net', /dynamic_resize)
x = Widget_label(lf, value = ' Counts ')
x = Widget_label(lf, value = ' Total Number Used ')
info.form.med_tot = Widget_Label(lf, value = ' ')
fr1 = Widget_Base(sframe, /col)
if ((dgrp.use_det[1] eq 1) and (dgrp.is_mca[1] eq 1)) then begin
mp = info.data.med_proto
; print, ' using MCA ', mp, ' as the master '
for nr = 0, MAX_ROI - 1 do begin
fr0 = Widget_Base(fr1, /row)
uvs = 'roi_use_all.' + strtrim(string(nr),2)
pr = dgrp.prefix[1]
x = get_detnam(prefix=pr,type='mca',elem=mp,roi=nr,net=0)
t = x.desc
if (x.desc eq '') then t = 'UNUSED'
x = Widget_Label(fr0, xsize=60, Value = t)
info.form.med_use_all[nr] = Widget_Button(fr0, value = 'Use All', uvalue = uvs)
fr00 = Widget_Base(fr0, /row, /nonexclusive)
for nm = 0, MAX_MED-1 do begin
xim = strtrim(string(nm+1),2)
uvs = 'med.' + strtrim(string(nr),2) + ',' + xim
info.form.med_use[nr,nm] = Widget_Button(fr00, value = xim, uvalue= uvs)
endfor
endfor
endif
print, ' Detectors: defaults'
;
; set defaults by what is actually in use
ns_x = 0
nm_x = 0
medpr = dgrp.prefix[1]
scapr = dgrp.prefix[0]
for i = 0, MAX_DET -1 do begin
if ( det.countPV[i] ne '') then begin
if (strpos(det.countPV[i],'scaler') ge 1) then begin
for n = 0, MAX_SCA -1 do begin
if (det.desc[i] eq info.snames[n]) then begin
ns_x = ns_x + 1
info.data.sca_use[n] = 1
Widget_Control, info.form.sca_use[n] , set_button=1
endif
endfor
endif else if (strpos(det.countPV[i],'mca') ge 1) then begin
for nm = 0, MAX_MED -1 do begin
xdet = medpr + 'mca' + strtrim(string(nm+1),2) + '.R'
for nr = 0, MAX_ROI -1 do begin
d = xdet + strtrim(string(nr),2)
if (det.countPV[i] eq d) then begin
nm_x = nm_x + 1
info.data.med_use[nr,nm] = 1
Widget_Control, info.form.med_use[nr,nm] , set_button=1
endif
endfor
endfor
endif
endif
endfor
widget_control, info.form.sca_tot, set_value = string(ns_x)
widget_control, info.form.med_tot, set_value = string(nm_x)
base2 = Widget_Base(main,/row)
X = Widget_Button(base2, value = 'Save Changes', uval='save')
X = Widget_Button(base2, value = 'Exit', uval='exit')
M_COLS = 4
M_ROWS = (MAX_DET/M_COLS) + 1
net_choices = ['Sum' , 'Net']
Widget_Control, info.form.sca_use_net, set_droplist_select=info.data.sca_use_net
Widget_Control, info.form.med_use_net, set_droplist_select=info.data.med_use_net
i = -1
Grid = Widget_Base(main, /ROW)
tcol = lonarr(M_COLS+1)
form_end:
Widget_Control, mine, /update
p_info = ptr_new(info,/NO_COPY)
Widget_Control, mine, set_uvalue=p_info
Widget_Control, mine, /REALIZE
xmanager, 'meta_detectors', mine, /NO_BLOCK
return, 0
end
escan/multi_2dscan.pro 0100664 0000621 0000620 00000005770 07320174705 014255 0 ustar epics epics pro multi_2dscan, scan_file=scan_file, prefix=prefix, number=number
;
; execute a defined 2dscan
;
s_file = 'default.scn'
if (keyword_set(scan_file) ne 0 ) then s_file = scan_file
es = obj_new('epics_scan', scan_file = s_file)
datafile = 'sr_line.001'
if (keyword_set(prefix) ne 0 ) then datafile = prefix
rep = 3
if (keyword_set(number) ne 0 ) then rep = number
x = es->load_to_crate()
x = es->set_param('datafile', datafile)
x = es->set_param('dimension', 1)
n = caget('13IDC:scan2.NPTS', npts2)
n = caget('13IDC:scan2.P1PA', p1pa)
n = caget('13IDC:scan2.P1PV', p1_drive)
scanPV = '13IDC:scan1'
scan_pause = '13IDC:scanPause.VAL'
for i = 0, npts2 - 1 do begin
print , ' move ' , p1_drive , ' to ', p1pa(i)
s = caput(p1_drive, p1pa(i))
wait, 3.0
for j = 0, rep - 1 do begin
print, ' repeat # ', j, ' datafile = ', datafile
wait, 3.0
lun = es->open_scanfile(/append)
printf, lun, '; Epics Scan 1 dimensional scan'
x = es->start_scan1d()
running = 1
wait, 5.0
while running eq 1 do begin
s = caget('13IDC:scan1.EXSC', running)
c = get_kbrd(0)
c = strlowcase(c)
if ((c eq string(16B)) or (c eq 'p')) then goto, interrupt
wait, 1.0
endwhile
resume:
print, ' scan is finished ! '
x = es->write_scan_data()
x = es->close_scanfile()
datafile = increment_scanname ( datafile )
x = es->set_param('datafile', datafile)
endfor
endfor
;;-----------------------------------;;
;; handle interrupts of scan
time_out:
print, ''
print, 'scan timed-out... cannot get scanning status'
print, 'aborting scan: not writing data file'
s = caput(scan_pause, 0)
if (lun gt 0) then begin
close, lun
free_lun, lun
endif
return
interrupt:
print, ''
print, ' ####################################'
print, ' scan paused by user'
print, ' type r to resume scan'
print, ' type a to abort scan'
print, ' type f to finish this scan, but not start any more'
print, ' (for multiple or multi-dimensional scans) '
print, ' ####################################'
s = caput(scan_pause, 1)
interrupt_2:
c = get_kbrd(1)
c = strlowcase(c)
case c of
'a': begin
print, 'aborting scan: not writing data file'
s = caput(scanPV+'.EXSC',0)
s = caput(scan_pause, 0)
if (lun gt 0) then begin
close, lun
free_lun, lun
endif
return
end
'r': begin
print, 'resuming scan'
s = caput(scan_pause, 0)
goto, resume
end
'f': begin
print, 'finishing this scan only'
retval = -1
s = caput(scan_pause, 0)
goto, resume
end
else: begin
print, ' scan paused: type r for resume, a for abort, f to finish current scan only'
goto, interrupt_2
end
endcase
;;-----------------------------------;;
return
end
escan/npts_calc.pro 0100644 0000621 0000620 00000000643 07237637100 013627 0 ustar epics epics function npts_calc, start_in, stop_in, step_in, step
@scan_dims
step = step_in
start = start_in
stop = stop_in
if (abs(step) le 1.d-8) then step = (stop - start)/20.0
if (abs(step) le 1.d-8) then begin
step = 1.
npts = 3
endif else begin
npts = 1 + round((abs(stop - start) )/abs(step))
npts = fix ( (npts > 2) < MAX_SCAN_POINTS)
step = (stop - start) / (npts-1)
endelse
return, npts
end
escan/pparse_head.pro 0100644 0000621 0000620 00000007467 07314222474 014147 0 ustar epics epics pro read_file, file=file
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
M_GROUPS = 50
M_DETECTORS = 20
;
if (n_elements(file) eq 0) then begin
print, 'read_file, file=file'
return
endif
str = '; '
do_parsing = 0
nline = 0
group_name = strarr(M_GROUPS)
detectors = intarr(M_GROUPS,M_DETECTORS)
intlist = intarr(M_DETECTORS)
group_list = strarr(M_GROUPS)
Det_String = strarr(m_groups)
openr, lun, file, /get_lun
while not (eof(lun)) do begin
readf,lun,str
nline = nline + 1
string= strtrim(str,2)
char1 = strmid(string, 0, 1)
char3 = strmid(string, 0, 3)
char8 = strmid(strtrim(string,2) , 0,8)
if (strlen(string) le 1) then goto, nextline
if (char8 eq ';-------') then begin
goto, endread
endif else if (char8 eq ';=======') then begin
do_parsing = 1
endif else if ( do_parsing eq 1) then begin
if (char3 ne '; D') then goto, nextline
slen = strlen(string) - 1
clast = strmid(string, slen, slen)
if (clast eq 'N') then begin
roi = strmid(string, slen-2, slen-1)
endif else begin
roi = strmid(string, slen-1, slen)
endelse
ds = strmid(string, 3, 2)
; print, roi, ds
for i = 0, m_groups - 1 do begin
if det_string[i] eq '' then begin
; print, ' New det = ', roi, i
det_string[i]=roi
group_list[i]=ds
i1 = strpos(string, '{')
i2 = strpos(string, '}')
group_name[i]=strmid(string, i1+1, i2-i1-1)
goto, nextline
endif else if(det_string[i] eq roi) then begin
group_list[i] = group_list[i] + ' ' + ds
goto, nextline
endif
endfor
endif
nextline:
endwhile
endread:
close, lun
free_lun, lun
read_escan2d, file=file, da=da, x=x,y=y
print, " "
print, 'Enter desired output format'
print, '1 map'
print, '2 plot'
read, output
print, " "
print, " Available Groups:"
print, "------------------"
for i = 0, m_groups - 1 do begin
if group_name[i] ne '' then begin
length = string_array(group_list[i], intlist)
for j = 0, length-1 do detectors[i,j] = intlist[j]
print, i+1 , ' ', group_name[i], ' > ', intlist
endif
endfor
print, ' '
if output eq '1' then begin
print, ' Select Group to Map:'
read, i_user
ix = i_user - 1
print, ' you picked: ', group_name[ix]
print, ' Do you want to normalize by i0? (Y/N) [Y]'
norm_ans= 'Y'
read, ans
norm_ans = strupcase(ans)
map = da(*,*,detectors[ix,0]-1)
print, ' start with ', detectors[ix,0]
for i = 1, m_detectors-1 do begin
if (detectors[ix,i] ne 0) then begin
print, ' add ', detectors[ix,i]
map = map + da(*,*,detectors[ix,i]-1)
endif
endfor
if norm_ans eq 'Y' then begin
map = map / da(*,*,detectors[0,0]-1)
endif
image_display, map, ydist=y,xdist=x(*,0)
endif else if output eq '2' then begin
print, 'Select 2 groups to plot (y axis, x axis)'
read, i_user1, i_user2
iy = i_user1 - 1
ix = i_user2 - 1
print, 'You Selected ', group_name[iy], ' and ', group_name[ix]
map1 = da(*,*,detectors[ix,0]-1)
map2 = da(*,*,detectors[iy,0]-1)
print, ' start with ', detectors[ix,0]
for i = 1, m_detectors-1 do begin
if (detectors[ix,i] ne 0) then begin
print, ' add ', detectors[ix,i]
map1 = map1 + da(*,*,detectors[ix,i]-1)
endif
if (detectors[iy,i] ne 0) then begin
print, ' add ', detectors[iy,i]
map2 = map2 + da(*,*,detectors[iy,i]-1)
endif
endfor
wset
plot, map1, map2, psym=1, xtitle=group_name[ix], ytitle=group_name[iy]
endif
return
end
;
escan/pscan.pro 0100644 0000621 0000620 00000001745 07237637100 012771 0 ustar epics epics pro scan_me, start=start, stop=stop,step=step, file=file
drive = '13LAB:m1.VAL'
read = '13LAB:m1.RBV'
det = ['13LAB:LAE500_Z', '13LAB:LAE500_X']
wait_time = 0.10
n_det = 2
pos = fltarr(1000)
det = fltarr(1000,4)
if (keyword_set(step) eq 0) then step = 0.1
if (keyword_set(start) eq 0) then start = 0
if (keyword_set(stop) eq 0) then stop = 1
if (keyword_set(file) eq 0) then file = 'scan.dat'
npts = 1 + fix((start -stop)/step)
for i = 0, npts -1 do begin
pos[i] = start + i * step
endfor
openw, lun, file, /get_lun, /append
printf, lun, '; Simple scan file '
printf, lun, '; '
for i = 0, npts-1 do begin
x = caput(drive,pos[i])
motor_move = 1
while(motor_move) do begin
wait, wait_time
x = caget('13LAB:m1.DMOV',motor_move)
endwhile
wait, wait_time
x = caget(rbv,mpos)
x = caget(det[0], d1)
x = caget(det[1], d2)
printf, lun, format='(3(1x,g14.7))', mpos, d1, d2
endfor
close, lun
free_lun, lun
return
end
escan/read_escan2d.pro 0100644 0000621 0000620 00000007634 07333545625 014211 0 ustar epics epics pro read_escan2d, file=file, da=da, x=x, y=y, npts=npts, npos=npos, $
ndet=ndet, nx=nx,ny=ny, help=help
@scan_dims
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
;
if (keyword_set(help) ne 0) then begin
print, 'Read_escan2d: Read data file from escan'
print, ' argument meaning '
print, ' file input file name '
print, ' x positioner array(s) for column fltarr(nx,npos)'
print, ' y positioner array for row'
print, ' da detector array [ fltarr([nx,ny,ndet)]'
print, ' npts number of data points in Scan'
print, ' npos number of positioners in Scan'
print, ' ndet number of detectors in Scan'
print, ' /help print this help message'
return
endif
;
if (n_elements(file) eq 0) then begin
print, 'read_sscan, file=file, da=da, pa=pa, npts=npts'
print, ' type read_sscan, /help for more details'
return
endif
str = '; '
print, format='(a,$)', 'opening file ...'
openr, lun, file, /get_lun
print, format='(a,$)', ' allocating memory ...'
MDIM = 500
tmp_x = fltarr(MDIM, MAX_POS)
tmp_det = fltarr(MDIM, MDIM, MAX_DET)
vars = fltarr(MAX_POS+MAX_DET)
tmp_y = fltarr(MDIM)
npts = -1
nrow = -1
npos = 4
ndet = MAX_DET
first_line = 1
ncols = 1
nline = 1
read_labels= 1
print, 'reading ...'
while not (eof(lun)) do begin
readf,lun,str
nline = nline + 1
string = strtrim(str,2)
if (strlen(string) gt 1) then begin
char1 = strmid(string, 0, 1)
if ((char1 ne ';') and (read_labels eq 0)) then begin
; read data
npts = npts + 1
reads, string, vars
if (nrow eq 0) then tmp_x[npts, 0:npos-1] = vars[0:npos-1]
tmp_det[npts, nrow, 0:ndet-1] = vars[npos:npos+ndet-1]
endif else begin
if (first_line eq 1) then begin
stmp = strmid(string, 0, 12)
s2 = strmid(string, 12, 13)
sx = str_sep(strtrim(s2,2), ' ')
if (((sx[0] ne '2') and (sx[0] ne '3')) or $
(stmp ne '; Epics Scan')) then begin
print, ' Not a 2d scan file! '
goto, endread
endif
first_line = 0
endif
char1 = strmid(string, 0, 1)
char3 = strmid(string, 0, 3)
char8 = strmid(strtrim(string,2) , 0,8)
if (char3 eq ';2D') then begin
nrow = nrow + 1
if ((nrow gt 5) and ( ((nrow) mod 10) eq 0)) then print, ";"
print, format='(a,i3,$)', ' ' , nrow
sc = strmid(string,3, strlen(string))
sx = str_sep(strtrim(sc,2), ' ' )
tmp_y[nrow] = sx[1]
npts_old = npts
npts = -1
endif else if ((read_labels eq 1) and (char8 eq ';-------')) then begin
read_labels = 0
readf,lun,string
label = strmid(strtrim(string,2) , 2,strlen(string))
nline = nline + 1
cols = str_sep(label, ' ')
npos = 0
ndet = 0
for k = 0, n_elements(cols)-1 do begin
if (strmid(strtrim(cols[k],2), 0,1) eq 'P') then npos = npos+1
if (strmid(strtrim(cols[k],2), 0,1) eq 'D') then ndet = ndet+1
endfor
vars = fltarr(npos+ndet)
endif
endelse
endif
endwhile
print, ""
nx = npts
if (nx eq -1) then nx = npts_old
ny = nrow
y = fltarr(ny+1)
da = fltarr(nx+1, ny+1, ndet)
x = fltarr(nx+1, npos)
for i = 0, nx do begin
for k = 0, npos-1 do x(i,k) = tmp_x(i,k)
for j = 0, ny do begin
for k = 0, ndet-1 do da(i,j,k) = tmp_det(i,j,k)
endfor
endfor
for j = 0, ny do y[j] = tmp_y[j]
endread:
close, lun
free_lun, lun
return
end
; ;
escan/read_escan2d_save.pro 0100644 0000621 0000620 00000007453 07332533167 015223 0 ustar epics epics pro read_escan2d, file=file, da=da, x=x, y=y, npts=npts, npos=npos, $
ndet=ndet, nx=nx,ny=ny
@scan_dims
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
;
if (keyword_set(help) ne 0) then begin
print, 'Read_escan: Read data file from escan'
print, ' argument meaning '
print, ' file input file name '
print, ' x positioner array(s) for column fltarr(nx,npos)'
print, ' y positioner array for row'
print, ' da detector array [ fltarr([nx,ny,ndet)]'
print, ' npts number of data points in Scan'
print, ' npos number of positioners in Scan'
print, ' ndet number of detectors in Scan'
print, ' /help print this help message'
return
endif
;
if (n_elements(file) eq 0) then begin
print, 'read_sscan, file=file, da=da, pa=pa, npts=npts'
print, ' type read_sscan, /help for more details'
return
endif
str = '; '
print, format='(a,$)', 'opening file ...'
openr, lun, file, /get_lun
print, format='(a,$)', ' allocating memory ...'
MDIM = 500
tmp_x = fltarr(MDIM, MAX_POS)
tmp_det = fltarr(MDIM, MDIM, MAX_DET)
tmp_y = fltarr(MDIM)
npts = -1
nrow = -1
npos = 4
ndet = MAX_DET
first_line = 1
nline = 1
read_labels= 1
print, 'reading ...'
while not (eof(lun)) do begin
readf,lun,str
nline = nline + 1
string = strtrim(str,2)
if (strlen(string) le 1) then goto, nextline
char1 = strmid(string, 0, 1)
if ((char1 ne ';') and (read_labels eq 0)) then begin
cols = str_sep(strcompress(strtrim(string,2)), ' ')
npts = npts + 1
; print, ' >> ',npts , k, nrow
if (nrow eq 0) then begin
for k = 0, npos - 1 do begin
; print, npts , k
tmp_x[npts, k] = double(strtrim(cols[k],2))
endfor
endif
; print, ' ndet = ', ndet, npts, nrow, npos, nline
for k = 0, ndet - 1 do begin
tmp_det[npts, nrow, k] = double(strtrim(cols[k+npos],2))
endfor
goto, nextline
endif
if (first_line eq 1) then begin
stmp = strmid(string, 0, 12)
s2 = strmid(string, 12, 13)
sx = str_sep(strtrim(s2,2), ' ')
if (((sx[0] ne '2') and (sx[0] ne '3')) or $
(stmp ne '; Epics Scan')) then begin
print, ' Not a 2d scan file! '
goto, endread
endif
first_line = 0
endif
char1 = strmid(string, 0, 1)
char3 = strmid(string, 0, 3)
char8 = strmid(strtrim(string,2) , 0,8)
if (char3 eq ';2D') then begin
nrow = nrow + 1
if ((nrow gt 5) and ( ((nrow) mod 10) eq 0)) then print, ";"
print, format='(a,i3,$)', ' ' , nrow
sc = strmid(string,3, strlen(string))
sx = str_sep(strtrim(sc,2), ' ' )
tmp_y[nrow] = sx[1]
npts_old = npts
npts = -1
endif else if ((read_labels eq 1) and (char8 eq ';-------')) then begin
read_labels = 0
readf,lun,string
label = strmid(strtrim(string,2) , 2,strlen(string))
nline = nline + 1
cols = str_sep(label, ' ')
npos = 0
ndet = 0
for k = 0, n_elements(cols)-1 do begin
if (strmid(strtrim(cols[k],2), 0,1) eq 'P') then npos = npos+1
if (strmid(strtrim(cols[k],2), 0,1) eq 'D') then ndet = ndet+1
endfor
endif
nextline:
endwhile
print, ""
nx = npts
if (nx eq -1) then nx = npts_old
ny = nrow
y = fltarr(ny+1)
da = fltarr(nx+1, ny+1, ndet)
x = fltarr(nx+1, npos)
for i = 0, nx do begin
for k = 0, npos-1 do x(i,k) = tmp_x(i,k)
for j = 0, ny do begin
for k = 0, ndet-1 do da(i,j,k) = tmp_det(i,j,k)
endfor
endfor
for j = 0, ny do y[j] = tmp_y[j]
endread:
close, lun
free_lun, lun
return
end
; ;
escan/read_escan.pro 0100644 0000621 0000620 00000004753 07332567607 013765 0 ustar epics epics pro read_escan, file=file, da=da, pa=pa, npts=npts, npa=npa, nda=nda, help=help
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
@scan_dims
;
if (keyword_set(help) ne 0) then begin
print, 'Read_escan: Read data file from escan'
print, ' argument meaning '
print, ' file input file name '
print, ' pa positioner array [ fltarr([npts,npa]'
print, ' da detector array [ fltarr([npts,nda)]'
print, ' npts number of data points in Scan'
print, ' npa number of positioners in Scan'
print, ' nda number of detectors in Scan'
print, ' /help print this help message'
return
endif
;
if (n_elements(file) eq 0) then begin
print, 'read_sscan, file=file, da=da, pa=pa, npts=npts'
print, ' type read_sscan, /help for more details'
return
endif
on_ioerror, io_problem
str = '; '
openr, lun, file, /get_lun
tmp_pos = fltarr(MAX_SCAN_POINTS,MAX_POS)
tmp_det = fltarr(MAX_SCAN_POINTS,MAX_DET)
npos = MAX_POS
ndet = MAX_DET
vars = fltarr(MAX_POS + MAX_DET)
npts = -1
while not (eof(lun)) do begin
readf,lun,str
string = strtrim(str,2)
if (strlen(string) le 1) then goto, nextline
char1 = strmid(strtrim(string,2) , 0,1)
char_ = strmid(strtrim(string,2) , 0,8)
if ( char_ eq ';-------') then begin
readf,lun,string
label = strmid(strtrim(string,2) , 2,strlen(string))
cols = str_sep(label, ' ')
npos = 0
ndet = 0
for k = 0, n_elements(cols)-1 do begin
if (strmid(strtrim(cols[k],2), 0,1) eq 'P') then npos = npos+1
if (strmid(strtrim(cols[k],2), 0,1) eq 'D') then ndet = ndet+1
endfor
vars = fltarr(npos+ndet)
endif else if ( char1 ne ';') then begin
cols = str_sep(strcompress(strtrim(string,2)), ' ')
npts = npts + 1
; read data
; vars = fltarr(npos+ndet)
reads, str, vars
tmp_pos[npts, 0:npos-1] = vars[0:npos-1]
tmp_det[npts, 0:ndet-1] = vars[npos:npos+ndet-1]
endif
nextline:
endwhile
io_problem:
print, " reads done: npts = ", npts, npos, ndet
close, lun
free_lun, lun
nda = ndet
npa = npos
da = fltarr(npts+1,nda)
pa = fltarr(npts+1,npa)
for i = 0, npts do begin
for j = 0, nda-1 do begin
da(i,j) = tmp_det(i,j)
endfor
endfor
for i = 0, npts do begin
for j = 0, npa-1 do begin
pa(i,j) = tmp_pos(i,j)
endfor
endfor
return
end
;
escan/read_map.pro 0100664 0000621 0000620 00000000116 07333137126 013426 0 ustar epics epics function read_map, file
x = obj_new('scan_data', file = file)
return, x
end
escan/read_scan.pro 0100664 0000621 0000620 00000000117 07333137112 013571 0 ustar epics epics function read_scan, file
x = obj_new('scan_data', file = file)
return, x
end
escan/save_epics_scan.pro 0100755 0000621 0000620 00000000616 07335064346 015016 0 ustar epics epics pro save_epics_scan, prefix, file_name
; This procedure reads data from an EPICS scan record and writes it to a disk file.
scan = obj_new('epics_scan', prefix=prefix)
s = scan->set_param('datafile', file_name)
s = scan->open_scanfile()
; s = scan->lookup_detectors()
; s = scan->lookup_positioners()
s = scan->write_scan_data() ; This calls read_data_from_crate()
s = scan->close_scanfile()
end
escan/scan_3d.pro 0100664 0000621 0000620 00000010727 07333066300 013174 0 ustar epics epics pro scan_3d, scan_file=scan_file, prefix=prefix, zvals=zvals, zpv=zpv
;
; execute a defined 3d scan as a series of 2d scans
; (defined in supplied scanfile) at each element of
; the array zvals for positioner zpv
;
; args:
; scan_file name of epics_scan parameter file for 2d scan
;
;
;
z_vals = [11850, 11865,11870,11920]
if (keyword_set(zvals) ne 0 ) then z_vals = zvals
z_pv = '13IDA:E:Energy'
if (keyword_set(zpos) ne 0 ) then z_pv = zpv
s_file = 'default.scn'
if (keyword_set(scan_file) ne 0 ) then s_file = scan_file
datafile = 'xx_tomo'
if (keyword_set(prefix) ne 0 ) then datafile = prefix
datafile = datafile + '.001'
rep = 1
if (keyword_set(number) ne 0 ) then rep = number
es= obj_new('epics_scan', scan_file = s_file)
x = es->load_to_crate()
print, ' loaded scan to crate'
x = es->set_param('datafile', datafile)
x = es->set_param('dimension', 2)
; sc1 = es->get_param('scan1')
; sc2 = es->get_param('scan2')
n = caget('13IDC:scan2.NPTS', npts2)
n = caget('13IDC:scan2.P1PA', p2a)
n = caget('13IDC:scan2.P1PV', p2_pv)
n = caget('13IDC:scan1.P1PA', p1a)
n = caget('13IDC:scan1.P1PV', p1_pv)
il1 = strlen(p1_pv)
il2 = strlen(p2_pv)
if (strupcase(strmid(p1_pv,il1-4,4)) eq '.VAL') then p1_pv = strmid(p1_pv,0,il1-4)
if (strupcase(strmid(p2_pv,il2-4,4)) eq '.VAL') then p2_pv = strmid(p2_pv,0,il2-4)
scanPV = '13IDC:scan1'
scan_pause = '13IDC:scanPause.VAL'
for i = 0, n_elements(z_vals) - 1 do begin
print , ' move ' , z_pv, ' to ', z_vals(i)
print , ' move ' , p1_pv, ' to ', p1a(i), ' and ' , p2_pv, ' to ', p2a(i)
s = caput(z_pv, z_vals[i])
s = caput(p2_pv + '.VAL', p2a(1))
s = caput(p1_pv + '.VAL', p1a(1))
s = wait_for_motor(motor = p2_pv, maxtrys=300, wait_time=0.1)
s = wait_for_motor(motor = p1_pv, maxtrys=300, wait_time=0.1)
for i2 = 0, npts2 - 1 do begin
s = caput(p2_pv, p2a[i2])
lun = es->open_scanfile(/append)
s = wait_for_motor(motor = p2_pv, maxtrys=300, wait_time=0.1)
wait, 0.5
if (i2 eq 0) then begin
printf, lun, '; Epics Scan 2 dimensional scan'
printf, lun, '; '
printf, lun, ';2D ', p2_pv, ': ', f2a(p2a[i2])
wait, 2.0
x = es->start_scan1d()
endif else begin
printf, lun, ';2D ', p2_pv, ': ', f2a(p2a[i2])
x = es->start_scan1d(/no_header)
endelse
wait, 0.5
running = 1
while running eq 1 do begin
s = caget('13IDC:scan1.EXSC', running)
c = get_kbrd(0)
c = strlowcase(c)
if ((c eq string(16B)) or (c eq 'p')) then goto, interrupt
wait, 1.0
endwhile
resume:
print, ' finished row ', i2+1, ' of ', npts2, ' for datafile = ', datafile
slabs = 0
if (i2 eq 0) then slabs = 1
x = es->write_scan_data(short_labels=slabs)
x = es->close_scanfile()
endfor
datafile = increment_scanname ( datafile )
x = es->set_param('datafile', datafile)
endfor
;;-----------------------------------;;
;; handle interrupts of scan
time_out:
print, ''
print, 'scan timed-out... cannot get scanning status'
print, 'aborting scan: not writing data file'
s = caput(scan_pause, 0)
if (lun gt 0) then begin
close, lun
free_lun, lun
endif
return
interrupt:
print, ''
print, ' ####################################'
print, ' scan paused by user'
print, ' type r to resume scan'
print, ' type a to abort scan'
print, ' type f to finish this scan, but not start any more'
print, ' (for multiple or multi-dimensional scans) '
print, ' ####################################'
s = caput(scan_pause, 1)
interrupt_2:
c = get_kbrd(1)
c = strlowcase(c)
case c of
'a': begin
print, 'aborting scan: not writing data file'
s = caput(scanPV+'.EXSC',0)
s = caput(scan_pause, 0)
if (lun gt 0) then begin
close, lun
free_lun, lun
endif
return
end
'r': begin
print, 'resuming scan'
s = caput(scan_pause, 0)
goto, resume
end
'f': begin
print, 'finishing this scan only'
retval = -1
s = caput(scan_pause, 0)
goto, resume
end
else: begin
print, ' scan paused: type r for resume, a for abort, f to finish current scan only'
goto, interrupt_2
end
endcase
;;-----------------------------------;;
return
end
escan/scan_data__define.pro 0100644 0000621 0000620 00000103647 07340311234 015247 0 ustar epics epics ;
; Scan Data Class: read and manipulate epics scan data and maps
;
; function scan_data::match_detector_name
; function scan_data::get_map
; pro scan_data::show_map
; pro scan_data::show_correl
; function scan_data::get_orig_detector_list
; function scan_data::get_detector_list
; function scan_data::set_detector_list
; pro scan_data::map_all_detectors
; pro scan_data::plot_all_detectors
; function scan_data::get_data
; pro scan_data::plot
; pro scan_data::oplot
; function scan_data::read_data_file
; pro scan_data::set_param
; function scan_data::get_param
; function scan_data::get_dimension
; function scan_data::get_filename
; function scan_data::get_plot_colors
; pro scan_data::set_plot_colors
; function scan_data::get_x
; function scan_data::get_y
; pro scan_data::help
; pro scan_data::show_params
; pro scan_data::show_detectors
; function scan_data::init
function scan_data::match_detector_name, str, strict=strict, show_error=show_error
;+
; NAME: scan_data::match_detector_name
;
; PURPOSE: look up detector group (ie, summed detectors)
; by name (or closest match), return array index
;
; CALLING SEQUENCE: n = scan_data->match_detector_name(string)
;
; INPUTS: str - string to look up as 'detector group name'
;
; KEYWORD PARAMETERS: strict - flag to force exact string match
; show_error - flag to show error messagee on failure
;
; OUTPUTS: integer index in scan_data.sums for detector group
;
; PROCEDURE: the input string is first checked for an exact match with
; the set of detector names in scan_data.det_names. if no
; exact match is found, then the passed string is checked
; for exact match of the first word (blank delimited) of
; each name in scan_data.det_names. finally, if strict=0
; (the default), the first close match is chosen.
;
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; n = d->match_detector_name('Cu')
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
if (n_elements(str) le 0) then begin
print, " match_detector_name error -- no string given"
return, -1
endif
s = strlowcase(str)
n = n_elements(*self.det_names)
; look for exact match
for i = 0, n - 1 do begin
if (s eq strlowcase((*self.det_names)[i])) then return, i
endfor
; inexact match: check first word
for i = 0, n - 1 do begin
sx = str_sep(strlowcase((*self.det_names)[i]), ' ')
if (s eq sx[0]) then return, i
endfor
;
; last resort: check for any similarity
if (keyword_set(strict) eq 0) then begin
for i = 0, n - 1 do begin
j = strpos(strlowcase((*self.det_names)[i]), s)
if (j ge 0) then begin
print, s, ' is sort of like ', (*self.det_names)[i]
return, i
endif
endfor
endif
if (keyword_set(show_error) ne 0) then begin
print, " can't find detector named ", str
print, " available detectors: "
self->show_detectors
endif
return, -1
end
function scan_data::get_map, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm
;+
; NAME: scan_data::get_map
;
; PURPOSE: return map data from scan_data object
;
; CALLING SEQUENCE: map = scan_data->get_map(name=name, index=index,...)
;
; KEYWORD PARAMETERS: name name of detector group to use for map
; index integer index for detector array to use
; use_sum flag to use summed detectors [default]
; use_raw flag to use raw (individual) detectors
; norm norm of detector group for normalization
; inorm index of detector for normalization
;
; OUTPUTS: 2d data for requested map
;
; PROCEDURE: the map requested can be selected by detector name or
; array index. by default, the summed detectors are used,
; and the index would be the element in the summed list.
;
; a map from the raw detectors can also be selected, but
; must be selected by index.
;
; the output map can be normalized by any other map using
; norm or inorm.
;
; the name for detector group (and optional normalization
; map) is found using match_detector_name
;
;
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; map1 = d->get_map(name='Cu')
; map2 = d->get_map(name='As', norm='i0')
; map23 = d->get_map(index=23, /use_raw)
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
stitle = ''
uname = ''
nname = ''
uindex = -1
nindex = -1
usum = 1
do_norm= 0
empty = fltarr(2,2) - 99
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (n_elements(use_sum) ne 0) then usum = 1
if (n_elements(use_raw) ne 0) then usum = 0
if (n_elements(norm) ne 0) then nname = norm
if (n_elements(inorm) ne 0) then nindex=inorm
if (nname ne '') then do_norm = 1
if (nindex ne -1) then do_norm = 2
;
;
if (self.dimension eq 1) then begin
print, ' get_map: not a map file -- try get_data '
return, empty
endif
if ((uname eq '') and (uindex eq -1)) then begin
print, ' get_map: no element index or name given'
return, empty
endif else if (uname ne '') then begin
uindex = self->match_detector_name(uname,/show_error)
if (uindex lt 0) then return, empty
endif
if (usum eq 0) then begin
map = (*self.raw)[*,*,uindex]
stitle = 'Raw Detector ' + strtrim(uindex,2)
endif else if (usum eq 1) then begin
map = (*self.sums)[*,*,uindex]
stitle = (*self.det_names)[uindex]
endif
;
; determine normalization array
if (do_norm eq 1) then begin
nindex = self->match_detector_name(nname, /show_error)
if (nindex lt 0) then return, empty
endif
;
; normalize here
if ((nindex ge 0) and (do_norm ge 1)) then begin
if (usum eq 0) then begin
map = map / (*self.raw)[*,*,nindex]
stitle = stitle + ' / Raw Detector ' + strtrim(nindex,2)
endif else if (usum eq 1) then begin
map = map / (*self.sums)[*,*,nindex]
stitle = stitle + ' / ' + (*self.det_names)[nindex]
endif
endif
self.subtitle = stitle
return, map
end
;;
pro scan_data::show_map, name=name, _extra=extra
;+
; NAME: scan_data::show_map
;
; PURPOSE: display selected map data from scan_data object
;
; CALLING SEQUENCE: scan_data->show_map(name=name, index=index,...)
;
; KEYWORD PARAMETERS: see scan_data::get_map for list
;
; OUTPUTS: none
;
; SIDE EFFECTS: a map image is displayed using image_display
;
; PROCEDURE: see notes in scan_data::get_map -- all keywords are
; the same as for that function
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; d->show_map, name='Cu'
; d->show_map, name='As', norm='i0'
; d->show_map, index=23, /use_raw
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
map = self->get_map(name=name, _extra=extra)
if ((map(0,0) ne -99) or (map(1,0) ne -99) or (n_elements(map) gt 4)) then begin
image_display, map, xdist=(*self.x),ydist=(*self.y),$
title=self.filename, subtitle=self.subtitle
endif
self.subtitle=''
return
end
;;
pro scan_data::dump_ascii, file=file, x=x, y=y, norm=norm, title=title, $
use_raw=use_raw, use_sum=use_sum, cchar=cchar, label=label
; writes out two (or three, if normalized) column ascii file from data
titl = ''
cchr = '#'
if (keyword_set(file) eq 0) then begin
file = self.filename + '.asc'
endif
if (keyword_set(x) eq 0) then begin
x1 = self->get_x()
labl = self.xpos
x1_is_det = 0
endif else begin
x1 = self->get_data(name=x, use_sum=usum)
labl = self.subtitle
x1_is_det = 1
endelse
if (keyword_set(y) eq 0) then begin
print, 'write_ascii: no y array'
return
endif
if (keyword_set(title) ne 0) then titl = title
if (keyword_set(cchar) ne 0) then cchr = cchar
usum = 1
if (keyword_set(use_raw) ne 0) then usum = 0
if (keyword_set(use_sum) ne 0) then usum = 1
x2 = self->get_data(name=y, use_sum=usum)
labl = labl + ' | ' + self.subtitle
use_norm = 0
if (keyword_set(norm) ne 0) then begin
xn = self->get_data(name=norm, use_sum=usum)
x2 = x2/xn
labl = labl + ' | ' + self.subtitle
use_norm = 1
endif
if (keyword_set(label) ne 0) then labl = label
openw, lun, file, /get_lun
if (titl ne '') then printf, lun, cchr, titl
printf, lun, cchr, ' data from ' , self.filename
printf, lun, cchr, '--------------------'
printf, lun, cchr, ' ', labl
nx = n_elements(x1)
if (use_norm eq 1) then begin
for i = 0, nx-1 do begin
printf, lun, format='(1x,f10.4,1x,g15.7,1x,g15.7)' , x1[i], x2[i], xn[i]
endfor
endif else begin
for i = 0, nx-1 do begin
printf, lun, format='(1x,f10.4,1x,g15.7)' , x1[i], x2[i]
endfor
endelse
print, 'wrote ', file
close, lun
free_lun, lun
return
end
pro scan_data::write_correl, x=x, y=y, file=file, cchar=cchar
map1 = self->get_map(name=x, /use_sum)
lab1 = self.subtitle
map2 = self->get_map(name=y, /use_sum)
lab2 = self.subtitle
npts = n_elements(map1)
m1 = reform(map1,1,npts)
m2 = reform(map2,1,npts)
titl = ''
cchr = '#'
labl = lab1 + ' | ' + lab2
if (keyword_set(title) ne 0) then titl = title
if (keyword_set(cchar) ne 0) then cchr = cchar
if (keyword_set(label) ne 0) then labl = label
if (keyword_set(file) eq 0) then file = self.filename + '.cor'
openw, lun, file, /get_lun
if (titl ne '') then printf, lun, cchr, titl
printf, lun, cchr, ' data from ' , self.filename
printf, lun, cchr, '--------------------'
printf, lun, cchr, ' ', labl
for i = 0, npts-1 do begin
printf, lun, format='(1x,g15.7,1x,g15.7)' , m1[0,i], m2[0,i]
endfor
print, 'wrote ', file
close, lun
free_lun, lun
return
end
pro scan_data::show_correl, x=x, y=y, _extra=extra
;+
; NAME: scan_data::show_correl
;
; PURPOSE: plot 2d correlation plot of two named detector groups
;
; CALLING SEQUENCE: scan_data->show_correl(x=x, y=y, ...)
;
; KEYWORD PARAMETERS: x name of detector group to use for x-axis
; y name of detector group to use for y-axis
; additional keywords are sent to IDL's plot command
;
; OUTPUTS: none
;
; SIDE EFFECTS: a 2d correlation plot is displayed
;
; PROCEDURE: this uses only summed detectors given by name
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; d->show_correl, x='Cu', y='Fe'
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
map1 = self->get_map(name=x, /use_sum)
lab1 = self.subtitle
map2 = self->get_map(name=y, /use_sum)
lab2 = self.subtitle
self.subtitle=''
if ((map1(0,0) ne -99) or (map1(1,0) ne -99) or (n_elements(map1) gt 4)) then begin
plot, map1, map2, psym=1, xtitle=lab1, ytitle=lab2, title=self.filename, $
back=set_color('white'), color=set_color('black'), _extra=extra
endif
return
end
;;
function scan_data::get_orig_detector_list, name=name, index=index
;+
; NAME: scan_data::get_orig_detector_list
;
; PURPOSE: return original list of detectors for a named detector groups
;
; CALLING SEQUENCE: s = scan_data->get_orig_detector_list(name=name, index=index)
;
; KEYWORD PARAMETERS: name name of detector group
; index integer index of detector group
;
; OUTPUTS: list of raw detectors assigned to this group when the
; data file was originally read. this list is not altered
; by scan_data::set_detector_list.
;
; SIDE EFFECTS: none.
;
; PROCEDURE: this uses only summed detectors given by name or index
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; o = d->get_orig_detector_list(name='Cu')
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
uname = ''
uindex= -1
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (uindex lt 0) then begin
uindex = self->match_detector_name(uname, /show_error)
endif
if (uindex lt 0) then return, uindex
n = n_elements((*self.det_orig))
tmp = intarr(n) - 1
cnt = 0
for i = 0, n - 1 do begin
if ((*self.det_orig)[i] eq uindex) then begin
tmp[cnt] = i
cnt = cnt + 1
endif
endfor
return, tmp(0:cnt-1)
end
function scan_data::get_detector_list, name=name, index=index
;+
; NAME: scan_data::get_detector_list
;
; PURPOSE: return current list of detectors for a named detector groups
;
; CALLING SEQUENCE: s = scan_data->get_detector_list(name=name, index=index)
;
; KEYWORD PARAMETERS: name name of detector group
; index integer index of detector group
;
; OUTPUTS: list of raw detectors assigned to the specified group.
; this list may be altered by scan_data::set_detector_list.
;
; SIDE EFFECTS: none.
;
; PROCEDURE: this uses only summed detectors given by name or index
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; lis= d->get_detector_list(name='Cu')
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
uname = ''
uindex= -1
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (uindex lt 0) then begin
uindex = self->match_detector_name(uname, /show_error)
endif
if (uindex lt 0) then return, uindex
n = n_elements((*self.det_list))
tmp = intarr(n) - 1
cnt = 0
for i = 0, n - 1 do begin
if ((*self.det_list)[i] eq uindex) then begin
tmp[cnt] = i
cnt = cnt + 1
endif
endfor
return, tmp(0:cnt-1)
end
function scan_data::set_detector_list, name=name, index=index, list=list
;+
; NAME: scan_data::set_detector_list
;
; PURPOSE: overwrite the current list of detectors for a named detector groups
;
; CALLING SEQUENCE: s = scan_data->set_detector_list(name=name, index=index,list=list)
;
; KEYWORD PARAMETERS: name name of detector group
; index integer index of detector group
; list list of integer indices of raw detectors
; for this detector group
;
; OUTPUTS: list of raw detectors assigned to the specified group.
; this list may be altered by scan_data::set_detector_list.
;
; SIDE EFFECTS: the sum for the specified detector group is recomputed.
;
; PROCEDURE: the specified list is used for the sum of grouped detectors.
; if any element in the list is less than 0, that element is ignored
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; old= d->get_detector_list(name='Cu')
; new= old
; new[3] = -1 ; remove detector 3 from the list
; tmp= d->set_detector_list(name='Cu')
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
uname = ''
uindex= -1
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (uindex lt 0) then begin
uindex = self->match_detector_name(uname, /show_error)
endif
if (uindex lt 0) then begin
print, ' set_detector_list : no detector to set'
return, -1
endif else if (n_elements(list) le 0) then begin
print, ' set_detector_list : no detector list given.'
return, -1
endif
n = n_elements((*self.det_list))
print, 'unindex = ', uindex
;
; unset all detector elements for this sum
for j = 0, n - 1 do begin
if ( (*self.det_list)[j] eq uindex ) then (*self.det_list)[j] = -1
endfor
help, (*self.sums), uindex
if (self.dimension eq 1) then begin
(*self.sums)[*,uindex] = 0
endif else begin
(*self.sums)[*,*,uindex] = 0
endelse
for i = 0, n_elements(list) - 1 do begin
j = list[i]
if (j ge 0) then begin
(*self.det_list)[j] = uindex
if (self.dimension eq 1) then begin
(*self.sums)[*,uindex] = (*self.sums)[*,uindex] + (*self.raw)[*,j]
endif else begin
(*self.sums)[*,*,uindex] = (*self.sums)[*,*,uindex] + (*self.raw)[*,*,j]
endelse
endif
endfor
return, list
end
pro scan_data::map_all_detectors, name=name, index=index, _extra=extra
self->plot_all_detectors, name=name, index=index, _extra=extra
return
end
pro scan_data::plot_all_detectors, name=name, index=index, _extra=extra
;
; plot all detectors in a named group
if (n_elements(name) ne 0) then begin
n = self->match_detector_name(name)
if (n ge 0) then name = (*self.det_names)[n]
endif
list = self->get_detector_list(name=name, index=index)
ytitle = 'detectors ' + strtrim(list[0],2) + ':' + strtrim(list[n_elements(list)-1],2)
if (n_elements(name) ne 0) then ytitle = name + ' ( ' + ytitle + ' )'
dim = self.dimension
if (n_elements(list) ge 1) then begin
if (dim eq 1) then begin
ymax = max( (*self.raw)[*,list] )
ymin = min( (*self.raw)[*,list] )
self->plot, index=list[0], /use_raw, $
yrange=[ymin,ymax], ytitle=ytitle, _extra=extra
for i = 1, n_elements(list) - 1 do begin
self->oplot, index=list[i], /use_raw, _extra=extra
endfor
endif else begin
for i = 0, n_elements(list) - 1 do begin
self->show_map, index=list[i], /use_raw, _extra=extra
endfor
endelse
endif
return
end
function scan_data::get_data, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm
empty = fltarr(2)
data = empty
stitle = ''
uname = ''
nname = ''
uindex = -1
nindex = -1
usum = 1
do_norm= 0
is_map = 0
empty = fltarr(2,2) - 99
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (n_elements(use_sum) ne 0) then usum = 1
if (n_elements(use_raw) ne 0) then usum = 0
if (n_elements(norm) ne 0) then nname = norm
if (n_elements(inorm) ne 0) then nindex=inorm
if (nname ne '') then do_norm = 1
if (nindex ne -1) then do_norm = 2
;
;
if (self.dimension eq 2) then begin
print, ' get_data: this is a map file -- getting row 0 (try get_map)!'
is_map = 1
endif
if ((uname eq '') and (uindex eq -1)) then begin
print, ' get_data: no element index or name given'
return, empty
endif else if (uname ne '') then begin
uindex = self->match_detector_name(uname,/show_error)
if (uindex lt 0) then return, empty
endif
if (usum eq 0) then begin
if (is_map eq 1) then begin
data = (*self.raw)[*,0,uindex]
endif else begin
data = (*self.raw)[*,uindex]
endelse
stitle = 'Raw Detector ' + strtrim(uindex,2)
endif else if (usum eq 1) then begin
if (is_map eq 1) then begin
data = (*self.sums)[*,0,uindex]
endif else begin
data = (*self.sums)[*,uindex]
endelse
stitle = (*self.det_names)[uindex]
endif
;
; determine normalization array
if (do_norm eq 1) then begin
nindex = self->match_detector_name(nname, /show_error)
if (nindex lt 0) then return, empty
endif
;
; normalize here
if ((nindex ge 0) and (do_norm ge 1)) then begin
if (usum eq 0) then begin
if (is_map eq 1) then begin
data = data / (*self.raw)[*,0,nindex]
endif else begin
data = data / (*self.raw)[*,nindex]
endelse
stitle = stitle + ' / Raw Detector ' + strtrim(nindex,2)
endif else if (usum eq 1) then begin
if (is_map eq 1) then begin
data = data / (*self.sums)[*,0,nindex]
endif else begin
data = data / (*self.sums)[*,nindex]
endelse
stitle = stitle + ' / ' + (*self.det_names)[nindex]
endif
endif
self.subtitle = stitle
return, data
end
;;
pro scan_data::plot, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm, color=color, psym=psym, bw=bw,$
_extra=extra
ydat = self->get_data(name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm)
lab1 = self.subtitle
self.subtitle=''
ucol = set_color((*self.plot_colors)[0])
usym = 0
if (n_elements(color) ne 0) then ucol = set_color(color)
if (n_elements(psym) ne 0) then usym = psym
if (keyword_set(bw) ne 0) then ucol = set_color('black')
plot, (*self.x), ydat, xtitle=self.xpos, ytitle=lab1, title=self.filename, chars=1.5, thick=2, $
back=set_color('white'), color=set_color('black'), _extra=extra, /nodata
oplot, (*self.x), ydat, psym=usym, color=ucol, _extra=extra
self.nplot = 0
return
end
pro scan_data::oplot, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm, color=color, psym=psym, bw=bw, $
_extra=extra
ydat = self->get_data(name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm)
self.nplot = self.nplot + 1
lab1 = self.subtitle
self.subtitle=''
nc = n_elements((*self.plot_colors))
ucol = set_color((*self.plot_colors)[self.nplot mod nc])
if (keyword_set(bw) ne 0) then begin
ucol = set_color('black')
nc = 1
endif
usym =-self.nplot/nc
if (n_elements(psym) ne 0) then usym = psym
if (n_elements(color) ne 0) then ucol = set_color(color)
oplot, (*self.x), ydat, psym=usym, color=ucol, _extra=extra
return
end
;;
function scan_data::read_data_file, file
; read epics scan data file
@scan_dims
M_GROUPS = 50
MDIM = 500
retval = -1
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
if ((n_elements(file) eq 0) or (keyword_set(help) ne 0)) then begin
print, ' function scan_data::read_data_file(filename)'
return, retval
endif
;
str = '; '
print, format='(3a,$)', 'opening file ', file, ' ... '
openr, lun, file, /get_lun
tmp_x = fltarr(MDIM, MAX_POS)
tmp_det = fltarr(MDIM, MDIM, MAX_DET)
vars = fltarr(MAX_POS+MAX_DET)
tmp_y = fltarr(MDIM)
det_name = strarr(M_GROUPS)
pos_name = strarr(MAX_POS)
ypos = ''
ypv = ''
det_list = intarr(MAX_DET)
group_list = strarr(M_GROUPS)
Det_String = strarr(m_groups)
npts = -1
nrow = -1
ngroups = -1
npos = 0
ndet = 0
first_line = 1
ncols = 1
nline = 1
read_labels= 1
dimen = 2
do_parsing = 0
print, 'reading ...'
while not (eof(lun)) do begin
readf,lun,str
nline = nline + 1
string = strtrim(str,2)
if (strlen(string) gt 1) then begin
char1 = strmid(string, 0, 1)
if ((char1 ne ';') and (read_labels eq 0)) then begin
; read data
npts = npts + 1
reads, string, vars
if (nrow lt 0) then nrow = 0
if (nrow eq 0) then tmp_x[npts, 0:npos-1] = vars[0:npos-1]
tmp_det[npts, nrow, 0:ndet-1] = vars[npos:npos+ndet-1]
endif else begin
if (first_line eq 1) then begin
stmp = strmid(string, 0, 12)
s2 = strmid(string, 12, 13)
sx = str_sep(strtrim(s2,2), ' ')
if (stmp ne '; Epics Scan') then begin
print, ' Not a valid scan file! '
goto, endread
endif
dimen = fix(sx[0])
first_line = 0
endif
char1 = strmid(string, 0, 1)
char3 = strmid(string, 0, 3)
char8 = strmid(strtrim(string,2) , 0,8)
if ((dimen ge 2) and (char3 eq ';2D')) then begin
nrow = nrow + 1
if ((nrow gt 5) and ( ((nrow) mod 10) eq 0)) then print, ";"
print, format='(a,i3,$)', ' ' , nrow
sc = strmid(string,3, strlen(string))
sx = str_sep(strtrim(sc,2), ' ' )
tmp_y[nrow] = sx[1]
npts_old = npts
npts = -1
if (ypv eq '') then begin
n = strpos(string,':', /reverse_search)
ypv = strmid(string,4, n-4)
endif
endif else if (char8 eq ';=======') then begin
; signal to start looking at
do_parsing = 1
endif else if ((read_labels eq 1) and (char8 eq ';-------')) then begin
; read column label: done reading list of pos/det, so declare size of vars here
read_labels = 0
readf,lun,string
vars = fltarr(npos+ndet)
endif else if ( do_parsing eq 1) then begin
; reading list of positioner/detectors for 1d scan
if (char3 eq '; P') then begin
npos = npos + 1
n = -1 + fix(strmid(string,3,3))
i1 = strpos(string, '{')
i2 = strpos(string, '}')
pos_name[n]=strmid(string, i1+1, i2-i1-1)
endif else if (char3 eq '; D') then begin
ndet = ndet + 1
slen = strlen(string) - 1
clast = strmid(string, slen, slen)
if (clast eq 'N') then begin
roi = strmid(string, slen-2, slen-1)
endif else begin
roi = strmid(string, slen-1, slen)
endelse
ds = strmid(string, 3, 2)
; force all non-mca detectors (like, scalars) into individual groups
if (strpos(string,'mca') lt 2) then roi = string
for i = 0, m_groups - 1 do begin
if det_string[i] eq '' then begin
ngroups = i
det_string[i]= roi
group_list[i]= ds
i1 = strpos(string, '{')
i2 = strpos(string, '}')
det_name[i]=strmid(string, i1+1, i2-i1-1)
i1 = strpos(det_name[i], 'mca')
if (i1 ge 0) then begin
i2 = strpos(det_name[i], ':')
il = i1+3 > i2
det_name[i] = strmid(det_name[i],il+1,strlen(det_name[i]))
endif
goto, det_found
endif else if(det_string[i] eq roi) then begin
group_list[i] = group_list[i] + ' ' + ds
goto, det_found
endif
endfor
endif
endif else if ((ypos eq '') and (ypv ne '')) then begin
;
; searching for name of 2D positioner in list of saved values
;
i1 = strpos(string, '(')
i2 = strpos(string, ')')
if (i2 gt i1) then begin
pv =strmid(string, i1+1, i2-i1-1)
if (pv eq ypv) then ypos = strtrim(strmid(string,2,i1-2),2)
endif
endif
endelse
det_found:
endif
endwhile
print, " Available groups from map: ", ngroups
dname = strarr(ngroups+1)
detectors= intarr(MAX_DET) - 1
for i = 0, ngroups do begin
if det_name[i] ne '' then begin
dname[i] = strtrim(det_name[i],2)
g = strtrim(group_list[i],2)
length = string_array(g, det_list)
for j = 0, length-1 do detectors[det_list[j]-1] = i
endif
endfor
; print, ' detector list:'
; for i = 0, MAX_DET -1 do print, i, detectors[i]
nx = npts
if (nx eq -1) then nx = npts_old
ny = nrow
; print, " nx,ny = ", nx, ny, npts , npts_old
y = fltarr(ny+1)
da = fltarr(nx+1, ny+1, ndet)
x = fltarr(nx+1)
for i = 0, nx do begin
for j = 0, ny do begin
for k = 0, ndet-1 do da(i,j,k) = tmp_det(i,j,k)
endfor
endfor
for j = 0, ny do y[j] = tmp_y[j]
for j = 0, nx do x[j] = tmp_x[j,0]
;; for k = 0, npos-1 do x(i,k) = tmp_x(i,k)
sums = fltarr(nx+1,ny+1,ngroups+1)
for i = 0, ngroups do begin
for j = 0, MAX_DET - 1 do begin
if (detectors[j] eq i) then sums(*,*,i) = sums(*,*,i) + da(*,*,j)
endfor
endfor
;
; refom 1d data
if (dimen eq 1) then begin
da = reform(da)
sums= reform(sums)
endif
retval = 0
endread:
close, lun
free_lun, lun
self.dimension = dimen
self.filename = file
self.xpos = pos_name[0]
self.ypos = ypos
self.raw = ptr_new(da)
self.sums = ptr_new(sums)
self.x = ptr_new(x)
self.y = ptr_new(y)
self.det_names = ptr_new(dname)
self.det_list = ptr_new(detectors)
self.det_orig = ptr_new(detectors)
return, retval
end
pro scan_data::set_param, par, val
;
; returns a single attribute of a particular scan
;
is = 0
if (keyword_set(iscan) ne 0) then is = iscan
if (keyword_set(par) ne 0) then begin
case par of
'dimension': self.dimension = val
'filename': self.filename = val
'raw_data': (*self.raw) = val
'sums': (*self.sums) = val
'x': (*self.x) = val
'y': (*self.y) = val
'xpos': self.xpos = val
'ypos': self.ypos = val
'det_names': (*self.det_names) = val
'det_list': (*self.det_list) = val
'plot_colors': (*self.plot_colors) = val
endcase
endif
return
end
function scan_data::get_param, par
;
; return a copy of an object member structure
; for outside manipulation and later 'set_param'ing
val = 0
if (keyword_set(par) ne 0) then begin
case par of
'dimension': val = self.dimension
'filename': val = self.filename
'raw_data': val = (*self.raw)
'sums': val = (*self.sums)
'x': val = (*self.x)
'y': val = (*self.y)
'xpos': val = self.xpos
'ypos': val = self.ypos
'det_names': val = (*self.det_names)
'det_list': val = (*self.det_list)
'det_orig': val = (*self.det_orig)
'plot_colors': val = (*self.plot_colors)
endcase
endif
return, val
end
function scan_data::get_dimension
return, self->get_param('dimension')
end
function scan_data::get_filename
return, self->get_param('filename')
end
function scan_data::get_plot_colors
return, self->get_param('plot_colors')
end
pro scan_data::set_plot_colors, val
self->set_param, 'plot_colors', val
end
function scan_data::get_x
return, self->get_param('x')
end
function scan_data::get_y
return, self->get_param('y')
end
pro scan_data::help
;+
; NAME:
;
;
;
; PURPOSE:
;
;
;
; CALLING SEQUENCE:
;
;
;
; INPUTS:
;
;
;
; OPTIONAL INPUTS:
;
;
;
; KEYWORD PARAMETERS:
;
;
;
; OUTPUTS:
;
;
;
; OPTIONAL OUTPUTS:
;
;
;
; COMMON BLOCKS:
;
;
;
; SIDE EFFECTS:
;
;
;
; RESTRICTIONS:
;
;
;
; PROCEDURE:
;
;
;
; EXAMPLE:
;
;
;
; MODIFICATION HISTORY:
;
;-
print, ' Methods for scan_data class:'
print, ' --------------------------------------------------------'
print, ' function get_map '
print, ' pro show_map '
print, ' pro show_correl '
print, ' pro show_detectors'
print, ' function read_data_file'
print, ' pro help'
print, ' pro set_param'
print, ' function get_param'
print, ' pro show_params'
print, ' function match_detector_name'
print, ' '
self->show_params
return
end
pro scan_data::show_params
;
; list available parameters
;
print, ' Parameters accessible for scan file '
print, ' using get_param / set_param:'
print, ' --------------------------------------------------------'
print, ' name meaning'
print, ' filename scan file name '
print, ' dimension scan dimension'
print, ' raw_data complete set of raw detector data '
print, ' sums summed detectors, grouped by detector element '
print, ' det_names names for summed detector groups'
print, ' det_list 2d integer array list of raw detectors for sums'
print, ' x array of x positions '
print, ' y array of y positions (for 2d scans)'
print, ' xpos name of x positioner'
print, ' ypos name of y positioner (for 2d scans)'
print, ' --------------------------------------------------------'
return
end
pro scan_data::show_detectors
n = n_elements(*self.det_names)
print, format='(a,$)', '[ '
for i = 0, n - 2 do begin
print, format='(a,a,$)', (*self.det_names)[i], ', '
endfor
print, format='(a,a)', (*self.det_names)[n-1], ' ]'
return
end
function scan_data::init, file=file
;
cols = ['blue', 'red', 'black', 'magenta', 'forestgreen']
self.plot_colors = ptr_new(cols)
if (n_elements(file) ne 0) then begin
u = self->read_data_file(file)
if (u eq 1) then begin
print, ' file ', file , ' is not a valid scan data file.'
endif else begin
print, ' OK.'
endelse
endif
return, 1
end
pro scan_data__define
;+
; NAME:
; EPICS_SCAN__DEFINE
;
; PURPOSE:
; Defines an object for EPICS scan data files from epics_scan object
;
;
; CALLING SEQUENCE:
; dat = obj_new('scan_data')
;
;
; INPUTS:
; None.
;
; OPTIONAL INPUTS:
; None.
;
; KEYWORD PARAMETERS:
; None.
;
;
; OUTPUTS:
; Return value will contain the object reference.
;
;
; OPTIONAL OUTPUTS:
; None.
;
;
; COMMON BLOCKS:
; None.
;
;
; SIDE EFFECTS:
; EPICS_Scan object is created.
;
;
; RESTRICTIONS:
; This routine is not called directly, but by IDL's own obj_new()
;
; PROCEDURE:
;
;
; EXAMPLE:
; data = obj_new('scan_data', 'my_data_file.001')
; data->read_scan_file('my_data_file.001')
;
; MODIFICATION HISTORY:
; Aug 03 2001: M Newville
;-
@scan_dims
MAX_SUM_ELEMS = 16 ; max number of detectors to add together for sum
p = ptr_new()
scan_data = { scan_data, filename: ' ', dimension: 1, $
subtitle:' ', $
raw: p, sums:p, plot_colors:p, nplot:0, $
x: p, y: p, xpos: '', ypos:'', $
det_names: p, det_list: p, det_orig: p}
end
escan/scan_data_save__define.pro 0100644 0000621 0000620 00000064243 07333540635 016276 0 ustar epics epics function scan_data::match_detector_name, str, strict=strict, show_error=show_error
;+
; NAME: scan_data::match_detector_name
;
; PURPOSE: look up detector group (ie, summed detectors)
; by name (or closest match), return array index
;
; CATEGORY: scan_data class lib
;
; CALLING SEQUENCE: n = scan_data->match_detector_name(string)
;
; INPUTS: str - string to look up as 'detector group name'
;
; KEYWORD PARAMETERS: strict - flag to force exact string match
; show_error - flag to show error messagee on failure
;
; OUTPUTS: integer index in scan_data.sums for detector group
;
; PROCEDURE: the input string is first checked for an exact match with
; the set of detector names in scan_data.det_names. if no
; exact match is found, then the passed string is checked
; for exact match of the first word (blank delimited) of
; each name in scan_data.det_names. finally, if strict=0
; (the default), the first close match is chosen.
;
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; n = d->match_detector_name('Cu')
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
if (n_elements(str) le 0) then begin
print, " match_detector_name error -- no string given"
return, -1
endif
s = strlowcase(str)
n = n_elements(*self.det_names)
; look for exact match
for i = 0, n - 1 do begin
if (s eq strlowcase((*self.det_names)[i])) then return, i
endfor
; inexact match: check first word
for i = 0, n - 1 do begin
sx = str_sep(strlowcase((*self.det_names)[i]), ' ')
if (s eq sx[0]) then return, i
endfor
;
; last resort: check for any similarity
if (keyword_set(strict) eq 0) then begin
for i = 0, n - 1 do begin
j = strpos(strlowcase((*self.det_names)[i]), s)
if (j ge 0) then begin
print, s, ' is sort of like ', (*self.det_names)[i]
return, i
endif
endfor
endif
if (keyword_set(show_error) ne 0) then begin
print, " can't find detector named ", str
print, " available detectors: "
self->show_detectors
endif
return, -1
end
function scan_data::get_map, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm
;+
; NAME: scan_data::get_map
;
; PURPOSE: return map data from scan_data object
;
; CATEGORY: scan_data class lib
;
; CALLING SEQUENCE: map = scan_data->get_map(name=name, index=index,...)
;
; INPUTS: name - string to look up as 'detector group name'
;
; KEYWORD PARAMETERS: name - flag to force exact string match
; index - flag to show error messagee on failure
;
; OUTPUTS: 2d data for requested map
;
; PROCEDURE: the ...
;
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; map = d->get_map(name='Cu')
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
stitle = ''
uname = ''
nname = ''
uindex = -1
nindex = -1
usum = 1
do_norm= 0
empty = fltarr(2,2) - 99
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (n_elements(use_sum) ne 0) then usum = 1
if (n_elements(use_raw) ne 0) then usum = 0
if (n_elements(norm) ne 0) then nname = norm
if (n_elements(inorm) ne 0) then nindex=inorm
if (nname ne '') then do_norm = 1
if (nindex ne -1) then do_norm = 2
;
;
if (self.dimension eq 1) then begin
print, ' get_map: not a map file -- try get_data '
return, empty
endif
if ((uname eq '') and (uindex eq -1)) then begin
print, ' get_map: no element index or name given'
return, empty
endif else if (uname ne '') then begin
uindex = self->match_detector_name(uname,/show_error)
if (uindex lt 0) then return, empty
endif
if (usum eq 0) then begin
map = (*self.raw)[*,*,uindex]
stitle = 'Raw Detector ' + strtrim(uindex,2)
endif else if (usum eq 1) then begin
map = (*self.sums)[*,*,uindex]
stitle = (*self.det_names)[uindex]
endif
;
; determine normalization array
if (do_norm eq 1) then begin
nindex = self->match_detector_name(nname, /show_error)
if (nindex lt 0) then return, empty
endif
;
; normalize here
if ((nindex ge 0) and (do_norm ge 1)) then begin
if (usum eq 0) then begin
map = map / (*self.raw)[*,*,nindex]
stitle = stitle + ' / Raw Detector ' + strtrim(nindex,2)
endif else if (usum eq 1) then begin
map = map / (*self.sums)[*,*,nindex]
stitle = stitle + ' / ' + (*self.det_names)[nindex]
endif
endif
self.subtitle = stitle
return, map
end
;;
pro scan_data::show_map, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm
;+
; NAME: scan_data::show_map
;
; PURPOSE: plot map data from scan_data object using image_display
;
; CATEGORY: scan_data class lib
;
; CALLING SEQUENCE: scan_data->show_map, name=name, index=index, ...
;
; INPUTS: name - string to look up as 'detector group name'
;
; KEYWORD PARAMETERS: name - flag to force exact string match
; index - flag to show error messagee on failure
;
; OUTPUTS: 2d data for requested map
;
; PROCEDURE: the ...
;
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; map = d->get_map(name='Cu')
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
map = self->get_map(name=name, index=index, use_sum=use_sum, $
use_raw=use_raw, norm=norm, inorm=inorm)
if ((map(0,0) ne -99) or (map(1,0) ne -99) or (n_elements(map) gt 4)) then begin
image_display, map, xdist=(*self.x),ydist=(*self.y),$
title=self.filename, subtitle=self.subtitle
endif
self.subtitle=''
return
end
;;
pro scan_data::show_correl, x=x, y=y, _extra=extra
;+
; NAME: scan_data::show_correl
;
; PURPOSE: plot map data from scan_data object using image_display
;
; CATEGORY: scan_data class lib
;
; CALLING SEQUENCE: scan_data->show_map, name=name, index=index, ...
;
; INPUTS: name - string to look up as 'detector group name'
;
; KEYWORD PARAMETERS: name - flag to force exact string match
; index - flag to show error messagee on failure
;
; OUTPUTS: 2d data for requested map
;
; PROCEDURE: the ...
;
;
; EXAMPLE: d = obj_new('scan_data','scan_file_001.dat')
; map = d->get_map(name='Cu')
;
; MODIFICATION HISTORY: 2001-aug-05 m newville
;
;-
map1 = self->get_map(name=x, /use_sum)
lab1 = self.subtitle
map2 = self->get_map(name=y, /use_sum)
lab2 = self.subtitle
self.subtitle=''
if ((map1(0,0) ne -99) or (map1(1,0) ne -99) or (n_elements(map1) gt 4)) then begin
plot, map1, map2, psym=1, xtitle=lab1, ytitle=lab2, title=self.filename, $
back=set_color('white'), color=set_color('black'), _extra=extra
endif
return
end
;;
function scan_data::get_orig_detector_list, name=name, index=index
;
; return list of detectors in the original 'raw' map for sum of a particular named group
;
uname = ''
uindex= -1
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (uindex lt 0) then begin
uindex = self->match_detector_name(uname, /show_error)
endif
if (uindex lt 0) then return, uindex
n = n_elements((*self.det_orig))
tmp = intarr(n) - 1
cnt = 0
for i = 0, n - 1 do begin
if ((*self.det_orig)[i] eq uindex) then begin
tmp[cnt] = i
cnt = cnt + 1
endif
endfor
return, tmp(0:cnt-1)
end
function scan_data::get_detector_list, name=name, index=index
;
; return list of detectors in 'raw' map for sum of a particular named group
;
uname = ''
uindex= -1
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (uindex lt 0) then begin
uindex = self->match_detector_name(uname, /show_error)
endif
if (uindex lt 0) then return, uindex
n = n_elements((*self.det_list))
tmp = intarr(n) - 1
cnt = 0
for i = 0, n - 1 do begin
if ((*self.det_list)[i] eq uindex) then begin
tmp[cnt] = i
cnt = cnt + 1
endif
endfor
return, tmp(0:cnt-1)
end
function scan_data::set_detector_list, name=name, index=index, list=list
;
; return list of detectors in 'raw' map for sum of a particular named group
;
uname = ''
uindex= -1
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (uindex lt 0) then begin
uindex = self->match_detector_name(uname, /show_error)
endif
if (uindex lt 0) then begin
print, ' set_detector_list : no detector to set'
return, -1
endif else if (n_elements(list) le 0) then begin
print, ' set_detector_list : no detector list given.'
endif
n = n_elements((*self.det_list))
(*self.sums)[*,*,uindex] = 0
for i = 0, n_elements(list) - 1 do begin
j = list[i]
(*self.det_list)[j] = uindex
(*self.sums)[*,*,uindex] = (*self.sums)[*,*,uindex] + (*self.raw)[*,*,j]
endfor
return, list
end
pro scan_data::map_all_detectors, name=name, index=index, _extra=extra
self->plot_all_detectors, name=name, index=index, _extra=extra
return
end
pro scan_data::plot_all_detectors, name=name, index=index, _extra=extra
;
; plot all detectors in a named group
if (n_elements(name) ne 0) then begin
n = self->match_detector_name(name)
if (n ge 0) then name = (*self.det_names)[n]
endif
list = self->get_detector_list(name=name, index=index)
ytitle = 'detectors ' + strtrim(list[0],2) + ':' + strtrim(list[n_elements(list)-1],2)
if (n_elements(name) ne 0) then ytitle = name + ' ( ' + ytitle + ' )'
dim = self.dimension
if (n_elements(list) ge 1) then begin
if (dim eq 1) then begin
ymax = max( (*self.raw)[*,list] )
ymin = min( (*self.raw)[*,list] )
self->plot, index=list[0], /use_raw, $
yrange=[ymin,ymax], ytitle=ytitle, _extra=extra
for i = 1, n_elements(list) - 1 do begin
self->oplot, index=list[i], /use_raw, _extra=extra
endfor
endif else begin
for i = 0, n_elements(list) - 1 do begin
self->show_map, index=list[i], /use_raw, _extra=extra
endfor
endelse
endif
return
end
function scan_data::get_data, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm
empty = fltarr(2)
data = empty
stitle = ''
uname = ''
nname = ''
uindex = -1
nindex = -1
usum = 1
do_norm= 0
is_map = 0
empty = fltarr(2,2) - 99
if (n_elements(name) ne 0) then uname = name
if (n_elements(index) ne 0) then uindex= index
if (n_elements(use_sum) ne 0) then usum = 1
if (n_elements(use_raw) ne 0) then usum = 0
if (n_elements(norm) ne 0) then nname = norm
if (n_elements(inorm) ne 0) then nindex=inorm
if (nname ne '') then do_norm = 1
if (nindex ne -1) then do_norm = 2
;
;
if (self.dimension eq 2) then begin
print, ' get_data: this is a map file -- getting row 0 (try get_map)!'
is_map = 1
endif
if ((uname eq '') and (uindex eq -1)) then begin
print, ' get_data: no element index or name given'
return, empty
endif else if (uname ne '') then begin
uindex = self->match_detector_name(uname,/show_error)
if (uindex lt 0) then return, empty
endif
if (usum eq 0) then begin
if (is_map eq 1) then begin
data = (*self.raw)[*,0,uindex]
endif else begin
data = (*self.raw)[*,uindex]
endelse
stitle = 'Raw Detector ' + strtrim(uindex,2)
endif else if (usum eq 1) then begin
if (is_map eq 1) then begin
data = (*self.sums)[*,0,uindex]
endif else begin
data = (*self.sums)[*,uindex]
endelse
stitle = (*self.det_names)[uindex]
endif
;
; determine normalization array
if (do_norm eq 1) then begin
nindex = self->match_detector_name(nname, /show_error)
if (nindex lt 0) then return, empty
endif
;
; normalize here
if ((nindex ge 0) and (do_norm ge 1)) then begin
if (usum eq 0) then begin
if (is_map eq 1) then begin
data = data / (*self.raw)[*,0,nindex]
endif else begin
data = data / (*self.raw)[*,nindex]
endelse
stitle = stitle + ' / Raw Detector ' + strtrim(nindex,2)
endif else if (usum eq 1) then begin
if (is_map eq 1) then begin
data = data / (*self.sums)[*,0,nindex]
endif else begin
data = data / (*self.sums)[*,nindex]
endelse
stitle = stitle + ' / ' + (*self.det_names)[nindex]
endif
endif
self.subtitle = stitle
return, data
end
;;
pro scan_data::plot, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm, color=color, bw=bw,$
_extra=extra
ydat = self->get_data(name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm)
lab1 = self.subtitle
self.subtitle=''
ucol = set_color((*self.plot_colors)[0])
if (n_elements(color) ne 0) then ucol = set_color(color)
if (keyword_set(bw) ne 0) then ucol = set_color('black')
plot, (*self.x), ydat, xtitle=self.xpos, ytitle=lab1, title=self.filename, chars=1.5, thick=2, $
back=set_color('white'), color=set_color('black'), _extra=extra, /nodata
oplot, (*self.x), ydat, psym=0, color=ucol, _extra=extra
self.nplot = 0
return
end
pro scan_data::oplot, name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm, color=color, bw=bw, $
_extra=extra
ydat = self->get_data(name=name, index=index, $
use_sum=use_sum, use_raw=use_raw, $
norm=norm, inorm=inorm)
self.nplot = self.nplot + 1
lab1 = self.subtitle
self.subtitle=''
nc = n_elements((*self.plot_colors))
ucol = set_color((*self.plot_colors)[self.nplot mod nc])
if (keyword_set(bw) ne 0) then begin
ucol = set_color('black')
nc = 1
endif
usym =-self.nplot/nc
if (n_elements(color) ne 0) then ucol = set_color(color)
oplot, (*self.x), ydat, psym=usym, color=ucol, _extra=extra
return
end
;;
function scan_data::read_data_file, file
; read epics scan data file
@scan_dims
M_GROUPS = 50
MDIM = 500
retval = -1
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
if ((n_elements(file) eq 0) or (keyword_set(help) ne 0)) then begin
print, ' function scan_data::read_data_file(filename)'
return, retval
endif
;
str = '; '
print, format='(3a,$)', 'opening file ', file, ' ... '
openr, lun, file, /get_lun
tmp_x = fltarr(MDIM, MAX_POS)
tmp_det = fltarr(MDIM, MDIM, MAX_DET)
vars = fltarr(MAX_POS+MAX_DET)
tmp_y = fltarr(MDIM)
det_name = strarr(M_GROUPS)
pos_name = strarr(MAX_POS)
ypos = ''
ypv = ''
det_list = intarr(MAX_DET)
group_list = strarr(M_GROUPS)
Det_String = strarr(m_groups)
npts = -1
nrow = -1
ngroups = -1
npos = 0
ndet = 0
first_line = 1
ncols = 1
nline = 1
read_labels= 1
dimen = 2
do_parsing = 0
print, 'reading ...'
while not (eof(lun)) do begin
readf,lun,str
nline = nline + 1
string = strtrim(str,2)
if (strlen(string) gt 1) then begin
char1 = strmid(string, 0, 1)
if ((char1 ne ';') and (read_labels eq 0)) then begin
; read data
npts = npts + 1
reads, string, vars
if (nrow lt 0) then nrow = 0
if (nrow eq 0) then tmp_x[npts, 0:npos-1] = vars[0:npos-1]
tmp_det[npts, nrow, 0:ndet-1] = vars[npos:npos+ndet-1]
endif else begin
if (first_line eq 1) then begin
stmp = strmid(string, 0, 12)
s2 = strmid(string, 12, 13)
sx = str_sep(strtrim(s2,2), ' ')
if (stmp ne '; Epics Scan') then begin
print, ' Not a valid scan file! '
goto, endread
endif
dimen = fix(sx[0])
first_line = 0
endif
char1 = strmid(string, 0, 1)
char3 = strmid(string, 0, 3)
char8 = strmid(strtrim(string,2) , 0,8)
if ((dimen ge 2) and (char3 eq ';2D')) then begin
nrow = nrow + 1
if ((nrow gt 5) and ( ((nrow) mod 10) eq 0)) then print, ";"
print, format='(a,i3,$)', ' ' , nrow
sc = strmid(string,3, strlen(string))
sx = str_sep(strtrim(sc,2), ' ' )
tmp_y[nrow] = sx[1]
npts_old = npts
npts = -1
if (ypv eq '') then begin
n = strpos(string,':', /reverse_search)
ypv = strmid(string,4, n-4)
endif
endif else if (char8 eq ';=======') then begin
; signal to start looking at
do_parsing = 1
endif else if ((read_labels eq 1) and (char8 eq ';-------')) then begin
; read column label: done reading list of pos/det, so declare size of vars here
read_labels = 0
readf,lun,string
vars = fltarr(npos+ndet)
endif else if ( do_parsing eq 1) then begin
; reading list of positioner/detectors for 1d scan
if (char3 eq '; P') then begin
npos = npos + 1
n = -1 + fix(strmid(string,3,3))
i1 = strpos(string, '{')
i2 = strpos(string, '}')
pos_name[n]=strmid(string, i1+1, i2-i1-1)
endif else if (char3 eq '; D') then begin
ndet = ndet + 1
slen = strlen(string) - 1
clast = strmid(string, slen, slen)
if (clast eq 'N') then begin
roi = strmid(string, slen-2, slen-1)
endif else begin
roi = strmid(string, slen-1, slen)
endelse
ds = strmid(string, 3, 2)
; force all non-mca detectors (like, scalars) into individual groups
if (strpos(string,'mca') lt 2) then roi = string
for i = 0, m_groups - 1 do begin
if det_string[i] eq '' then begin
ngroups = i
det_string[i]= roi
group_list[i]= ds
i1 = strpos(string, '{')
i2 = strpos(string, '}')
det_name[i]=strmid(string, i1+1, i2-i1-1)
i1 = strpos(det_name[i], 'mca')
if (i1 ge 0) then begin
i2 = strpos(det_name[i], ':')
il = i1+3 > i2
det_name[i] = strmid(det_name[i],il+1,strlen(det_name[i]))
endif
goto, det_found
endif else if(det_string[i] eq roi) then begin
group_list[i] = group_list[i] + ' ' + ds
goto, det_found
endif
endfor
endif
endif else if ((ypos eq '') and (ypv ne '')) then begin
;
; searching for name of 2D positioner in list of saved values
;
i1 = strpos(string, '(')
i2 = strpos(string, ')')
if (i2 gt i1) then begin
pv =strmid(string, i1+1, i2-i1-1)
if (pv eq ypv) then ypos = strtrim(strmid(string,2,i1-2),2)
endif
endif
endelse
det_found:
endif
endwhile
print, " Available groups from map: ", ngroups
dname = strarr(ngroups+1)
detectors= intarr(MAX_DET) - 1
for i = 0, ngroups do begin
if det_name[i] ne '' then begin
dname[i] = strtrim(det_name[i],2)
g = strtrim(group_list[i],2)
length = string_array(g, det_list)
for j = 0, length-1 do detectors[det_list[j]-1] = i
endif
endfor
; print, ' detector list:'
; for i = 0, MAX_DET -1 do print, i, detectors[i]
nx = npts
if (nx eq -1) then nx = npts_old
ny = nrow
; print, " nx,ny = ", nx, ny, npts , npts_old
y = fltarr(ny+1)
da = fltarr(nx+1, ny+1, ndet)
x = fltarr(nx+1)
for i = 0, nx do begin
for j = 0, ny do begin
for k = 0, ndet-1 do da(i,j,k) = tmp_det(i,j,k)
endfor
endfor
for j = 0, ny do y[j] = tmp_y[j]
for j = 0, nx do x[j] = tmp_x[j,0]
;; for k = 0, npos-1 do x(i,k) = tmp_x(i,k)
sums = fltarr(nx+1,ny+1,ngroups+1)
for i = 0, ngroups do begin
for j = 0, MAX_DET - 1 do begin
if (detectors[j] eq i) then sums(*,*,i) = sums(*,*,i) + da(*,*,j)
endfor
endfor
;
; refom 1d data
if (dimen eq 1) then begin
da = reform(da)
sums= reform(sums)
endif
retval = 0
endread:
close, lun
free_lun, lun
self.dimension = dimen
self.filename = file
self.xpos = pos_name[0]
self.ypos = ypos
self.raw = ptr_new(da)
self.sums = ptr_new(sums)
self.x = ptr_new(x)
self.y = ptr_new(y)
self.det_names = ptr_new(dname)
self.det_list = ptr_new(detectors)
self.det_orig = ptr_new(detectors)
return, retval
end
pro scan_data::set_param, par, val
;
; returns a single attribute of a particular scan
;
is = 0
if (keyword_set(iscan) ne 0) then is = iscan
if (keyword_set(par) ne 0) then begin
case par of
'dimension': self.dimension = val
'filename': self.filename = val
'raw_data': (*self.raw) = val
'sums': (*self.sums) = val
'x': (*self.x) = val
'y': (*self.y) = val
'xpos': self.xpos = val
'ypos': self.ypos = val
'det_names': (*self.det_names) = val
'det_list': (*self.det_list) = val
'plot_colors': (*self.plot_colors) = val
endcase
endif
return
end
function scan_data::get_x
return, self->get_param('x')
end
function scan_data::get_y
return, self->get_param('y')
end
function scan_data::get_param, par
;
; return a copy of an object member structure
; for outside manipulation and later 'set_param'ing
val = 0
if (keyword_set(par) ne 0) then begin
case par of
'dimension': val = self.dimension
'filename': val = self.filename
'raw_data': val = (*self.raw)
'sums': val = (*self.sums)
'x': val = (*self.x)
'y': val = (*self.y)
'xpos': val = self.xpos
'ypos': val = self.ypos
'det_names': val = (*self.det_names)
'det_list': val = (*self.det_list)
'det_orig': val = (*self.det_orig)
'plot_colors': val = (*self.plot_colors)
endcase
endif
return, val
end
pro scan_data::help
;+
; NAME:
;
;
;
; PURPOSE:
;
;
;
; CATEGORY:
;
;
;
; CALLING SEQUENCE:
;
;
;
; INPUTS:
;
;
;
; OPTIONAL INPUTS:
;
;
;
; KEYWORD PARAMETERS:
;
;
;
; OUTPUTS:
;
;
;
; OPTIONAL OUTPUTS:
;
;
;
; COMMON BLOCKS:
;
;
;
; SIDE EFFECTS:
;
;
;
; RESTRICTIONS:
;
;
;
; PROCEDURE:
;
;
;
; EXAMPLE:
;
;
;
; MODIFICATION HISTORY:
;
;-
print, ' Methods for scan_data class:'
print, ' --------------------------------------------------------'
print, ' function get_map '
print, ' pro show_map '
print, ' pro show_correl '
print, ' pro show_detectors'
print, ' function read_data_file'
print, ' pro help'
print, ' pro set_param'
print, ' function get_param'
print, ' pro show_params'
print, ' function match_detector_name'
print, ' '
self->show_params
return
end
pro scan_data::show_params
;
; list available parameters
;
print, ' Parameters accessible for scan file '
print, ' using get_param / set_param:'
print, ' --------------------------------------------------------'
print, ' name meaning'
print, ' filename scan file name '
print, ' dimension scan dimension'
print, ' raw_data complete set of raw detector data '
print, ' sums summed detectors, grouped by detector element '
print, ' det_names names for summed detector groups'
print, ' det_list 2d integer array list of raw detectors for sums'
print, ' x array of x positions '
print, ' y array of y positions (for 2d scans)'
print, ' xpos name of x positioner'
print, ' ypos name of y positioner (for 2d scans)'
print, ' --------------------------------------------------------'
return
end
pro scan_data::show_detectors
n = n_elements(*self.det_names)
print, format='(a,$)', '[ '
for i = 0, n - 2 do begin
print, format='(a,a,$)', (*self.det_names)[i], ', '
endfor
print, format='(a,a)', (*self.det_names)[n-1], ' ]'
return
end
function scan_data::init, file=file
;
cols = ['blue', 'red', 'black', 'magenta', 'forestgreen']
self.plot_colors = ptr_new(cols)
if (n_elements(file) ne 0) then begin
u = self->read_data_file(file)
if (u eq 1) then begin
print, ' file ', file , ' is not a valid scan data file.'
endif else begin
print, ' OK.'
endelse
endif
return, 1
end
pro scan_data__define
;+
; NAME:
; EPICS_SCAN__DEFINE
;
; PURPOSE:
; Defines an object for EPICS scan data files from epics_scan object
;
; CATEGORY:
; EPICS scan class library.
;
; CALLING SEQUENCE:
; dat = obj_new('scan_data')
;
;
; INPUTS:
; None.
;
; OPTIONAL INPUTS:
; None.
;
; KEYWORD PARAMETERS:
; None.
;
;
; OUTPUTS:
; Return value will contain the object reference.
;
;
; OPTIONAL OUTPUTS:
; None.
;
;
; COMMON BLOCKS:
; None.
;
;
; SIDE EFFECTS:
; EPICS_Scan object is created.
;
;
; RESTRICTIONS:
; This routine is not called directly, but by IDL's own obj_new()
;
; PROCEDURE:
;
;
; EXAMPLE:
; data = obj_new('scan_data', 'my_data_file.001')
; data->read_scan_file('my_data_file.001')
;
; MODIFICATION HISTORY:
; Aug 03 2001: M Newville
;-
@scan_dims
MAX_SUM_ELEMS = 16 ; max number of detectors to add together for sum
p = ptr_new()
scan_data = { scan_data, filename: ' ', dimension: 1, $
subtitle:' ', $
raw: p, sums:p, plot_colors:p, nplot:0, $
x: p, y: p, xpos: '', ypos:'', $
det_names: p, det_list: p, det_orig: p}
end
escan/scan_dims.pro 0100644 0000621 0000620 00000000231 07237637100 013612 0 ustar epics epics MAX_POS = 4
MAX_DET = 70
MAX_SCAN_POINTS = 1000 ; maximum number of points in scan record
ETOK = 0.2624682917
escan/scan_include.pro 0100644 0000621 0000620 00000000722 07237637100 014306 0 ustar epics epics
@scan_dims
Widget_Control, event.top, get_uval = p
ErrorNo = 0
Catch, ErrorNo
if (ErrorNo ne 0) then begin
Catch, /CANCEL
ErrA = ['Error!', 'Number' + strtrim(!error, 2), !Err_String]
a = Dialog_Message(ErrA, /ERROR)
return
endif
current_scan = (*p).es->get_param('current_scan')
_scan = 'scan' + string(strtrim(current_scan, 2))
sc = (*p).es->get_param(_scan)
imotor = sc.drives[0]
motor = (*p).es->get_motor(imotor)
escan/scan_viewer_1.pro 0100777 0000621 0000620 00000045121 07237637100 014415 0 ustar epics epics pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
; print, ' in Do_Scan'
write_header = 1
if (keyword_set(no_header)) then write_header= 0
x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
px = fltarr(1000)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
(*p).data.cpt1d = cpt
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
; print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim eq 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
; print, ' time remaining = ' , dt, x, c2, (*p).data.mpts2d
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif
s = caget(sPV+'.EXSC', r)
if (r eq 0) then begin
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
;
wait, 1.50
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan ', (*p).data.scan_dim , ' dimensional scan'
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if ((*p).data.scan_dim eq 2) then begin
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + $
' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
px = (*p).data.p2a[i,*]
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.5
endif else begin
widget_control, event.id, get_uvalue=uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim eq 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
; print, 'Scan Viewer'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
for i = 0, n_elements(det.desc) - 1 do begin
if (det.desc[i] eq '') then det.desc[i] = '-unused-'
endfor
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 495
cpt2d = 0
cpt1d= 0
;
data = {da:da, pa:pa, p2a:p2a, mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
npts2:0, p2pv:p2pv, ipts2:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'yellow', 'red', 'cyan']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot}
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
x = 5.0
info.form.wait2dscan = CW_Field(mid, value= x, uval= 'wait2dscan', $
title = 'Delay Between scans ', $
/return_events, /floating)
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer_2.pro 0100664 0000621 0000620 00000050042 07237637100 014407 0 ustar epics epics pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
; print, ' in Do_Scan'
write_header = 1
if (keyword_set(no_header)) then write_header= 0
x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
px = fltarr(1000)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
(*p).data.cpt1d = cpt
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
; print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim eq 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif else if ((*p).data.scan_dim eq 3) then begin
prog_str = '3D Scan '+ f2a((*p).data.ipts3) + ' / ' + $
f2a((*p).data.npts3) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
; print, ' time remaining = ' , dt, x, c2, (*p).data.mpts2d
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif
s = caget(sPV+'.EXSC', running)
if (running eq 0) then begin
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
;
wait, 1.50
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan ', (*p).data.scan_dim , ' dimensional scan'
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if (((*p).data.scan_dim ge 2)) then begin
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + $
' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
px = (*p).data.p2a[i,*]
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ((*p).data.scan_dim eq 3) and
(*p).data.scan_dim eq 3)) then begin
endif
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.5
endif else begin
widget_control, event.id, get_uvalue=uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim eq 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif else if (dim eq 3) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
; print, 'Scan Viewer'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
for i = 0, n_elements(det.desc) - 1 do begin
if (det.desc[i] eq '') then det.desc[i] = '-unused-'
endfor
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 495
cpt2d = 0
cpt1d= 0
;
data = {da:da, pa:pa, p2a:p2a, mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
npts2:0, p2pv:p2pv, ipts2:0, ipts3:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'yellow', 'red', 'cyan']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot}
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
x = 5.0
info.form.wait2dscan = CW_Field(mid, value= x, uval= 'wait2dscan', $
title = 'Delay Between scans ', $
/return_events, /floating)
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer2.pro 0100664 0000621 0000620 00000050042 07237626145 014257 0 ustar epics epics pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
; print, ' in Do_Scan'
write_header = 1
if (keyword_set(no_header)) then write_header= 0
x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
px = fltarr(1000)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
(*p).data.cpt1d = cpt
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
; print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim eq 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif else if ((*p).data.scan_dim eq 3) then begin
prog_str = '3D Scan '+ f2a((*p).data.ipts3) + ' / ' + $
f2a((*p).data.npts3) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
; print, ' time remaining = ' , dt, x, c2, (*p).data.mpts2d
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif
s = caget(sPV+'.EXSC', running)
if (running eq 0) then begin
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
;
wait, 1.50
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan ', (*p).data.scan_dim , ' dimensional scan'
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if (((*p).data.scan_dim ge 2)) then begin
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + $
' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
px = (*p).data.p2a[i,*]
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ((*p).data.scan_dim eq 3) and
(*p).data.scan_dim eq 3)) then begin
endif
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.5
endif else begin
widget_control, event.id, get_uvalue=uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim eq 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif else if (dim eq 3) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
; print, 'Scan Viewer'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
for i = 0, n_elements(det.desc) - 1 do begin
if (det.desc[i] eq '') then det.desc[i] = '-unused-'
endfor
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 495
cpt2d = 0
cpt1d= 0
;
data = {da:da, pa:pa, p2a:p2a, mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
npts2:0, p2pv:p2pv, ipts2:0, ipts3:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'yellow', 'red', 'cyan']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot}
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
x = 5.0
info.form.wait2dscan = CW_Field(mid, value= x, uval= 'wait2dscan', $
title = 'Delay Between scans ', $
/return_events, /floating)
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer_3.pro 0100644 0000621 0000620 00000063307 07237637100 014416 0 ustar epics epics pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
; print, ' in Do_Scan1d'
@scan_dims
write_header = 1
if (keyword_set(no_header)) then write_header= 0
; unpause scan
x = caget((*p).data.pausepv, is_paused)
if (is_paused eq 1) then x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
px = fltarr(MAX_SCAN_POINTS)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
; print, ' do_scan1d, time = ', x
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
; print, ' scan_viewer timer : ', cpt
(*p).data.cpt1d = cpt
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
; print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim ge 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif
if ((*p).data.scan_dim eq 3) then begin
prog_str = '3D Scan '+ f2a((*p).data.ipts3) + ' / ' + $
f2a((*p).data.npts3) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
; print, ' time remaining = ' , dt, x, c2
if (x ge 0.000) then begin
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif else begin
widget_control, (*p).form.time_rem, set_value = 'unknown'
endelse
endif
s = caget(sPV+'.EXSC', running)
if (running eq 0) then begin
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
;
wait, 0.50
;
; 1d scan: close scanfile, increment scanfile, open next scanfile
;
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan 1 dimensional scan'
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
; print, ' waiting ', (*p).data.wait2dscan
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if (((*p).data.scan_dim ge 2)) then begin
; 2d / 3d scans:
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' $
+ f2a((*p).data.npts2) + ' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
; print, ' Scan 2d ' , (*p).data.ipts2 , ' of ', (*p).data.npts2
; move to next point in 2d scan
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
; wait for stage to finish
wait_for_motor(motor=(*p).data.p2pv[0], wait_time=0.05, $
maxtrys=200)
; wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
; 2d scan done, return to starting position
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
; return scan 2 to starting point
for i = 0, 3 do begin
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,0])
endif
endfor
; wait for stage to finish
wait_for_motor(motor=(*p).data.p2pv[0], wait_time=0.05, $
maxtrys=200)
; increment scan name, fill in progres line
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
; decide if this is a 3d or multi-2d scan
scan_is_multi_2d = ( (*p).data.n_scans gt (*p).data.iscan)
scan_is_3d = (((*p).data.scan_dim eq 3 ) and $
((*p).data.ipts3 lt (*p).data.npts3))
;
; 3d and multi-2d scans
if ( scan_is_multi_2d or scan_is_3d) then begin
widget_control, (*p).form.progress, set_value=' Waiting ...'
if (scan_is_multi_2d) then begin
; multi-2d scan
; print, ' MULTI 2D SCANS '
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
(*p).data.ipts2 = 1
(*p).data.start_time = xtime_s()
endif else begin
; 3d scan
inn = (*p).data.ipts3
if (inn lt (*p).data.npts3 ) then begin
print, ' 3D SCAN moving to ', (*p).data.p3a[0,inn]
(*p).data.ipts3 = (*p).data.ipts3 + 1
(*p).data.ipts2 = 1
for i = 0, 3 do begin
pv_n = (*p).data.p3pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p3a[i,inn] )
endif
endfor
; wait for stage to finish
wait_for_motor(motor=(*p).data.p3pv[0], wait_time=0.05, $
maxtrys=200)
widget_control, (*p).form.iscan, set_value= f2a((*p).data.ipts3)
widget_control, (*p).form.n_scans , sensitive=0
(*p).data.start_time = xtime_s()
endif else begin
print, 'SCAN_VIEWER CANT GET HERE!! '
endelse
endelse
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
;
; note that 3d scans are written as a series of 2d scans
printf, lun, '; Epics Scan 2 dimensional scan'
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
; print, ' waiting ', (*p).data.wait2dscan
wait, (*p).data.wait2dscan
prog_str = ' starting 2D scan '+ f2a((*p).data.iscan) + $
' of '+ f2a((*p).data.n_scans)
if (scan_is_3d) then begin
prog_str = ' 3D scan starting sscan '+ $
f2a((*p).data.ipts2)+ ' of '+ f2a((*p).data.npts3)
endif
widget_control, (*p).form.progress, set_value= prog_str
; start 1d scan as part of 2d or 3d scan
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else if (((*p).data.scan_dim eq 3 ) and $
((*p).data.ipts3 ge (*p).data.npts3)) then begin
; finished 3d scan, return to starting position
prog_str = ' SCAN 3D done. '
widget_control, (*p).form.progress, set_value= prog_str
for i = 0, 3 do begin
pv_n = (*p).data.p3pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p3a[i,0])
endif
endfor
(*p).data.start_time = xtime_s()
widget_control, (*p).form.time_rem, set_value = sec2hms(0.)
(*p).data.ipts3 = 1
widget_control, (*p).form.n_scans , sensitive=1
endif
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.25
endif else begin
widget_control, event.id, get_uvalue=uval
; print, ' scan_viewer_event uval ', uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim ge 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
if (dim eq 3) then begin
; 3d scan: get pvs needed for 2d scan, move to starting point
sc3 = (*p).es->get_param('scan3')
s3PV = sc3.scanPV
(*p).data.npts3 = sc3.npts_total
px = fltarr(sc3.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(s3PV+'.P'+x+'PA', px)
s = caget(s3PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p3a[i,jj] = px[jj]
endfor
(*p).data.p3pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p3a[i,0] )
endif
endfor
(*p).data.ipts3 = 1
widget_control, (*p).form.n_scans , sensitive=0
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'norm_sel': begin ;detector for normalization
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
if ((*p).data.scan_dim eq 3) then begin
widget_control, (*p).form.n_scans , sensitive=0
endif else begin
widget_control, (*p).form.n_scans , sensitive=0
endelse
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'linestyles': begin
end
else: print, ' scan_viewer unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
; print, 'Scan Viewer'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
for i = 0, n_elements(det.desc) - 1 do begin
if (det.desc[i] eq '') then det.desc[i] = '-unused-'
endfor
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
p3a = fltarr( 4, MAX_SCAN_POINTS)
p3pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 495
cpt2d = 0
cpt1d= 0
;
data = {da:da, pa:pa, p2a:p2a, p2pv:p2pv, p3a:p3a, p3pv:p3pv, $
mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
npts2:0, npts3:0, ipts2:0, ipts3:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'yellow', 'red', 'cyan']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot}
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
x = 5.0
info.form.wait2dscan = CW_Field(mid, value= x, uval= 'wait2dscan', $
title = 'Delay Between scans ', $
/return_events, /floating)
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer_4a.pro 0100644 0000621 0000620 00000074170 07237637100 014560 0 ustar epics epics pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
@scan_dims
write_header = 1
if (keyword_set(no_header)) then write_header= 0
; unpause a scan that hasn't been paused by the
; user (user_paused) or by a programmatic control
; (auto_paused)
x = caget((*p).data.pausepv, is_paused)
print, ' in Do_Scan1d auto_paused: ', (*p).data.auto_paused, (*p).data.user_paused
if ((is_paused eq 1) and ((*p).data.auto_paused eq 0) and $
((*p).data.user_paused eq 0)) then begin
print, ' unpausing a paused scan'
x = caput((*p).data.pausepv, 0)
endif
; if scan is not paused, execute 1d scan
wait, 0.10
x = caget((*p).data.pausepv, is_paused)
; print, ' in Do_Scan1d ', is_paused
if (is_paused eq 0) then begin
(*p).data.scanning = 1
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
px = fltarr(MAX_SCAN_POINTS)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
; print, ' do_scan1d, time = ', x
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
endif else begin
print, ' AAA '
widget_control, (*p).form.progress, set_value='Scan is Paused '
endelse
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
; print, ' scan_viewer timer : ', cpt
(*p).data.cpt1d = cpt
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
; print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim ge 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif
if ((*p).data.scan_dim eq 3) then begin
prog_str = '3D Scan '+ f2a((*p).data.ipts3) + ' / ' + $
f2a((*p).data.npts3) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
t0 = (*p).data.start_time
t1 = xtime_s()
dt = t1 - t0
x = dt * ((*p).data.mpts2d - c2) / c2
; print, ' time remaining = ' , dt, t1, t0, x, c2
if (x ge 0.000) then begin
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif else begin
widget_control, (*p).form.time_rem, set_value = 'unknown'
endelse
endif
s = caget(sPV+'.EXSC', running)
; print, ' SCAN RUNNING ', running
if (running eq 0) then begin
(*p).data.scanning = 0
(*p).data.user_paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
;
;
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan 1 dimensional scan'
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
; print, ' waiting ', (*p).data.wait2dscan
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if (((*p).data.scan_dim ge 2)) then begin
; 2d / 3d scans:
print, ' scan dim ' , (*p).data.scan_dim
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' $
+ f2a((*p).data.npts2) + ' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
print, ' Scan 2d ' , (*p).data.ipts2 , ' of ', (*p).data.npts2
; move to next point in 2d scan
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
; wait for stage to finish
nx = wait_for_motor(motor=(*p).data.p2pv[0], wait_time=0.05, $
maxtrys=200)
; wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
; 2d scan done, return to starting position
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
; return scan 2 to starting point
for i = 0, 3 do begin
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,0])
endif
endfor
; wait for stage to finish
nx = wait_for_motor(motor=(*p).data.p2pv[0], wait_time=0.05, $
maxtrys=200)
; increment scan name, fill in progres line
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
; decide if this is a 3d or multi-2d scan
scan_is_multi_2d = ( (*p).data.n_scans gt (*p).data.iscan)
scan_is_3d = (((*p).data.scan_dim eq 3 ) and $
((*p).data.ipts3 lt (*p).data.npts3))
;
; 3d and multi-2d scans
print, 'X ', scan_is_3d, scan_is_multi_2d
if ( scan_is_multi_2d or scan_is_3d) then begin
widget_control, (*p).form.progress, set_value=' Waiting ...'
if (scan_is_multi_2d) then begin
; multi-2d scan
print, ' MULTI 2D SCANS ', (*p).data.iscan
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
(*p).data.ipts2 = 1
(*p).data.start_time = xtime_s()
endif else begin
; 3d scan
inn = (*p).data.ipts3
if (inn lt (*p).data.npts3 ) then begin
print, ' 3D SCAN moving to ', (*p).data.p3a[0,inn]
(*p).data.ipts3 = (*p).data.ipts3 + 1
(*p).data.ipts2 = 1
for i = 0, 3 do begin
pv_n = (*p).data.p3pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p3a[i,inn] )
endif
endfor
; wait for stage to finish
nx = wait_for_motor(motor=(*p).data.p3pv[0], wait_time=0.05, $
maxtrys=200)
widget_control, (*p).form.iscan, set_value= f2a((*p).data.ipts3)
widget_control, (*p).form.n_scans , sensitive=0
(*p).data.start_time = xtime_s()
endif else begin
print, 'SCAN_VIEWER CANT GET HERE!! '
endelse
endelse
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
;
; note that 3d scans are written as a series of 2d scans
printf, lun, '; Epics Scan 2 dimensional scan'
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
print, ' waiting ', (*p).data.wait2dscan
wait, (*p).data.wait2dscan
prog_str = ' starting 2D scan '+ f2a((*p).data.iscan) + $
' of '+ f2a((*p).data.n_scans)
if (scan_is_3d) then begin
prog_str = ' 3D scan starting sscan '+ $
f2a((*p).data.ipts2)+ ' of '+ f2a((*p).data.npts3)
endif
widget_control, (*p).form.progress, set_value= prog_str
; start 1d scan as part of 2d or 3d scan
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else if (((*p).data.scan_dim eq 3 ) and $
((*p).data.ipts3 ge (*p).data.npts3)) then begin
; finished 3d scan, return to starting position
prog_str = ' SCAN 3D done. '
widget_control, (*p).form.progress, set_value= prog_str
for i = 0, 3 do begin
pv_n = (*p).data.p3pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p3a[i,0])
endif
endfor
(*p).data.start_time = xtime_s()
widget_control, (*p).form.time_rem, set_value = sec2hms(0.)
(*p).data.ipts3 = 1
widget_control, (*p).form.n_scans , sensitive=1
endif
endelse
endif
endif else begin
; print, ' SCAN : check ring current and feedback '
;
; check that shutter is open. If not, open it. If still not open,
; do something intelligent like pause scan and send up dialog box
SRCurrentPV = 'S:SRcurrentAI.VAL'
s = caget(SRCurrentPV, ring_current)
ring_current = 100
; print, ' ring current ', ring_current
if (ring_current le 2.0) then begin
(*p).data.auto_paused = 1
widget_control, (*p).form.progress, set_value='Waiting for Beam '
wait, 5.00
endif else if ((ring_current gt 60) and ((*p).data.auto_paused eq 1)) then begin
widget_control, (*p).form.progress, set_value='Resuming after Beam Returned'
(*p).data.auto_paused = 0
wait, 5.00
endif
s = caget((*p).data.shutter_pv, shutter_stat)
; print, ' shutter_stat = ', shutter_stat
if (shutter_stat eq 0) then begin
print, 'shutter is closed, attempting to open '
s = caput( (*p).data.shutter_pv, 1)
wait, 0.25
s = caget((*p).data.shutter_pv, shutter_stat)
if (shutter_stat eq 0) then begin
print, 'shutter is still closed ! '
(*p).data.auto_paused = 1
; widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, $
set_value='Scan Paused: Shutter Closed'
x = caput((*p).data.pausepv, 1)
;check eps
s = caget( (*p).data.eps_pv, eps_stat)
if (eps_stat eq 0) then begin ; EPS OK
widget_control, (*p).form.progress, $
set_value=' *** CANNOT OPEN SHUTTER, EPS OK. ***'
endif else begin ; EPS Error
widget_control, (*p).form.progress, $
set_value=' *** EPS Fault! *** '
endelse
endif
endif
; check piezo feedback status and re-start feedback if lost
PVpiezo = '13IDA:DAC1_3.VAL'
PVfeedback = '13IDA:mono_pid1.FBON'
PVfb_target = '13IDA:mono_pid1.VAL'
PVfb_current= '13IDA:mono_pid1.CVAL'
x = caget(PVfeedback,fb_is_on)
x = caget(PVpiezo, piezo_val)
if (fb_is_on eq 1) and (abs(piezo_val*1.0) gt 4.9) then begin
widget_control, (*p).form.progress, $
set_value=' Lost Mono Feedback -- Resetting '
x = caput(PVfeedback,0)
target = - 4.85
if (piezo_val lt -1.) then target = - target
x = caput(PVpiezo, target)
x = caput(PVfeedback,1)
(*p).data.auto_paused = 1
wait_for_fb = 1
nw_count = 0
while (wait_for_fb eq 1) do begin
nw_count = nw_count + 1
wait, 1.00
x = caget(PVfb_target, fb_targ)
x = caget(PVfb_current,fb_curr)
x = caget(PVpiezo, piezo_val)
if (abs(fb_curr - fb_targ) le fb_targ*0.8) then wait_for_fb = 0
if (nw_count ge 20 ) then wait_for_fb = 0
endwhile
widget_control, (*p).form.progress, set_value=' Resuming Scan '
(*p).data.auto_paused = 0
endif
endelse
; note that auto_paused scans still generate timer events
; (so that we can look for beam recovery, etc)
if (((*p).data.scanning eq 1) and $
((*p).data.user_paused eq 0) ) then widget_control, event.id, timer=0.25
endif else begin
widget_control, event.id, get_uvalue=uval
; print, ' scan_viewer_event uval ', uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim ge 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
if (dim eq 3) then begin
; 3d scan: get pvs needed for 2d scan, move to starting point
sc3 = (*p).es->get_param('scan3')
s3PV = sc3.scanPV
(*p).data.npts3 = sc3.npts_total
px = fltarr(sc3.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(s3PV+'.P'+x+'PA', px)
s = caget(s3PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p3a[i,jj] = px[jj]
endfor
(*p).data.p3pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p3a[i,0] )
endif
endfor
(*p).data.ipts3 = 1
widget_control, (*p).form.n_scans , sensitive=0
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.user_paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.user_paused eq 0) then begin
(*p).data.user_paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.user_paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'norm_sel': begin ;detector for normalization
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
if ((*p).data.scan_dim eq 3) then begin
widget_control, (*p).form.n_scans , sensitive=0
endif else begin
widget_control, (*p).form.n_scans , sensitive=0
endelse
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'linestyles': begin
end
else: print, ' scan_viewer unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
; print, 'Scan Viewer'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
prefix = es->get_param('prefix')
shutter_pv = es->get_param('shutter_pv')
eps_pv = prefix + 'eps_mbbi5'
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
for i = 0, n_elements(det.desc) - 1 do begin
if (det.desc[i] eq '') then det.desc[i] = '-unused-'
endfor
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
p3a = fltarr( 4, MAX_SCAN_POINTS)
p3pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 495
cpt2d = 0
cpt1d= 0
;
data = {da:da, pa:pa, p2a:p2a, p2pv:p2pv, p3a:p3a, p3pv:p3pv, $
mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $
scanning:0, user_paused:0, auto_paused:0, $
n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
npts2:0, npts3:0, ipts2:0, ipts3:0, lun:0, wait2dscan:5.00, scanabort:0, $
shutter_pv:shutter_pv, eps_pv:eps_pv}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'yellow', 'red', 'cyan']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.auto_paused = 0
data.user_paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot}
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
x = 5.0
info.form.wait2dscan = CW_Field(mid, value= x, uval= 'wait2dscan', $
title = 'Delay Between scans ', $
/return_events, /floating)
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer_4.pro 0100644 0000621 0000620 00000074476 07237637100 014430 0 ustar epics epics pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
@scan_dims
write_header = 1
if (keyword_set(no_header)) then write_header= 0
; unpause a scan that hasn't been paused by the
; user (user_paused) or by a programmatic control
; (auto_paused)
x = caget((*p).data.pausepv, is_paused)
; print, ' in Do_Scan1d auto_paused: ', (*p).data.auto_paused, (*p).data.user_paused
if ((is_paused eq 1) and ((*p).data.auto_paused eq 0) and $
((*p).data.user_paused eq 0)) then begin
print, ' unpausing a paused scan'
x = caput((*p).data.pausepv, 0)
endif
; if scan is not paused, execute 1d scan
x = caget((*p).data.pausepv, is_paused)
is_paused = 0
wait, 0.10
x = caput((*p).data.pausepv, 0)
; print, ' in Do_Scan1d paused ', is_paused
if (is_paused eq 0) then begin
(*p).data.scanning = 1
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
px = fltarr(MAX_SCAN_POINTS)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
; print, ' do_scan1d, time = ', x
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
endif else begin
; print, ' AAA '
widget_control, (*p).form.progress, set_value='Scan is Paused '
endelse
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
; print, ' scan_viewer timer : ', cpt
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
; print, ' scan_viewer timer : ', cpt
(*p).data.cpt1d = cpt
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
; print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim ge 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif
if ((*p).data.scan_dim eq 3) then begin
prog_str = '3D Scan '+ f2a((*p).data.ipts3) + ' / ' + $
f2a((*p).data.npts3) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
t0 = (*p).data.start_time
t1 = xtime_s()
dt = t1 - t0
x = dt * ((*p).data.mpts2d - c2) / c2
; print, ' time remaining = ' , dt, t1, t0, x, c2
if (x ge 0.000) then begin
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif else begin
widget_control, (*p).form.time_rem, set_value = 'unknown'
endelse
endif
s = caget(sPV+'.EXSC', running)
; print, ' SCAN RUNNING ', running
if (running eq 0) then begin
(*p).data.scanning = 0
(*p).data.user_paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
;
;
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan 1 dimensional scan'
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
; print, ' waiting ', (*p).data.wait2dscan
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if (((*p).data.scan_dim ge 2)) then begin
; 2d / 3d scans:
print, ' scan dim ' , (*p).data.scan_dim, (*p).data.ipts2, (*p).data.npts2
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' $
+ f2a((*p).data.npts2) + ' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
print, ' Scan 2d ' , (*p).data.ipts2 , ' of ', (*p).data.npts2
; move to next point in 2d scan
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
; wait for stage to finish
nx = wait_for_motor(motor=(*p).data.p2pv[0], wait_time=0.05, $
maxtrys=200)
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
; 2d scan done, return to starting position
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
; return scan 2 to starting point
for i = 0, 3 do begin
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,0])
endif
endfor
; wait for stage to finish
nx = wait_for_motor(motor=(*p).data.p2pv[0], wait_time=0.05, $
maxtrys=200)
; increment scan name, fill in progres line
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
; decide if this is a 3d or multi-2d scan
scan_is_multi_2d = ( (*p).data.n_scans gt (*p).data.iscan)
scan_is_3d = (((*p).data.scan_dim eq 3 ) and $
((*p).data.ipts3 lt (*p).data.npts3))
;
; 3d and multi-2d scans
print, 'Scan is Multi? ', scan_is_3d, scan_is_multi_2d
if ( scan_is_multi_2d or scan_is_3d) then begin
widget_control, (*p).form.progress, set_value=' Waiting ...'
if (scan_is_multi_2d) then begin
; multi-2d scan
print, ' MULTI 2D SCANS ', (*p).data.iscan
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
(*p).data.ipts2 = 1
(*p).data.ipts1 = 1
(*p).data.start_time = xtime_s()
endif else begin
; 3d scan
inn = (*p).data.ipts3
if (inn lt (*p).data.npts3 ) then begin
print, ' 3D SCAN moving to ', (*p).data.p3a[0,inn]
(*p).data.ipts3 = (*p).data.ipts3 + 1
(*p).data.ipts2 = 1
for i = 0, 3 do begin
pv_n = (*p).data.p3pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p3a[i,inn] )
endif
endfor
; wait for stage to finish
nx = wait_for_motor(motor=(*p).data.p3pv[0], wait_time=0.05, $
maxtrys=200)
widget_control, (*p).form.iscan, set_value= f2a((*p).data.ipts3)
widget_control, (*p).form.n_scans , sensitive=0
(*p).data.start_time = xtime_s()
endif else begin
print, 'SCAN_VIEWER CANT GET HERE!! '
endelse
endelse
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
;
; note that 3d scans are written as a series of 2d scans
printf, lun, '; Epics Scan 2 dimensional scan'
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
; print, ' waiting ', (*p).data.wait2dscan
wait, (*p).data.wait2dscan
prog_str = ' starting 2D scan '+ f2a((*p).data.iscan) + $
' of '+ f2a((*p).data.n_scans)
if (scan_is_3d) then begin
prog_str = ' 3D scan starting sscan '+ $
f2a((*p).data.ipts2)+ ' of '+ f2a((*p).data.npts3)
endif
widget_control, (*p).form.progress, set_value= prog_str
; start 1d scan as part of 2d or 3d scan
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else if (((*p).data.scan_dim eq 3 ) and $
((*p).data.ipts3 ge (*p).data.npts3)) then begin
; finished 3d scan, return to starting position
prog_str = ' SCAN 3D done. '
widget_control, (*p).form.progress, set_value= prog_str
for i = 0, 3 do begin
pv_n = (*p).data.p3pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p3a[i,0])
endif
endfor
(*p).data.start_time = xtime_s()
widget_control, (*p).form.time_rem, set_value = sec2hms(0.)
(*p).data.ipts3 = 1
widget_control, (*p).form.n_scans , sensitive=1
endif
endelse
endif
endif else begin
; print, ' SCAN : check ring current and feedback '
;
; check that shutter is open. If not, open it. If still not open,
; do something intelligent like pause scan and send up dialog box
SRCurrentPV = 'S:SRcurrentAI.VAL'
s = caget(SRCurrentPV, ring_current)
ring_current = 100
; print, ' ring current ', ring_current
if (ring_current le 2.0) then begin
(*p).data.auto_paused = 1
widget_control, (*p).form.progress, set_value='Waiting for Beam '
wait, 5.00
endif else if ((ring_current gt 60) and ((*p).data.auto_paused eq 1)) then begin
widget_control, (*p).form.progress, set_value='Resuming after Beam Returned'
(*p).data.auto_paused = 0
wait, 5.00
endif
s = caget((*p).data.shutter_pv, shutter_stat)
; print, ' shutter_stat = ', shutter_stat
if (shutter_stat eq 0) then begin
print, 'shutter is closed, attempting to open '
s = caput( (*p).data.shutter_pv, 1)
wait, 0.25
s = caget((*p).data.shutter_pv, shutter_stat)
if (shutter_stat eq 0) then begin
print, 'shutter is still closed ! '
(*p).data.auto_paused = 1
; widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, $
set_value='Scan Paused: Shutter Closed'
x = caput((*p).data.pausepv, 1)
;check eps
s = caget( (*p).data.eps_pv, eps_stat)
if (eps_stat eq 0) then begin ; EPS OK
widget_control, (*p).form.progress, $
set_value=' *** CANNOT OPEN SHUTTER, EPS OK. ***'
endif else begin ; EPS Error
widget_control, (*p).form.progress, $
set_value=' *** EPS Fault! *** '
endelse
endif
endif
; check piezo feedback status and re-start feedback if lost
PVpiezo = '13IDA:DAC1_3.VAL'
PVfeedback = '13IDA:mono_pid1.FBON'
PVfb_target = '13IDA:mono_pid1.VAL'
PVfb_current= '13IDA:mono_pid1.CVAL'
x = caget(PVfeedback,fb_is_on)
x = caget(PVpiezo, piezo_val)
if (fb_is_on eq 1) and (abs(piezo_val*1.0) gt 4.9) then begin
widget_control, (*p).form.progress, $
set_value=' Lost Mono Feedback -- Resetting '
x = caput(PVfeedback,0)
target = - 4.85
if (piezo_val lt -1.) then target = - target
x = caput(PVpiezo, target)
x = caput(PVfeedback,1)
(*p).data.auto_paused = 1
wait_for_fb = 1
nw_count = 0
while (wait_for_fb eq 1) do begin
nw_count = nw_count + 1
wait, 1.00
x = caget(PVfb_target, fb_targ)
x = caget(PVfb_current,fb_curr)
x = caget(PVpiezo, piezo_val)
if (abs(fb_curr - fb_targ) le fb_targ*0.8) then wait_for_fb = 0
if (nw_count ge 20 ) then wait_for_fb = 0
endwhile
widget_control, (*p).form.progress, set_value=' Resuming Scan '
(*p).data.auto_paused = 0
endif
endelse
; print, ' flow B1 ' , (*p).data.scanning
; note that auto_paused scans still generate timer events
; (so that we can look for beam recovery, etc)
if (((*p).data.scanning eq 1) and $
((*p).data.user_paused eq 0) ) then widget_control, event.id, timer=0.25
endif else begin
widget_control, event.id, get_uvalue=uval
; print, ' scan_viewer_event uval ', uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim ge 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
if (dim eq 3) then begin
; 3d scan: get pvs needed for 2d scan, move to starting point
sc3 = (*p).es->get_param('scan3')
s3PV = sc3.scanPV
(*p).data.npts3 = sc3.npts_total
px = fltarr(sc3.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(s3PV+'.P'+x+'PA', px)
s = caget(s3PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p3a[i,jj] = px[jj]
endfor
(*p).data.p3pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p3a[i,0] )
endif
endfor
(*p).data.ipts3 = 1
widget_control, (*p).form.n_scans , sensitive=0
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.user_paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.user_paused eq 0) then begin
(*p).data.user_paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.user_paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'norm_sel': begin ;detector for normalization
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
if ((*p).data.scan_dim eq 3) then begin
widget_control, (*p).form.n_scans , sensitive=0
endif else begin
widget_control, (*p).form.n_scans , sensitive=0
endelse
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'linestyles': begin
end
else: print, ' scan_viewer unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
; print, 'Scan Viewer'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
prefix = es->get_param('prefix')
shutter_pv = es->get_param('shutter_pv')
eps_pv = prefix + 'eps_mbbi5'
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
for i = 0, n_elements(det.desc) - 1 do begin
if (det.desc[i] eq '') then det.desc[i] = '-unused-'
endfor
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
p3a = fltarr( 4, MAX_SCAN_POINTS)
p3pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 495
cpt2d = 0
cpt1d= 0
;
data = {da:da, pa:pa, p2a:p2a, p2pv:p2pv, p3a:p3a, p3pv:p3pv, $
mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $
scanning:0, user_paused:0, auto_paused:0, $
n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
npts2:0, npts3:0, ipts2:0, ipts3:0, lun:0, wait2dscan:5.00, scanabort:0, $
shutter_pv:shutter_pv, eps_pv:eps_pv}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'yellow', 'red', 'cyan']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.auto_paused = 0
data.user_paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot}
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
x = 5.0
info.form.wait2dscan = CW_Field(mid, value= x, uval= 'wait2dscan', $
title = 'Delay Between scans ', $
/return_events, /floating)
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer__bb.pro 0100644 0000621 0000620 00000043643 07237637100 014777 0 ustar epics epics pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
;; print, ' in Do_Scan'
write_header = 1
if (keyword_set(no_header)) then write_header= 0
x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
ret = (*p).es->start_scan1d(user_titles=titles)
endif else begin
ret = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
px = fltarr(2000)
; print, 'Float X = ' , sPV
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
; print, ' total time calc'
x = (*p).es->get_param('total_time')
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
(*p).data.cpt1d = cpt
for i = 0, 14 do begin
det = string(i+1,format='(i1.1)')
if (i ge 9) then det = string(byte(i + 56))
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
; print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim eq 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
; print, ' time remaining = ' , dt, x, c2, (*p).data.mpts2d
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif
s = caget(sPV+'.EXSC', r)
if (r eq 0) then begin
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
det = string(i+1,format='(i1.1)')
if (i ge 9) then det = string(byte(i + 56))
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4
;
wait, 1.50
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan ', (*p).data.scan_dim , ' dimensional scan'
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if ((*p).data.scan_dim eq 2) then begin
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + $
' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
px = (*p).data.p2a[i,*]
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.5
endif else begin
widget_control, event.id, get_uvalue=uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
; start scan
widget_control, (*p).form.progress, set_value='Waiting ...'
(*p).data.iscan = 1
dim = (*p).data.scan_dim
print, ' scan_viewer : start scan dim = ', dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
print, 'dimension = ', dim
if (dim eq 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
; print, ' Dim 2, 2: ', s2PV
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
; print, ' -- ', n_elements(px)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
; print, ' pv_n = ', pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
; print, ' Set '
(*p).data.ipts2 = 1
; print, ' Dim 2,3'
endif
(*p).data.start_time = xtime_s()
; print, ' --> Do_Scan'
do_scan1d, p
endif else begin
; abort scan
; print, ' ABORTING SCAN '
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
; print, ' scan datafile = ', t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
; print, 'Scan Viewer'
;
; current scan is __always__ scan1
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
for i = 0, n_elements(det.desc) - 1 do begin
if (det.desc[i] eq '') then det.desc[i] = '-unused-'
endfor
pa = fltarr( 4, 2000)
p2a = fltarr( 4, 2000)
p2pv = strarr( 4)
da = fltarr(15, 2000)
xsize = 800
ysize = 495
cpt2d = 0
cpt1d= 0
;
data = {da:da, pa:pa, p2a:p2a, mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
npts2:0, p2pv:p2pv, ipts2:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot = {det:0, monitor:0L, color:0L, psym:-1, xlab:'',ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot}
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2) )
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
x = 5.0
info.form.wait2dscan = CW_Field(mid, value= x, uval= 'wait2dscan', $
title = 'Delay Between scans ', $
/floating)
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer_mm.pro 0100644 0000621 0000620 00000052371 07317212372 014663 0 ustar epics epics function write_med_file, p, cpt
;
; write med data file for full spectra
;
med_file = (*p).data.datafile + '_med_'+ f2a(cpt) +'_'+ f2a((*p).data.ipts2)
(*p).med_obj->write_file, med_file
print, ' saved med ', med_file
x = caput((*p).data.med_clientwait_pv, 0)
; wait for
repeat x = caget((*p).data.med_clientwait_pv, counting) until (counting)
return, x
end
pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
write_header = 1
if (keyword_set(no_header)) then write_header= 0
x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
; print, ' Do_Scan started scan ', sPV
px = fltarr(1000)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
; print, ' Do_Scan Done'
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
(*p).data.cpt1d = cpt
print, ' Point ', cpt, ' of ', (*p).data.mpts1d
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim eq 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
print, ' time remaining = ' , dt, x, c2, (*p).data.mpts2d
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif
if ((*p).data.save_med eq 1) then begin
x = caget((*p).data.med_clientwait_pv, busy)
if (busy eq 0) then x = write_med_file(p,cpt)
endif
s = caget(sPV+'.EXSC', r)
if (s ne 0) then begin
wait, 0.05
s = caget(sPV+'.EXSC', r)
endif
if ((s eq 0) and (r eq 0)) then begin
print, 'scan finished ', cpt, f2a((*p).data.mpts1d)
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
if( (*p).data.save_med eq 1) then begin
x = caget((*p).data.med_clientwait_pv, busy)
if (busy eq 0) then x = write_med_file(p,cpt)
endif
;
wait, 1.50
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
(*p).data.cpt2d = 0
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan ', (*p).data.scan_dim , ' dimensional scan'
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.cpt2d = 0
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if ((*p).data.scan_dim eq 2) then begin
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + $
' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
px = (*p).data.p2a[i,*]
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.25
endif else begin
widget_control, event.id, get_uvalue=uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; update detector selection
det = (*p).es->get_param('detectors')
det_desc = list_detectors(det,MAX_DET)
Widget_Control, (*p).form.ysel, set_value=det_desc
Widget_Control, (*p).form.ysel, set_droplist_SELECT = 0
;
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim eq 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
print , ' ABORT !! '
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'pcolor': begin ; color to plot with
isym = Widget_Info( (*p).form.pcol, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'save_med': begin
(*p).data.save_med = event.select
print, ' set save med to ', (*p).data.save_med
x = caput((*p).data.med_enableclient, event.select)
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
print, 'Scan Viewer version 1.0'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
dgrp = es->get_param('detgroups')
MED_PV = dgrp.prefix[1]
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
!p.background = set_color('white')
!p.color = set_color('black')
caSetTimeout, 0.01
caSetRetryCount, 200
det_desc = list_detectors(det,MAX_DET)
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 500
cpt2d = 0
cpt1d = 0
medx = obj_new('EPICS_MED', MED_PV)
med_enableclient = MED_PV + 'EnableClientWait'
med_clientwait_pv = MED_PV + 'ClientWait'
;
data = {da:da, pa:pa, p2a:p2a, mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $,
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
save_med:0L, med_enableclient:med_enableclient, med_clientwait_pv:med_clientwait_pv, $
npts2:0, p2pv:p2pv, ipts2:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, save_med:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'black', $
'yellow', 'red', 'cyan', 'blue']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',$
ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot, med_obj:medx}
info.data.save_med = 0
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det_desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det_desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
mright = widget_base(mid,/col)
mxx = widget_base(mright,/row)
x = Widget_Label(mxx, value = 'Delay Between Scans')
timx = 5.0
info.form.wait2dscan = CW_Field(mxx, value= timx, uval= 'wait2dscan', $
title = '', xsize=5,$
/return_events, /floating)
mxx = widget_base(mright,/row)
bbase = Widget_Base(mxx, /nonexclusive)
info.form.save_med = Widget_Button(bbase, xsize=60, value = ' ', uvalue= 'save_med')
x = Widget_Label(mxx, value = 'Save full MED spectra')
Widget_Control, info.form.save_med, set_button=0
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer.pro 0100644 0000621 0000620 00000053134 07335344043 014171 0 ustar epics epics function write_med_file, p, cpt
;
; write med data file for full spectra
;
med_file = (*p).data.datafile + '_xrf_'+ f2a(cpt+1)
if ((*p).data.scan_dim eq 2) then begin
med_file = (*p).data.datafile + '_xrf_'+ f2a((*p).data.ipts2+1) + '_' + f2a(cpt+1)
endif
(*p).med_obj->write_file, med_file
print, ' wrote med file = ', med_file
return, 0
end
pro check_feedback, p
print, ' check feedback'
return
end
pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
write_header = 1
if (keyword_set(no_header)) then write_header= 0
x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
; print, ' Do_Scan started scan ', sPV
px = fltarr(1000)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
; print, ' Do_Scan Done'
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
(*p).data.cpt1d = cpt
print, ' Point ', cpt, ' of ', (*p).data.mpts1d
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
; print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim eq 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
; print, ' time remaining = ' , dt, x, c2, (*p).data.mpts2d
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif
if ((*p).data.save_med eq 1) then begin
am_waiting = 0
x = caget((*p).data.scan_iswaiting, am_waiting)
; print, ' save med, scan wait: ', am_waiting
if (am_waiting eq 1) then begin
x = write_med_file(p,cpt)
wait, 0.05
x = caput((*p).data.scan_waitcount, 0)
endif
endif
s = caget(sPV+'.EXSC', r)
if (s ne 0) then begin
wait, 0.02
s = caget(sPV+'.EXSC', r)
endif
if ((s eq 0) and (r eq 0)) then begin
print, 'scan done. '
cpt = -1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
(*p).data.cpt2d = 0
(*p).data.cpt1d = 0
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan ', (*p).data.scan_dim , ' dimensional scan'
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.cpt2d = 0
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if ((*p).data.scan_dim eq 2) then begin
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + $
' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
px = (*p).data.p2a[i,*]
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
x = wait_for_motor(motor = (*p).data.p2pv[0], maxtrys=200, wait_time=0.2)
wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.25
endif else begin
widget_control, event.id, get_uvalue=uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; update detector selection
det = (*p).es->get_param('detectors')
det_desc = list_detectors(det,MAX_DET)
Widget_Control, (*p).form.ysel, set_value=det_desc
Widget_Control, (*p).form.ysel, set_droplist_SELECT = (*p).plot.det
;
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim eq 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
; print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
print , ' SCAN ABORTING '
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'pcolor': begin ; color to plot with
isym = Widget_Info( (*p).form.pcol, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'save_med': begin
(*p).data.save_med = event.select
x = caput ((*p).data.scan_autowait, event.select)
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
print, 'Scan Viewer version 1.0'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
dgrp = es->get_param('detgroups')
MED_PV = dgrp.prefix[1]
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
!p.background = set_color('white')
!p.color = set_color('black')
caSetTimeout, 0.01
caSetRetryCount, 200
det_desc = list_detectors(det,MAX_DET)
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 500
cpt2d = 0
cpt1d = 0
medx = obj_new('EPICS_MED', MED_PV)
scan_autowait = sPV + '.AWCT'
scan_iswaiting = sPV + '.WTNG'
scan_waitcount = sPV + '.WAIT'
;
data = {da:da, pa:pa, p2a:p2a, mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $,
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, save_med:0L, $
scan_autowait:scan_autowait, scan_iswaiting:scan_iswaiting, $
scan_waitcount:scan_waitcount, $
npts2:0, p2pv:p2pv, ipts2:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, save_med:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'black', $
'yellow', 'red', 'cyan', 'blue']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',$
ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot, med_obj:medx}
info.data.save_med = 0
x = caget(scan_autowait, m)
if (m ge 1) then begin
info.data.save_med = 1
x = caput(scan_autowait, 1)
endif
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det_desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det_desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='Titles:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
mright = widget_base(mid,/col)
mxx = widget_base(mright,/row)
x = Widget_Label(mxx, value = 'Delay Between Scans')
timx = 5.0
info.form.wait2dscan = CW_Field(mxx, value= timx, uval= 'wait2dscan', $
title = '', xsize=5,$
/return_events, /floating)
mxx = widget_base(mright,/row)
bbase = Widget_Base(mxx, /nonexclusive)
info.form.save_med = Widget_Button(bbase, xsize=60, value = '', uvalue= 'save_med')
x = Widget_Label(mxx, value = 'Save full MED spectra')
Widget_Control, info.form.save_med, set_button= info.data.save_med
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer_save.pro 0100644 0000621 0000620 00000051701 07316223457 015211 0 ustar epics epics function write_med_file, p, cpt
med_file = (*p).data.datafile + '_med_'+ f2a(cpt) +'_'+ f2a((*p).data.ipts2)
print, ' saving med ', med_file
(*p).med_obj->write_file, med_file
return, 0
end
pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
; print, ' in Do_Scan'
write_header = 1
if (keyword_set(no_header)) then write_header= 0
x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
print, ' Do_Scan started scan ', sPV
px = fltarr(1000)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
print, ' Do_Scan Done'
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
(*p).data.cpt1d = cpt
print, ' Point ', cpt, ' of ', (*p).data.mpts1d
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
if( (*p).data.save_med eq 1) then begin
print, ' pause to write med file, ', cpt
x = caput((*p).data.pausepv, 1)
x = write_med_file(p,cpt)
x = caput((*p).data.pausepv, 0)
print, ' unpause from med write'
endif
endif
if ( (*p).data.save_med eq 1 ) then begin
print, ' pause to write med file, ', cpt
x = caput((*p).data.pausepv, 1)
x = write_med_file(p,cpt)
x = caput((*p).data.pausepv, 0)
print, ' unpause from med write'
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim eq 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
print, ' time remaining = ' , dt, x, c2, (*p).data.mpts2d
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif
s = caget(sPV+'.EXSC', r)
if (s ne 0) then begin
wait, 0.05
s = caget(sPV+'.EXSC', r)
endif
if ((s eq 0) and (r eq 0)) then begin
print, 'scan finished ', cpt, f2a((*p).data.mpts1d)
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
if( (*p).data.save_med eq 1) then begin
print, ' pause to write med file, ', cpt
x = caput((*p).data.pausepv, 1)
x = write_med_file(p,cpt)
x = caput((*p).data.pausepv, 0)
print, ' unpause from med write'
endif
;
wait, 1.50
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
(*p).data.cpt2d = 0
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan ', (*p).data.scan_dim , ' dimensional scan'
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.cpt2d = 0
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if ((*p).data.scan_dim eq 2) then begin
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + $
' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
px = (*p).data.p2a[i,*]
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.25
endif else begin
widget_control, event.id, get_uvalue=uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim eq 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
print , ' ABORT !! '
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'save_med': begin
(*p).data.save_med = event.select
print, ' set save med to ', (*p).data.save_med
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
print, 'Scan Viewer version 1.0'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
caSetTimeout, 0.01
caSetRetryCount, 200
; print, ' scanPV = ', sc.scanPV, cur_dim
; print, 'mpts: ' , mpts1d, mpts2d, ' current dimension = ', cur_dim
for i = 0, n_elements(det.desc) - 1 do begin
if (det.desc[i] eq '') then det.desc[i] = '-unused-'
endfor
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 500
cpt2d = 0
cpt1d = 0
medx = obj_new('EPICS_MED', '13GE1:med:' )
;
data = {da:da, pa:pa, p2a:p2a, mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $,
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, save_med:0L, $
npts2:0, p2pv:p2pv, ipts2:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, save_med:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'black', $
'yellow', 'red', 'cyan', 'blue']
colorsvals = ['FFFFFF'x, '000000'x, $,
'00FFFF'x, '0000FF'x, 'FFFF00'x, 'FF0000'x]
; !p.background = set_color('white')
; !p.color = set_color('black')
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',$
ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot, med_obj:medx}
info.data.save_med = 0
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det.desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
mright = widget_base(mid,/col)
mxx = widget_base(mright,/row)
x = Widget_Label(mxx, value = 'Delay Between Scans')
timx = 5.0
info.form.wait2dscan = CW_Field(mxx, value= timx, uval= 'wait2dscan', $
title = '', xsize=5,$
/return_events, /floating)
mxx = widget_base(mright,/row)
bbase = Widget_Base(mxx, /nonexclusive)
info.form.save_med = Widget_Button(bbase, xsize=60, value = ' ', uvalue= 'save_med')
x = Widget_Label(mxx, value = 'Save full MED spectra')
Widget_Control, info.form.save_med, set_button=0
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/scan_viewer_work.pro 0100644 0000621 0000620 00000052366 07316442745 015250 0 ustar epics epics function write_med_file, p, cpt
;
; write med data file for full spectra
;
med_file = (*p).data.datafile + '_med_'+ f2a(cpt) +'_'+ f2a((*p).data.ipts2)
(*p).med_obj->write_file, med_file
print, ' saved med ', med_file
x = caput((*p).data.med_clientwait_pv, 0)
; wait for
repeat x = caget((*p).data.med_clientwait_pv, counting) until (counting)
return, x
end
pro do_scan1d, p, no_header=no_header
;
; does 'scan1' for scan_viewer
write_header = 1
if (keyword_set(no_header)) then write_header= 0
x = caput((*p).data.pausepv, 0)
(*p).data.scanning = 1
(*p).data.paused = 0
; (*p).data.start_time = xtime_s()
Widget_Control, (*p).form.usertext, get_value=titles
if (write_header) then begin
x = (*p).es->start_scan1d(user_titles=titles)
endif else begin
x = (*p).es->start_scan1d(/no_header)
endelse
sPV = (*p).data.scanPV
; print, ' Do_Scan started scan ', sPV
px = fltarr(1000)
for i = 0, 3 do begin
x = string(i+1,format='(i1.1)')
s = caget(sPV+'.P'+x+'PA', px)
(*p).data.pa[i,*] = px
endfor
x = (*p).es->get_param('total_time')
widget_control, (*p).form.time_est, set_value= sec2hms( x )
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
widget_control, (*p).form.start_btn, set_value='Abort Scan'
widget_control, (*p).form.progress, set_value='Scan Starting'
widget_control, (*p).form.timer, time = 0.25
; print, ' Do_Scan Done'
return
end
pro scan_viewer_event, event
@scan_include
sPV = (*p).data.scanPV
if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin
cpt = -1
j = caget(sPV+'.CPT', ipt)
if (j eq 0) then cpt = ipt
if (cpt gt (*p).data.cpt1d) then begin
(*p).data.cpt1d = cpt
print, ' Point ', cpt, ' of ', (*p).data.mpts1d
for i = 0, MAX_DET-1 do begin
; det = string(i+1,format='(i1.1)')
; if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'CV', x)
(*p).data.da[i,cpt-1] = x
endfor
iya = (*p).plot.det
jmon = (*p).plot.monitor
print, ' ', cpt, (*p).data.pa[0,cpt-1], (*p).data.da[iya,cpt-1]
if (cpt gt 1) then begin
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
(*p).data.x_cur = (*p).data.pa[0,cpt-1]
(*p).data.y_cur = (*p).data.da[iya,cpt-1]
(*p).data.monitor = (*p).data.da[jmon,cpt-1]
widget_control, (*p).form.xpos, set_value= f2a((*p).data.x_cur)
widget_control, (*p).form.ypos, set_Value= f2a((*p).data.y_cur)
widget_control, (*p).form.imon, set_Value= f2a((*p).data.monitor)
prog_str = " Point " + f2a(cpt) + " / " + f2a( (*p).data.mpts1d )
if ((*p).data.scan_dim eq 2) then begin
prog_str = '2D Scan '+ f2a((*p).data.ipts2) + ' / ' + $
f2a((*p).data.npts2) + ' ' + prog_str
endif
widget_control, (*p).form.progress, set_value = prog_str
(*p).data.cpt2d = (*p).data.cpt2d + 1
c2 = (*p).data.cpt2d
dt = (xtime_s() - (*p).data.start_time)
x = dt * ((*p).data.mpts2d - c2) / c2
print, ' time remaining = ' , dt, x, c2, (*p).data.mpts2d
widget_control, (*p).form.time_rem, set_value = sec2hms(x)
endif
if ((*p).data.save_med eq 1) then begin
x = caget((*p).data.med_clientwait_pv, busy)
if (busy eq 0) then x = write_med_file(p,cpt)
endif
s = caget(sPV+'.EXSC', r)
if (s ne 0) then begin
wait, 0.05
s = caget(sPV+'.EXSC', r)
endif
if ((s eq 0) and (r eq 0)) then begin
print, 'scan finished ', cpt, f2a((*p).data.mpts1d)
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt1d = 0
widget_control, (*p).form.start_btn, set_value= 'Start Scan'
widget_control, (*p).form.progress, set_value= 'Scan Finished'
; final plot
i = (*p).plot.det
;det = string(i+1,format='(i1.1)')
;if (i ge 9) then det = string(byte(i + 56))
det = string(i+1,format='(i2.2)')
s = caget(sPV+'.D'+det+'DA', x)
(*p).data.da[i,*] = x
npt = (*p).data.mpts1d
plot, (*p).data.pa[0,0:npt-1], (*p).data.da[i,0:npt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
if( (*p).data.save_med eq 1) then begin
x = caget((*p).data.med_clientwait_pv, busy)
if (busy eq 0) then x = write_med_file(p,cpt)
endif
;
wait, 1.50
; 1d scan: close scanfile, increment scanfile, open next scanfile
if ((*p).data.scan_dim eq 1) then begin
x = (*p).es->write_scan_data()
x = (*p).es->close_scanfile()
(*p).data.cpt2d = 0
prog_str = ' Scan Done: wrote '+ (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
; multiple 1d scan:
if ((*p).data.n_scans gt (*p).data.iscan) then begin
(*p).data.iscan = (*p).data.iscan + 1
widget_control, (*p).form.progress, set_value=' Waiting ...'
widget_control, (*p).form.iscan , set_value= f2a((*p).data.iscan)
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
printf, lun, '; Epics Scan ', (*p).data.scan_dim , ' dimensional scan'
wait, (*p).data.wait2dscan
prog_str = ' starting scan '+ f2a((*p).data.iscan)+ ' of '+ f2a((*p).data.n_scans)
widget_control, (*p).form.progress, set_value= prog_str
(*p).data.cpt2d = 0
(*p).data.start_time = xtime_s()
do_scan1d, p
endif
endif else if ((*p).data.scan_dim eq 2) then begin
short_labels= 1
if ((*p).data.ipts2 gt 1 ) then short_labels=0
x = (*p).es->write_scan_data(short_labels=short_labels)
prog_str = ' 2D Scan: ' + f2a((*p).data.ipts2) + ' / ' + f2a((*p).data.npts2) + $
' Done: wrote ' + (*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
if ( ((*p).data.scanabort eq 0 ) and $
((*p).data.ipts2 lt (*p).data.npts2) ) then begin
inn = (*p).data.ipts2
(*p).data.ipts2 = (*p).data.ipts2 + 1
(*p).data.lun = (*p).es->get_param('lun')
for i = 0, 3 do begin
px = (*p).data.p2a[i,*]
pv_n = (*p).data.p2pv[i]
if (pv_n ne '') then begin
x = caput(pv_n, (*p).data.p2a[i,inn] )
printf, (*p).data.lun, ';2D ', pv_n, ': ', f2a((*p).data.p2a[i,inn])
endif
endfor
wait, (*p).data.wait2dscan
widget_control, (*p).form.progress, set_value='Starting ...'
do_scan1d, p, /no_header
endif else begin
x = (*p).es->close_scanfile()
prog_str = ' 2D Scan Done: wrote ' + (*p).data.datafile
(*p).data.datafile = increment_scanname ( (*p).data.datafile )
x = (*p).es->set_param('datafile', (*p).data.datafile )
widget_control, (*p).form.datafile, set_value=(*p).data.datafile
widget_control, (*p).form.progress, set_value= prog_str
endelse
endif
endif
if (((*p).data.scanning eq 1) and $
((*p).data.paused eq 0) ) then widget_control, event.id, timer=0.25
endif else begin
widget_control, event.id, get_uvalue=uval
case uval of
'exit': Widget_Control, event.top, /destroy
'proc': begin
end
'start_scan': begin
(*p).data.scanabort= 0
if ((*p).data.scanning eq 0) then begin
widget_control, (*p).form.progress, set_value='Waiting ...'
; update detector selection
det = (*p).es->get_param('detectors')
det_desc = list_detectors(det,MAX_DET)
Widget_Control, (*p).form.ysel, set_value=det_desc
Widget_Control, (*p).form.ysel, set_droplist_SELECT = 0
;
; get data file name from form.datafile widget, open file and start writing
; to it
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
(*p).data.iscan = 1
dim = (*p).data.scan_dim
lun = (*p).es->open_scanfile(/append)
(*p).data.lun = lun
sc1 = (*p).es->get_param('scan1')
(*p).data.mpts1d = sc1.npts_total
(*p).data.mpts2d = (*p).es->get_param('npts_total')
printf, lun, '; Epics Scan ', dim , ' dimensional scan'
if (dim eq 2) then begin
; 2d scan: get pvs needed for 2d scan, move to starting point
sc2 = (*p).es->get_param('scan2')
s2PV = sc2.scanPV
(*p).data.npts2 = sc2.npts_total
px = fltarr(sc2.npts_total+2)
pv_n = ''
for i = 0, 3 do begin
print, ' i = ', i
x = string(i+1,format='(i1.1)')
s = caget(s2PV+'.P'+x+'PA', px)
s = caget(s2PV+'.P'+x+'PV', pv_n)
for jj = 0, n_elements(px)-1 do begin
(*p).data.p2a[i,jj] = px[jj]
endfor
(*p).data.p2pv[i] = pv_n
if (pv_n ne '') then begin
x = caput( pv_n , (*p).data.p2a[i,0] )
printf, (*p).data.lun, ';2D ', pv_n, $
': ', f2a((*p).data.p2a[i,0])
endif
endfor
(*p).data.ipts2 = 1
endif
(*p).data.start_time = xtime_s()
do_scan1d, p
endif else begin
; abort scan
(*p).data.scanabort= 1
(*p).data.scanning = 0
(*p).data.paused = 0
(*p).data.cpt2d = 0
x = caput((*p).data.abortpv, 1)
print , ' ABORT !! '
x = caput(sPV + '.EXSC', 0)
widget_control, (*p).form.start_btn, set_value='Start Scan'
widget_control, (*p).form.progress, set_value='Scan Aborted'
endelse
end
'pause_scan': begin
if ((*p).data.scanning eq 1) then begin
if ((*p).data.paused eq 0) then begin
(*p).data.paused = 1
widget_control, (*p).form.pause_btn, set_value='Resume '
widget_control, (*p).form.progress, set_value='Scan Paused'
x = caput((*p).data.pausepv, 1)
endif else begin
(*p).data.paused = 0
widget_control, (*p).form.pause_btn, set_value='Pause Scan'
x = caput((*p).data.pausepv, 0)
widget_control, (*p).form.timer, time = 0.25
endelse
endif
end
'psym': begin ; symbol to plot with
isym = Widget_Info( (*p).form.psym, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'pcolor': begin ; color to plot with
isym = Widget_Info( (*p).form.pcol, /droplist_select)
case isym of
0: (*p).plot.psym = 0
1: (*p).plot.psym = -1
2: (*p).plot.psym = -2
3: (*p).plot.psym = 1
4: (*p).plot.psym = 2
endcase
end
'ysel': begin ;detector to plot
iya = Widget_Info( (*p).form.ysel, /droplist_select)
(*p).plot.det = iya
cpt = -1
st = caget(sPV+'.CPT', ipt)
if (st eq 0) then begin
cpt = ipt
wset, (*p).form.draw_id
plot, (*p).data.pa[0,0:cpt-1], (*p).data.da[iya,0:cpt-1], $
psym=fix((*p).plot.psym), chars = 1.4, ystyle=16
endif
end
'mon_sel': begin ;monitor: show value of this detector
j = Widget_Info( (*p).form.mon_sel, /droplist_select)
(*p).plot.monitor = j
end
'wait2dscan': begin ;time to wait to start 2d scan
Widget_Control, (*p).form.wait2dscan, get_value=t
(*p).data.wait2dscan = a2f(t)
end
'n_scans': begin
Widget_Control, (*p).form.n_scans, get_value=t
; print, ' # of scans = ', t
(*p).data.n_scans = fix(strtrim(t,2))
end
'scan_dim': begin
t = Widget_Info( (*p).form.scan_dim, /droplist_select)
; print, ' scan dimension = ', t
(*p).data.scan_dim = t + 1
x = (*p).es->set_param('dimension', (*p).data.scan_dim )
end
'datafile': begin
Widget_Control, (*p).form.datafile, get_value=t
(*p).data.datafile = strtrim(t,2)
x = (*p).es->set_param('datafile', (*p).data.datafile )
end
'usertext': begin
end
'colors': begin
end
'save_med': begin
(*p).data.save_med = event.select
print, ' set save med to ', (*p).data.save_med
x = caput((*p).data.med_enableclient, event.select)
end
'linestyles': begin
end
else: print, ' unknown event ', uval
endcase
endelse
return
end
function scan_viewer, es
;
; gui for selecting detectors
;
print, 'Scan Viewer version 1.0'
;
; current scan is __always__ scan1
@scan_dims
sc = es->get_param('scan1')
datafile = es->get_param('datafile')
mpts2d = es->get_param('npts_total')
det = es->get_param('detectors')
cur_dim = es->get_param('dimension')
dgrp = es->get_param('detgroups')
MED_PV = d.prefix[1]
prefix = es->get_param('prefix')
pausepv = prefix + 'scanPause.VAL'
abortpv = prefix + 'AbortScans.PROC'
sPV = sc.scanPV
mpts1d = sc.npts_total
!p.background = set_color('white')
!p.color = set_color('black')
caSetTimeout, 0.01
caSetRetryCount, 200
det_desc = list_detectors(det,MAX_DET)
pa = fltarr( 4, MAX_SCAN_POINTS)
p2a = fltarr( 4, MAX_SCAN_POINTS)
p2pv = strarr( 4)
da = fltarr(MAX_DET, MAX_SCAN_POINTS)
xsize = 800
ysize = 500
cpt2d = 0
cpt1d = 0
medx = obj_new('EPICS_MED', MED_PV)
med_enableclient = MED_PV + 'EnableClientWait'
med_clientwait_pv = MED_PV + 'ClientWait'
;
data = {da:da, pa:pa, p2a:p2a, mpts1d:mpts1d, mpts2d:mpts2d,xsize:xsize, ysize:ysize, $
x_cur:0., y_cur:0., monitor:0., datafile:datafile, scan_dim:1, $,
scanning:0, paused:0, n_scans:1, cpt2d:cpt2d, cpt1d:cpt1d, scanPV:sPV ,$
pausepv:pausepv, abortpv:abortpv, iscan:1 , start_time:0.d00, $
save_med:0L, med_enableclient:med_enableclient, med_clientwait_pv:med_clientwait_pv, $
npts2:0, p2pv:p2pv, ipts2:0, lun:0, wait2dscan:5.00, scanabort:0}
form = {xpos:0L, ypos:0L, imon:0L, ppos:0L, datafile:0L, $
ysel:0L, mon_sel:0L, iscan:0L, usertext:0L, psym:0L, $
pause_btn:0L, start_btn:0L, progress:0L, wait2dscan:0L, save_med:0L, $
user_text:0L, n_scans:0L, scan_dim:0L, time_est:0L, time_rem:0L,$
det_choice:0L, time:0L, timer:0L, draw:0L, draw_id:0L}
plot_syms = ['Solid', '-+-', '-*-', ' + ', ' * ']
plot_colors = ['white', 'black', $
'yellow', 'red', 'cyan', 'blue']
plot = {det:0, monitor:0L, color:0L, psym:0, xlab:'',$
ylab:'', title:'', charsize:1.3}
data.scanning = 0
data.scanabort = 0
data.paused = 0
info = {es:es, det:det, data:data, form:form, plot:plot, med_obj:medx}
info.data.save_med = 0
main = Widget_Base(title = 'Scan Viewer', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
top = widget_base(main,/row)
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = 'Detector to Plot: ')
info.form.ysel = Widget_DROPLIST(tl, value = det_desc, title=' ', $
uvalue = 'ysel', /dynamic_resize)
info.form.ypos = Widget_Label(tl, value = strtrim(string(data.y_cur),2), xsize=100 )
Widget_Control, info.form.ysel, set_droplist_SELECT = 0
X = Widget_Label(tl, value = 'Symbol: ')
info.form.psym = Widget_DROPLIST(tl, value = plot_syms, title=' ', $
uvalue = 'psym', /dynamic_resize)
Widget_Control, info.form.psym, set_droplist_SELECT = 0
tl = widget_base(top,/row,/frame)
X = Widget_Label(tl, value = ' Monitor: ')
info.form.mon_sel = Widget_DROPLIST(tl, value = det_desc, title=' ', $
uvalue = 'mon_sel', /dynamic_resize)
info.form.imon = Widget_Label(tl, value = strtrim(string(data.monitor),2),xsize=100)
Widget_Control, info.form.mon_sel, set_droplist_SELECT = 0
info.form.timer = widget_base(main,/row)
info.form.draw = widget_draw(info.form.timer, xsize=xsize, ysize=ysize)
mid = widget_base(main,/row)
scs = widget_base(mid,/row, /frame)
info.form.datafile = CW_Field(scs, title = 'File Name', $
xsize = 35, uval = 'datafile', $
value = strtrim(datafile,2), $
/return_events)
scs = widget_base(mid,/row, /frame)
x = Widget_Label(scs, value = 'Scan # ')
info.form.iscan = Widget_Label(scs, value = strtrim(string(data.iscan),2) )
info.form.n_scans = CW_Field(scs, title = 'of Total # of Scans', $
xsize = 4, uval = 'n_scans', $
value = strtrim(string(data.n_scans),2), $
/return_events, /floating)
scan_dims = ['1', '2', '3']
info.data.scan_dim = cur_dim
cur_dim = cur_dim - 1
scs = widget_base(mid,/row, /frame)
info.form.scan_dim = Widget_Droplist(scs, value= scan_dims, uval= 'scan_dim', $
title = ' Scan dimension: ')
Widget_Control, info.form.scan_dim, set_Droplist_SELECT = cur_dim
mid = widget_base(main,/row)
x = widget_label(mid, value='title lines:')
info.form.usertext = Widget_Text(mid, xsize=60,ysize=3, uval='usertext',$
/editable, value="")
mright = widget_base(mid,/col)
mxx = widget_base(mright,/row)
x = Widget_Label(mxx, value = 'Delay Between Scans')
timx = 5.0
info.form.wait2dscan = CW_Field(mxx, value= timx, uval= 'wait2dscan', $
title = '', xsize=5,$
/return_events, /floating)
mxx = widget_base(mright,/row)
bbase = Widget_Base(mxx, /nonexclusive)
info.form.save_med = Widget_Button(bbase, xsize=60, value = ' ', uvalue= 'save_med')
x = Widget_Label(mxx, value = 'Save full MED spectra')
Widget_Control, info.form.save_med, set_button=0
bot = widget_base(main,/row)
but = widget_base(bot, /row)
; x = widget_button(but, val='Zoom', uval = 'zoom')
info.form.start_btn = widget_button(but, val='Start Scan', $
uval = 'start_scan')
info.form.pause_btn = widget_button(but, val='Pause Scan', uval = 'pause_scan')
x = widget_button(but, val=' Exit ', uval = 'exit')
x = widget_label(bot, value = 'Estimated time:')
info.form.time_est = Widget_Label(bot, xsize=190,value = ' ')
x = es->get_param('total_time')
widget_control, info.form.time_est, set_Value= sec2hms( x )
bot = widget_base(main,/row)
pbar = widget_base(bot,/row,/frame)
x = Widget_Label(pbar, value = "Info:")
info.form.progress = Widget_Label(pbar, xsize =300, value = 'Ready To Scan')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'X Position: ')
info.form.xpos = Widget_Label(xbar, xsize = 110, value = ' ')
xbar = widget_base(bot,/row,/frame)
x = Widget_Label(xbar, value = 'Time Remaining: ')
info.form.time_rem = Widget_Label(xbar, xsize = 120, value = ' ')
Widget_Control, main, /realize
Widget_Control, info.form.draw, get_value=d
info.form.draw_id = d
wset, info.form.draw_id
device, retain=2
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_viewer', main, /no_block
return, 0
end
escan/sc_test.pro 0100664 0000621 0000620 00000000110 07333116474 013317 0 ustar epics epics x = obj_new('scan_data', file = 'test_map.dat')
m = x->show_detectors()
escan/sec2hms.pro 0100644 0000621 0000620 00000000726 07243360521 013224 0 ustar epics epics function sec2hms, x
; convert time in seconds to hhh:mm:ss.dd string
rem = double(x)
hh = long(rem / 3600.)
rem = rem - hh * 3600.
mm = long(rem / 60.)
rem = rem - mm * 60.
ss = abs(long(rem)) < 100
dd = abs(long((rem - ss)*100)) < 1
; print, ' time: ', x
; print, ' hh , mm, ss = ', hh, mm, ss
ff = '(i2.2)'
s = strtrim(string(hh),2) + ':' + string(mm,format=ff) + ':' + $
string(ss,format=ff) + '.' + string(dd,format=ff)
return, s
end
escan/set_color.pro 0100644 0000621 0000620 00000072774 07316233206 013665 0 ustar epics epics function set_color, s
;
; return idl color value based on X color string
;
c = 0
t = strlowcase(strtrim(s,2))
i = 256L
case t of
'floralwhite': c = 255 + (250 + 240 *i) * i
'oldlace': c = 253 + (245 + 230 *i) * i
'linen': c = 250 + (240 + 230 *i) * i
'antiquewhite': c = 250 + (235 + 215 *i) * i
'papayawhip': c = 255 + (239 + 213 *i) * i
'blanchedalmond': c = 255 + (235 + 205 *i) * i
'bisque': c = 255 + (228 + 196 *i) * i
'peachpuff': c = 255 + (218 + 185 *i) * i
'navajowhite': c = 255 + (222 + 173 *i) * i
'moccasin': c = 255 + (228 + 181 *i) * i
'cornsilk': c = 255 + (248 + 220 *i) * i
'ivory': c = 255 + (255 + 240 *i) * i
'lemonchiffon': c = 255 + (250 + 205 *i) * i
'seashell': c = 255 + (245 + 238 *i) * i
'honeydew': c = 240 + (255 + 240 *i) * i
'mint cream': c = 245 + (255 + 250 *i) * i
'mintcream': c = 245 + (255 + 250 *i) * i
'azure': c = 240 + (255 + 255 *i) * i
'aliceblue': c = 240 + (248 + 255 *i) * i
'lavender': c = 230 + (230 + 250 *i) * i
'lavenderblush': c = 255 + (240 + 245 *i) * i
'mistyrose': c = 255 + (228 + 225 *i) * i
'white': c = 255 + (255 + 255 *i) * i
'black': c = 0 + ( 0 + 0 *i) * i
'darkslategray': c = 47 + ( 79 + 79 *i) * i
'darkslategrey': c = 47 + ( 79 + 79 *i) * i
'dimgray': c = 105 + (105 + 105 *i) * i
'dimgrey': c = 105 + (105 + 105 *i) * i
'slategray': c = 112 + (128 + 144 *i) * i
'slategrey': c = 112 + (128 + 144 *i) * i
'lightslategray':c = 119 + (136 + 153 *i) * i
'lightslategrey':c = 119 + (136 + 153 *i) * i
'gray': c = 190 + (190 + 190 *i) * i
'grey': c = 190 + (190 + 190 *i) * i
'lightgrey': c = 211 + (211 + 211 *i) * i
'lightgray': c = 211 + (211 + 211 *i) * i
'midnightblue': c = 25 + ( 25 + 112 *i) * i
'navy': c = 0 + ( 0 + 128 *i) * i
'navyblue': c = 0 + ( 0 + 128 *i) * i
'cornflowerblue':c = 100 + (149 + 237 *i) * i
'darkslateblue': c = 72 + ( 61 + 139 *i) * i
'slateblue': c = 106 + ( 90 + 205 *i) * i
'mediumslateblue': c = 123 + (104 + 238 *i) * i
'lightslateblue': c = 132 + (112 + 255 *i) * i
'mediumblue': c = 0 + ( 0 + 205 *i) * i
'royalblue': c = 65 + (105 + 225 *i) * i
'blue': c = 0 + ( 0 + 255 *i) * i
'dodgerblue': c = 30 + (144 + 255 *i) * i
'deepskyblue': c = 0 + (191 + 255 *i) * i
'skyblue': c = 135 + (206 + 235 *i) * i
'lightskyblue': c = 135 + (206 + 250 *i) * i
'steelblue': c = 70 + (130 + 180 *i) * i
'lightsteelblue': c = 176 + (196 + 222 *i) * i
'lightblue': c = 173 + (216 + 230 *i) * i
'powderblue': c = 176 + (224 + 230 *i) * i
'paleturquoise': c = 175 + (238 + 238 *i) * i
'darkturquoise': c = 0 + (206 + 209 *i) * i
'mediumturquoise': c = 72 + (209 + 204 *i) * i
'turquoise': c = 64 + (224 + 208 *i) * i
'cyan': c = 0 + (255 + 255 *i) * i
'lightcyan': c = 224 + (255 + 255 *i) * i
'cadetblue': c = 95 + (158 + 160 *i) * i
'mediumaquamarine': c = 102 + (205 + 170 *i) * i
'aquamarine': c = 127 + (255 + 212 *i) * i
'darkgreen': c = 0 + (100 + 0 *i) * i
'darkolivegreen': c = 85 + (107 + 47 *i) * i
'darkseagreen': c = 143 + (188 + 143 *i) * i
'seagreen': c = 46 + (139 + 87 *i) * i
'mediumseagreen': c = 60 + (179 + 113 *i) * i
'lightseagreen': c = 32 + (178 + 170 *i) * i
'palegreen': c = 152 + (251 + 152 *i) * i
'springgreen': c = 0 + (255 + 127 *i) * i
'lawngreen': c = 124 + (252 + 0 *i) * i
'green': c = 0 + (255 + 0 *i) * i
'chartreuse': c = 127 + (255 + 0 *i) * i
'mediumspringgreen': c = 0 + (250 + 154 *i) * i
'greenyellow': c = 173 + (255 + 47 *i) * i
'limegreen': c = 50 + (205 + 50 *i) * i
'yellowgreen': c = 154 + (205 + 50 *i) * i
'forestgreen': c = 34 + (139 + 34 *i) * i
'olivedrab': c = 107 + (142 + 35 *i) * i
'darkkhaki': c = 189 + (183 + 107 *i) * i
'khaki': c = 240 + (230 + 140 *i) * i
'palegoldenrod': c = 238 + (232 + 170 *i) * i
'lightgoldenrodyellow': c = 250 + (250 + 210 *i) * i
'lightyellow': c = 255 + (255 + 224 *i) * i
'yellow': c = 255 + (255 + 0 *i) * i
'gold': c = 255 + (215 + 0 *i) * i
'lightgoldenrod': c = 238 + (221 + 130 *i) * i
'goldenrod': c = 218 + (165 + 32 *i) * i
'darkgoldenrod': c = 184 + (134 + 11 *i) * i
'rosybrown': c = 188 + (143 + 143 *i) * i
'indianred': c = 205 + ( 92 + 92 *i) * i
'saddlebrown': c = 139 + ( 69 + 19 *i) * i
'sienna': c = 160 + ( 82 + 45 *i) * i
'peru': c = 205 + (133 + 63 *i) * i
'burlywood': c = 222 + (184 + 135 *i) * i
'beige': c = 245 + (245 + 220 *i) * i
'wheat': c = 245 + (222 + 179 *i) * i
'sandybrown': c = 244 + (164 + 96 *i) * i
'tan': c = 210 + (180 + 140 *i) * i
'chocolate': c = 210 + (105 + 30 *i) * i
'firebrick': c = 178 + ( 34 + 34 *i) * i
'brown': c = 165 + ( 42 + 42 *i) * i
'darksalmon': c = 233 + (150 + 122 *i) * i
'salmon': c = 250 + (128 + 114 *i) * i
'lightsalmon': c = 255 + (160 + 122 *i) * i
'orange': c = 255 + (165 + 0 *i) * i
'darkorange': c = 255 + (140 + 0 *i) * i
'coral': c = 255 + (127 + 80 *i) * i
'lightcoral': c = 240 + (128 + 128 *i) * i
'tomato': c = 255 + ( 99 + 71 *i) * i
'orangered': c = 255 + ( 69 + 0 *i) * i
'red': c = 255 + ( 0 + 0 *i) * i
'hotpink': c = 255 + (105 + 180 *i) * i
'deeppink': c = 255 + ( 20 + 147 *i) * i
'pink': c = 255 + (192 + 203 *i) * i
'lightpink': c = 255 + (182 + 193 *i) * i
'palevioletred': c = 219 + (112 + 147 *i) * i
'maroon': c = 176 + ( 48 + 96 *i) * i
'mediumvioletred': c = 199 + ( 21 + 133 *i) * i
'violetred': c = 208 + ( 32 + 144 *i) * i
'magenta': c = 255 + ( 0 + 255 *i) * i
'violet': c = 238 + (130 + 238 *i) * i
'plum': c = 221 + (160 + 221 *i) * i
'orchid': c = 218 + (112 + 214 *i) * i
'mediumorchid': c = 186 + ( 85 + 211 *i) * i
'darkorchid': c = 153 + ( 50 + 204 *i) * i
'darkviolet': c = 148 + ( 0 + 211 *i) * i
'blueviolet': c = 138 + ( 43 + 226 *i) * i
'purple': c = 160 + ( 32 + 240 *i) * i
'mediumpurple': c = 147 + (112 + 219 *i) * i
'thistle': c = 216 + (191 + 216 *i) * i
'snow1': c = 255 + (250 + 250 *i) * i
'snow2': c = 238 + (233 + 233 *i) * i
'snow3': c = 205 + (201 + 201 *i) * i
'snow4': c = 139 + (137 + 137 *i) * i
'seashell1': c = 255 + (245 + 238 *i) * i
'seashell2': c = 238 + (229 + 222 *i) * i
'seashell3': c = 205 + (197 + 191 *i) * i
'seashell4': c = 139 + (134 + 130 *i) * i
'antiquewhite1': c = 255 + (239 + 219 *i) * i
'antiquewhite2': c = 238 + (223 + 204 *i) * i
'antiquewhite3': c = 205 + (192 + 176 *i) * i
'antiquewhite4': c = 139 + (131 + 120 *i) * i
'bisque1': c = 255 + (228 + 196 *i) * i
'bisque2': c = 238 + (213 + 183 *i) * i
'bisque3': c = 205 + (183 + 158 *i) * i
'bisque4': c = 139 + (125 + 107 *i) * i
'peachpuff1': c = 255 + (218 + 185 *i) * i
'peachpuff2': c = 238 + (203 + 173 *i) * i
'peachpuff3': c = 205 + (175 + 149 *i) * i
'peachpuff4': c = 139 + (119 + 101 *i) * i
'navajowhite1': c = 255 + (222 + 173 *i) * i
'navajowhite2': c = 238 + (207 + 161 *i) * i
'navajowhite3': c = 205 + (179 + 139 *i) * i
'navajowhite4': c = 139 + (121 + 94 *i) * i
'lemonchiffon1': c = 255 + (250 + 205 *i) * i
'lemonchiffon2': c = 238 + (233 + 191 *i) * i
'lemonchiffon3': c = 205 + (201 + 165 *i) * i
'lemonchiffon4': c = 139 + (137 + 112 *i) * i
'cornsilk1': c = 255 + (248 + 220 *i) * i
'cornsilk2': c = 238 + (232 + 205 *i) * i
'cornsilk3': c = 205 + (200 + 177 *i) * i
'cornsilk4': c = 139 + (136 + 120 *i) * i
'ivory1': c = 255 + (255 + 240 *i) * i
'ivory2': c = 238 + (238 + 224 *i) * i
'ivory3': c = 205 + (205 + 193 *i) * i
'ivory4': c = 139 + (139 + 131 *i) * i
'honeydew1': c = 240 + (255 + 240 *i) * i
'honeydew2': c = 224 + (238 + 224 *i) * i
'honeydew3': c = 193 + (205 + 193 *i) * i
'honeydew4': c = 131 + (139 + 131 *i) * i
'lavenderblush1': c = 255 + (240 + 245 *i) * i
'lavenderblush2': c = 238 + (224 + 229 *i) * i
'lavenderblush3': c = 205 + (193 + 197 *i) * i
'lavenderblush4': c = 139 + (131 + 134 *i) * i
'mistyrose1': c = 255 + (228 + 225 *i) * i
'mistyrose2': c = 238 + (213 + 210 *i) * i
'mistyrose3': c = 205 + (183 + 181 *i) * i
'mistyrose4': c = 139 + (125 + 123 *i) * i
'azure1': c = 240 + (255 + 255 *i) * i
'azure2': c = 224 + (238 + 238 *i) * i
'azure3': c = 193 + (205 + 205 *i) * i
'azure4': c = 131 + (139 + 139 *i) * i
'slateblue1': c = 131 + (111 + 255 *i) * i
'slateblue2': c = 122 + (103 + 238 *i) * i
'slateblue3': c = 105 + ( 89 + 205 *i) * i
'slateblue4': c = 71 + ( 60 + 139 *i) * i
'royalblue1': c = 72 + (118 + 255 *i) * i
'royalblue2': c = 67 + (110 + 238 *i) * i
'royalblue3': c = 58 + ( 95 + 205 *i) * i
'royalblue4': c = 39 + ( 64 + 139 *i) * i
'blue1': c = 0 + ( 0 + 255 *i) * i
'blue2': c = 0 + ( 0 + 238 *i) * i
'blue3': c = 0 + ( 0 + 205 *i) * i
'blue4': c = 0 + ( 0 + 139 *i) * i
'dodgerblue1': c = 30 + (144 + 255 *i) * i
'dodgerblue2': c = 28 + (134 + 238 *i) * i
'dodgerblue3': c = 24 + (116 + 205 *i) * i
'dodgerblue4': c = 16 + ( 78 + 139 *i) * i
'steelblue1': c = 99 + (184 + 255 *i) * i
'steelblue2': c = 92 + (172 + 238 *i) * i
'steelblue3': c = 79 + (148 + 205 *i) * i
'steelblue4': c = 54 + (100 + 139 *i) * i
'deepskyblue1': c = 0 + (191 + 255 *i) * i
'deepskyblue2': c = 0 + (178 + 238 *i) * i
'deepskyblue3': c = 0 + (154 + 205 *i) * i
'deepskyblue4': c = 0 + (104 + 139 *i) * i
'skyblue1': c = 135 + (206 + 255 *i) * i
'skyblue2': c = 126 + (192 + 238 *i) * i
'skyblue3': c = 108 + (166 + 205 *i) * i
'skyblue4': c = 74 + (112 + 139 *i) * i
'lightskyblue1': c = 176 + (226 + 255 *i) * i
'lightskyblue2': c = 164 + (211 + 238 *i) * i
'lightskyblue3': c = 141 + (182 + 205 *i) * i
'lightskyblue4': c = 96 + (123 + 139 *i) * i
'slategray1': c = 198 + (226 + 255 *i) * i
'slategray2': c = 185 + (211 + 238 *i) * i
'slategray3': c = 159 + (182 + 205 *i) * i
'slategray4': c = 108 + (123 + 139 *i) * i
'lightsteelblue1': c = 202 + (225 + 255 *i) * i
'lightsteelblue2': c = 188 + (210 + 238 *i) * i
'lightsteelblue3': c = 162 + (181 + 205 *i) * i
'lightsteelblue4': c = 110 + (123 + 139 *i) * i
'lightblue1': c = 191 + (239 + 255 *i) * i
'lightblue2': c = 178 + (223 + 238 *i) * i
'lightblue3': c = 154 + (192 + 205 *i) * i
'lightblue4': c = 104 + (131 + 139 *i) * i
'lightcyan1': c = 224 + (255 + 255 *i) * i
'lightcyan2': c = 209 + (238 + 238 *i) * i
'lightcyan3': c = 180 + (205 + 205 *i) * i
'lightcyan4': c = 122 + (139 + 139 *i) * i
'paleturquoise1': c = 187 + (255 + 255 *i) * i
'paleturquoise2': c = 174 + (238 + 238 *i) * i
'paleturquoise3': c = 150 + (205 + 205 *i) * i
'paleturquoise4': c = 102 + (139 + 139 *i) * i
'cadetblue1': c = 152 + (245 + 255 *i) * i
'cadetblue2': c = 142 + (229 + 238 *i) * i
'cadetblue3': c = 122 + (197 + 205 *i) * i
'cadetblue4': c = 83 + (134 + 139 *i) * i
'turquoise1': c = 0 + (245 + 255 *i) * i
'turquoise2': c = 0 + (229 + 238 *i) * i
'turquoise3': c = 0 + (197 + 205 *i) * i
'turquoise4': c = 0 + (134 + 139 *i) * i
'cyan1': c = 0 + (255 + 255 *i) * i
'cyan2': c = 0 + (238 + 238 *i) * i
'cyan3': c = 0 + (205 + 205 *i) * i
'cyan4': c = 0 + (139 + 139 *i) * i
'darkslategray1': c = 151 + (255 + 255 *i) * i
'darkslategray2': c = 141 + (238 + 238 *i) * i
'darkslategray3': c = 121 + (205 + 205 *i) * i
'darkslategray4': c = 82 + (139 + 139 *i) * i
'aquamarine1': c = 127 + (255 + 212 *i) * i
'aquamarine2': c = 118 + (238 + 198 *i) * i
'aquamarine3': c = 102 + (205 + 170 *i) * i
'aquamarine4': c = 69 + (139 + 116 *i) * i
'darkseagreen1': c = 193 + (255 + 193 *i) * i
'darkseagreen2': c = 180 + (238 + 180 *i) * i
'darkseagreen3': c = 155 + (205 + 155 *i) * i
'darkseagreen4': c = 105 + (139 + 105 *i) * i
'seagreen1': c = 84 + (255 + 159 *i) * i
'seagreen2': c = 78 + (238 + 148 *i) * i
'seagreen3': c = 67 + (205 + 128 *i) * i
'seagreen4': c = 46 + (139 + 87 *i) * i
'palegreen1': c = 154 + (255 + 154 *i) * i
'palegreen2': c = 144 + (238 + 144 *i) * i
'palegreen3': c = 124 + (205 + 124 *i) * i
'palegreen4': c = 84 + (139 + 84 *i) * i
'springgreen1': c = 0 + (255 + 127 *i) * i
'springgreen2': c = 0 + (238 + 118 *i) * i
'springgreen3': c = 0 + (205 + 102 *i) * i
'springgreen4': c = 0 + (139 + 69 *i) * i
'green1': c = 0 + (255 + 0 *i) * i
'green2': c = 0 + (238 + 0 *i) * i
'green3': c = 0 + (205 + 0 *i) * i
'green4': c = 0 + (139 + 0 *i) * i
'chartreuse1': c = 127 + (255 + 0 *i) * i
'chartreuse2': c = 118 + (238 + 0 *i) * i
'chartreuse3': c = 102 + (205 + 0 *i) * i
'chartreuse4': c = 69 + (139 + 0 *i) * i
'olivedrab1': c = 192 + (255 + 62 *i) * i
'olivedrab2': c = 179 + (238 + 58 *i) * i
'olivedrab3': c = 154 + (205 + 50 *i) * i
'olivedrab4': c = 105 + (139 + 34 *i) * i
'darkolivegreen1': c = 202 + (255 + 112 *i) * i
'darkolivegreen2': c = 188 + (238 + 104 *i) * i
'darkolivegreen3': c = 162 + (205 + 90 *i) * i
'darkolivegreen4': c = 110 + (139 + 61 *i) * i
'khaki1': c = 255 + (246 + 143 *i) * i
'khaki2': c = 238 + (230 + 133 *i) * i
'khaki3': c = 205 + (198 + 115 *i) * i
'khaki4': c = 139 + (134 + 78 *i) * i
'lightgoldenrod1': c = 255 + (236 + 139 *i) * i
'lightgoldenrod2': c = 238 + (220 + 130 *i) * i
'lightgoldenrod3': c = 205 + (190 + 112 *i) * i
'lightgoldenrod4': c = 139 + (129 + 76 *i) * i
'lightyellow1': c = 255 + (255 + 224 *i) * i
'lightyellow2': c = 238 + (238 + 209 *i) * i
'lightyellow3': c = 205 + (205 + 180 *i) * i
'lightyellow4': c = 139 + (139 + 122 *i) * i
'yellow1': c = 255 + (255 + 0 *i) * i
'yellow2': c = 238 + (238 + 0 *i) * i
'yellow3': c = 205 + (205 + 0 *i) * i
'yellow4': c = 139 + (139 + 0 *i) * i
'gold1': c = 255 + (215 + 0 *i) * i
'gold2': c = 238 + (201 + 0 *i) * i
'gold3': c = 205 + (173 + 0 *i) * i
'gold4': c = 139 + (117 + 0 *i) * i
'goldenrod1': c = 255 + (193 + 37 *i) * i
'goldenrod2': c = 238 + (180 + 34 *i) * i
'goldenrod3': c = 205 + (155 + 29 *i) * i
'goldenrod4': c = 139 + (105 + 20 *i) * i
'darkgoldenrod1': c = 255 + (185 + 15 *i) * i
'darkgoldenrod2': c = 238 + (173 + 14 *i) * i
'darkgoldenrod3': c = 205 + (149 + 12 *i) * i
'darkgoldenrod4': c = 139 + (101 + 8 *i) * i
'rosybrown1': c = 255 + (193 + 193 *i) * i
'rosybrown2': c = 238 + (180 + 180 *i) * i
'rosybrown3': c = 205 + (155 + 155 *i) * i
'rosybrown4': c = 139 + (105 + 105 *i) * i
'indianred1': c = 255 + (106 + 106 *i) * i
'indianred2': c = 238 + ( 99 + 99 *i) * i
'indianred3': c = 205 + ( 85 + 85 *i) * i
'indianred4': c = 139 + ( 58 + 58 *i) * i
'sienna1': c = 255 + (130 + 71 *i) * i
'sienna2': c = 238 + (121 + 66 *i) * i
'sienna3': c = 205 + (104 + 57 *i) * i
'sienna4': c = 139 + ( 71 + 38 *i) * i
'burlywood1': c = 255 + (211 + 155 *i) * i
'burlywood2': c = 238 + (197 + 145 *i) * i
'burlywood3': c = 205 + (170 + 125 *i) * i
'burlywood4': c = 139 + (115 + 85 *i) * i
'wheat1': c = 255 + (231 + 186 *i) * i
'wheat2': c = 238 + (216 + 174 *i) * i
'wheat3': c = 205 + (186 + 150 *i) * i
'wheat4': c = 139 + (126 + 102 *i) * i
'tan1': c = 255 + (165 + 79 *i) * i
'tan2': c = 238 + (154 + 73 *i) * i
'tan3': c = 205 + (133 + 63 *i) * i
'tan4': c = 139 + ( 90 + 43 *i) * i
'chocolate1': c = 255 + (127 + 36 *i) * i
'chocolate2': c = 238 + (118 + 33 *i) * i
'chocolate3': c = 205 + (102 + 29 *i) * i
'chocolate4': c = 139 + ( 69 + 19 *i) * i
'firebrick1': c = 255 + ( 48 + 48 *i) * i
'firebrick2': c = 238 + ( 44 + 44 *i) * i
'firebrick3': c = 205 + ( 38 + 38 *i) * i
'firebrick4': c = 139 + ( 26 + 26 *i) * i
'brown1': c = 255 + ( 64 + 64 *i) * i
'brown2': c = 238 + ( 59 + 59 *i) * i
'brown3': c = 205 + ( 51 + 51 *i) * i
'brown4': c = 139 + ( 35 + 35 *i) * i
'salmon1': c = 255 + (140 + 105 *i) * i
'salmon2': c = 238 + (130 + 98 *i) * i
'salmon3': c = 205 + (112 + 84 *i) * i
'salmon4': c = 139 + ( 76 + 57 *i) * i
'lightsalmon1': c = 255 + (160 + 122 *i) * i
'lightsalmon2': c = 238 + (149 + 114 *i) * i
'lightsalmon3': c = 205 + (129 + 98 *i) * i
'lightsalmon4': c = 139 + ( 87 + 66 *i) * i
'orange1': c = 255 + (165 + 0 *i) * i
'orange2': c = 238 + (154 + 0 *i) * i
'orange3': c = 205 + (133 + 0 *i) * i
'orange4': c = 139 + ( 90 + 0 *i) * i
'darkorange1': c = 255 + (127 + 0 *i) * i
'darkorange2': c = 238 + (118 + 0 *i) * i
'darkorange3': c = 205 + (102 + 0 *i) * i
'darkorange4': c = 139 + ( 69 + 0 *i) * i
'coral1': c = 255 + (114 + 86 *i) * i
'coral2': c = 238 + (106 + 80 *i) * i
'coral3': c = 205 + ( 91 + 69 *i) * i
'coral4': c = 139 + ( 62 + 47 *i) * i
'tomato1': c = 255 + ( 99 + 71 *i) * i
'tomato2': c = 238 + ( 92 + 66 *i) * i
'tomato3': c = 205 + ( 79 + 57 *i) * i
'tomato4': c = 139 + ( 54 + 38 *i) * i
'orangered1': c = 255 + ( 69 + 0 *i) * i
'orangered2': c = 238 + ( 64 + 0 *i) * i
'orangered3': c = 205 + ( 55 + 0 *i) * i
'orangered4': c = 139 + ( 37 + 0 *i) * i
'red1': c = 255 + ( 0 + 0 *i) * i
'red2': c = 238 + ( 0 + 0 *i) * i
'red3': c = 205 + ( 0 + 0 *i) * i
'red4': c = 139 + ( 0 + 0 *i) * i
'deeppink1': c = 255 + ( 20 + 147 *i) * i
'deeppink2': c = 238 + ( 18 + 137 *i) * i
'deeppink3': c = 205 + ( 16 + 118 *i) * i
'deeppink4': c = 139 + ( 10 + 80 *i) * i
'hotpink1': c = 255 + (110 + 180 *i) * i
'hotpink2': c = 238 + (106 + 167 *i) * i
'hotpink3': c = 205 + ( 96 + 144 *i) * i
'hotpink4': c = 139 + ( 58 + 98 *i) * i
'pink1': c = 255 + (181 + 197 *i) * i
'pink2': c = 238 + (169 + 184 *i) * i
'pink3': c = 205 + (145 + 158 *i) * i
'pink4': c = 139 + ( 99 + 108 *i) * i
'lightpink1': c = 255 + (174 + 185 *i) * i
'lightpink2': c = 238 + (162 + 173 *i) * i
'lightpink3': c = 205 + (140 + 149 *i) * i
'lightpink4': c = 139 + ( 95 + 101 *i) * i
'palevioletred1': c = 255 + (130 + 171 *i) * i
'palevioletred2': c = 238 + (121 + 159 *i) * i
'palevioletred3': c = 205 + (104 + 137 *i) * i
'palevioletred4': c = 139 + ( 71 + 93 *i) * i
'maroon1': c = 255 + ( 52 + 179 *i) * i
'maroon2': c = 238 + ( 48 + 167 *i) * i
'maroon3': c = 205 + ( 41 + 144 *i) * i
'maroon4': c = 139 + ( 28 + 98 *i) * i
'violetred1': c = 255 + ( 62 + 150 *i) * i
'violetred2': c = 238 + ( 58 + 140 *i) * i
'violetred3': c = 205 + ( 50 + 120 *i) * i
'violetred4': c = 139 + ( 34 + 82 *i) * i
'magenta1': c = 255 + ( 0 + 255 *i) * i
'magenta2': c = 238 + ( 0 + 238 *i) * i
'magenta3': c = 205 + ( 0 + 205 *i) * i
'magenta4': c = 139 + ( 0 + 139 *i) * i
'orchid1': c = 255 + (131 + 250 *i) * i
'orchid2': c = 238 + (122 + 233 *i) * i
'orchid3': c = 205 + (105 + 201 *i) * i
'orchid4': c = 139 + ( 71 + 137 *i) * i
'plum1': c = 255 + (187 + 255 *i) * i
'plum2': c = 238 + (174 + 238 *i) * i
'plum3': c = 205 + (150 + 205 *i) * i
'plum4': c = 139 + (102 + 139 *i) * i
'mediumorchid1': c = 224 + (102 + 255 *i) * i
'mediumorchid2': c = 209 + ( 95 + 238 *i) * i
'mediumorchid3': c = 180 + ( 82 + 205 *i) * i
'mediumorchid4': c = 122 + ( 55 + 139 *i) * i
'darkorchid1': c = 191 + ( 62 + 255 *i) * i
'darkorchid2': c = 178 + ( 58 + 238 *i) * i
'darkorchid3': c = 154 + ( 50 + 205 *i) * i
'darkorchid4': c = 104 + ( 34 + 139 *i) * i
'purple1': c = 155 + ( 48 + 255 *i) * i
'purple2': c = 145 + ( 44 + 238 *i) * i
'purple3': c = 125 + ( 38 + 205 *i) * i
'purple4': c = 85 + ( 26 + 139 *i) * i
'mediumpurple1': c = 171 + (130 + 255 *i) * i
'mediumpurple2': c = 159 + (121 + 238 *i) * i
'mediumpurple3': c = 137 + (104 + 205 *i) * i
'mediumpurple4': c = 93 + ( 71 + 139 *i) * i
'thistle1': c = 255 + (225 + 255 *i) * i
'thistle2': c = 238 + (210 + 238 *i) * i
'thistle3': c = 205 + (181 + 205 *i) * i
'thistle4': c = 139 + (123 + 139 *i) * i
'gray0': c = 0 + ( 0 + 0 *i) * i
'grey0': c = 0 + ( 0 + 0 *i) * i
'gray1': c = 3 + ( 3 + 3 *i) * i
'grey1': c = 3 + ( 3 + 3 *i) * i
'gray2': c = 5 + ( 5 + 5 *i) * i
'grey2': c = 5 + ( 5 + 5 *i) * i
'gray3': c = 8 + ( 8 + 8 *i) * i
'grey3': c = 8 + ( 8 + 8 *i) * i
'gray4': c = 10 + ( 10 + 10 *i) * i
'grey4': c = 10 + ( 10 + 10 *i) * i
'gray5': c = 13 + ( 13 + 13 *i) * i
'grey5': c = 13 + ( 13 + 13 *i) * i
'gray6': c = 15 + ( 15 + 15 *i) * i
'grey6': c = 15 + ( 15 + 15 *i) * i
'gray7': c = 18 + ( 18 + 18 *i) * i
'grey7': c = 18 + ( 18 + 18 *i) * i
'gray8': c = 20 + ( 20 + 20 *i) * i
'grey8': c = 20 + ( 20 + 20 *i) * i
'gray9': c = 23 + ( 23 + 23 *i) * i
'grey9': c = 23 + ( 23 + 23 *i) * i
'gray10': c = 26 + ( 26 + 26 *i) * i
'grey10': c = 26 + ( 26 + 26 *i) * i
'gray11': c = 28 + ( 28 + 28 *i) * i
'grey11': c = 28 + ( 28 + 28 *i) * i
'gray12': c = 31 + ( 31 + 31 *i) * i
'grey12': c = 31 + ( 31 + 31 *i) * i
'gray13': c = 33 + ( 33 + 33 *i) * i
'grey13': c = 33 + ( 33 + 33 *i) * i
'gray14': c = 36 + ( 36 + 36 *i) * i
'grey14': c = 36 + ( 36 + 36 *i) * i
'gray15': c = 38 + ( 38 + 38 *i) * i
'grey15': c = 38 + ( 38 + 38 *i) * i
'gray16': c = 41 + ( 41 + 41 *i) * i
'grey16': c = 41 + ( 41 + 41 *i) * i
'gray17': c = 43 + ( 43 + 43 *i) * i
'grey17': c = 43 + ( 43 + 43 *i) * i
'gray18': c = 46 + ( 46 + 46 *i) * i
'grey18': c = 46 + ( 46 + 46 *i) * i
'gray19': c = 48 + ( 48 + 48 *i) * i
'grey19': c = 48 + ( 48 + 48 *i) * i
'gray20': c = 51 + ( 51 + 51 *i) * i
'grey20': c = 51 + ( 51 + 51 *i) * i
'gray21': c = 54 + ( 54 + 54 *i) * i
'grey21': c = 54 + ( 54 + 54 *i) * i
'gray22': c = 56 + ( 56 + 56 *i) * i
'grey22': c = 56 + ( 56 + 56 *i) * i
'gray23': c = 59 + ( 59 + 59 *i) * i
'grey23': c = 59 + ( 59 + 59 *i) * i
'gray24': c = 61 + ( 61 + 61 *i) * i
'grey24': c = 61 + ( 61 + 61 *i) * i
'gray25': c = 64 + ( 64 + 64 *i) * i
'grey25': c = 64 + ( 64 + 64 *i) * i
'gray26': c = 66 + ( 66 + 66 *i) * i
'grey26': c = 66 + ( 66 + 66 *i) * i
'gray27': c = 69 + ( 69 + 69 *i) * i
'grey27': c = 69 + ( 69 + 69 *i) * i
'gray28': c = 71 + ( 71 + 71 *i) * i
'grey28': c = 71 + ( 71 + 71 *i) * i
'gray29': c = 74 + ( 74 + 74 *i) * i
'grey29': c = 74 + ( 74 + 74 *i) * i
'gray30': c = 77 + ( 77 + 77 *i) * i
'grey30': c = 77 + ( 77 + 77 *i) * i
'gray31': c = 79 + ( 79 + 79 *i) * i
'grey31': c = 79 + ( 79 + 79 *i) * i
'gray32': c = 82 + ( 82 + 82 *i) * i
'grey32': c = 82 + ( 82 + 82 *i) * i
'gray33': c = 84 + ( 84 + 84 *i) * i
'grey33': c = 84 + ( 84 + 84 *i) * i
'gray34': c = 87 + ( 87 + 87 *i) * i
'grey34': c = 87 + ( 87 + 87 *i) * i
'gray35': c = 89 + ( 89 + 89 *i) * i
'grey35': c = 89 + ( 89 + 89 *i) * i
'gray36': c = 92 + ( 92 + 92 *i) * i
'grey36': c = 92 + ( 92 + 92 *i) * i
'gray37': c = 94 + ( 94 + 94 *i) * i
'grey37': c = 94 + ( 94 + 94 *i) * i
'gray38': c = 97 + ( 97 + 97 *i) * i
'grey38': c = 97 + ( 97 + 97 *i) * i
'gray39': c = 99 + ( 99 + 99 *i) * i
'grey39': c = 99 + ( 99 + 99 *i) * i
'gray40': c = 102 + (102 + 102 *i) * i
'grey40': c = 102 + (102 + 102 *i) * i
'gray41': c = 105 + (105 + 105 *i) * i
'grey41': c = 105 + (105 + 105 *i) * i
'gray42': c = 107 + (107 + 107 *i) * i
'grey42': c = 107 + (107 + 107 *i) * i
'gray43': c = 110 + (110 + 110 *i) * i
'grey43': c = 110 + (110 + 110 *i) * i
'gray44': c = 112 + (112 + 112 *i) * i
'grey44': c = 112 + (112 + 112 *i) * i
'gray45': c = 115 + (115 + 115 *i) * i
'grey45': c = 115 + (115 + 115 *i) * i
'gray46': c = 117 + (117 + 117 *i) * i
'grey46': c = 117 + (117 + 117 *i) * i
'gray47': c = 120 + (120 + 120 *i) * i
'grey47': c = 120 + (120 + 120 *i) * i
'gray48': c = 122 + (122 + 122 *i) * i
'grey48': c = 122 + (122 + 122 *i) * i
'gray49': c = 125 + (125 + 125 *i) * i
'grey49': c = 125 + (125 + 125 *i) * i
'gray50': c = 127 + (127 + 127 *i) * i
'grey50': c = 127 + (127 + 127 *i) * i
'gray51': c = 130 + (130 + 130 *i) * i
'grey51': c = 130 + (130 + 130 *i) * i
'gray52': c = 133 + (133 + 133 *i) * i
'grey52': c = 133 + (133 + 133 *i) * i
'gray53': c = 135 + (135 + 135 *i) * i
'grey53': c = 135 + (135 + 135 *i) * i
'gray54': c = 138 + (138 + 138 *i) * i
'grey54': c = 138 + (138 + 138 *i) * i
'gray55': c = 140 + (140 + 140 *i) * i
'grey55': c = 140 + (140 + 140 *i) * i
'gray56': c = 143 + (143 + 143 *i) * i
'grey56': c = 143 + (143 + 143 *i) * i
'gray57': c = 145 + (145 + 145 *i) * i
'grey57': c = 145 + (145 + 145 *i) * i
'gray58': c = 148 + (148 + 148 *i) * i
'grey58': c = 148 + (148 + 148 *i) * i
'gray59': c = 150 + (150 + 150 *i) * i
'grey59': c = 150 + (150 + 150 *i) * i
'gray60': c = 153 + (153 + 153 *i) * i
'grey60': c = 153 + (153 + 153 *i) * i
'gray61': c = 156 + (156 + 156 *i) * i
'grey61': c = 156 + (156 + 156 *i) * i
'gray62': c = 158 + (158 + 158 *i) * i
'grey62': c = 158 + (158 + 158 *i) * i
'gray63': c = 161 + (161 + 161 *i) * i
'grey63': c = 161 + (161 + 161 *i) * i
'gray64': c = 163 + (163 + 163 *i) * i
'grey64': c = 163 + (163 + 163 *i) * i
'gray65': c = 166 + (166 + 166 *i) * i
'grey65': c = 166 + (166 + 166 *i) * i
'gray66': c = 168 + (168 + 168 *i) * i
'grey66': c = 168 + (168 + 168 *i) * i
'gray67': c = 171 + (171 + 171 *i) * i
'grey67': c = 171 + (171 + 171 *i) * i
'gray68': c = 173 + (173 + 173 *i) * i
'grey68': c = 173 + (173 + 173 *i) * i
'gray69': c = 176 + (176 + 176 *i) * i
'grey69': c = 176 + (176 + 176 *i) * i
'gray70': c = 179 + (179 + 179 *i) * i
'grey70': c = 179 + (179 + 179 *i) * i
'gray71': c = 181 + (181 + 181 *i) * i
'grey71': c = 181 + (181 + 181 *i) * i
'gray72': c = 184 + (184 + 184 *i) * i
'grey72': c = 184 + (184 + 184 *i) * i
'gray73': c = 186 + (186 + 186 *i) * i
'grey73': c = 186 + (186 + 186 *i) * i
'gray74': c = 189 + (189 + 189 *i) * i
'grey74': c = 189 + (189 + 189 *i) * i
'gray75': c = 191 + (191 + 191 *i) * i
'grey75': c = 191 + (191 + 191 *i) * i
'gray76': c = 194 + (194 + 194 *i) * i
'grey76': c = 194 + (194 + 194 *i) * i
'gray77': c = 196 + (196 + 196 *i) * i
'grey77': c = 196 + (196 + 196 *i) * i
'gray78': c = 199 + (199 + 199 *i) * i
'grey78': c = 199 + (199 + 199 *i) * i
'gray79': c = 201 + (201 + 201 *i) * i
'grey79': c = 201 + (201 + 201 *i) * i
'gray80': c = 204 + (204 + 204 *i) * i
'grey80': c = 204 + (204 + 204 *i) * i
'gray81': c = 207 + (207 + 207 *i) * i
'grey81': c = 207 + (207 + 207 *i) * i
'gray82': c = 209 + (209 + 209 *i) * i
'grey82': c = 209 + (209 + 209 *i) * i
'gray83': c = 212 + (212 + 212 *i) * i
'grey83': c = 212 + (212 + 212 *i) * i
'gray84': c = 214 + (214 + 214 *i) * i
'grey84': c = 214 + (214 + 214 *i) * i
'gray85': c = 217 + (217 + 217 *i) * i
'grey85': c = 217 + (217 + 217 *i) * i
'gray86': c = 219 + (219 + 219 *i) * i
'grey86': c = 219 + (219 + 219 *i) * i
'gray87': c = 222 + (222 + 222 *i) * i
'grey87': c = 222 + (222 + 222 *i) * i
'gray88': c = 224 + (224 + 224 *i) * i
'grey88': c = 224 + (224 + 224 *i) * i
'gray89': c = 227 + (227 + 227 *i) * i
'grey89': c = 227 + (227 + 227 *i) * i
'gray90': c = 229 + (229 + 229 *i) * i
'grey90': c = 229 + (229 + 229 *i) * i
'gray91': c = 232 + (232 + 232 *i) * i
'grey91': c = 232 + (232 + 232 *i) * i
'gray92': c = 235 + (235 + 235 *i) * i
'grey92': c = 235 + (235 + 235 *i) * i
'gray93': c = 237 + (237 + 237 *i) * i
'grey93': c = 237 + (237 + 237 *i) * i
'gray94': c = 240 + (240 + 240 *i) * i
'grey94': c = 240 + (240 + 240 *i) * i
'gray95': c = 242 + (242 + 242 *i) * i
'grey95': c = 242 + (242 + 242 *i) * i
'gray96': c = 245 + (245 + 245 *i) * i
'grey96': c = 245 + (245 + 245 *i) * i
'gray97': c = 247 + (247 + 247 *i) * i
'grey97': c = 247 + (247 + 247 *i) * i
'gray98': c = 250 + (250 + 250 *i) * i
'grey98': c = 250 + (250 + 250 *i) * i
'gray99': c = 252 + (252 + 252 *i) * i
'grey99': c = 252 + (252 + 252 *i) * i
'gray100': c = 255 + (255 + 255 *i) * i
'grey100': c = 255 + (255 + 255 *i) * i
'darkgrey': c = 169 + (169 + 169 *i) * i
'darkgray': c = 169 + (169 + 169 *i) * i
'darkblue': c = 0 + ( 0 + 139 *i) * i
'darkcyan': c = 0 + (139 + 139 *i) * i
'darkmagenta': c = 139 + ( 0 + 139 *i) * i
'darkred': c = 139 + ( 0 + 0 *i) * i
'lightgreen': c = 144 + (238 + 144 *i) * i
else: c = 0
endcase
return, c
end
escan/show_correl.pro 0100755 0000621 0000620 00000000221 07317671730 014210 0 ustar epics epics pro show_correl, file=file, data=data
wset
print, 'show correl'
show_mapcorrel, file=file, data=data, type='correl'
return
end
escan/show_mapcorrel.pro 0100664 0000621 0000620 00000012640 07332653245 014713 0 ustar epics epics pro show_mapcorrel, file=file, data=data, type=type, use_data=use_data, map=map
;
; show correlations from a map file:
;
; oread detector and positioner arrays from ascii-dump versions
; of data-catcher files
M_GROUPS = 50
M_DETECTORS = 20
;
xtype = ''
if (keyword_set(type) ne 0) then xtype = type
if ((n_elements(file) eq 0) and (n_elements(data) eq 0)) then begin
print, ' syntax: show_map, file=file, data=data'
print, ' show_correl, file=file, data=data'
print, ' '
print, ' purpose: show maps and correlation plots from 2D Epics Scan'
print, ' '
print, ' notes: show_correl and show_map will read data from a map'
print, ' data file into the temporary data variable named by'
print, ' the data keyword. This data variable can be usd in'
print, ' in subsequent calls to show_correl or show_map to '
print, ' avoid having to re-read the whole file.'
print, ' '
print, ' That is, you can first say'
print, " > show_correl, file='big_map.001', data=bigmap"
print, ' to read the data, and then'
print, " > show_correl, data=bigmap"
print, ' and even'
print, " > show_map, data=bigmap"
print, ' for faster maps and correlation plots'
return
endif
str = '; '
do_parsing = 0
nline = 0
group_name = strarr(M_GROUPS)
detectors = intarr(M_GROUPS,M_DETECTORS)
intlist = intarr(M_DETECTORS)
group_list = strarr(M_GROUPS)
Det_String = strarr(m_groups)
will_read = 1
if (keyword_set(use_data) eq 1) then will_read = 0
if ((n_elements(file) eq 0) and (n_elements(data) ne 0)) then begin
ErrorNo = 0
Catch, ErrorNo
if (ErrorNo ne 0) then begin
print, ' the map data you gave is not the correct form.'
print, ' Please read in the map with show_correl or show_map first.'
return
endif
x = data.x
will_read = 0
endif
if (keyword_set(will_read) eq 0) then begin
da = data.da
x = data.x
y = data.y
group_name = data.group_name
group_list = data.group_list
filename = data.filename
endif else begin
print, 'reading datafile ', file
read_escan2d, file=file, da=da, x=x,y=y
filename = file
openr, lun, file, /get_lun
while not (eof(lun)) do begin
readf,lun,str
nline = nline + 1
string= strtrim(str,2)
char1 = strmid(string, 0, 1)
char3 = strmid(string, 0, 3)
char8 = strmid(strtrim(string,2) , 0,8)
if (strlen(string) le 1) then goto, nextline
if (char8 eq ';-------') then begin
goto, endread
endif else if (char8 eq ';=======') then begin
do_parsing = 1
endif else if ( do_parsing eq 1) then begin
if (char3 ne '; D') then goto, nextline
slen = strlen(string) - 1
clast = strmid(string, slen, slen)
if (clast eq 'N') then begin
roi = strmid(string, slen-2, slen-1)
endif else begin
roi = strmid(string, slen-1, slen)
endelse
ds = strmid(string, 3, 2)
for i = 0, m_groups - 1 do begin
if det_string[i] eq '' then begin
det_string[i]=roi
group_list[i]=ds
i1 = strpos(string, '{')
i2 = strpos(string, '}')
group_name[i]=strmid(string, i1+1, i2-i1-1)
goto, det_found
endif else if(det_string[i] eq roi) then begin
group_list[i] = group_list[i] + ' ' + ds
goto, det_found
endif
endfor
det_found:
endif
nextline:
endwhile
endread:
close, lun
free_lun, lun
endelse
i_user1 = 1
i_user2 = 2
print, " Available Data Groups from this map:"
for i = 0, m_groups - 1 do begin
if group_name[i] ne '' then begin
length = string_array(group_list[i], intlist)
for j = 0, length-1 do detectors[i,j] = intlist[j]
print, i+1 , ' ', group_name[i]
endif
endfor
; print, ' type= ', xtype
if (xtype eq 'map') then begin
print, ' Select Data Group (by number) to Map: '
read, i_user1
ix = i_user1 - 1
map = da(*,*,detectors[ix,0]-1)
for i = 1, m_detectors-1 do begin
if (detectors[ix,i] ne 0) then map = map + da(*,*,detectors[ix,i]-1)
endfor
map = map / (da(*,*,detectors[0,0]-1)>1)
image_display, map, ydist=y, xdist=x(*,0), title=group_name[ix], subtitle=filename
endif else if (xtype eq 'correl') then begin
print, 'Select 2 Data Groups to plot by number [x axis, y axis]'
read, i_user1, i_user2
ix = i_user1 - 1
iy = i_user2 - 1
map = da(*,*,detectors[ix,0]-1)
map2 = da(*,*,detectors[iy,0]-1)
for i = 1, m_detectors-1 do begin
if (detectors[ix,i] ne 0) then map = map + da(*,*,detectors[ix,i]-1)
if (detectors[iy,i] ne 0) then map2 = map2 + da(*,*,detectors[iy,i]-1)
endfor
plot, map, map2, psym=1, xtitle=group_name[ix], ytitle=group_name[iy], title=filename
endif else begin
print, "I can't tell whether you want a map or correlation plot"
endelse
data = {da:da, x:x,y:y, group_name:group_name, group_list:group_list, filename:filename}
return
end
;
escan/show_map.pro 0100755 0000621 0000620 00000000172 07332416651 013500 0 ustar epics epics pro show_map, file=file, data=data, map=map
show_mapcorrel, file=file, data=data, type='map',map=map
return
end
escan/size_of.pro 0100644 0000621 0000620 00000000076 07312216140 013306 0 ustar epics epics function size_of, a
m = size(a)
n = m[1]
return, n
end
escan/split_det_name.pro 0100644 0000621 0000620 00000002341 07237637100 014645 0 ustar epics epics ; munge detector names
function split_det_name, group, ending, is_mca
;
; given a detector group, ending, and mca flag return a struct containing
; elem:
; roi:
;
s = {elem:0, roi:0}
; print, 'Split Det Name 2: ', s.use_net, s.desc
return, s
end
; str = strtrim(detPV,2)
; ; print, 'Split Det Name 1: ', detPV
; if (str ne '') then begin
; len = strlen(str)
; iscal = strpos(str, 'scaler')
; imca = strpos(str, 'med:mca')
; ; print, ' S_D_N: ', iscal, imca
; if (iscal gt 0) then begin
; s.type = 'scaler'
; ; print, ' SCALER: ', str , iscal-1
; s.prefix = strmid(str, 0, iscal+7)
; ; print, ' prefix ', s.prefix
; tmp = strmid(str, iscal+6, len)
; ix = strpos(tmp, '.S')
; s.elem = fix(strmid(tmp, 0, ix) )
; s.roi = fix(strmid(tmp,ix+2, strlen(tmp))) - 1
; endif else if (imca gt 0) then begin
; s.type = 'med:mca'
; s.prefix = strmid(str, 0, imca-1)
; tmp = strmid(str, imca+7, len)
; idot = strpos(tmp, '.')
; s.elem= strmid(tmp,0, idot)
; s.roi= strmid(tmp,idot+2, 1)
; endif
; endif
; ; print, 'Split Det Name 2: ', s.prefix, s.type, s.elem, s.roi
; return, s
; end
escan/string_array.pro 0100664 0000621 0000620 00000000331 07237637100 014361 0 ustar epics epics function string_array, str, array
; convert string of space-separated values to an array
array = str_sep(strcompress(str),' ')
n = n_elements(array)
for i = 0, n-1 do array[i] = strtrim(array[i],2)
return, n
end
escan/t.pro 0100644 0000621 0000620 00000000065 07237637100 012122 0 ustar epics epics j = obj_new('EPICS_SCAN', scan_file = 'default.scn')
escan/u.pro 0100664 0000621 0000620 00000001006 07333622104 012114 0 ustar epics epics x = read_scan('data/asis_typho.002')
d = read_scan('data/oil_typho.002')
d->show_detectors
; x->show_map, name='As', norm='i0'
; window, 2
; wset, 2
; x->show_correl, x='As', y='Cu'
window, 2
wset, 2
device,decomposed=2
l1 = d->get_detector_list(name='As')
l2 = l1
l2[2] = -1
m_x = d->get_x()
m_t = d->get_data(name='As')
m_2 = d->get_data(index=l1[2], /use_raw)
print, l1
l3 = d->set_detector_list(name='As',list=l2)
m_y = d->get_data(name='As')
plot, m_x, m_t
oplot, m_x, m_y
oplot, m_x, m_y+m_2
escan/v_map.pro 0100664 0000621 0000620 00000013565 07332671417 013001 0 ustar epics epics function read_map, file=file
@scan_dims
M_GROUPS = 50
M_DETECTORS = 20
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
if ((n_elements(file) eq 0) or (keyword_set(help) ne 0)) then begin
print, 'function read_map: read 2d scan data file'
print, ' d = read_map(file=file)'
return,0
endif
;
str = '; '
print, format='(a,$)', 'opening file ...'
openr, lun, file, /get_lun
; print, format='(a,$)', ' allocating memory ...'
MDIM = 500
tmp_x = fltarr(MDIM, MAX_POS)
tmp_det = fltarr(MDIM, MDIM, MAX_DET)
vars = fltarr(MAX_POS+MAX_DET)
tmp_y = fltarr(MDIM)
det_name = strarr(M_GROUPS)
det_list = intarr(M_DETECTORS)
group_list = strarr(M_GROUPS)
Det_String = strarr(m_groups)
npts = -1
nrow = -1
npos = 4
ndet = MAX_DET
ngroups = -1
first_line = 1
ncols = 1
nline = 1
read_labels= 1
do_parsing = 0
print, 'reading ...'
while not (eof(lun)) do begin
readf,lun,str
nline = nline + 1
string = strtrim(str,2)
if (strlen(string) gt 1) then begin
char1 = strmid(string, 0, 1)
if ((char1 ne ';') and (read_labels eq 0)) then begin
; read data
npts = npts + 1
reads, string, vars
if (nrow eq 0) then tmp_x[npts, 0:npos-1] = vars[0:npos-1]
tmp_det[npts, nrow, 0:ndet-1] = vars[npos:npos+ndet-1]
endif else begin
if (first_line eq 1) then begin
stmp = strmid(string, 0, 12)
s2 = strmid(string, 12, 13)
sx = str_sep(strtrim(s2,2), ' ')
if (((sx[0] ne '2') and (sx[0] ne '3')) or $
(stmp ne '; Epics Scan')) then begin
print, ' Not a 2d scan file! '
goto, endread
endif
first_line = 0
endif
char1 = strmid(string, 0, 1)
char3 = strmid(string, 0, 3)
char8 = strmid(strtrim(string,2) , 0,8)
if (char3 eq ';2D') then begin
nrow = nrow + 1
if ((nrow gt 5) and ( ((nrow) mod 10) eq 0)) then print, ";"
print, format='(a,i3,$)', ' ' , nrow
sc = strmid(string,3, strlen(string))
sx = str_sep(strtrim(sc,2), ' ' )
tmp_y[nrow] = sx[1]
npts_old = npts
npts = -1
endif else if (char8 eq ';=======') then begin
do_parsing = 1
endif else if ((read_labels eq 1) and (char8 eq ';-------')) then begin
read_labels = 0
readf,lun,string
label = strmid(strtrim(string,2) , 2,strlen(string))
nline = nline + 1
cols = str_sep(label, ' ')
npos = 0
ndet = 0
for k = 0, n_elements(cols)-1 do begin
if (strmid(strtrim(cols[k],2), 0,1) eq 'P') then npos = npos+1
if (strmid(strtrim(cols[k],2), 0,1) eq 'D') then ndet = ndet+1
endfor
vars = fltarr(npos+ndet)
endif else if ( do_parsing eq 1) then begin
if (char3 ne '; D') then goto, nextline
slen = strlen(string) - 1
clast = strmid(string, slen, slen)
if (clast eq 'N') then begin
roi = strmid(string, slen-2, slen-1)
endif else begin
roi = strmid(string, slen-1, slen)
endelse
ds = strmid(string, 3, 2)
for i = 0, m_groups - 1 do begin
if det_string[i] eq '' then begin
ngroups = i
det_string[i]=roi
group_list[i]=ds
i1 = strpos(string, '{')
i2 = strpos(string, '}')
det_name[i]=strmid(string, i1+1, i2-i1-1)
i1 = strpos(det_name[i], 'mca')
if (i1 ge 0) then begin
i2 = strpos(det_name[i], ':')
il = i1+3 > i2
det_name[i] = strmid(det_name[i],il+1,strlen(det_name[i]))
endif
goto, det_found
endif else if(det_string[i] eq roi) then begin
group_list[i] = group_list[i] + ' ' + ds
goto, det_found
endif
endfor
endif
endelse
det_found:
nextline:
endif
endwhile
print, ""
; print, " Available groups from map: ", ngroups
dname = strarr(ngroups+1)
detectors= intarr(ngroups+1,M_DETECTORS) - 1
for i = 0, ngroups do begin
if det_name[i] ne '' then begin
dname[i] = strtrim(det_name[i],2)
g = strtrim(group_list[i],2)
length = string_array(g, det_list)
; print, ' g : ', i, ' :: ', group_list[i], ' :: ', length
for j = 0, length-1 do detectors[i,j] = det_list[j] - 1
; print, dname[i]
endif
endfor
nx = npts
if (nx eq -1) then nx = npts_old
ny = nrow
; print, " nx,ny = ", nx, ny, npts , npts_old
y = fltarr(ny+1)
da = fltarr(nx+1, ny+1, ndet)
x = fltarr(nx+1)
for i = 0, nx do begin
for j = 0, ny do begin
for k = 0, ndet-1 do da(i,j,k) = tmp_det(i,j,k)
endfor
endfor
for j = 0, ny do y[j] = tmp_y[j]
for j = 0, nx do x[j] = tmp_x[j,0]
;; for k = 0, npos-1 do x(i,k) = tmp_x(i,k)
sums = fltarr(nx+1,ny+1,ngroups+1)
for i = 0, ngroups do begin
for j = 0, M_DETECTORS-1 do begin
if (detectors[i,j] gt 0) then begin
sums(*,*,i) = sums(*,*,i) + da(*,*,detectors[i,j])
endif
; print, dname[i]
endfor
endfor
data = {map_data, filename:file, map:da, sums:sums, x:x,y:y, $
det_name:dname, det:detectors}
endread:
close, lun
free_lun, lun
return, data
end
; ;
escan/wait_for_motor.pro 0100664 0000621 0000620 00000001722 07332415420 014707 0 ustar epics epics function wait_for_motor, motor=motor, maxtrys=maxtrys, wait_time=wait_time
;
; wait for a motor to finish moving
; defined as a motor's DMOV field going to 1
;
; returns number of 'wait interval' (calls to caget)
;
;
if (n_elements(motor) eq 0) then begin
print, ' Wait For Motor Needs Motor Name'
return, -1
endif
if (n_elements(maxtrys) eq 0) then maxtrys = 200
if (n_elements(wait_time) eq 0) then wait_time = 0.05
; munge motor name to DMOV variable
motor_dmov = motor
len = strlen(motor_dmov)
if (strupcase(strmid(motor_dmov,len-4,4)) eq '.VAL') then begin
motor_dmov = strmid(motor_dmov,0,len-4) + '.DMOV'
endif else begin
motor_dmov = motor_dmov + '.DMOV'
endelse
; print, ' waiting for ', motor, ' to be done : ', motor_dmov
;
; wait for motor
ntrys = 0
dmov = 0
while (dmov eq 0) do begin
wait, wait_time
ntrys = ntrys + 1
s = caget(motor_dmov, dmov)
if (ntrys ge maxtrys) then dmov = 1
endwhile
return, ntrys
end
escan/write_xafs.pro 0100664 0000621 0000620 00000002011 07337560361 014032 0 ustar epics epics pro write_xafs, file=file, energy=energy, xmu=xmu, title=title
;
; writes out an exafs energy/xmu file from data
; 'points' : header.npoints = long(words[1])
; 'begin' : header.emax = angstroms_to_kev/(long(words[1]) / 1.e4)
; 'end' : header.emin = angstroms_to_kev/(long(words[1]) / 1.e4)
; 'sltsiz' : header.slit_size = float(words[1])
; 'sltpos' : header.slit_position = float(words[1])
if (keyword_set(file) eq 0) then begin
print, ' no output file'
return
endif
if (keyword_set(energy) eq 0) then begin
print, ' no energy array'
return
endif
if (keyword_set(xmu) eq 0) then begin
print, ' no xmu array'
return
endif
titl = ' '
if (keyword_set(title) ne 0) then titl = title
openw, lun,file, /get_lun
printf, lun, '# ', titl
printf, lun, '#--------------------'
printf, lun, '# energy xmu'
nx = size_of(xmu)
for i = 0, nx-1 do begin
printf, lun, format='(1x,f9.3,1x,g15.7)' , energy[i], xmu[i]
endfor
print, 'wrote ', file
close, lun
free_lun, lun
return
end
escan/xtime_s.pro 0100644 0000621 0000620 00000000204 07243360072 013320 0 ustar epics epics function xtime_s
; return current time offset by a constant
x = double(systime(1)) - 9.500e8
; print, 'xtime = ', x
return, x
end
escan/xyz_scan.pro 0100664 0000621 0000620 00000013054 07320351453 013516 0 ustar epics epics pro xyz_scan, scan_file=scan_file, xyz_file=xyz_file, number=number, datafile=datafile
; execute a defined 1d epics scan multiple times at a set
; of predefined x/y/z stage positions
s_file = 'default.scn'
def_file = 'xyzstage.def'
outfile = 'scan.dat'
nrepeat = 3
if (keyword_set(scan_file) ne 0 ) then s_file = scan_file
if (keyword_set(xyz_file) ne 0 ) then def_file = xyz_file
if (keyword_set(number) ne 0 ) then nrepeat = number
if (keyword_set(datafile) ne 0 ) then outfile = datafile
es = obj_new('epics_scan', scan_file = s_file)
x = es->load_to_crate()
x = es->set_param('datafile', outfile)
x = es->set_param('dimension', 1)
scanPV = '13IDC:scan1'
scan_pause = '13IDC:scanPause.VAL'
print, ' reading xyzstage definition file ' , def_file
on_ioerror, bad_file
openr, dlun, def_file, /get_lun
str = ' '
line1 = 1
npts = 0
point = {point, name:'', x:0., y:0., z:0. }
while not (eof(dlun)) do begin
readf, dlun, str
str = strtrim(str,2)
if ((str eq '') or (strmid(str, 0, 1) eq '#')) then goto, loop_end
if (line1 eq 1) then begin
line1 = 0
s = strmid(str, 0, 26)
t = strmid(str, 26, strlen(str))
if (s ne ';XYZ Stage Definition File') then begin
print, ' File ', s_file, ' is not a valid scan file'
return
endif
endif
icol = strpos(str, ':')
ismc = strpos(str, ';')
if ((ismc eq -1) and (icol ge 2)) then begin
key = strmid(str,0, icol)
val = strtrim(strmid(str,icol+1, strlen(str)), 2)
case key of
'motor_x': motor_x = val
'motor_y': motor_y = val
'motor_z': motor_z = val
'point': begin
tmp = point
tmp.name = val
readf, dlun, str
str = strtrim(str,2)
n = string_array(str, arr)
if (n ge 1) then tmp.x = arr[0]
if (n ge 2) then tmp.y = arr[1]
if (n ge 3) then tmp.z = arr[2]
if (npts ge 1) then begin
pts = [pts, tmp]
endif else begin
pts = tmp
endelse
npts = npts + 1
tmp = ''
end
else: x = 1
endcase
endif
loop_end:
endwhile
close, dlun
free_lun, dlun
tmp = ''
continue_to_next = 1
print, ' will scan ', npts, ' points '
for i = 0, npts - 1 do begin
print , ' moving to position ' , pts[i].name , ' to ', pts[i].x, pts[i].y, pts[i].z
outfile = pts[i].name + '.001'
s = caput(motor_x, pts[i].x)
s = caput(motor_y, pts[i].y)
s = caput(motor_z, pts[i].z)
wait, 10.0
for j = 0, nrepeat - 1 do begin
x = es->set_param('datafile', outfile )
print, ' repeat ', j+1, ' of ', nrepeat
wait, 1.0
x = es->set_param('dimension', 1)
lun = es->open_scanfile(/append)
printf, lun, '; Epics Scan 1 dimensional scan'
x = es->start_scan1d()
wait, 1.0
scanning = 1
while scanning eq 1 do begin
resume:
s = caget('13IDC:scan1.EXSC', scanning)
c = get_kbrd(0)
c = strlowcase(c)
if ((c eq string(16B)) or (c eq 'p')) then goto, interrupt
wait, 0.5
endwhile
x = es->write_scan_data()
x = es->close_scanfile()
print, ' scan done, wrote ', outfile
next_scan:
outfile = increment_scanname ( outfile )
if (continue_to_next eq 0) then return
endfor
endfor
return
;;-----------------------------------;;
bad_file:
print, ' Warning: XYZ definition file ', bad_file, ' could not be loaded.'
return
time_out:
print, ''
print, 'scan timed-out... cannot get scanning status'
print, 'aborting scan: not writing data file'
s = caput(scan_pause, 0)
if (lun gt 0) then begin
close, lun
free_lun, lun
endif
return
;; handle interrupts of scan
interrupt:
s = caput(scan_pause, 1)
print, ''
print, ' ####################################'
print, ' scan paused by user. Type one of the following options:'
print, ' r to resume scan sequence'
print, ' n to abort this scan and go to next'
print, ' a to abort all scans'
print, ' f to finish this scan, but not start any more'
print, ' (for multiple or multi-dimensional scans) '
print, ' ####################################'
interrupt_2:
c = strlowcase(get_kbrd(1))
case c of
'a': begin
print, 'aborting scan: not writing data file'
s = caput(scanPV+'.EXSC',0)
s = caput(scan_pause, 0)
if (lun gt 0) then begin
close, lun
free_lun, lun
endif
return
end
'n': begin
print, 'aborting this scan: not writing data file'
s = caput(scanPV+'.EXSC',0)
s = caput(scan_pause, 0)
continue_to_next = 1
s = caput(scan_pause, 0)
goto, next_scan
end
'r': begin
print, 'resuming scan'
continue_to_next = 1
s = caput(scan_pause, 0)
goto, resume
end
'f': begin
print, 'finishing this scan only'
continue_to_next = 0
s = caput(scan_pause, 0)
goto, resume
end
else: begin
print, ' scan paused: type r for resume, a for abort, f to finish current scan only'
goto, interrupt_2
end
endcase
;;-----------------------------------;;
end
sscan/exafs_scan.pro 0100755 0000621 0000620 00000076355 07060250505 014023 0 ustar epics epics pro set_exafs_regions, e0=e0, e1=e1, de1=de1, e2=e2, de2=de2, $
e3=e3, de3=de3, emax=emax, verbose=verbose,quiet=quiet,$
relative=relative,absolute=absolute, nregions=nregions, $
kmax=kmax, dk=dk, kspace=kspace, espace=espace, $
energy = energy, npts=npts, mpts=mpts, time=time,$
load=load, help=help, prefix=prefix, scanPV=scanPV
;
; define EXAFS scan with regions three regions
;
; type 'set_exafs_regions, /help' for syntax
;
if (keyword_set(help) ne 0) then begin
print, 'Help on SET_EXAFS_REGION: An EXAFS Scan consists of 3 regions'
print, ' Regions 1 and 2 are in constant energy steps'
print, ' Region 3 can be in either constant energy or wavenumber steps'
print, ' '
print, ' The following parameters specify a scan (default values in []):'
print, ' e0 : Edge Energy [5465]'
print, ' e1 : Starting Energy for Region 1 (Pre-Edge) [-100]'
print, ' de1 : Energy Increment for Region 1 (Pre-Edge) [ 10]'
print, ' e2 : Starting Energy for Region 2 (Edge) [ -20]'
print, ' de2 : Energy Increment for Region 2 (Edge) [ 0.5]'
print, ' e3 : Starting Energy for Region 3 (Post-Edge) [ 30]'
print, ' de3 : Energy Increment for Region 3 (Post-Edge) [ 2.0]'
print, ' emax : Highest Energy for Scan [ 200]'
print, ' dk : K-space Increment for Region 3 (Post-Edge)[0.05]'
print, ' kmax : Highest Wavenumber for Scan [13]'
print, ' /kspace : set Region 3 as constant wavenumber [1]'
print, ' /espace : set Region 3 as constant energy [0]'
print, ' /relative : use energies relative to e0 for e1, e2, e3 [1]'
print, ' /absolute : use absolute energies for e1, e2, e3 [0]'
print, ' nregions : number of regions to use [3]'
print, 'These arguments control the interaction with the Scan Record'
print, ' time : integration time [current scaler count time]'
print, ' scanPV : sets the scan PV [scan1]'
print, ' prefix : sets the scan prefix [13IDC:]'
print, ' /load : load energy array into scan record [0]'
print, 'These arguments return useful output values:'
print, ' energy : array of energy points calculated'
print, ' npts : useful length of energy array'
print, ' mpts : total length of energy array'
print, ' /verbose : print parameters and debugging info'
return
endif
;
; default values
prefix_ = '13IDC:'
SPV = '13IDC:scan1'
if (n_elements(scanPV) ne 0) then SPV = scanPV
if (n_elements(prefix) ne 0) then Prefix_ = prefix
pos1 = prefix_ + 'E:Energy'
rbv1 = prefix_ + 'E:Energy'
medPV = prefix_ + 'med:'
scalerPV = prefix_ + 'scaler1'
ETOK = 0.2624682917
E_0 = 6540.0
E_1 = -160.0
E_2 = -20.0
E_3 = 30.0
E_MAX = 500.0
DE_1 = 10.0
DE_2 = 0.50
DE_3 = 2.00
K_MAX = 15.00
DK_1 = 0.05
is_kspace = 1
is_verbose = 1
is_relative = 1
n_regs = 3
count_time = -1
load_pvs = 0
; read arguments into local variables
if (keyword_set(kspace)) then is_kspace = 1
if (keyword_set(espace)) then is_kspace = 0
if (keyword_set(relative)) then is_relative= 1
if (keyword_set(absolute)) then is_relative= 0
if (keyword_set(verbose)) then is_verbose = 1
if (keyword_set(quiet)) then is_verbose = 0
if (keyword_set(load)) then load_pvs = 1
;;;;
if (n_elements(time) ne 0) then count_time= time
if (n_elements(nregions) ne 0) then n_regs = nregions > 1
if (n_elements(e0) ne 0) then E_0 = e0
if (n_elements(e1) ne 0) then E_1 = e1
if (n_elements(e2) ne 0) then E_2 = e2
if (n_elements(e3) ne 0) then E_3 = e3
if (n_elements(emax) ne 0) then E_MAX = emax
if (n_elements(de1) ne 0) then DE_1 = de1
if (n_elements(de2) ne 0) then DE_2 = de2
if (n_elements(de3) ne 0) then DE_3 = de3
if (n_elements(kmax) ne 0) then K_MAX = kmax
if (n_elements(dk) ne 0) then DK_1 = dk
if (n_elements(relative) ne 0) then is_relative = relative
if (n_elements(kspace) ne 0) then is_kspace = kspace
if (n_elements(de1) ne 0) then DE_1 = de1
; print, ' relative , kspace = ', is_relative, is_kspace
; print, ' E_0 E_1 E_2 E_3 = ', E_0, E_1, E_2, E_3
if (is_relative) then begin
E_1 = E_1 + E_0
E_2 = E_2 + E_0
E_3 = E_3 + E_0
E_MAX = E_MAX + E_0
endif
if (n_regs le 2) then begin
E_MAX = E_3 + 0.001
is_kspace = 0
endif
if (n_regs eq 1) then begin
e_3 = e_2 + 0.005
e_max = e_3 + 0.005
endif
if (is_kspace) then E_MAX = E_0 + (K_MAX * K_MAX) / ETOK
if (count_time le 0) then s = caget(scalerPV + '.TP', count_time)
;-------------------------
; error checking and warnings
error= 0
if ( (abs(E_2-E_1) gt 1000) or $
(abs(E_2-E_0) gt 1000) or $
(abs(E_3-E_2) gt 1000) or $
(abs(E_MAX-E_3) gt 2000)) then begin
print, ' WARNING: Mixed Absolute and Relative Energies??'
print, ' e0 = ' , e_0
print, ' e1, e2, e3, emax = ' , e_1, e_2, e_3, e_max
endif
if ( is_kspace and (E_3 le E_0)) then begin
print, ' ERROR: E3 must be greater than E0 in k-space mode'
print, ' e0, e3 = ' , e_0, e_3
error = 1
endif
if ( (E_1 ge E_2) or (E_2 ge E_3) or (E_3 ge E_MAX)) then begin
print, ' ERROR: These energies must be in ascending order:'
print, ' e1, e2, e3, emax = ' , e_1, e_2, e_3, e_max
error = 2
endif
if (error gt 0) then return
;-------------------------
; get max number of points from scan record, create energy array
mpts = 1000
mpts_str = SPV + '.MPTS'
ret = caget(mpts_str, mpts)
energy = fltarr(mpts)
npts = 0
npts_1 = 0
npts_2 = 0
npts_3 = 0
energy[0]= E_1
while (energy[npts] lt E_2) do begin
npts = npts + 1
energy[npts] = energy[npts - 1] + DE_1
endwhile
npts_1 = npts + 1
if (n_regs ge 2) then begin
while (energy[npts] lt E_3) do begin
npts = npts + 1
energy[npts] = energy[npts - 1] + DE_2
endwhile
npts_2 = npts - npts_1 + 1
endif
if (n_regs ge 3) then begin
if (is_kspace) then begin
K_INIT = sqrt( (energy[npts] -E_0) * ETOK)
nkpts = npts
while (energy[npts] le E_MAX) do begin
npts = npts + 1
K_VAL = K_INIT + (npts - nkpts) * DK_1
energy[npts] = E_0 + (K_VAL * K_VAL) / ETOK
endwhile
endif else begin
while (energy[npts] le E_MAX) do begin
npts = npts + 1
energy[npts] = energy[npts - 1] + DE_3
endwhile
endelse
npts_3 = npts - npts_2 - npts_1 + 1
endif
npts = npts + 1
;
if (is_verbose) then begin
reg_str = 'regions'
if (n_regs eq 1) then reg_str = 'region'
print, format='(1x,a,i5,a,i5,1x,2a,f9.2)', 'SET_EXAFS_REGIONS:', npts, $
' points, ', n_regs, reg_str, ', e0 =', E_0
if (is_kspace) then begin
print, format='(3x,a,4f9.2,a,f7.2,a)', 'e1, e2, e3, emax, kmax= ',$
E_1,E_2,E_3,E_MAX, ' (', K_MAX, ' Ang^-1)'
print, format='(3x,a,4x,3f9.2,a)', 'de1, de2, dk = ',$
DE_1,DE_2,DK_1, ' Ang^-1'
endif else begin
print, format='(3x,a,4f9.2)', 'e1, e2, e3, emax = ',$
E_1,E_2,E_3,E_MAX
print, format='(3x,a,4x,3f9.2)', 'de1, de2, de3 = ',$
DE_1,DE_2,DE_3
endelse
print, format='(3x,a,3x,3i9)', 'npts per region = ',$
npts_1, npts_2, npts_3
endif
;---
; check that energy array is strictly increasing
order_ok = 1
for i = 1, npts-1 do begin
if (energy[i] le energy[i-1]) then order_ok = 0
endfor
if (not order_ok) then begin
print, ' --- WARNING --- energy array is out of order'
if (load_pvs) then begin
print, ' --- NOT LOADING ARRAY ---'
load_pvs = 0
endif
endif
if (load_pvs) then begin
x = -1
if (is_verbose) then print, format='(1x,a,$)', $
'writing to EPICS Scan Record ... '
x = caput( SPV + '.PASM', 2) ; 'Prior Pos' after scan
x = caput( SPV + '.P1AR', 0) ; 'Absolute' mode
x = caput( SPV + '.P1SM', 1) ; 'Table' mode, duh
x = caput( SPV + '.P1PV', pos1)
x = caput( SPV + '.R1PV', rbv1)
x = caput( SPV + '.NPTS', npts)
x = caput( SPV + '.P1PA', energy)
; positioner and detector settling time for SSCAN record: set minima
x = caget( SPV + '.PDLY', p_delay)
if (p_delay le 0.10) then begin
p_delay = 0.10
x = caput( SPV + '.PDLY', p_delay)
endif
x = caget( SPV + '.DDLY', d_delay)
if (d_delay le 0.05) then begin
d_delay = 0.05
x = caput( SPV + '.DDLY', d_delay)
endif
; put scaler in one-shot mode
x = caput( scalerPV + '.CONT', 0)
; set scaler count time
x = caput( scalerPV + '.TP', count_time)
;
; set med count time
x = caput( medPV + 'PresetReal', count_time)
x = caput( medPV + 'StatusSeq.SCAN', 8) ; set med status rate to 0.2sec
x = caput( medPV + 'ReadSeq.SCAN', 0) ; set med in 'passive read rate'
if (x ne 0) and (is_verbose) then print, ' ... Med Count Time Failed!'
;
print, ' ready to scan!'
endif
return
end
function exafs_scan_help
print, ' in exafs_scan_help'
return, 0
end
function set_sensitive_exafs_regions, p
x = (*p).scan1.nregs
if (x eq 1) then begin
Widget_Control, (*p).wid.r3space, SENSITIVE = 0
Widget_Control, (*p).wid.r3start, SENSITIVE = 0
Widget_Control, (*p).wid.r3stop, SENSITIVE = 0
Widget_Control, (*p).wid.r3step, SENSITIVE = 0
Widget_Control, (*p).wid.r2start, SENSITIVE = 0
Widget_Control, (*p).wid.r2stop, SENSITIVE = 0
Widget_Control, (*p).wid.r2step, SENSITIVE = 0
endif else if (x eq 2) then begin
Widget_Control, (*p).wid.r3space, SENSITIVE = 0
Widget_Control, (*p).wid.r3start, SENSITIVE = 0
Widget_Control, (*p).wid.r3stop, SENSITIVE = 0
Widget_Control, (*p).wid.r3step, SENSITIVE = 0
Widget_Control, (*p).wid.r2start, SENSITIVE = 1
Widget_Control, (*p).wid.r2stop, SENSITIVE = 1
Widget_Control, (*p).wid.r2step, SENSITIVE = 1
endif else begin
Widget_Control, (*p).wid.r3space, SENSITIVE = 1
Widget_Control, (*p).wid.r3start, SENSITIVE = 1
Widget_Control, (*p).wid.r3stop, SENSITIVE = 1
Widget_Control, (*p).wid.r3step, SENSITIVE = 1
Widget_Control, (*p).wid.r2start, SENSITIVE = 1
Widget_Control, (*p).wid.r2stop, SENSITIVE = 1
Widget_Control, (*p).wid.r2step, SENSITIVE = 1
endelse
return,0
end
PRO exafs_scan_event, event
Widget_Control, event.top, GET_UVALUE = p
Widget_Control, event.id, GET_UVALUE = uval
ErrorNo = 0
Catch, ErrorNo
if (ErrorNo ne 0) then begin;
Catch, /CANCEL
ErrArray = ['Application Error!', $
'Error Number: '+strtrim(!error,2), !Err_String]
a = DIALOG_MESSAGE(ErrArray, /ERROR)
return
endif
ETOK = 0.2624682917
; print , ' see event: ', uval
case uval of
'exit': Widget_Control, event.top, /DESTROY
'load_cfg': begin
f = (*p).main.file
retval = read_scan_param_file(p)
Widget_Control, (*p).wid.e0, SET_VALUE = string((*p).scan1.e0)
Widget_Control, (*p).wid.nregs, SET_VALUE = string((*p).scan1.nregs)
Widget_Control, (*p).wid.time, SET_VALUE = string((*p).scan1.time)
Widget_Control, (*p).wid.r1start, SET_VALUE = string((*p).scan1.r1start)
Widget_Control, (*p).wid.r1stop, SET_VALUE = string((*p).scan1.r1stop)
Widget_Control, (*p).wid.r1step, SET_VALUE = string((*p).scan1.r1step)
Widget_Control, (*p).wid.r2start, SET_VALUE = string((*p).scan1.r2start)
Widget_Control, (*p).wid.r2stop, SET_VALUE = string((*p).scan1.r2stop)
Widget_Control, (*p).wid.r2step, SET_VALUE = string((*p).scan1.r2step)
Widget_Control, (*p).wid.r3start, SET_VALUE = string((*p).scan1.r3start)
Widget_Control, (*p).wid.r3stop, SET_VALUE = string((*p).scan1.r3stop)
Widget_Control, (*p).wid.r3step, SET_VALUE = string((*p).scan1.r3step)
Widget_Control, (*p).wid.r3space, SET_DROPLIST_SELECT = string((*p).scan1.is_kspace)
Widget_Control, (*p).wid.is_rel, SET_DROPLIST_SELECT = string((*p).scan1.is_rel)
retval = set_sensitive_exafs_regions(p)
end
'start_scan': begin
print, ' starting scan'
sfile = (*p).main.scanname
pdet = (*p).main.plotdet
x = sscan(file = sfile, view = pdet , scan= '13IDC:scan1')
end
'pause_scan': begin
print, ' sending pause scan'
x = caput('13IDC:scanPause.VAL', 1)
end
'scanname': begin
Widget_Control, (*p).wid.scanname, GET_VALUE = t
t = strtrim(t[0],2)
(*p).main.scanname = t
end
'plotdet': begin
Widget_Control, (*p).wid.plotdet, GET_VALUE = t
(*p).main.plotdet = t
end
'save_cfg': begin
f = (*p).main.file
retval = save_scan_param_file(p,1)
end
'saveas_cfg': begin
f = (*p).main.file
retval = save_scan_param_file(p,1)
end
'EXAFS_help': begin
retval = exafs_scan_help()
end
'IDLhelp': begin
online_help
end
'e0': begin
Widget_Control, (*p).wid.e0, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.e0 = t
end
'nregs': begin
Widget_Control, (*p).wid.nregs, GET_VALUE = t
x = fix(strtrim(t[0],2))
if ((x ne 1) and (x ne 2)) then x = 3
(*p).scan1.nregs = x
retval = set_sensitive_exafs_regions(p)
end
'time': begin
Widget_Control, (*p).wid.time, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.time = t
end
'r1start': begin
Widget_Control, (*p).wid.r1start, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r1start = t
end
'r1stop': begin
Widget_Control, (*p).wid.r1stop, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r1stop = t
(*p).scan1.r2start = t
Widget_Control, (*p).wid.r2start, SET_VALUE = t
end
'r1step': begin
Widget_Control, (*p).wid.r1step, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r1step = t
end
'r1npts': begin
Widget_Control, (*p).wid.r1npts, GET_VALUE = t
start = (*p).scan1.r1start
stop = (*p).scan1.r1stop
npts = strtrim(t,2)
if (npts le 1) then npts = 2
step = abs(start-stop)/(npts - 1)
print, 'npts = ' , npts, ' step = ', step
(*p).scan1.r1step = step
Widget_Control, (*p).wid.r1step, SET_VALUE = strtrim(string(step),2)
end
'r2start': begin
Widget_Control, (*p).wid.r2start, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r2start = t
(*p).scan1.r1stop = t
Widget_Control, (*p).wid.r1stop, SET_VALUE = t
end
'r2stop': begin
Widget_Control, (*p).wid.r2stop, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r2stop = t
s = double(t)
if ((*p).scan1.is_kspace) then begin
if ((*p).scan1.is_rel eq 0) then s = s - (*p).scan1.e0
s = sqrt(abs(s) * ETOK)
endif
Widget_Control, (*p).wid.r3start, SET_VALUE = strtrim(string(s),2)
end
'r2step': begin
Widget_Control, (*p).wid.r2step, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r2step = t
end
'r3start': begin
Widget_Control, (*p).wid.r3start, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r3start = t
s = double(t)
if ((*p).scan1.is_kspace eq 1) then begin
s = s*s / ETOK
if ((*p).scan1.is_rel eq 0) then s = s + (*p).scan1.e0
endif
Widget_Control, (*p).wid.r2stop, SET_VALUE = strtrim(string(s),2)
end
'r3stop': begin
Widget_Control, (*p).wid.r3stop, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r3stop = t
end
'r3step': begin
Widget_Control, (*p).wid.r3step, GET_VALUE = t
t = strtrim(t,2)
(*p).scan1.r3step = t
end
'EXAFS_space': begin
space = event.index
is_rela = (*p).scan1.is_rel
if (space eq 1) then begin ; choose 'Ang^-1'
if ((*p).scan1.is_kspace eq 0) then begin
; switching from E to k space
(*p).scan1.is_kspace = 1
Widget_Control, (*p).wid.r3start, GET_VALUE = t
t = strtrim(t,2)
d = double(t)
if (is_rela eq 0) then d = d - (*p).scan1.e0
d = sqrt(d * ETOK)
(*p).scan1.r3start = d
Widget_Control, (*p).wid.r3start, SET_VALUE = strtrim(string(d),2)
d = d*d/ETOK
(*p).scan1.r2stop = d
if (is_rela eq 0) then d = d + (*p).scan1.e0
Widget_Control, (*p).wid.r2stop, SET_VALUE = strtrim(string(d),2)
Widget_Control, (*p).wid.r3stop, GET_VALUE = t
t = strtrim(t,2)
d = double(t)
if (is_rela eq 0) then d = d - (*p).scan1.e0
d = sqrt(d * ETOK)
(*p).scan1.r3stop = d
Widget_Control, (*p).wid.r3stop, SET_VALUE = strtrim(string(d),2)
d = 0.05
(*p).scan1.r3step = d
Widget_Control, (*p).wid.r3step, SET_VALUE = strtrim(string(d),2)
endif
endif else begin; choose 'eV'
if ((*p).scan1.is_kspace eq 1) then begin
; switching from k to E space
(*p).scan1.is_kspace = 0
Widget_Control, (*p).wid.r3start, GET_VALUE = t
t = strtrim(t,2)
d = double(t) * double(t) / ETOK
if (is_rela eq 0) then d = d + (*p).scan1.e0
(*p).scan1.r3start = d
Widget_Control, (*p).wid.r3start, SET_VALUE = strtrim(string(d),2)
(*p).scan1.r2stop = d
Widget_Control, (*p).wid.r2stop, SET_VALUE = strtrim(string(d),2)
Widget_Control, (*p).wid.r3stop, GET_VALUE = t
t = strtrim(t,2)
d = double(t) * double(t) / ETOK
if (is_rela eq 0) then d = d + (*p).scan1.e0
(*p).scan1.r3stop = d
Widget_Control, (*p).wid.r3stop, SET_VALUE = strtrim(string(d),2)
d = 2.0
(*p).scan1.r3step = d
Widget_Control, (*p).wid.r3step, SET_VALUE = strtrim(string(d),2)
endif
endelse
end
'use_rel': begin
do_change = 0
if ((event.index eq 1) and ((*p).scan1.is_rel eq 0)) then begin ;
do_change = 1
(*p).scan1.is_rel = 1
de0 = -( (*p).scan1.e0)
endif else if ((event.index eq 0) and ((*p).scan1.is_rel eq 1)) then begin
do_change = 1
(*p).scan1.is_rel = 0
de0 = (*p).scan1.e0
endif
if (do_change eq 1) then begin
Widget_Control, (*p).wid.r1start, GET_VALUE = d1
Widget_Control, (*p).wid.r1stop, GET_VALUE = d2
Widget_Control, (*p).wid.r2stop, GET_VALUE = d3
d1 = d1 + de0
d2 = d2 + de0
d3 = d3 + de0
(*p).scan1.r1start = d1
(*p).scan1.r1stop = d2
(*p).scan1.r2start = d2
(*p).scan1.r2stop = d3
Widget_Control, (*p).wid.r1start, SET_VALUE = strtrim(string(d1),2)
Widget_Control, (*p).wid.r1stop, SET_VALUE = strtrim(string(d2),2)
Widget_Control, (*p).wid.r2start, SET_VALUE = strtrim(string(d2),2)
Widget_Control, (*p).wid.r2stop, SET_VALUE = strtrim(string(d3),2)
if ((*p).scan1.is_kspace eq 0) then begin
d1 = (*p).scan1.r3start + de0
d2 = (*p).scan1.r3stop + de0
(*p).scan1.r3start = d1
(*p).scan1.r3stop = d2
Widget_Control, (*p).wid.r3start, $
SET_VALUE = strtrim(string(d1),2)
Widget_Control, (*p).wid.r2stop, $
SET_VALUE = strtrim(string(d1),2)
Widget_Control, (*p).wid.r3stop, $
SET_VALUE = strtrim(string(d2),2)
endif
endif
end
'load': begin
print, ' loading scan parameters'
; make sure we have the latest parameters
Widget_Control, (*p).wid.e0, GET_VALUE = t
(*p).scan1.e0 = t
Widget_Control, (*p).wid.nregs, GET_VALUE = t
(*p).scan1.nregs = t
Widget_Control, (*p).wid.r1start, GET_VALUE = t
(*p).scan1.r1start = t
Widget_Control, (*p).wid.time, GET_VALUE = t
(*p).scan1.time = t
Widget_Control, (*p).wid.r1start, GET_VALUE = t
(*p).scan1.r1start = t
Widget_Control, (*p).wid.r2start, GET_VALUE = t
(*p).scan1.r2start = t
Widget_Control, (*p).wid.r3start, GET_VALUE = t
(*p).scan1.r3start = t
Widget_Control, (*p).wid.r1stop, GET_VALUE = t
(*p).scan1.r1stop = t
Widget_Control, (*p).wid.r2stop, GET_VALUE = t
(*p).scan1.r2stop = t
Widget_Control, (*p).wid.r3stop, GET_VALUE = t
(*p).scan1.r3stop = t
Widget_Control, (*p).wid.r1step, GET_VALUE = t
(*p).scan1.r1step = t
Widget_Control, (*p).wid.r2step, GET_VALUE = t
(*p).scan1.r2step = t
Widget_Control, (*p).wid.r3step, GET_VALUE = t
(*p).scan1.r3step = t
;
if ((*p).scan1.is_kspace eq 1) then begin
e3 = (*p).scan1.r3start
e3 = e3*e3/ETOK
if ((*p).scan1.is_rel eq 0) then e3 = e3 + (*p).scan1.e0
set_exafs_regions, $
e0 = (*p).scan1.e0, $
e1 = (*p).scan1.r1start, $
de1 = (*p).scan1.r1step, $
e2 = (*p).scan1.r2start, $
de2 = (*p).scan1.r2step, $
e3 = e3, $
dk = (*p).scan1.r3step, $
kmax = (*p).scan1.r3stop, $
relative = (*p).scan1.is_rel, $
nregions = (*p).scan1.nregs, $
time = (*p).scan1.time, $
verbose = 0, kspace=1, /load
endif else begin
set_exafs_regions, $
e0 = (*p).scan1.e0, $
e1 = (*p).scan1.r1start, $
de1 = (*p).scan1.r1step, $
e2 = (*p).scan1.r2start, $
de2 = (*p).scan1.r2step, $
e3 = (*p).scan1.r3start, $
de3 = (*p).scan1.r3step, $
emax = (*p).scan1.r3stop, $
relative = (*p).scan1.is_rel, $
nregions = (*p).scan1.nregs, $
time = (*p).scan1.time, $
verbose = 0, kspace=0, /load
endelse
end
else: begin
print, 'unknown event: uval = ', uval
end
endcase
return
end
pro exafs_scan
;
; GUI interface to set_exafs_regions
;
ETOK = 0.2624682917
;
R3_spaces = ['eV', 'Ang^(-1) ']
Rel_choices = ['Absolute', 'Relative']
; default values
main = {prefix:'13IDC:', file:'unknown.scn', dimension:'1',$
detectors: 15, current_scan:1, plotdet:1L,$
scanname:'scan.001', $
trigger1:'med:EraseStart', trigger2:'scaler1.CNT'}
scan1 = {type:'EXAFS', ScanPV:'scan1', motor_name:'E:Energy',$
pos1: 'E:Energy.VAL', rbv1: 'E:Energy', units:'eV', $
llimit:0.0, ulimit:0.0, cur_pos:0.0, plotdet:1L, $
e0:7112., is_rel:1, is_kspace:1, nregs:3, time:1.0, $
r1start:-200., r1step: 10. , r1stop: -30., r1npts: 18, $
r2start: -30., r2step: 0.5 , r2stop: 30., r2npts: 61, $
r3start: 0., r3step: 0.05, r3stop: 15. , r3npts: 300 }
scan2 = {type:'Motor', ScanPV:'scan2', motor_name:'',$
pos1: '', rbv1: '', units:'mm', $
llimit:0.0, ulimit:0.0, cur_pos:0.0, $
e0:0., is_rel:1, is_kspace:0, nregs:1, time:1.0, $
r1start:-200., r1step: 10. , r1stop: 200., $
r2start: -30., r2step: 0.5 , r2stop: 30., $
r3start: 0., r3step: 0.05, r3stop: 15. }
scan3 = {type:'Motor', ScanPV:'scan3', motor_name:'',$
pos1: '', rbv1: '', units:'mm', $
llimit:0.0, ulimit:0.0, cur_pos:0.0, $
e0:0., is_rel:1, is_kspace:0, nregs:1, time:1.0, $
r1start:-200., r1step: 10. , r1stop: 200., $
r2start: -30., r2step: 0.5 , r2stop: 30., $
r3start: 0., r3step: 0.05, r3stop: 15. }
wid = {e0:0L, nregs:0L, time:0L, is_rel:Rel_choices[1],$
startscan:0L, pausescan:0L, scanname:' ', $
plotdet:1L, $
r1start:0L, r1stop:0L, r1step:0L, r1npts:0L, $
r2start:0L, r2stop:0L, r2step:0L, r2npts:0L, $
r3start:0L, r3stop:0L, r3step:0L, r3space:R3_spaces[1], r3npts:0L}
info = {main:main, scan1:scan1, scan2:scan2, scan3:scan3, wid:wid}
s = scan1.r2stop
s = sqrt(double(s) * ETOK)
info.scan1.r3start = strtrim(string(s),2)
info.scan1.r1npts = fix ( abs(info.scan1.r1start - info.scan1.r1stop) / info.scan1.r1step) + 1
info.scan1.r2npts = fix ( abs(info.scan1.r2start - info.scan1.r2stop) / info.scan1.r2step) + 1
info.scan1.r3npts = fix ( abs(info.scan1.r3start - info.scan1.r3stop) / info.scan1.r3step) + 1
MAIN = Widget_Base(TITLE = 'EXAFS Scan', /COLUMN, APP_MBAR = menubar)
fileMenu = Widget_Button(menubar, VALUE = 'File', /HELP)
loadMB = Widget_Button(fileMenu, VALUE = 'Read Scan File ...', UVALUE = 'load_cfg')
saveMB = Widget_Button(fileMenu, VALUE = 'Save Scan File ...', UVALUE = 'save_cfg')
saveasMB = Widget_Button(fileMenu, VALUE = 'Save As ...', UVALUE = 'saveas_cfg')
exitMB = Widget_Button(fileMenu, VALUE = 'Exit', UVALUE = 'exit', $
/SEPARATOR)
; Help menu
helpMenu = Widget_Button(menubar, VALUE = 'Help', /MENU, /HELP)
exahelpMB = Widget_Button(helpMenu, VALUE = 'Help on EXAFS Scan', UVALUE = 'EXAFS_help')
idlhelpMB = Widget_Button(helpMenu, VALUE = 'Help on IDL', UVALUE = 'IDLhelp')
MAINFRAME = Widget_Base(MAIN, /COLUMN)
R0_Base = Widget_Base(MAINFRAME, /ROW)
info.wid.e0 = CW_FIELD(R0_Base, /FLOATING, /ROW, XSIZE = 9, $
TITLE = 'E0 ', UVALUE = 'e0', $
VALUE = strtrim(string(info.scan1.e0),2), $
/ALL_EVENTS)
info.wid.nregs = CW_FIELD(R0_Base, /INTEGER, /ROW, XSIZE = 5, $
TITLE = 'Number of Regions', UVALUE = 'nregs', $
VALUE = strtrim(string(info.scan1.nregs),2), $
/ALL_EVENTS)
info.wid.time = CW_FIELD(R0_Base, /FLOATING, /ROW, XSIZE = 7, $
TITLE = 'Count Time', UVALUE = 'time', $
VALUE = strtrim(string(info.scan1.time),2), $
/ALL_EVENTS)
X = Widget_Label(R0_Base, SCR_XSIZE=40, VALUE = 'sec')
R4_Base = Widget_Base(MAINFRAME, /ROW)
info.wid.is_rel = Widget_DROPLIST(R4_Base, TITLE = 'use ', $
VALUE = Rel_choices, UVALUE = 'use_rel')
Widget_Control, info.wid.is_rel, SET_DROPLIST_SELECT = 1
X = Widget_Label(R4_Base, SCR_XSIZE=90, VALUE = ' Energies ')
T = Widget_Base(MAINFRAME, /ROW, /FRAME)
X = Widget_Label(T, XSIZE=100, VALUE = ' Region ', /ALIGN_LEFT)
X = Widget_Label(T, XSIZE=100, VALUE = ' Start ', /ALIGN_LEFT)
X = Widget_Label(T, XSIZE=100, VALUE = ' Stop ', /ALIGN_LEFT)
X = Widget_Label(T, XSIZE=100, VALUE = ' Step ', /ALIGN_LEFT)
X = Widget_Label(T, XSIZE=100, VALUE = ' Units ', /ALIGN_LEFT)
; X = Widget_Label(T, SCR_XSIZE=90, VALUE = ' Npts ')
R1_Base = Widget_Base(MAINFRAME, /ROW)
X = Widget_Label(R1_Base, XSIZE= 90, VALUE = ' Pre-edge', /ALIGN_LEFT)
info.wid.r1start = CW_FIELD(R1_Base, Title= ' ', XSIZE = 11, UVALUE = 'r1start', $
VALUE = strtrim(string(info.scan1.r1start),2), $
/ALL_EVENTS, /FLOATING)
info.wid.r1stop = CW_FIELD(R1_Base, Title= ' ', XSIZE = 11, UVALUE = 'r1stop', $
VALUE = strtrim(string(info.scan1.r1stop),2), $
/ALL_EVENTS, /FLOATING)
info.wid.r1step = CW_FIELD(R1_Base, Title = ' ', XSIZE = 11, UVALUE = 'r1step', $
VALUE = strtrim(string(info.scan1.r1step),2), $
/ALL_EVENTS, /FLOATING)
X = Widget_Label(R1_Base, XSIZE=65, VALUE = ' eV ', /ALIGN_LEFT)
R2_Base = Widget_Base(MAINFRAME, /ROW)
X = Widget_Label(R2_Base, XSIZE = 90, VALUE = ' Edge ', /ALIGN_LEFT)
info.wid.r2start = CW_FIELD(R2_Base, Title = ' ', XSIZE = 11, UVALUE = 'r2start', $
VALUE = strtrim(string(info.scan1.r2start),2), $
/ALL_EVENTS, /FLOATING)
info.wid.r2stop = CW_FIELD(R2_Base, Title = ' ', XSIZE = 11, UVALUE = 'r2stop', $
VALUE = strtrim(string(info.scan1.r2stop),2), $
/ALL_EVENTS, /FLOATING)
info.wid.r2step = CW_FIELD(R2_Base, Title= ' ', XSIZE = 11, UVALUE = 'r2step', $
VALUE = strtrim(string(info.scan1.r2step),2), $
/ALL_EVENTS, /FLOATING)
X = Widget_Label(R2_Base, XSIZE=65, VALUE = ' eV ', /ALIGN_LEFT)
R3_Base = Widget_Base(MAINFRAME, /ROW)
X = Widget_Label(R3_Base,XSIZE= 90, VALUE = ' EXAFS ', /ALIGN_LEFT)
info.wid.r3start = CW_FIELD(R3_Base, Title=' ', XSIZE = 11, UVALUE = 'r3start', $
VALUE = strtrim(string(info.scan1.r3start),2), $
/ALL_EVENTS, /FLOATING)
info.wid.r3stop = CW_FIELD(R3_Base, Title=' ', XSIZE = 11, UVALUE = 'r3stop', $
VALUE = strtrim(string(info.scan1.r3stop),2), $
/ALL_EVENTS, /FLOATING)
info.wid.r3step = CW_FIELD(R3_Base, Title =' ', XSIZE=11, UVALUE = 'r3step', $
VALUE = strtrim(string(info.scan1.r3step),2), $
/ALL_EVENTS, /FLOATING)
R3a_Base = Widget_Base(R3_Base, /ROW)
info.wid.r3space = Widget_DROPLIST(R3a_Base, TITLE = ' ', $
VALUE = R3_spaces, UVALUE = 'EXAFS_space')
Widget_Control, info.wid.r3space, SET_DROPLIST_SELECT = 1
R4_Base = Widget_Base(MAINFRAME, /ROW)
X = Widget_Label(R4_Base,XSIZE= 90, VALUE = 'Scan File ', /ALIGN_LEFT)
info.wid.scanname = WIDGET_TEXT(R4_Base, UVALUE = 'scanname', /editable, $
VALUE = info.main.scanname)
;X = Widget_Label(R4_Base,XSIZE= 100, VALUE = 'Detector to Plot', /ALIGN_LEFT)
info.wid.plotdet = CW_FIELD(R4_Base, Title ='Detector to Plot', XSIZE=8, UVALUE = 'plotdet', $
VALUE = strtrim(string(info.main.plotdet),2), $
/ALL_EVENTS, /FLOATING)
R5_Base = Widget_Base(MAINFRAME, /ROW)
X = Widget_Button(R5_Base, VALUE = 'Load Scan Parameters', UVALUE='load')
info.wid.startscan = Widget_Button(R5_Base, VALUE = 'Begin Scan', UVALUE='start_scan')
; info.wid.pausescan = Widget_Button(R5_Base, VALUE = 'Pause Scan', UVALUE='pause_scan')
X = Widget_Button(R5_Base, VALUE = 'EXIT ', UVALUE='exit')
; render widgets, load info structure into MAIN
Widget_Control, MAIN, /REALIZE
p_info = ptr_new(info,/NO_COPY)
Widget_Control, MAIN, SET_UVALUE=p_info
xmanager, 'exafs_scan', MAIN, /NO_BLOCK
return
end
sscan/motor_scan.pro 0100755 0000621 0000620 00000063114 07010363525 014044 0 ustar epics epics ;
; Gui for motor scanning
pro set_motor_scan, motor= motor, name=name, start=start, stop=stop, step=step, $
time=time, relative=relative, scanPV=scanPV, list=list
;
; define linear motor scan
;
; default values
prefix = '13IDC:'
motorPV = 'null'
scanPV_ = 'scan1'
scalerPV = prefix + 'scaler1'
medPV = prefix + 'med:'
count_time = 1
is_relative = 0
motor_p = ['m1','m2','m3','m4','m5','m6','m8','m9','m10',$
'm11', 'm12', 'm13', 'm14', 'm16', 'm15', 'm17',$
'm18', 'm19', 'm20', 'm21', 'm22', 'm23', 'm24','Energy','1D_pDummy']
motor_n = ["Table Y upstream","Table Y inboard","Table Y outboard",$
"Table X upstream","Table X downstream","Table Base Y",$
"Mono angle","TT Slit H Pos","TT Slit H Wid","TT Slit V Pos",$
"TT Slit V Wid","Stage X", "Stage Y","Stage Z","WDS Stage X ",$
"KB V x", "KB V angle","KB V Fup","KB V Fdn", $
"KB H x", "KB H angle","KB H Fup", "KB H Fdn", "Energy","Dummy"]
; read arguments into local variables
if (keyword_set(scanPV)) then begin
scanPV_ = scanPV
if (scanPV eq '1') then begin
scanPV_ =+ 'scan1'
endif else if (scanPV eq '2') then begin
scanPV_ = 'scan2'
endif else if (scanPV eq '3') then begin
scanPV_ = 'scan3'
endif
endif
SPV = prefix + ScanPV_
motorPV = '1D_pDummy'
if (scanPV_ eq 'scan2') then motorPV = '2D_pDummy'
if (scanPV_ eq 'scan3') then motorPV = '1D_pDummy'
if (keyword_set(relative) ne 0) then is_relative = relative
if (n_elements(time) ne 0) then count_time= time
if (n_elements(motor) ne 0) then motorPV = motor
if (n_elements(name) ne 0) then begin
if (name eq 'Sample X') then name = 'Stage X'
if (name eq 'Sample Y') then name = 'Stage Y'
if (name eq 'Sample Z') then name = 'Stage Z'
if (name ne 'Dummy') then begin
n = n_elements(motor_n)
for i = 0, n-1 do begin
if (name eq motor_n[i]) then motorPV = motor_p[i]
endfor
endif
if (motorPV eq 'null') then begin
print, ' unknown motor name: ', name
print, ' type set_motor_scan, /list for list of motor names'
return
endif
endif
if (n_elements(list) ne 0) then begin
n = n_elements(motor_n)
for i = 0, n-1 do print, ' ', motor_n[i]
return
endif
;
if ((keyword_set(help) ne 0) or (motorPV eq 'null')) then begin
print, "SET_MOTOR_SCAN: setup a linear scan (but don't execute)"
print, ' parameters:'
print, ' name motor name (use /list for list of names)'
print, " motor motor PV name ('m1', 'm2', ... )"
print, ' start starting position'
print, ' stop stopping position'
print, ' step step size'
print, ' time integration time'
print, ' scan index of scan record to use (1, 2, or 3)'
print, ' /relative use values relative to current postion '
print, ' /list print list of motor names'
return
endif
pos1 = prefix + motorPV + '.VAL'
rbv1 = prefix + motorPV + '.RBV'
if (motorPV eq 'Energy') then begin
pos1 = '13IDC:Energy.VAL'
rbv1 = '13IDC:Energy.VAL'
endif
init_pos = 22.000
s = caget(pos1, init_pos)
Mstart = init_pos
Mstep = 1.
Mstop = init_pos + Mstep
if (n_elements(start) ne 0) then Mstart = start
if (n_elements(stop) ne 0) then Mstop = stop
if (n_elements(step) ne 0) then Mstep = abs(step)
if (Mstop lt Mstart) then Mstep = -Mstep
if (count_time le 0) then s = caget(scalerPV + 'TP', count_time)
Mstep_extra = abs(Mstep - (Mstep * 0.0001 + 1.d-12))
npts = fix(1 + (abs(Mstart - Mstop)/abs(Mstep_extra)))
x = caput( SPV + '.PASM', 2) ; 'Prior Pos' after scan
x = caput( SPV + '.P1AR', is_relative) ; 'Absolute mode'
x = caput( SPV + '.P1SM', 0) ; 'linear mode'
x = caput( SPV + '.P1PV', pos1)
x = caput( SPV + '.R1PV', rbv1)
x = caput( SPV + '.P1SP', Mstart)
x = caput( SPV + '.P1EP', Mstop)
x = caput( SPV + '.P1SI', Mstep)
x = caput( SPV + '.NPTS', npts)
; positioner and detector settling time for SSCAN record: set minima
x = caget( SPV + '.PDLY', p_delay)
if (p_delay le 0.10) then begin
p_delay = 0.10
x = caput( SPV + '.PDLY', p_delay)
endif
x = caget( SPV + '.DDLY', d_delay)
if (d_delay le 0.05) then begin
d_delay = 0.05
x = caput( SPV + '.DDLY', d_delay)
endif
x = caput( scalerPV + '.CONT', 0) ; put scaler in one-shot mode
x = caput( scalerPV + '.TP', count_time) ; set scaler count time
x = caput( medPV + 'PresetReal', count_time) ; set med count time
x = caput( medPV + 'StatusSeq.SCAN', 8) ; set med status rate to 0.2sec
x = caput( medPV + 'ReadSeq.SCAN', 0) ; set med in 'passive read rate'
print, format='(1x,2a,$)', 'Ready to scan ', pos1
if (is_relative) then begin
print, ' relative to current position '
endif else print, ' '
print, ' Start, Stop, Step, Npts = ', Mstart, Mstop, Mstep, npts
return
end
pro get_motor_settings, prefix=prefix, motor=motor, scanPV=scanPV, $
value=value, llimit=llimit, ulimit=ulimit, $
pv=pv, rbv=rbv, units=units
motor_name2pv, name = motor, pv = pv, scanPV=scanPV
pvo = pv
p = prefix + pv
print, ' getting motor settings for "', motor, '" ', p
value = 0.00
llimit = -100.
ulimit = 100.
units = ' '
pv = p + '.VAL'
rbv = p + '.RBV'
if (motor eq 'Dummy') then begin
rbv = p + '.VAL'
endif else begin
units = 'mm'
s = caget(p + '.VAL', value)
s = caget(p + '.EGU', units)
if (pvo eq 'Energy') then begin
rbv = pv
ulimit = '40000.'
llimit = '4000.'
endif else begin
s = caget(p + '.LLM', llimit)
s = caget(p + '.HLM', ulimit)
endelse
endelse
if (double(llimit) ge double(ulimit)) then begin
tmp = ulimit
ulimit = llimit
llimit = tmp
endif
return
end
pro motor_name2pv, name=name, pv=pv, scanPV=scanPV
motor_p = ['m1','m2','m3','m4','m5','m6','m8','m9','m10',$
'm11', 'm12', 'm13', 'm14', 'm16', 'm15', 'm17',$
'm18', 'm19', 'm20', 'm21', 'm22', 'm23', 'm24','Energy']
motor_n = ["Table Y upstream","Table Y inboard","Table Y outboard",$
"Table X upstream","Table X downstream","Table Base Y",$
"Mono angle","TT Slit H Pos","TT Slit H Wid","TT Slit V Pos",$
"TT Slit V Wid","Sample X", "Sample Y","Sample Z","WDS Stage X ",$
"KB V x", "KB V angle","KB V Fup","KB V Fdn", $
"KB H x", "KB H angle","KB H Fup", "KB H Fdn", "Energy"]
n = n_elements(motor_n)
pv = '1D_pDummy.VAL'
if (scanPV eq 'scan2') then pv = '2D_pDummy.VAL'
if (scanPV eq 'scan3') then pv = '1D_pDummy.VAL'
if (name eq 'Stage X') then name = 'Sample X'
if (name eq 'Stage Y') then name = 'Sample Y'
if (name eq 'Stage Z') then name = 'Sample Z'
for i = 0, n-1 do begin
if (name eq motor_n[i]) then pv = motor_p[i]
endfor
if (pv eq 'null') then begin
print, ' unknown motor name: ', name
print, ' type motor_scan, /list for list of motor names'
endif
return
end
function npts_of_start_stop_step, start, stop, step
MAX_SCAN_POINTS = 1000 ; maximum number of points in scan record
step = abs(step)
if (step le 1.d-8) then step = 1.d-8
npts = 1 + round((abs(stop - start) )/abs(step))
npts = fix ( (npts > 2) < MAX_SCAN_POINTS)
step = (stop - start) / (npts-1)
return, npts
end
pro motor_redraw_window, p
; redraw motor screen (say, after loading a scan parameter file)
; note: scan1 is updated, and brought to the foreground
Widget_Control, (*p).wid.scan, SET_DROPLIST_SELECT = 0
Widget_Control, (*p).wid.is_rel, SET_DROPLIST_SELECT = (*p).scan1.is_rel
Widget_Control, (*p).wid.time, SET_VALUE = (*p).scan1.time
Widget_Control, (*p).wid.units, SET_VALUE = (*p).scan1.units
Widget_Control, (*p).wid.start, SET_VALUE = (*p).scan1.r1start
Widget_Control, (*p).wid.stop, SET_VALUE = (*p).scan1.r1stop
Widget_Control, (*p).wid.step, SET_VALUE = (*p).scan1.r1step
Widget_Control, (*p).wid.npts, SET_VALUE = (*p).scan1.r1npts
;;
n = n_elements((*p).m_names)
name = strtrim((*p).scan1.motor_name,2)
(*p).scan1.motor_name = name
for i = 0, n-1 do begin
if (name eq (*p).m_names[i]) then goto, scan_choice_found
endfor
i = 0
scan_choice_found:
WIDGET_CONTROL, (*p).wid.motor, SET_DROPLIST_SELECT = i
;;
get_motor_settings, prefix=(*p).main.prefix, motor=(*p).scan1.motor_name, $
scanPV=(*p).scan1.scanPV,$
value=val, llimit=ll, ulimit=ul, units=ut, pv=pv, rbv=rbv
(*p).scan1.cur_pos= val
(*p).scan1.units = ut
(*p).scan1.ulimit = ul
(*p).scan1.llimit = ll
(*p).scan1.pos1 = pv
(*p).scan1.rbv1 = rbv
WIDGET_CONTROL, (*p).wid.llimit, SET_VALUE = strtrim(string(ll),2)
WIDGET_CONTROL, (*p).wid.ulimit, SET_VALUE = strtrim(string(ul),2)
WIDGET_CONTROL, (*p).wid.cur_pos, SET_VALUE = strtrim(string(val),2)
WIDGET_CONTROL, (*p).wid.units, SET_VALUE = strtrim(string(ut),2)
return
end
pro motor_scan_event, event
WIDGET_CONTROL, event.top, GET_UVALUE = p
WIDGET_CONTROL, event.id, GET_UVALUE = uval
MAX_SCAN_POINTS = 1000 ; maximum number of points in scan record
ErrorNo = 0
Catch, ErrorNo
if (ErrorNo ne 0) then begin ;
Catch, /CANCEL
ErrArray = ['Application Error!', $
'Error Number: '+strtrim(!error,2), !Err_String]
a = DIALOG_MESSAGE(ErrArray, /ERROR)
return
endif
update_scans = 1
current_scan = fix((*p).main.current_scan)
case current_scan of
1: scan = (*p).scan1
2: scan = (*p).scan2
3: scan = (*p).scan3
else: print, ' error : current_scan ', current_scan , ' out of range '
endcase
; print , ' see event: "', uval, '" for ', scan.ScanPV
case uval of
'exit': WIDGET_CONTROL, event.top, /DESTROY
'load_cfg': begin
f = (*p).main.file
retval = read_scan_param_file(p)
motor_redraw_window, p
update_scans = 0 ; don't overwrite read-in scans with old values!!
end
'save_cfg': begin
f = (*p).main.file
retval = save_scan_param_file(p,1)
end
'saveas_cfg': begin
f = (*p).main.file
retval = save_scan_param_file(p,1)
end
'time': begin
WIDGET_CONTROL, (*p).wid.time, GET_VALUE = t
t = strtrim(t,2)
scan.time = t
end
'start_pos': begin
WIDGET_CONTROL, (*p).wid.start, GET_VALUE = t
start = strtrim(t,2)
new_pos = double(start)
ul = scan.ulimit
ll = scan.llimit
if (scan.is_rel) then new_pos = new_pos + scan.cur_pos
if ((new_pos lt ll) or (new_pos gt ul)) then begin
if (new_pos lt ll) then new_pos = ll
if (new_pos gt ul) then new_pos = ul
if (scan.is_rel) then new_pos = new_pos - scan.cur_pos
WIDGET_CONTROL, (*p).wid.start, $
SET_VALUE = strtrim(string(new_pos),2)
endif
WIDGET_CONTROL, (*p).wid.start, GET_VALUE = t
start = double(strtrim(t,2))
step = scan.r1step
stop = scan.r1stop
npts = npts_of_start_stop_step(start,stop,step)
scan.r1npts = npts
scan.r1start = start
scan.r1stop = stop
scan.r1step = step
WIDGET_CONTROL, (*p).wid.step, SET_VALUE = strtrim(string(step),2)
WIDGET_CONTROL, (*p).wid.npts, SET_VALUE = strtrim(string(npts),2)
end
'stop_pos': begin
WIDGET_CONTROL, (*p).wid.stop, GET_VALUE = t
stop = strtrim(t,2)
new_pos = double(stop)
ul = scan.ulimit
ll = scan.llimit
if (scan.is_rel) then new_pos = new_pos + scan.cur_pos
if ((new_pos lt ll) or (new_pos gt ul)) then begin
if (new_pos lt ll) then new_pos = ll
if (new_pos gt ul) then new_pos = ul
if (scan.is_rel) then new_pos = new_pos - scan.cur_pos
WIDGET_CONTROL, (*p).wid.stop, $
SET_VALUE = strtrim(string(new_pos),2)
endif
WIDGET_CONTROL, (*p).wid.stop, GET_VALUE = t
stop = double(strtrim(t,2))
step = scan.r1step
start = scan.r1start
npts = npts_of_start_stop_step(start,stop,step)
scan.r1npts = npts
scan.r1start = start
scan.r1stop = stop
scan.r1step = step
WIDGET_CONTROL, (*p).wid.step, SET_VALUE = strtrim(string(step),2)
WIDGET_CONTROL, (*p).wid.npts, SET_VALUE = strtrim(string(npts),2)
end
'step': begin
WIDGET_CONTROL, (*p).wid.step, GET_VALUE = t
step = double(strtrim(t,2))
start = scan.r1start
stop = scan.r1stop
npts = npts_of_start_stop_step(start,stop,step)
scan.r1npts = npts
scan.r1start = start
scan.r1stop = stop
scan.r1step = step
WIDGET_CONTROL, (*p).wid.step, SET_VALUE = strtrim(string(step),2)
WIDGET_CONTROL, (*p).wid.npts, SET_VALUE = strtrim(string(npts),2)
end
'npts': begin
WIDGET_CONTROL, (*p).wid.npts, GET_VALUE = t
npts = strtrim(t,2)
start = scan.r1start
stop = scan.r1stop
npts = ((npts > 2) < MAX_SCAN_POINTS)
scan.r1npts = npts
step = abs(scan.r1start - scan.r1stop)/(npts - 1)
if (scan.r1start gt scan.r1stop) then step = -step
scan.r1step = step
WIDGET_CONTROL, (*p).wid.step, SET_VALUE = strtrim(string(step),2)
WIDGET_CONTROL, (*p).wid.npts, SET_VALUE = strtrim(string(npts),2)
end
'scan_choice': begin
case event.index of
0: scan = (*p).scan1
1: scan = (*p).scan2
2: scan = (*p).scan3
else:
endcase
current_scan = event.index + 1
(*p).main.current_scan = current_scan
pre = (*p).main.prefix
name = scan.motor_name
print, 'scan_choice : ', current_scan, ' -> get_motor_settings ', name
get_motor_settings, prefix=(*p).main.prefix, motor=name, scanPV=scan.scanPV,$
value=val, llimit=ll, ulimit=ul, units=ut, pv=pv, rbv=rbv
scan.cur_pos= val
scan.units = ut
scan.ulimit = ul
scan.llimit = ll
scan.pos1 = pv
scan.rbv1 = rbv
WIDGET_CONTROL, (*p).wid.llimit, SET_VALUE = strtrim(string(ll),2)
WIDGET_CONTROL, (*p).wid.ulimit, SET_VALUE = strtrim(string(ul),2)
WIDGET_CONTROL, (*p).wid.cur_pos, SET_VALUE = strtrim(string(val),2)
WIDGET_CONTROL, (*p).wid.units, SET_VALUE = strtrim(string(ut),2)
for i = 0, n_elements((*p).m_names) do begin
if (name eq (*p).m_names[i]) then goto, scan_choice_found
endfor
scan_choice_found:
WIDGET_CONTROL, (*p).wid.motor, SET_DROPLIST_SELECT = i
start = scan.r1start
stop = scan.r1stop
step = scan.r1step
npts = scan.r1npts
is_rel = scan.is_rel
print , ' start stop step npts is_rel = ', $
start, stop , step, npts, is_rel
WIDGET_CONTROL, (*p).wid.start, SET_VALUE = strtrim(string(start),2)
WIDGET_CONTROL, (*p).wid.stop, SET_VALUE = strtrim(string(stop),2)
WIDGET_CONTROL, (*p).wid.step, SET_VALUE = strtrim(string(step),2)
WIDGET_CONTROL, (*p).wid.npts, SET_VALUE = strtrim(string(npts),2)
WIDGET_CONTROL, (*p).wid.is_rel, SET_DROPLIST_SELECT = is_rel
end
'use_rel': begin
do_change = 0
dx = 0
; print , ' use_rel ', scan.cur_pos, event.index, scan.is_rel
if ((event.index eq 1) and (scan.is_rel eq 0)) then begin ;
do_change = 1
scan.is_rel = 1
dx = - scan.cur_pos
endif else if ((event.index eq 0) and (scan.is_rel eq 1)) then begin
do_change = 1
scan.is_rel = 0
dx = scan.cur_pos
endif
if (do_change eq 1) then begin
start = scan.r1start + dx
stop = scan.r1stop + dx
scan.r1start = start
scan.r1stop = stop
WIDGET_CONTROL, (*p).wid.start, SET_VALUE = strtrim(string(start),2)
WIDGET_CONTROL, (*p).wid.stop, SET_VALUE = strtrim(string(stop),2)
endif
end
'motor_name': begin
name = (*p).m_names[event.index]
get_motor_settings, prefix=(*p).main.prefix, motor=name, scanPV=scan.scanPV, $
value=val, llimit=ll, ulimit=ul, units=ut, pv=pv, rbv=rbv
scan.motor_name = name
scan.cur_pos= val
scan.units = ut
scan.ulimit = ul
scan.llimit = ll
scan.pos1 = pv
scan.rbv1 = rbv
WIDGET_CONTROL, (*p).wid.llimit, SET_VALUE = strtrim(string(ll),2)
WIDGET_CONTROL, (*p).wid.ulimit, SET_VALUE = strtrim(string(ul),2)
WIDGET_CONTROL, (*p).wid.cur_pos, SET_VALUE = strtrim(string(val),2)
WIDGET_CONTROL, (*p).wid.units, SET_VALUE = strtrim(string(ut),2)
end
'cur_pos': begin
WIDGET_CONTROL, (*p).wid.cur_pos, GET_VALUE = cur
val = double(strtrim(cur,2))
ll = scan.llimit
ul = scan.ulimit
pos = scan.pos1
if ((val le ul) and (val ge ll)) then begin
rbv = val
s = caput(pos, val)
s = caget(pos, rbv)
scan.cur_pos = rbv
WIDGET_CONTROL, (*p).wid.cur_pos, SET_VALUE = strtrim(string(rbv),2)
endif else begin
print, ' requested position is outside limits'
endelse
end
'llimit': begin
WIDGET_CONTROL, (*p).wid.llimit, SET_VALUE = string(scan.llimit)
end
'ulimit': begin
WIDGET_CONTROL, (*p).wid.ulimit, SET_VALUE = string(scan.ulimit)
end
'load': begin
name = scan.motor_name
start = scan.r1start
stop = scan.r1stop
step = scan.r1step
time = scan.time
scanPV = scan.scanPV
rel = scan.is_rel
set_motor_scan, name=name, start=start, stop=stop, step=step, $
time=time, relative=rel, scanPV= scanPV
end
else: print , ' unknown event ', uval
endcase
;
; put back scan structure into (*p)
; print, 'putting ' , current_scan, ' back into heap'
if (update_scans eq 1) then begin
case current_scan of
1: (*p).scan1 = scan
2: (*p).scan2 = scan
3: (*p).scan3 = scan
else: print, 'cannot put current_scan back!!' , current_scan
endcase
endif
;
return
end
pro motor_scan
m_names = ["Dummy", "Energy", "Sample X", "Sample Y","Sample Z", $
"Table Y upstream","Table Y inboard",$
"Table Y outboard", "Table X upstream",$
"Table X downstream","Table Base Y",$
"Mono angle","TT Slit H Pos","TT Slit H Wid","TT Slit V Pos",$
"TT Slit V Wid","WDS Stage X ",$
"KB V x", "KB V angle","KB V Fup","KB V Fdn", $
"KB H x", "KB H angle","KB H Fup", "KB H Fdn"]
scan_choices = ['Scan 1', 'Scan 2', 'Scan 3']
Rel_choices = ['Absolute', 'Relative']
main = {prefix:'13IDC:', file:'unknown.scn', dimension:'1',$
detectors: 15, current_scan:1, trigger1:'med:Start.VAL', trigger2:'scaler1.CNT'}
scan1 = {type:'Motor', ScanPV:'scan1', motor_name:m_names[2],$
pos1: '', rbv1: '', units:'mm', $
llimit:0.0, ulimit:0.0, cur_pos:0.0, $
r1start:-10., r1step: 1. , r1stop: 10., r1npts: 21 , $
e0:7112., is_rel:1, is_kspace:0, nregs:3, time:1.0, $
r2start: -30., r2step: 0.5 , r2stop: 30., r2npts: 61, $
r3start: 0., r3step: 0.05, r3stop: 15. , r3npts: 300 }
scan2 = {type:'Motor', ScanPV:'scan2', motor_name:m_names[3],$
pos1: '', rbv1: '', units:'mm', $
llimit:0.0, ulimit:0.0, cur_pos:0.0, $
r1start:-10., r1step: 1. , r1stop: 10., r1npts: 21 , $
e0:7112., is_rel:1, is_kspace:0, nregs:3, time:1.0, $
r2start: -30., r2step: 0.5 , r2stop: 30., r2npts: 61, $
r3start: 0., r3step: 0.05, r3stop: 15. , r3npts: 300 }
scan3 = {type:'Motor', ScanPV:'scan3', motor_name:m_names[4],$
pos1: '', rbv1: '', units:'mm', $
llimit:0.0, ulimit:0.0, cur_pos:0.0, $
r1start:-10., r1step: 1. , r1stop: 10., r1npts: 21 , $
e0:7112., is_rel:1, is_kspace:0, nregs:3, time:1.0, $
r2start: -30., r2step: 0.5 , r2stop: 30., r2npts: 61, $
r3start: 0., r3step: 0.05, r3stop: 15. , r3npts: 300 }
wid = {scan:scan_choices[0], motor:m_names[2], time:0L, $
is_rel:Rel_choices[1], units:0L, $
start:0L, stop:0L, step:0L, npts:0L, $
cur_pos:0L, llimit:0L, ulimit:0L}
; get settings for default motor:
l = -20.
u = 70.
c = 10.5
get_motor_settings, prefix=main.prefix, motor=scan1.motor_name, scanPV=scan1.ScanPV,$
value=c, llimit=l, ulimit=u, units=t, pv=pv, rbv=rbv
scan1.llimit = l
scan1.ulimit = u
scan1.cur_pos = c
scan1.units = t
scan1.pos1 = pv
scan1.rbv1 = rbv
get_motor_settings, prefix=main.prefix, motor=scan2.motor_name, scanPV=scan2.ScanPV,$
value=c, llimit=l, ulimit=u, units=t, pv=pv, rbv=rbv
scan2.llimit = l
scan2.ulimit = u
scan2.cur_pos = c
scan2.units = t
scan2.pos1 = pv
scan2.rbv1 = rbv
get_motor_settings, prefix=main.prefix, motor=scan3.motor_name, scanPV=scan3.ScanPV,$
value=c, llimit=l, ulimit=u, units=t, pv=pv, rbv=rbv
scan3.llimit = l
scan3.ulimit = u
scan3.cur_pos = c
scan3.units = t
scan3.pos1 = pv
scan3.rbv1 = rbv
info = {main:main, scan1:scan1, scan2:scan2, scan3:scan3, wid:wid, m_names:m_names}
;
MAIN = Widget_Base(TITLE = 'Motor Scan', /COLUMN, APP_MBAR = menubar)
fileMenu = WIDGET_BUTTON(menubar, VALUE = 'File', /HELP)
loadMB = WIDGET_BUTTON(fileMenu, VALUE = 'Read Scan File ...', UVALUE = 'load_cfg')
saveMB = WIDGET_BUTTON(fileMenu, VALUE = 'Save Scan File ...', UVALUE = 'save_cfg')
saveasMB = WIDGET_BUTTON(fileMenu, VALUE = 'Save As ...', UVALUE = 'saveas_cfg')
exitMB = WIDGET_BUTTON(fileMenu, VALUE = 'Exit', UVALUE = 'exit', $
/SEPARATOR)
; Help menu
helpMenu = WIDGET_BUTTON(menubar, VALUE = 'Help', /MENU, /HELP)
scnhelpMB = WIDGET_BUTTON(helpMenu, VALUE = 'Help on Motor REGIONS', UVALUE = 'scan_help')
idlhelpMB = WIDGET_BUTTON(helpMenu, VALUE = 'Help on IDL', UVALUE = 'IDLhelp')
MAINFRAME = WIDGET_BASE(MAIN, /COLUMN)
R0_base = WIDGET_BASE(MAINFRAME, /ROW)
MAINFRAME = WIDGET_BASE(MAIN, /COLUMN)
R0_base = WIDGET_BASE(MAINFRAME, /ROW)
info.wid.scan = WIDGET_DROPLIST(R0_base, TITLE = ' Scan ', $
VALUE = scan_choices, UVALUE = 'scan_choice')
WIDGET_CONTROL, info.wid.scan, SET_DROPLIST_SELECT = 0
info.wid.motor = WIDGET_DROPLIST(R0_base, TITLE = ' Motor ', $
VALUE = m_names, UVALUE = 'motor_name')
WIDGET_CONTROL, info.wid.motor, SET_DROPLIST_SELECT = 2
info.wid.time = CW_FIELD(R0_base, /FLOATING, /ROW, XSIZE = 7, $
TITLE = ' Count Time', UVALUE = 'time', $
VALUE = strtrim(string(info.scan1.time),2), $
/ALL_EVENTS)
X = WIDGET_LABEL(R0_base, SCR_XSIZE=40, VALUE = 'sec')
R_base = WIDGET_BASE(MAINFRAME, /COLUMN)
R1_base = WIDGET_BASE(R_base, /ROW, /FRAME)
info.wid.cur_pos = CW_FIELD(R1_base, /FLOATING, Title = 'Current Position', $
XSIZE = 11, UVALUE = 'cur_pos', $
VALUE = strtrim(string(info.scan1.cur_pos),2), $
/RETURN_EVENTS)
info.wid.units = WIDGET_LABEL(R1_base, XSIZE=80, $ ; /ALIGN_LEFT, $
VALUE= strtrim(info.scan1.units,2), $
UVALUE = 'units')
info.wid.llimit = CW_FIELD(R1_base, /FLOATING, Title = 'Limits :', $
XSIZE = 11, UVALUE = 'llimit', $
VALUE = strtrim(string(info.scan1.llimit),2), $
/RETURN_EVENTS)
info.wid.ulimit = CW_FIELD(R1_base, /FLOATING, Title = ' : ', $
XSIZE = 11, UVALUE = 'ulimit', $
VALUE = strtrim(string(info.scan1.ulimit),2), $
/RETURN_EVENTS)
R2_base = WIDGET_BASE(R_base, /ROW)
info.wid.is_rel = WIDGET_DROPLIST(R2_base, TITLE = 'use ', $
VALUE = Rel_choices, UVALUE = 'use_rel')
WIDGET_CONTROL, info.wid.is_rel, SET_DROPLIST_SELECT = 1
X = WIDGET_LABEL(R2_base, XSIZE=120, VALUE = ' Positions ')
R = WIDGET_BASE(MAINFRAME, /COLUMN,/FRAME)
T = WIDGET_BASE(R, /ROW)
X = WIDGET_LABEL(T, XSIZE=100, VALUE = ' Start ')
X = WIDGET_LABEL(T, XSIZE=100, VALUE = ' Stop ')
X = WIDGET_LABEL(T, XSIZE=100, VALUE = ' Step ')
X = WIDGET_LABEL(T, XSIZE=100, VALUE = ' Npts ')
S = WIDGET_BASE(R, /ROW)
info.wid.start = CW_FIELD(S, Title= ' ', XSIZE = 11, UVALUE = 'start_pos', $
VALUE = strtrim(string(info.scan1.r1start),2), $
/RETURN_EVENTS, /FLOATING)
info.wid.stop = CW_FIELD(S, Title= ' ', XSIZE = 11, UVALUE = 'stop_pos', $
VALUE = strtrim(string(info.scan1.r1stop),2), $
/RETURN_EVENTS, /FLOATING)
info.wid.step = CW_FIELD(S, Title = ' ', XSIZE = 11, UVALUE = 'step', $
VALUE = strtrim(string(info.scan1.r1step),2), $
/RETURN_EVENTS, /FLOATING)
info.wid.npts = CW_FIELD(S, Title = ' ', XSIZE = 11, UVALUE = 'npts', $
VALUE = strtrim(string(info.scan1.r1npts),2), $
/RETURN_EVENTS, /FLOATING)
R4_base = WIDGET_BASE(MAINFRAME,/ROW)
X = WIDGET_BUTTON(R4_base, VALUE = 'Load Scan Parameters', UVALUE='load')
X = WIDGET_BUTTON(R4_base, VALUE = 'EXIT ', UVALUE='exit')
; render widgets, load info structure into MAIN
p_info = ptr_new(info,/NO_COPY)
Widget_Control, MAIN, SET_UVALUE=p_info
Widget_Control, MAIN, /REALIZE
xmanager, 'motor_scan', MAIN, /NO_BLOCK
return
end
sscan/multi_xrf.pro 0100644 0000621 0000620 00000004610 07011574136 013705 0 ustar epics epics pro multi_xrf, file=file, number=number, view=view, start=start, help=help
;
; repetition of sscan
;
if (keyword_set(help) ne 0) then begin
print, 'multi_xrf: Repeated collection of XRF spectra'
print, ' argument meaning '
print, ' file prefix of output file name'
print, ' number number of spectra to collect'
print, ' start starting index for file name suffix [default=001]'
print, ' /help print this help message'
return
endif
prefix ='13IDC:med:'
preset_real = prefix + 'PresetReal'
med_start = prefix + 'Start.VAL'
med= obj_new('EPICS_MED', prefix)
out_file = 'm_xrf'
if (n_elements(file) eq 0) then file = ''
if (file ne '') then out_file = file
imax = 1
if (n_elements(number) ne 0) then imax = number>1
imin = 1
if (n_elements(start) ne 0) then imin = start>1
x = caget(preset_real,collect_time)
wait_time = collect_time/20.0
for i = imin, imax+imin-1 do begin
xrf_file = out_file + '_' + string(i,format='(i3.3)') + '.xrf'
x = caput(med_start, 1)
collecting = 1
while (collecting) do begin
; check for keyboard interrupt
c = get_kbrd(0)
c = strlowcase(c)
if ((c eq string(16B)) or (c eq 'p')) then goto, interrupt
resume:
;
wait, wait_time
x = caget(med_start, still_going)
if (still_going eq 0) then begin
collecting = 0
med->write_file, xrf_file
print, ' wrote ', xrf_file
endif
endwhile
endfor
return
interrupt:
print, ''
print, ' ####################################'
print, ' xrf collection paused by user'
print, ' type r to resume collection'
print, ' type a to abort collection'
print, ' type w to write spectra so far and quit now'
print, ' ####################################'
interrupt_2:
c = get_kbrd(1)
c = strlowcase(c)
case c of
'a': begin
print, 'aborting scan: not writing data file'
s = caput(med_start,0)
return
end
'w': begin
print, 'writing abbreviated spectra ... '
med->write_file, xrf_file
print, ' wrote ', xrf_file
return
end
'r': begin
print, 'resuming scan'
goto, resume
end
else: begin
print, ' scan paused: type r for resume, a for abort, w to write and quit'
goto, interrupt_2
end
endcase
end
sscan/read_scan_param_file.pro 0100644 0000621 0000620 00000014266 07006410342 015772 0 ustar epics epics ; read scan parameter file
function read_scan_param_file, p
init_file = (*p).main.file
file = ''
file = dialog_pickfile(filter='*.scn', get_path=path,$
/must_exist, /read, file = init_file)
file = strtrim(file,2)
if (file eq '') then return, -1
openr, lun, file, /get_lun
print, ' Reading scan parameters from ', file
nline = 0
str = ' '
retval= -1
mode = 'null'
while not (eof(lun)) do begin
nline = nline + 1
readf, lun, str
str = strtrim(str,2)
if (nline eq 1) then begin
s = strmid(str, 0, 17)
t = strmid(str, 18, strlen(str))
if (s ne ';Scan Parameters:') then begin
print, ' File ', file, ' is not a valid scan file'
goto, ret
endif
version = t
endif
icol = strpos(str, ':')
ismc = strpos(str, ';')
if ((ismc eq 0) and (icol ge 0)) then begin
s = strmid(str,ismc+1, icol-1)
mode = s
case s of
'Scan Parameters': mode = 'main'
'scan 1': mode = 'scan1'
'scan 2': mode = 'scan2'
'scan 3': mode = 'scan3'
'triggers':
'detectors':
else: mode = 'null'
endcase
endif else begin
key = strmid(str,0, icol)
val = strtrim(strmid(str,icol+1, strlen(str)), 2)
case mode of
'main': begin
case key of
'prefix': (*p).main.prefix = val
'dimension': (*p).main.dimension = val
'detectors': (*p).main.detectors = val
'trigger1': (*p).main.trigger1 = val
'trigger2': (*p).main.trigger2 = val
'current_scan': (*p).main.current_scan = val
endcase
end
'scan1': begin
case key of
'type': (*p).scan1.type = val
'ScanPV': (*p).scan1.scanPV = val
'motor_name': (*p).scan1.motor_name = val
'pos1': (*p).scan1.pos1 = val
'rbv1': (*p).scan1.rbv1 = val
'units': (*p).scan1.units = val
'time': (*p).scan1.time = val
'nregs': (*p).scan1.nregs = val
'is_rel': (*p).scan1.is_rel = val
'is_kspace': (*p).scan1.is_kspace = val
'r1start': (*p).scan1.r1start = val
'r1step': (*p).scan1.r1step = val
'r1stop': (*p).scan1.r1stop = val
'r2start': (*p).scan1.r2start = val
'r2step': (*p).scan1.r2step = val
'r2stop': (*p).scan1.r2stop = val
'r3start': (*p).scan1.r3start = val
'r3step': (*p).scan1.r3step = val
'r3stop': (*p).scan1.r3stop = val
'e0': (*p).scan1.e0 = val
else:
endcase
end
'scan2': begin
case key of
'type': (*p).scan2.type = val
'ScanPV': (*p).scan2.scanPV = val
'motor_name': (*p).scan2.motor_name = val
'pos1': (*p).scan2.pos1 = val
'rbv1': (*p).scan2.rbv1 = val
'units': (*p).scan2.units = val
'time': (*p).scan2.time = val
'nregs': (*p).scan2.nregs = val
'is_rel': (*p).scan2.is_rel = val
'is_kspace': (*p).scan2.is_kspace = val
'r1start': (*p).scan2.r1start = val
'r1step': (*p).scan2.r1step = val
'r1stop': (*p).scan2.r1stop = val
'r2start': (*p).scan2.r2start = val
'r2step': (*p).scan2.r2step = val
'r2stop': (*p).scan2.r2stop = val
'r3start': (*p).scan2.r3start = val
'r3step': (*p).scan2.r3step = val
'r3stop': (*p).scan2.r3stop = val
'e0': (*p).scan2.e0 = val
else:
endcase
end
'scan3': begin
case key of
'type': (*p).scan3.type = val
'ScanPV': (*p).scan3.scanPV = val
'motor_name': (*p).scan3.motor_name = val
'pos1': (*p).scan3.pos1 = val
'rbv1': (*p).scan3.rbv1 = val
'units': (*p).scan3.units = val
'time': (*p).scan3.time = val
'nregs': (*p).scan3.nregs = val
'is_rel': (*p).scan3.is_rel = val
'is_kspace': (*p).scan3.is_kspace = val
'r1start': (*p).scan3.r1start = val
'r1step': (*p).scan3.r1step = val
'r1stop': (*p).scan3.r1stop = val
'r2start': (*p).scan3.r2start = val
'r2step': (*p).scan3.r2step = val
'r2stop': (*p).scan3.r2stop = val
'r3start': (*p).scan3.r3start = val
'r3step': (*p).scan3.r3step = val
'r3stop': (*p).scan3.r3stop = val
'e0': (*p).scan3.e0 = val
else:
endcase
end
else:
endcase
endelse
endwhile
retval = 0
ret:
close, lun
free_lun, lun
return, retval
end
sscan/read_sscan.pro 0100644 0000621 0000620 00000003741 07005676476 014017 0 ustar epics epics pro read_sscan, file=file, da=da, pa=pa, npts=npts, help=help
;
; read detector and positioner arrays from ascii-dump versions
; of data-catcher files
;
if (keyword_set(help) ne 0) then begin
print, 'Read_sscan: Read data file from sscan'
print, ' argument meaning '
print, ' file input file name '
print, ' pa positioner array [ fltarr([npts,4)]'
print, ' da detector array [ fltarr([npts,15)]'
print, ' npts number of data points in Scan'
print, ' /help print this help message'
return
endif
;
if (n_elements(file) eq 0) then begin
print, 'read_sscan, file=file, da=da, pa=pa, npts=npts'
print, ' type read_sscan, /help for more details'
return
endif
string = '; '
openr, lun, file, /get_lun
tmp_pos = fltarr(1000,4)
tmp_data = fltarr(1000,15)
npts = -1
while not (eof(lun)) do begin
readf,lun,string
char1 = strmid(strtrim(string,2) , 0,1)
if ( char1 ne ';') then begin
;; print, string
reads, string, p1,p2,p3,p4, d01, d02, d03, d04, d05, $
d06,d07,d08,d09,d10,d11,d12,d13,d14,d15
; reads, string, p1,d01, d02, d03, d04
npts = npts + 1
tmp_pos[npts, 0] = p1
tmp_pos[npts, 1] = p2
tmp_pos[npts, 2] = p3
tmp_pos[npts, 3] = p4
tmp_data[npts, 0] = d01
tmp_data[npts, 1] = d02
tmp_data[npts, 2] = d03
tmp_data[npts, 3] = d04
tmp_data[npts, 4] = d05
tmp_data[npts, 5] = d06
tmp_data[npts, 6] = d07
tmp_data[npts, 7] = d08
tmp_data[npts, 8] = d09
tmp_data[npts, 9] = d10
tmp_data[npts,10] = d11
tmp_data[npts,11] = d12
tmp_data[npts,12] = d13
tmp_data[npts,13] = d14
tmp_data[npts,14] = d15
endif
endwhile
print, " npts = ", npts
da = fltarr(npts+1,15)
da = tmp_data(0:npts,*)
pa = fltarr(npts+1,4)
pa = tmp_pos(0:npts,*)
close, lun
free_lun, lun
return
end
;
sscan/save_scan_param_file.pro 0100644 0000621 0000620 00000007204 07006410331 016005 0 ustar epics epics function save_scan_param_file, p, save_as
main = (*p).main
scan1 = (*p).scan1
scan2 = (*p).scan2
scan3 = (*p).scan3
init_file = main.file
file = ''
if (save_as eq 1) then file = dialog_pickfile(filter='*.scn', $
get_path=path, $
/write, file = init_file)
file = strtrim(file,2)
if (file eq '') then return, -1
(*p).main.file = file
openw, lun, file, /get_lun
printf, lun, ';Scan Parameters: v1.0'
printf, lun, ' prefix: ', main.prefix
printf, lun, ' dimension: ', main.dimension
printf, lun, ' detectors: ', main.detectors
printf, lun, ' trigger1: ', main.trigger1
printf, lun, ' trigger2: ', main.trigger2
printf, lun, ';scan 1:'
printf, lun, ' type: ', scan1.type
printf, lun, ' scanPV: ', scan1.scanPV
printf, lun, ' motor_name: ', scan1.motor_name
printf, lun, ' pos1: ', scan1.pos1
printf, lun, ' rbv1: ', scan1.rbv1
printf, lun, ' units: ', scan1.units
printf, lun, ' nregs: ', scan1.nregs
printf, lun, ' time: ', scan1.time
printf, lun, ' is_rel: ', scan1.is_rel
printf, lun, ' is_kspace: ', scan1.is_kspace
printf, lun, ' r1start: ', scan1.r1start
printf, lun, ' r1stop: ', scan1.r1stop
printf, lun, ' r1step: ', scan1.r1step
printf, lun, ' r2start: ', scan1.r2start
printf, lun, ' r2stop: ', scan1.r2stop
printf, lun, ' r2step: ', scan1.r2step
printf, lun, ' r3start: ', scan1.r3start
printf, lun, ' r3stop: ', scan1.r3stop
printf, lun, ' r3step: ', scan1.r3step
printf, lun, ' e0: ', scan1.e0
printf, lun, ';scan 2:'
printf, lun, ' type: ', scan2.type
printf, lun, ' scanPV: ', scan2.scanPV
printf, lun, ' motor_name:', scan2.motor_name
printf, lun, ' pos1: ', scan2.pos1
printf, lun, ' rbv1: ', scan2.rbv1
printf, lun, ' units: ', scan2.units
printf, lun, ' nregs: ', scan2.nregs
printf, lun, ' time: ', scan2.time
printf, lun, ' is_rel: ', scan2.is_rel
printf, lun, ' is_kspace: ', scan2.is_kspace
printf, lun, ' r1start: ', scan2.r1start
printf, lun, ' r1stop: ', scan2.r1stop
printf, lun, ' r1step: ', scan2.r1step
printf, lun, ' r2start: ', scan2.r2start
printf, lun, ' r2stop: ', scan2.r2stop
printf, lun, ' r2step: ', scan2.r2step
printf, lun, ' r3start: ', scan2.r3start
printf, lun, ' r3stop: ', scan2.r3stop
printf, lun, ' r3step: ', scan2.r3step
printf, lun, ' e0: ', scan2.e0
printf, lun, ';scan 3:'
printf, lun, ' type: ', scan3.type
printf, lun, ' scanPV: ', scan3.scanPV
printf, lun, ' motor_name:', scan3.motor_name
printf, lun, ' pos1: ', scan3.pos1
printf, lun, ' rbv1: ', scan3.rbv1
printf, lun, ' units: ', scan3.units
printf, lun, ' nregs: ', scan3.nregs
printf, lun, ' time: ', scan3.time
printf, lun, ' is_rel: ', scan3.is_rel
printf, lun, ' is_kspace: ', scan3.is_kspace
printf, lun, ' r1start: ', scan3.r1start
printf, lun, ' r1stop: ', scan3.r1stop
printf, lun, ' r1step: ', scan3.r1step
printf, lun, ' r2start: ', scan3.r2start
printf, lun, ' r2stop: ', scan3.r2stop
printf, lun, ' r2step: ', scan3.r2step
printf, lun, ' r3start: ', scan3.r3start
printf, lun, ' r3stop: ', scan3.r3stop
printf, lun, ' r3step: ', scan3.r3step
printf, lun, ' e0: ', scan3.e0
printf, lun, ';detectors:'
close, lun
free_lun, lun
print, ' wrote file = ', file
return, 0
end
sscan/scan_plot.pro 0100644 0000621 0000620 00000003704 07055037561 013665 0 ustar epics epics pro scan_plot_event, event
Widget_Control, event.top, get_uval = p
Widget_Control, event.id, get_uval = uval
print, ' scan_exec_event: ', uval
return
end
function scan_plot, p
;
; gui for selecting detectors
;
print, 'scan and plot'
ret = (*p).es->lookup_detectors()
det = (*p).es->get_param('detectors')
info = {es:(*p).es, draw_id:0L }
main = Widget_Base(title = 'Scan Plotter', /col, app_mbar = mbar)
menu = Widget_Button(mbar, value = 'File')
x = Widget_Button(menu, value = 'Print ', uval = 'print')
x = Widget_Button(menu, value = 'Set Preferences', uval = 'set_pref')
x = Widget_Button(menu, value = 'Exit', uval = 'exit', /separator)
menu = Widget_Button(mbar, value = 'Detectors')
x = Widget_Button(menu, value = 'Select ...', uval = 'det_select')
x = Widget_Button(menu, value = 'Advanced ...', uval = 'advanced')
menu = Widget_Button(mbar, value = 'Options')
x = Widget_Button(menu, value = 'Colors ...', uval = 'colors')
x = Widget_Button(menu, value = 'Line Styles ...', uval = 'styles')
base = widget_base(main,/row)
draw = widget_draw(base, graphics_level=2, xsize=700, ysize=500)
bot = widget_base(main,/row)
but = widget_base(bot, /row)
x = widget_button(but, val='Quit', uval = 'exit')
x = widget_button(but, val='Zoom', uval = 'zoom')
x = widget_button(but, val='Show Cursor', uval = 'curs')
x = widget_button(but, val='Pause Scan', uval = 'pause_scan')
Widget_Control, draw, timer=0.25
Widget_Control, main, /realize
widget_control, id, get_val=draw_id
info.draw_id =draw_id
p_info = ptr_new(info,/no_copy)
Widget_Control, main, set_uvalue=p_info
xmanager, 'scan_plot', main, /no_block
x = fltarr(100)
y = fltarr(100)
wset, draw_id
for i = 0, 20 do begin
x[i] = i * 1.0
y[i] = sin(x[i])
plot, x(0:i), y(0:i), psym=-1
wait, 0.5
endfor
print, 'done '
return, 0
end
sscan/sscan_1d.pro 0100644 0000621 0000620 00000002462 07203566501 013372 0 ustar epics epics pro sscan_1d, file=file, view=view, comment = comment, prefix=prefix, help=help
;
; simple emulation of 1D EPICS scan, reading values set from
; scan record, and then performing 1d 'sscan' repeatedly.
;
; -- assumes scan1 is setup in scan record properly
if (keyword_set(help) ne 0) then begin
print, 'Sscan 1d: Execute EPICS sscan'
print, ' argument meaning [default]'
print, ' file output file name [scan.dat]'
print, ' prefix EPICS pv prefix [13IDC:] '
print, ' comment title line to add to file [] '
print, ' view detector to plot during scan [2]'
print, ' /help print this help message'
print, ' '
print, ' While scanning, hit P to pause scan'
return
endif
out_file = 'sscan.dat'
if (n_elements(file) eq 0) then file = ''
if (file ne '') then out_file = file
pref = '13IDC:'
if (n_elements(prefix) ne 0) then pref = prefix
title = ' '
if (n_elements(comment) ne 0) then title = comment + title
print, ' file = ', out_file
wait, 0.2
status = sscan(file= out_file, view=view, prefix=pref , $
comment= comment, /append)
if (status ne 0) then begin
print, 'sscan_1d saw interrupt from sscan'
return
endif
print, ' sscan_1d is done.'
return
end
sscan/sscan_2d.pro 0100644 0000621 0000620 00000004430 07203566550 013374 0 ustar epics epics pro sscan_2d, file=file, view=view, comment = comment, $
start=start, no_append=no_append, number = number
;
; simple emulation of 2D EPICS scan, reading values set from
; scan record, and then performing 1d 'sscan' repeatedly.
;
; -- assumes scan2 is setup in scan record properly
out_file = 'sscan'
if (n_elements(file) ne 0) then out_file =file
new_file = 0
if (keyword_set(no_append) ne 0) then new_file = 1
title = ' '
if (n_elements(comment) ne 0) then title = comment + title
ibeg= 1
if (n_elements(start) ne 0) then ibeg = start>1
icount= 1
if (n_elements(number) ne 0) then icount = number>1
P='13IDC:scan2.'
; start scan, with some error checking
s = caget(P+'NPTS', s_npts)
s = caget(P+'P1SM', s_mode)
s = caget(P+'P1PA', s_p1pa)
s = caget(P+'P1PV', pos)
if (s_mode eq 0) then begin
s = caget(P+'P1SP', s_p1sp)
s = caget(P+'P1SI', s_p1si)
for i = 0, s_npts-1 do s_p1pa[i] = s_p1sp + s_p1si * i
s_p1pa[s_npts] = s_p1pa[s_npts-1]
s_p1pa[s_npts+1] = s_p1pa[s_npts-1]
endif
; update index, perform simple scan
print, 'ibeg, s_npts = ', ibeg, s_npts
for i = ibeg, s_npts - 1 + ibeg do begin
j = i - ibeg
print, ' move ', pos, ' to ', s_p1pa[j], ' point ' , j
s = caput(pos, s_p1pa[j])
for k = 1, icount do begin
print, format='(1x,3a,f12.6,a,i3,a,i3)', ' move ', pos , ' to ',$
s_p1pa[j], ' : point ',i,' of ', s_npts
otitle = title + pos + '=' + string(s_p1pa[j])
scan_file = out_file
if (new_file eq 1) then begin
scan_file = out_file + string(i,format='(i3.3)') + '.dat'
if (k gt 1) then scan_file = out_file + $
string(i,format='(i3.3)') + '_' + string(k,format='(i2.2)') + '.dat'
endif
wait, 0.5
if ((i gt ibeg)) then begin
status = sscan(file=scan_file , view=view, $
comment = otitle, /append, $
/no_motors, /no_detectors)
endif else begin
status = sscan(file=scan_file , view=view, $
comment = otitle, /append)
endelse
if (status ne 0) then begin
print, 'sscan_2d saw interrupt from sscan'
return
endif
endfor
endfor
print, ' sscan_2d is done.'
return
end
sscan/sscan_3d.pro 0100644 0000621 0000620 00000005467 07203566537 013415 0 ustar epics epics pro sscan_3d, file=file, view=view, comment = comment
;
; simple emulation of 2D EPICS scan, reading values set from
; scan record, and then performing 1d 'sscan' repeatedly.
;
; -- assumes scan2 is setup in scan record properly
out_file = 'scan'
if (n_elements(file) eq 0) then file = ''
if (file ne '') then out_file = file
title = ' '
if (n_elements(comment) ne 0) then title = comment + title
P3d ='13IDC:scan3.'
; start scan, with some error checking
s = caget(P3d+'NPTS', s3d_npts)
s = caget(P3d+'P1SM', s3d_mode)
s = caget(P3d+'P1PA', s3d_p1pa)
s = caget(P3d+'P1PV', s3d_pos)
; print, ' 3d: mode = ', s3d_mode
if (s3d_mode eq 0) then begin
s = caget(P3d+'P1SP', s3d_p1sp)
s = caget(P3d+'P1SI', s3d_p1si)
s = caget(P3d+'P1AR', s3d_p1ar)
if (s3d_p1ar eq 1) then begin
s = caget(s3d_pos, xx)
s3d_p1sp = s3d_p1sp + xx
endif
for i = 0, s3d_npts-1 do s3d_p1pa[i] = s3d_p1sp + s3d_p1si * i
endif
P2d ='13IDC:scan2.'
; start scan, with some error checking
s = caget(P2d+'NPTS', s2d_npts)
s = caget(P2d+'P1SM', s2d_mode)
s = caget(P2d+'P1PA', s2d_p1pa)
s = caget(P2d+'P1PV', s2d_pos)
; print, ' 2d: mode = ', s2d_mode, ' -- ', p2d
if (s2d_mode eq 0) then begin
s = caget(P2d+'P1SP', s2d_p1sp)
s = caget(P2d+'P1SI', s2d_p1si)
s = caget(P2d+'P1AR', s2d_p1ar)
if (s2d_p1ar eq 1) then begin
s = caget(s2d_pos, xx)
s2d_p1sp = s2d_p1sp + xx
endif
; print, ' 2d: mode = ', s2d_mode, s2d_p1ar
; print, ' 2d: pos = ', s2d_pos
; print, ' 2d: start = ', s2d_p1sp
for i = 0, s2d_npts-1 do s2d_p1pa[i] = s2d_p1sp + s2d_p1si * i
endif
; update index, perform simple scan
for i3d = 0, s3d_npts - 1 do begin
s = caput(s3d_pos, s3d_p1pa[i3d])
print, format='(1x,3a,f12.6,a,i3,a,i3)', ' move ', s3d_pos , ' to ',$
s3d_p1pa[i3d], ' : point ',i3d+1,' of ', s3d_npts
scan_file = out_file + '_' + string(i3d+1,format='(i3.3)') + '.dat'
otitle = title + s3d_pos + '=' + string(s3d_p1pa[i3d]) + ' | '
for i2d = 0, s2d_npts - 1 do begin
s = caput(s2d_pos, s2d_p1pa[i2d])
print, format='(1x,3a,f12.6,a,i3,a,i3)', ' move ', s2d_pos , ' to ',$
s2d_p1pa[i2d], ' : point ',i2d+1,' of ', s2d_npts
otitle = otitle + s2d_pos + '=' + string(s2d_p1pa[i2d])
wait, 1.
if (i2d eq 0) then begin
status = sscan(file=scan_file , view=view, $
comment = otitle, /append)
endif else begin
status = sscan(file=scan_file , view=view, $
comment = otitle, /append, $
/no_motors, /no_detectors)
endelse
if (status ne 0) then begin
print, 'sscan_3d saw interrupt from sscan'
return
endif
endfor
endfor
print, ' sscan_3d is done.'
return
end
sscan/sscan_multi.pro 0100644 0000621 0000620 00000003123 07054101674 014213 0 ustar epics epics pro sscan_multi, file=file, number=number, view=view, start=start, help=help, $
comment=comment, no_motors=no_motors
;
; repetition of sscan
;
if (keyword_set(help) ne 0) then begin
print, 'Sscan_multi: Repeated 1D scans'
print, ' argument meaning '
print, ' file prefix of output file name '
print, ' view array of detectors to view'
print, ' number number of scans to repeat'
print, ' start starting index for file name suffix [default=001]'
print, ' /no_motors do not collect motors for each scan'
print, ' /help print this help message'
return
endif
out_file = 'sscan'
if (n_elements(file) eq 0) then file = ''
if (file ne '') then out_file = file
comment_ = ' '
if (n_elements(comment) ne 0) then comment_ = comment
imax = 1
if (n_elements(number) ne 0) then imax = number>1
get_motors = 1
if (keyword_set(no_motors) ne 0) then get_motors = 0
imin = 1
if (n_elements(start) ne 0) then imin = start>1
for i = imin, imax+imin-1 do begin
scan_file = out_file + '_' + string(i,format='(i3.3)') + '.dat'
if ((i gt imin) and (get_motors eq 0)) then begin
status = sscan(file=scan_file , view=view, /no_motors, $
comment=comment_)
print, ' sscan status = ', status
endif else begin
status = sscan(file=scan_file , view=view, comment=comment_)
print, ' sscan status = ', status
endelse
if (status ne 0) then begin
print, 'sscan_multi saw interrupt from sscan'
return
endif
endfor
return
end
sscan/sscan.pro 0100644 0000621 0000620 00000025467 07233673700 013023 0 ustar epics epics function sscan, file=file, view=view, comment=comment,$
scan=scan, append=append, overwrite=overwrite, $
no_motors=no_motors, no_detectors=no_detectors, $
save_xrf=save_xrf, med=med, $
help=help, debug=debug, prefix=prefix
;
; simple scan program using 1d epics scan record,
; saving data as ASCII and doing a simple 1-detector plot
;
;
if (keyword_set(help) ne 0) then begin
print, 'SScan: Execute scan set up in EPICS scan record'
print, ' argument meaning [default]'
print, ' file output file name [scan.dat]'
print, ' comment title line to add to file [] '
print, ' view detector to plot during scan [2]'
print, ' scan Epics scan PV to use ["13IDC:scan1"]'
print, ' /append append to file if it exists [yes]'
print, ' /overwrite overwrite file if it exists [no]'
print, ' /nomotors do not collect motor positions'
print, ' /help print this help message'
print, ' '
print, ' While scanning, hit P to pause scan'
return, 0
endif
; get postioner/detector names
pos_names = ['UNUSED', 'UNUSED', 'UNUSED', 'UNUSED', 'UNUSED']
det_names = ['d0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', $
'd8', 'd9', 'd10', 'd11', 'd12', 'd13', 'd14', 'd15','d16','d17']
det_to_plot = 2
append_file = 1
retval = 0
scanning = 1
debug_level = 0
wait_time = 0.05
max_check_count = 1000
current_point = 0
prev_point = 0
get_motors = 1
list_detectors = 1
lun = 0
write_xrf = 0
pref = '13IDC:'
outfile = 'scan.dat'
out_comment = ';Simple Scan: '
if (n_elements(file) ne 0) then outfile = file
if (n_elements(debug) ne 0) then debug_level = debug
if (keyword_set(no_motors)) then get_motors = 0
if (keyword_set(no_detectors)) then list_detectors = 0
if (keyword_set(save_xrf)) then write_xrf = 1
; if (n_elements(med) ne 0) then med_obj = med
if (keyword_set(append)) then append_file = 1
if (keyword_set(overwrite)) then append_file = 0
if (n_elements(comment) ne 0) then out_comment = out_comment + comment
if (n_elements(prefix) ne 0) then pref = prefix
if (n_elements(view) ne 0) then begin
print, ' view =', view
det_to_plot = view
endif
if (n_elements(scan) ne 0) then scanPV = scan
; catch, error
; if (error ne 0) then begin
; print, ' Simple Scan error ' , error, ' aborting scan!'
; s = caput(scanPV+'.EXSC',0)
; return, -1
; endif
scan_pause = pref + 'scanPause.VAL'
scanPV = pref + 'scan1'
scalerPV = pref + 'scaler1'
motor_pv = pref + 'm'
;
; gather scan parameters
s = caget(scanPV+'.NPTS', npts)
s = caget(scanPV+'.MPTS', mpts)
s = caget(scanPV+'.P1PA', p1pa)
s = caget(scanPV+'.P2PA', p2pa)
s = caget(scanPV+'.P3PA', p3pa)
s = caget(scanPV+'.P4PA', p4pa)
det = fltarr(70,mpts)
x = caget( scanPV + '.P1PV', p)
x = caget( scanPV + '.P1NV', v)
if ((x eq 0) and (v eq 0)) then pos_names[1] = p
x = caget( scanPV + '.P2PV', p)
x = caget( scanPV + '.P2NV', v)
if ((x eq 0) and (v eq 0)) then pos_names[2] = p
x = caget( scanPV + '.P3PV', p)
x = caget( scanPV + '.P3NV', v)
if ((x eq 0) and (v eq 0)) then pos_names[3] = p
x = caget( scanPV + '.P4PV', p)
x = caget( scanPV + '.P4NV', v)
if ((x eq 0) and (v eq 0)) then pos_names[4] = p
s = caget(scanPV+'.P1SM', m)
if (m eq 0) then begin
s = caget(scanPV+'.P1SP', p1sp)
s = caget(scanPV+'.P1SI', p1si)
for i = 0, npts-1 do p1pa[i] = p1sp + p1si * i
endif else begin
s = caget(scanPV+'.P1PA', p1pa)
endelse
s = caget(scanPV+'.P2NV', v)
s = caget(scanPV+'.P2SM', m)
if ((v eq 0) and (m eq 0)) then begin
s = caget(scanPV+'.P2SP', p2sp)
s = caget(scanPV+'.P2SI', p2si)
for i = 0, npts-1 do p2pa[i] = p2sp + p2si * i
endif else if ((v eq 0) and (m eq 1)) then begin
s = caget(scanPV+'.P2PA', p2pa)
endif
s = caget(scanPV+'.P3NV', v)
s = caget(scanPV+'.P3SM', m)
if ((v eq 0) and (m eq 0)) then begin
s = caget(scanPV+'.P3SP', p3sp)
s = caget(scanPV+'.P3SI', p3si)
for i = 0, npts-1 do p3pa[i] = p3sp + p3si * i
endif else if ((v eq 0) and (m eq 1)) then begin
s = caget(scanPV+'.P3PA', p2pa)
endif
s = caget(scanPV+'.P4NV', v)
s = caget(scanPV+'.P4SM', m)
if ((v eq 0) and (m eq 0)) then begin
s = caget(scanPV+'.P4SP', p4sp)
s = caget(scanPV+'.P4SI', p4si)
for i = 0, npts-1 do p4pa[i] = p4sp + p4si * i
endif else if ((v eq 0) and (m eq 1)) then begin
s = caget(scanPV+'.P4PA', p2pa)
endif
ddx = ['01', '01', '02', '03', '04', '05', '06', '07', '08', '09', $
'10', '11', '12', '13', '14', '15']
; print, 'a', scanPV
for i = 1, 15 do begin
PV = scanPV + '.D' + ddx[i] + 'PV'
s = caget(PV, x)
det_names[i] = x
endfor
nplots = n_elements(det_to_plot)
dx = det_to_plot[0]
;
; open output file
es = obj_new('EPICS_SCAN')
j = es->set_param('datafile', outfile)
lun = es->open_scanfile(append=1)
j = es->write_pv_list(lun=lun)
print, ' ==== type P to pause scan ===='
s = caput(scanPV+'.EXSC',1)
plotpv = strarr(10)
for ip = 0, nplots-1 do begin
case det_to_plot[ip] of
1: plotpv[ip] = scanPV+'.D01CV'
2: plotpv[ip] = scanPV+'.D02CV'
3: plotpv[ip] = scanPV+'.D03CV'
4: plotpv[ip] = scanPV+'.D04CV'
5: plotpv[ip] = scanPV+'.D05CV'
6: plotpv[ip] = scanPV+'.D06CV'
7: plotpv[ip] = scanPV+'.D07CV'
8: plotpv[ip] = scanPV+'.D08CV'
9: plotpv[ip] = scanPV+'.D09CV'
10: plotpv[ip] = scanPV+'.D10CV'
11: plotpv[ip] = scanPV+'.D11CV'
12: plotpv[ip] = scanPV+'.D12CV'
13: plotpv[ip] = scanPV+'.D13CV'
14: plotpv[ip] = scanPV+'.D14CV'
15: plotpv[ip] = scanPV+'.D15CV'
endcase
endfor
wait, wait_time
prev_point = -1
while(scanning) do begin
cpt = -3
j = caget(scanPV+'.CPT', current_point)
if (j eq 0) then cpt = current_point
; check for keyboard interrupt
c = get_kbrd(0)
c = strlowcase(c)
x = caget(scan_pause, ex_pause)
;; print, ' xx ' , j, current_point, ex_pause, c
if ((c eq string(16B)) or (c eq 'p') or $
(ex_pause eq 1)) then goto, interrupt
;; print, 'xx OK ', cpt, prev_point
resume:
if (cpt gt prev_point) then begin
;------------
; hack to try to reset eps burps: this will push the 'reset' button
; at every point so that temporary (or bogus) eps faults that have
; latched, don't kill the whole scan. Of course, the reset button
; doesn't do any good if I can't open the shutter too!
; j = caget('13IDA:eps_mbbi5', eps_stat)
; j = caget('13IDA:eps_mbbi81', vac_stat)
; j = caput('13IDA:eps_bo2', 1)
;------------
;
; get latest data, and update plot
prev_point = cpt
s = caget(scanPV+'.NPTS', npts)
;; print, ' B ', x, npts, nplots, cpt
s = caget(plotpv[0],d_curr)
; print message
;; print, 'MMM; '
print, format='(g11.3,$)', d_curr
if ((cpt mod 10) eq 0) then print, format='(a,i4,a,i4,a)', $
' (point ', cpt, '/', npts, ')'
; print, ' B ', x, npts
; get plot ranges
; plot_xmax = p1pa(cpt) + (p1pa(cpt)-p1pa(cpt-1))
; plot_ymax = max(det(0,0:cpt-1),imax)
; plot_ymin = min(det(0,0:cpt-1),imin)
; if (nplots gt 1) then begin
; for ip = 1, nplots-1 do begin
; pl = max(det(ip,0:cpt-1),imax)
; if (pl gt plot_ymax) then plot_ymax = pl
; pl = min(det(ip,0:cpt-1),imin)
; if (pl lt plot_ymin) then plot_ymin = pl
; endfor
; endif
; ; plot arrays
; plot, p1pa(0:cpt-1), det(0,0:cpt-1), $
; xrange = [p1pa(0), plot_xmax], $
; yrange = [plot_ymin, plot_ymax], $
; xstyle=19, charsize=1.4, $
; xtitle = xtitle, ytitle=ytitle, title= plot_title, psym=-1
; if (nplots gt 1) then begin
; for ip = 1, nplots-1 do begin
; psym = -(1 + ip)
; oplot, p1pa(0:cpt-1), det(ip,0:cpt-1), psym=psym
; endfor
; endif
endif
; check status after each point (for abort)
keep_checking = 1
check_count = 0
; print, ' check = ', keep_checking
while (keep_checking) do begin
s = caget(scanPV+'.EXSC',ss)
if (s eq 0) then begin
scanning = ss
keep_checking = 0
endif else begin
check_count = check_count + 1
if (check_count ge max_check_count) then goto, time_out
wait, wait_time
endelse
endwhile
endwhile
wait, wait_time
if ((cpt mod 10) ne 0) then print, ' '
write_output:
; get results
j = es->write_scan_data(short_labels=0)
j = es->close_scanfile()
if (append_file) then begin
print, ' appended file ', outfile
endif else begin
print, ' wrote file ', outfile
endelse
close, lun
free_lun, lun
;
busy = 1
while (busy ne 0) do begin
x = caget(scanPV + '.FAZE', busy)
endwhile
print, ' returning ', retval
return, retval
;;-----------------------------------;;
;; handle interrupts of scan
time_out:
print, ''
print, 'scan timed-out... cannot get scanning status'
print, 'aborting scan: not writing data file'
s = caput(scanPV+'.EXSC',0)
s = caput(scan_pause, 0)
if (lun gt 0) then begin
close, lun
free_lun, lun
endif
return, -1
interrupt:
print, ''
print, ' ####################################'
print, ' scan paused by user'
print, ' type r to resume scan'
print, ' type a to abort scan'
print, ' type w to write scan so far and quit now'
print, ' type f to finish this scan, but not start any more'
print, ' (for multiple or multi-dimensional scans) '
print, ' ####################################'
s = caput(scan_pause, 1)
interrupt_2:
c = get_kbrd(1)
c = strlowcase(c)
case c of
'a': begin
print, 'aborting scan: not writing data file'
s = caput(scanPV+'.EXSC',0)
s = caput(scan_pause, 0)
if (lun gt 0) then begin
close, lun
free_lun, lun
endif
return, -1
end
'w': begin
print, 'writing abbreviated scan ... '
print, 'last few points may be garbage.'
retval = -1
npts = cpt
s = caput(scanPV+'.EXSC',0)
s = caput(scan_pause, 0)
goto, write_output
end
'r': begin
print, 'resuming scan'
s = caput(scan_pause, 0)
goto, resume
end
'f': begin
print, 'finishing this scan only'
retval = -1
s = caput(scan_pause, 0)
goto, resume
end
else: begin
print, ' scan paused: type r for resume, a for abort, f to finish current scan only'
goto, interrupt_2
end
endcase
;;-----------------------------------;;
end
sscan/sscan_xrf.pro 0100644 0000621 0000620 00000002150 07011417232 013650 0 ustar epics epics pro sscan_1d, file=file, view=view, comment = comment, help=help
;
; simple emulation of 1D EPICS scan, reading values set from
; scan record, and then performing 1d 'sscan' repeatedly.
;
; -- assumes scan1 is setup in scan record properly
if (keyword_set(help) ne 0) then begin
print, 'Sscan 1d: Execute EPICS sscan'
print, ' argument meaning [default]'
print, ' file output file name [scan.dat]'
print, ' comment title line to add to file [] '
print, ' view detector to plot during scan [2]'
print, ' /help print this help message'
print, ' '
print, ' While scanning, hit P to pause scan'
return
endif
out_file = 'sscan.dat'
if (n_elements(file) eq 0) then file = ''
if (file ne '') then out_file = file
title = ' '
if (n_elements(comment) ne 0) then title = comment + title
status = sscan(file= out_file, view=view, $
comment= comment, /overwrite)
if (status ne 0) then begin
print, 'sscan_1d saw interrupt from sscan'
return
endif
print, ' sscan_1d is done.'
return
end
sscan/xrf_scan.pro 0100644 0000621 0000620 00000002241 07011421557 013473 0 ustar epics epics pro xrf_scan, file=file, view=view, comment = comment, help=help
;
; simple emulation of 1D EPICS scan, reading values set from
; scan record, and then performing 1d 'sscan' repeatedly.
;
; -- assumes scan1 is setup in scan record properly
if (keyword_set(help) ne 0) then begin
print, 'Sscan 1d: Execute EPICS sscan'
print, ' argument meaning [default]'
print, ' file output file name [scan.dat]'
print, ' comment title line to add to file [] '
print, ' view detector to plot during scan [2]'
print, ' /help print this help message'
print, ' '
print, ' While scanning, hit P to pause scan'
return
endif
m = obj_new('EPICS_MED', '13IDC:med:')
out_file = 'sscan.dat'
if (n_elements(file) eq 0) then file = ''
if (file ne '') then out_file = file
title = ' '
if (n_elements(comment) ne 0) then title = comment + title
status = sscan(file= out_file, view=view, /save_xrf, med=m, $
comment= comment, /overwrite)
if (status ne 0) then begin
print, 'sscan_1d saw interrupt from sscan'
return
endif
print, ' sscan_1d is done.'
return
end
sscan/z.pro 0100644 0000621 0000620 00000000746 07054604304 012151 0 ustar epics epics pro z
pos_name = 'UNUSED'
pos_desc = 'UNUSED'
scanPV ='13IDC:scan1'
x = caget( scanPV + '.P1PV', p)
if (x eq 0) then pos_name = p
str = pos_name
print, ' p = ', p, str
if (str ne 'UNUSED') then begin
iv = strpos(str, '.VAL')
len = strlen(str)
if (iv lt 0) then iv = len
nn = strmid(str, 0, iv) + '.DESC'
stmp = 'AA'
print, 'NN=',nn, stmp, iv
s = caget(nn, stmp)
if (s eq 0) then pos_desc = stmp
endif
print, ' desc = ', pos_desc
return
end