pearl-area-live.ipf
Go to the documentation of this file.
#pragma rtGlobals=3// Use modern global access method and strict wave access.
#pragma IgorVersion = 6.1
#pragma ModuleName = PearlAreaLive
#pragma version = 1.03
#include "pearl-epics", version >= 1.02
// preview panel for EPICS area detectors
// such as CCD cameras, 2D electron analysers
// the image is read from the NDPluginStdArrays plugin of the area detector
// make sure that plugin is enabled
// created: matthias.muntwiler@psi.ch, 2013-05-29
// $Id$
static const string package_name = "pearl_epics";
static const string package_path = "root:pearl_epics:";
// semicolon-separated list of persistent variable, string, and wave names
static const string prefs_objects = "";
variable ad_connect(string epicsname, string nickname){
// connects to the necessary EPICS channels of the detector
// to disconnect, call epics_disconnect()
// (caution: this will disconnect all EPICS channels of all PEARL EPICS procedures!)
string epicsname// base name of the detector, e.g. X03DA-SCIENTA:
// image1: and cam1: are appended by the function
string nickname// nick name under which this detector is referred to in Igor
// must be a valid data folder name
// the data folder is created under root:pearl_epics
dfref savedf = GetDataFolderDFR()
setdatafolder root:
// data folder for common EPICS metadata
newdatafolder /o/s $package_name
dfref epicsdf = GetDataFolderDFR()
string /g ad_chids
string /g ad_nicknames
// data folder this detector
string foldername = nickname
newdatafolder /s/o $foldername
dfref detectordf = GetDataFolderDFR()
// create variables and waves
make /n=(1)/o arraydata, xscale, yscale
make /n=(1,1)/o image
variable /g ndimensions
variable /g arraysize0, arraysize1
variable /g datatype
variable /g colormode
string /g controls, monitors
string /g xunits, yunits
print "connecting EPICS channels..."
// channel lists
controls = ""
monitors = ""
string imagename = epicsname + "image1:"
string camname = epicsname + "cam1:"
// we will set our own monitor on ArrayData, so add this to the controls list
controls = ReplaceStringByKey("ArrayData", controls, imagename + "ArrayData", "=")
// check whether it has been set already
variable chidArrayData = epics_chid(imagename + "ArrayData")
variable array_connected = chidArrayData > 0
monitors = ReplaceStringByKey("NDimensions", monitors, imagename + "NDimensions_RBV", "=")
monitors = ReplaceStringByKey("ArraySize0", monitors, imagename + "ArraySize0_RBV", "=")
monitors = ReplaceStringByKey("ArraySize1", monitors, imagename + "ArraySize1_RBV", "=")
monitors = ReplaceStringByKey("DataType", monitors, imagename + "DataType_RBV", "=")
monitors = ReplaceStringByKey("ColorMode", monitors, imagename + "ColorMode_RBV", "=")
monitors = ReplaceStringByKey("XScale", monitors, camname + "CHANNEL_SCALE_RBV", "=")
monitors = ReplaceStringByKey("YScale", monitors, camname + "SLICE_SCALE_RBV", "=")
variable nroi = 4
variable iroi
string roikey, roiname
for (iroi = 0; iroi < nroi; iroi += 1)
roikey = "ROI" + num2str(iroi + 1)
roiname = epicsname + "ROI" + num2str(iroi + 1) + ":"
controls = ReplaceStringByKey(roikey + "Enable", controls, roiname + "EnableCallbacks", "=")
controls = ReplaceStringByKey(roikey + "EnableX", controls, roiname + "EnableX", "=")
controls = ReplaceStringByKey(roikey + "MinX", controls, roiname + "MinX", "=")
controls = ReplaceStringByKey(roikey + "SizeX", controls, roiname + "SizeX", "=")
controls = ReplaceStringByKey(roikey + "EnableY", controls, roiname + "EnableY", "=")
controls = ReplaceStringByKey(roikey + "MinY", controls, roiname + "MinY", "=")
controls = ReplaceStringByKey(roikey + "SizeY", controls, roiname + "SizeY", "=")
monitors = ReplaceStringByKey(roikey + "Enable", monitors, roiname + "EnableCallbacks_RBV", "=")
monitors = ReplaceStringByKey(roikey + "EnableX", monitors, roiname + "EnableX_RBV", "=")
monitors = ReplaceStringByKey(roikey + "MinX", monitors, roiname + "MinX_RBV", "=")
monitors = ReplaceStringByKey(roikey + "SizeX", monitors, roiname + "SizeX_RBV", "=")
monitors = ReplaceStringByKey(roikey + "EnableY", monitors, roiname + "EnableY_RBV", "=")
monitors = ReplaceStringByKey(roikey + "MinY", monitors, roiname + "MinY_RBV", "=")
monitors = ReplaceStringByKey(roikey + "SizeY", monitors, roiname + "SizeY_RBV", "=")
endfor
// connect EPICS channels
epics_connect(controls, monitors)
// keep track of detector IDs
ad_nicknames = AddListItem(nickname, ad_nicknames)
variable iad = WhichListItem(nickname, ad_nicknames, ";", 0, 0)
ad_chids = AddListItem(num2istr(epics_chid(imagename + "ArrayData")), ad_chids, ";", iad)
// set callback function
if (!array_connected)
pvMonitor /F=ad_live_callback epics_chid(imagename + "ArrayData")
endif
print "...done"
setdatafolder savedf
};
variable ad_live_callback(variable chan){
variable chan
dfref savedf = GetDataFolderDFR()
setdatafolder $package_path
// find the data folder of the detector
svar ad_chids
svar ad_nicknames
variable iad = WhichListItem(num2istr(chan), ad_chids, ";", 0, 0)
if (iad >= 0)
string nickname = StringFromList(iad, ad_nicknames)
else
return -1
endif
setdatafolder $nickname
// retrieve data
svar controls
svar monitors
variable chidArrayData = epics_chid(StringByKey("ArrayData", controls, "="))
variable chidNDimensions = epics_chid(StringByKey("NDimensions", monitors, "="))
variable chidArraySize0 = epics_chid(StringByKey("ArraySize0", monitors, "="))
variable chidArraySize1 = epics_chid(StringByKey("ArraySize1", monitors, "="))
variable chidDataType = epics_chid(StringByKey("DataType", monitors, "="))
variable chidColorMode = epics_chid(StringByKey("ColorMode", monitors, "="))
variable chidXScale = epics_chid(StringByKey("XScale", monitors, "="))
variable chidYScale = epics_chid(StringByKey("YScale", monitors, "="))
wave arraydata
wave image
nvar ndimensions
nvar arraysize0
nvar arraysize1
nvar datatype
nvar colormode
wave xscale
wave yscale
pvGet chidNDimensions, ndimensions
pvGet chidArraySize0, arraysize0
pvGet chidArraySize1, arraysize1
pvGet chidDataType, datatype
pvGet chidColorMode, colormode
// sanity checks
if (ndimensions != 2)
return -2
endif
if (colormode != 0)
return -3
endif
redimension /n=(arraysize0 * arraysize1) arraydata
redimension /n=(arraysize0, arraysize1) image
redimension /n=(arraysize0) xscale
redimension /n=(arraysize1) yscale
switch(datatype)
case 0:// int8
redimension /b arraydata, image
break
case 1:// uint8
redimension /b/u arraydata, image
break
case 2:// int16
redimension /w arraydata, image
break
case 3:// uint16
redimension /w/u arraydata, image
break
case 4:// int32
redimension /i arraydata, image
break
case 5:// uint32
redimension /i/u arraydata, image
break
case 6:// float32
redimension /s arraydata, image
break
case 7:// float64
redimension /d arraydata, image
break
endswitch
pvGetWave chidArrayData, arraydata
pvGetWave chidXScale, xscale
pvGetWave chidYScale, yscale
image = arraydata[p + q * arraysize0]
setscale /i x xscale[0], xscale[numpnts(xscale)-1], image
setscale /i y yscale[0], yscale[numpnts(yscale)-1], image
ad_update_profiles(image)
// update ROI rectangles
svar /z graphname = :view_image:prof_graphname
if (svar_exists(graphname))
variable nroi = 4
variable iroi
for (iroi = 0; iroi < nroi; iroi += 1)
ad_update_ROI(graphname, iroi)
endfor
endif
setdatafolder savedf
return 0
};
static variable ad_update_ROI(string graphname, variable iroi){
string graphname
variable iroi
string roikey
variable enable
svar monitors
wave xscale
wave yscale
variable enableX = 0
variable minX = 0
variable sizeX = numpnts(xscale)
variable enableY = 0
variable minY = 0
variable sizeY = numpnts(yscale)
roikey = "ROI" + num2str(iroi + 1)
enable = epics_get_num(StringByKey(roikey + "Enable", monitors, "="))
if (enable)
enableX = epics_get_num(StringByKey(roikey + "EnableX", monitors, "="))
if (enableX)
minX = epics_get_num(StringByKey(roikey + "MinX", monitors, "="))
sizeX = epics_get_num(StringByKey(roikey + "SizeX", monitors, "="))
endif
enableY = epics_get_num(StringByKey(roikey + "EnableY", monitors, "="))
if (enableY)
minY = epics_get_num(StringByKey(roikey + "MinY", monitors, "="))
sizeY = epics_get_num(StringByKey(roikey + "SizeY", monitors, "="))
endif
variable x1 = xscale[minX]
variable x2 = xscale[minX + sizeX - 1]
variable y1 = yscale[minY]
variable y2 = yscale[minY + sizeY - 1]
endif
ad_update_ROI_rect(graphname, iroi, x1, y1, x2, y2, enable)
};
static variable ad_update_ROI_rect(string graphname, variable iroi, variable x1, variable y1, variable x2, variable y2, variable enable){
string graphname
variable iroi// 0...3
variable x1,y1,x2,y2
variable enable// enable = 1; disable = 0
string roiname = "roi" + num2str(iroi + 1)
variable color = 65536 * (1 - iroi/8) - 1
if (enable)
DrawAction /w=$graphname getgroup=$roiname, delete, begininsert
SetDrawEnv /w=$graphname gstart,gname=$roiname
SetDrawEnv /w=$graphname xcoord= bottom,ycoord= left
SetDrawEnv /w=$graphname linefgc= (65535,color,color)
SetDrawEnv /w=$graphname fillpat= 0
SetDrawEnv /w=$graphname linethick= 0.50
DrawRect /w=$graphname x1,y1,x2,y2
SetDrawEnv /w=$graphname gstop
DrawAction /w=$graphname endinsert
else
DrawAction /w=$graphname getgroup=$roiname, delete
endif
};
variable ad_set_ROI(string nickname, variable iroi, variable p1, variable q1, variable p2, variable q2, variable enable){
// set a ROI rectangle to the given coordinates
string nickname
variable iroi// 0...3
variable p1,q1,p2,q2// rectangular coordinates of the new ROI (point scaling)
variable enable// enable = 1; disable = 0
string roiname = "roi" + num2str(iroi + 1)
string roikey
dfref savedf = GetDataFolderDFR()
setdatafolder $package_path
setdatafolder $nickname
svar controls
wave xscale
wave yscale
variable minX = min(p1, p2)
variable sizeX = max(p1, p2) - min(p1, p2) + 1
variable enableX = sizeX > 0
variable minY = min(q1, q2)
variable sizeY = max(q1, q2) - min(q1, q2) + 1
variable enableY = sizeY > 0
roikey = "ROI" + num2str(iroi + 1)
epics_set_num(StringByKey(roikey + "Enable", controls, "="), enable)
if (enable)
epics_set_num(StringByKey(roikey + "EnableX", controls, "="), enableX)
if (enableX)
epics_set_num(StringByKey(roikey + "MinX", controls, "="), minX)
epics_set_num(StringByKey(roikey + "SizeX", controls, "="), sizeX)
endif
epics_set_num(StringByKey(roikey + "EnableY", controls, "="), enableY)
if (enableY)
epics_set_num(StringByKey(roikey + "MinY", controls, "="), minY)
epics_set_num(StringByKey(roikey + "SizeY", controls, "="), sizeY)
endif
endif
svar graphname = :view_image:prof_graphname
ad_update_ROI(graphname, iroi)
setdatafolder savedf
};
variable add_roi_controls(){
PopupMenu pm_set_roi mode=0,value="ROI 1;ROI 2;ROI 3;ROI 4",title="Set ROI"
PopupMenu pm_set_roi pos={400,0},bodyWidth=60,proc=PearlAreaLive#pmp_set_roi
PopupMenu pm_set_roi help={"Set a detector ROI to the current cursor selection"}
};
static variable pmp_set_roi(WMPopupAction* pa){
STRUCT WMPopupAction &pa
switch( pa.eventCode )
case 2:// mouse up
variable popNum = pa.popNum
string imgname = StringFromList(0, ImageNameList(pa.win, ";"))
wave /z image = ImageNameToWaveRef(pa.win, imgname)
if (waveexists(image))
wave /z source = PearlAreaDisplay#get_source_image(image)
if (waveexists(source))
dfref sourcedf = GetWavesDataFolderDFR(source)
string nickname = GetDataFolder(0, sourcedf)
ad_set_ROI(nickname, popNum - 1, pcsr(A, pa.win), qcsr(A, pa.win), pcsr(B, pa.win), qcsr(B, pa.win), 1)
endif
endif
break
case -1:// control being killed
break
endswitch
return 0
};
epics_connect
static variable epics_connect()
connect the angle scan tracker to EPICS
Definition: pearl-anglescan-tracker.ipf:675
ad_update_profiles
variable ad_update_profiles(wave image)
update a profiles graph with new data.
Definition: pearl-area-display.ipf:288
version
version
Definition: pearl-area-live.ipf:5
package_path
static const string package_path
Definition: pearl-area-live.ipf:16
prefs_objects
static const string prefs_objects
Definition: pearl-area-live.ipf:18
PearlAreaDisplay
instant visualization of angle scan and manipulator position.
get_source_image
static wave get_source_image(wave view)
find the source image wave corresponding to the given view.
Definition: pearl-area-display.ipf:441
package_name
static const string package_name
Definition: pearl-anneal.ipf:93
add_roi_controls
variable add_roi_controls()
Definition: pearl-area-live.ipf:339
imgname
static const string imgname
Definition: pearl-arpes-scans.ipf:16
ad_update_ROI
static variable ad_update_ROI(string graphname, variable iroi)
Definition: pearl-area-live.ipf:226
ad_set_ROI
variable ad_set_ROI(string nickname, variable iroi, variable p1, variable q1, variable p2, variable q2, variable enable)
Definition: pearl-area-live.ipf:292
camname
static const string camname
Definition: pearl-arpes-scans.ipf:14
ad_live_callback
variable ad_live_callback(variable chan)
Definition: pearl-area-live.ipf:117
ad_connect
variable ad_connect(string epicsname, string nickname)
Definition: pearl-area-live.ipf:20
ad_update_ROI_rect
static variable ad_update_ROI_rect(string graphname, variable iroi, variable x1, variable y1, variable x2, variable y2, variable enable)
Definition: pearl-area-live.ipf:269
pmp_set_roi
static variable pmp_set_roi(WMPopupAction *pa)
Definition: pearl-area-live.ipf:346