PEARL Procedures
Igor procedures for the analysis of PEARL data
pearl-area-live.ipf
Go to the documentation of this file.
1 #pragma rtGlobals=3// Use modern global access method and strict wave access.
2 #pragma IgorVersion = 6.1
3 #pragma ModuleName = PearlAreaLive
4 #pragma version = 1.03
5 #include "pearl-epics", version >= 1.02
6 
7 // preview panel for EPICS area detectors
8 // such as CCD cameras, 2D electron analysers
9 // the image is read from the NDPluginStdArrays plugin of the area detector
10 // make sure that plugin is enabled
11 
12 // created: matthias.muntwiler@psi.ch, 2013-05-29
13 // $Id$
14 
15 static const string package_name = "pearl_epics";
16 static const string package_path = "root:pearl_epics:";
17 // semicolon-separated list of persistent variable, string, and wave names
18 static const string prefs_objects = "";
19 
20 variable ad_connect(string epicsname, string nickname){
21  // connects to the necessary EPICS channels of the detector
22  // to disconnect, call epics_disconnect()
23  // (caution: this will disconnect all EPICS channels of all PEARL EPICS procedures!)
24  string epicsname// base name of the detector, e.g. X03DA-SCIENTA:
25  // image1: and cam1: are appended by the function
26  string nickname// nick name under which this detector is referred to in Igor
27  // must be a valid data folder name
28  // the data folder is created under root:pearl_epics
29 
30  dfref savedf = GetDataFolderDFR()
31  setdatafolder root:
32 
33  // data folder for common EPICS metadata
34  newdatafolder /o/s $package_name
35  dfref epicsdf = GetDataFolderDFR()
36  string /g ad_chids
37  string /g ad_nicknames
38 
39  // data folder this detector
40  string foldername = nickname
41  newdatafolder /s/o $foldername
42  dfref detectordf = GetDataFolderDFR()
43 
44  // create variables and waves
45  make /n=(1)/o arraydata, xscale, yscale
46  make /n=(1,1)/o image
47  variable /g ndimensions
48  variable /g arraysize0, arraysize1
49  variable /g datatype
50  variable /g colormode
51  string /g controls, monitors
52  string /g xunits, yunits
53 
54  print "connecting EPICS channels..."
55 
56  // channel lists
57  controls = ""
58  monitors = ""
59  string imagename = epicsname + "image1:"
60  string camname = epicsname + "cam1:"
61 
62  // we will set our own monitor on ArrayData, so add this to the controls list
63  controls = ReplaceStringByKey("ArrayData", controls, imagename + "ArrayData", "=")
64  // check whether it has been set already
65  variable chidArrayData = epics_chid(imagename + "ArrayData")
66  variable array_connected = chidArrayData > 0
67 
68  monitors = ReplaceStringByKey("NDimensions", monitors, imagename + "NDimensions_RBV", "=")
69  monitors = ReplaceStringByKey("ArraySize0", monitors, imagename + "ArraySize0_RBV", "=")
70  monitors = ReplaceStringByKey("ArraySize1", monitors, imagename + "ArraySize1_RBV", "=")
71  monitors = ReplaceStringByKey("DataType", monitors, imagename + "DataType_RBV", "=")
72  monitors = ReplaceStringByKey("ColorMode", monitors, imagename + "ColorMode_RBV", "=")
73  monitors = ReplaceStringByKey("XScale", monitors, camname + "CHANNEL_SCALE_RBV", "=")
74  monitors = ReplaceStringByKey("YScale", monitors, camname + "SLICE_SCALE_RBV", "=")
75 
76  variable nroi = 4
77  variable iroi
78  string roikey, roiname
79  for (iroi = 0; iroi < nroi; iroi += 1)
80  roikey = "ROI" + num2str(iroi + 1)
81  roiname = epicsname + "ROI" + num2str(iroi + 1) + ":"
82 
83  controls = ReplaceStringByKey(roikey + "Enable", controls, roiname + "EnableCallbacks", "=")
84  controls = ReplaceStringByKey(roikey + "EnableX", controls, roiname + "EnableX", "=")
85  controls = ReplaceStringByKey(roikey + "MinX", controls, roiname + "MinX", "=")
86  controls = ReplaceStringByKey(roikey + "SizeX", controls, roiname + "SizeX", "=")
87  controls = ReplaceStringByKey(roikey + "EnableY", controls, roiname + "EnableY", "=")
88  controls = ReplaceStringByKey(roikey + "MinY", controls, roiname + "MinY", "=")
89  controls = ReplaceStringByKey(roikey + "SizeY", controls, roiname + "SizeY", "=")
90 
91  monitors = ReplaceStringByKey(roikey + "Enable", monitors, roiname + "EnableCallbacks_RBV", "=")
92  monitors = ReplaceStringByKey(roikey + "EnableX", monitors, roiname + "EnableX_RBV", "=")
93  monitors = ReplaceStringByKey(roikey + "MinX", monitors, roiname + "MinX_RBV", "=")
94  monitors = ReplaceStringByKey(roikey + "SizeX", monitors, roiname + "SizeX_RBV", "=")
95  monitors = ReplaceStringByKey(roikey + "EnableY", monitors, roiname + "EnableY_RBV", "=")
96  monitors = ReplaceStringByKey(roikey + "MinY", monitors, roiname + "MinY_RBV", "=")
97  monitors = ReplaceStringByKey(roikey + "SizeY", monitors, roiname + "SizeY_RBV", "=")
98  endfor
99 
100  // connect EPICS channels
101  epics_connect(controls, monitors)
102 
103  // keep track of detector IDs
104  ad_nicknames = AddListItem(nickname, ad_nicknames)
105  variable iad = WhichListItem(nickname, ad_nicknames, ";", 0, 0)
106  ad_chids = AddListItem(num2istr(epics_chid(imagename + "ArrayData")), ad_chids, ";", iad)
107 
108  // set callback function
109  if (!array_connected)
110  pvMonitor /F=ad_live_callback epics_chid(imagename + "ArrayData")
111  endif
112 
113  print "...done"
114  setdatafolder savedf
115 };
116 
117 variable ad_live_callback(variable chan){
118  variable chan
119 
120  dfref savedf = GetDataFolderDFR()
121  setdatafolder $package_path
122 
123  // find the data folder of the detector
124  svar ad_chids
125  svar ad_nicknames
126  variable iad = WhichListItem(num2istr(chan), ad_chids, ";", 0, 0)
127  if (iad >= 0)
128  string nickname = StringFromList(iad, ad_nicknames)
129  else
130  return -1
131  endif
132  setdatafolder $nickname
133 
134  // retrieve data
135  svar controls
136  svar monitors
137  variable chidArrayData = epics_chid(StringByKey("ArrayData", controls, "="))
138  variable chidNDimensions = epics_chid(StringByKey("NDimensions", monitors, "="))
139  variable chidArraySize0 = epics_chid(StringByKey("ArraySize0", monitors, "="))
140  variable chidArraySize1 = epics_chid(StringByKey("ArraySize1", monitors, "="))
141  variable chidDataType = epics_chid(StringByKey("DataType", monitors, "="))
142  variable chidColorMode = epics_chid(StringByKey("ColorMode", monitors, "="))
143  variable chidXScale = epics_chid(StringByKey("XScale", monitors, "="))
144  variable chidYScale = epics_chid(StringByKey("YScale", monitors, "="))
145 
146  wave arraydata
147  wave image
148  nvar ndimensions
149  nvar arraysize0
150  nvar arraysize1
151  nvar datatype
152  nvar colormode
153  wave xscale
154  wave yscale
155 
156  pvGet chidNDimensions, ndimensions
157  pvGet chidArraySize0, arraysize0
158  pvGet chidArraySize1, arraysize1
159  pvGet chidDataType, datatype
160  pvGet chidColorMode, colormode
161 
162  // sanity checks
163  if (ndimensions != 2)
164  return -2
165  endif
166  if (colormode != 0)
167  return -3
168  endif
169 
170  redimension /n=(arraysize0 * arraysize1) arraydata
171  redimension /n=(arraysize0, arraysize1) image
172  redimension /n=(arraysize0) xscale
173  redimension /n=(arraysize1) yscale
174 
175  switch(datatype)
176  case 0:// int8
177  redimension /b arraydata, image
178  break
179  case 1:// uint8
180  redimension /b/u arraydata, image
181  break
182  case 2:// int16
183  redimension /w arraydata, image
184  break
185  case 3:// uint16
186  redimension /w/u arraydata, image
187  break
188  case 4:// int32
189  redimension /i arraydata, image
190  break
191  case 5:// uint32
192  redimension /i/u arraydata, image
193  break
194  case 6:// float32
195  redimension /s arraydata, image
196  break
197  case 7:// float64
198  redimension /d arraydata, image
199  break
200  endswitch
201 
202  pvGetWave chidArrayData, arraydata
203  pvGetWave chidXScale, xscale
204  pvGetWave chidYScale, yscale
205 
206  image = arraydata[p + q * arraysize0]
207  setscale /i x xscale[0], xscale[numpnts(xscale)-1], image
208  setscale /i y yscale[0], yscale[numpnts(yscale)-1], image
209 
210  ad_update_profiles(image)
211 
212  // update ROI rectangles
213  svar /z graphname = :view_image:prof_graphname
214  if (svar_exists(graphname))
215  variable nroi = 4
216  variable iroi
217  for (iroi = 0; iroi < nroi; iroi += 1)
218  ad_update_ROI(graphname, iroi)
219  endfor
220  endif
221 
222  setdatafolder savedf
223  return 0
224 };
225 
226 static variable ad_update_ROI(string graphname, variable iroi){
227  string graphname
228  variable iroi
229 
230  string roikey
231  variable enable
232  svar monitors
233 
234  wave xscale
235  wave yscale
236 
237  variable enableX = 0
238  variable minX = 0
239  variable sizeX = numpnts(xscale)
240 
241  variable enableY = 0
242  variable minY = 0
243  variable sizeY = numpnts(yscale)
244 
245  roikey = "ROI" + num2str(iroi + 1)
246  enable = epics_get_num(StringByKey(roikey + "Enable", monitors, "="))
247  if (enable)
248  enableX = epics_get_num(StringByKey(roikey + "EnableX", monitors, "="))
249  if (enableX)
250  minX = epics_get_num(StringByKey(roikey + "MinX", monitors, "="))
251  sizeX = epics_get_num(StringByKey(roikey + "SizeX", monitors, "="))
252  endif
253 
254  enableY = epics_get_num(StringByKey(roikey + "EnableY", monitors, "="))
255  if (enableY)
256  minY = epics_get_num(StringByKey(roikey + "MinY", monitors, "="))
257  sizeY = epics_get_num(StringByKey(roikey + "SizeY", monitors, "="))
258  endif
259 
260  variable x1 = xscale[minX]
261  variable x2 = xscale[minX + sizeX - 1]
262  variable y1 = yscale[minY]
263  variable y2 = yscale[minY + sizeY - 1]
264  endif
265 
266  ad_update_ROI_rect(graphname, iroi, x1, y1, x2, y2, enable)
267 };
268 
269 static variable ad_update_ROI_rect(string graphname, variable iroi, variable x1, variable y1, variable x2, variable y2, variable enable){
270  string graphname
271  variable iroi// 0...3
272  variable x1,y1,x2,y2
273  variable enable// enable = 1; disable = 0
274  string roiname = "roi" + num2str(iroi + 1)
275  variable color = 65536 * (1 - iroi/8) - 1
276 
277  if (enable)
278  DrawAction /w=$graphname getgroup=$roiname, delete, begininsert
279  SetDrawEnv /w=$graphname gstart,gname=$roiname
280  SetDrawEnv /w=$graphname xcoord= bottom,ycoord= left
281  SetDrawEnv /w=$graphname linefgc= (65535,color,color)
282  SetDrawEnv /w=$graphname fillpat= 0
283  SetDrawEnv /w=$graphname linethick= 0.50
284  DrawRect /w=$graphname x1,y1,x2,y2
285  SetDrawEnv /w=$graphname gstop
286  DrawAction /w=$graphname endinsert
287  else
288  DrawAction /w=$graphname getgroup=$roiname, delete
289  endif
290 };
291 
292 variable ad_set_ROI(string nickname, variable iroi, variable p1, variable q1, variable p2, variable q2, variable enable){
293  // set a ROI rectangle to the given coordinates
294  string nickname
295  variable iroi// 0...3
296  variable p1,q1,p2,q2// rectangular coordinates of the new ROI (point scaling)
297  variable enable// enable = 1; disable = 0
298 
299  string roiname = "roi" + num2str(iroi + 1)
300  string roikey
301 
302  dfref savedf = GetDataFolderDFR()
303  setdatafolder $package_path
304  setdatafolder $nickname
305 
306  svar controls
307  wave xscale
308  wave yscale
309 
310  variable minX = min(p1, p2)
311  variable sizeX = max(p1, p2) - min(p1, p2) + 1
312  variable enableX = sizeX > 0
313  variable minY = min(q1, q2)
314  variable sizeY = max(q1, q2) - min(q1, q2) + 1
315  variable enableY = sizeY > 0
316 
317  roikey = "ROI" + num2str(iroi + 1)
318  epics_set_num(StringByKey(roikey + "Enable", controls, "="), enable)
319  if (enable)
320  epics_set_num(StringByKey(roikey + "EnableX", controls, "="), enableX)
321  if (enableX)
322  epics_set_num(StringByKey(roikey + "MinX", controls, "="), minX)
323  epics_set_num(StringByKey(roikey + "SizeX", controls, "="), sizeX)
324  endif
325 
326  epics_set_num(StringByKey(roikey + "EnableY", controls, "="), enableY)
327  if (enableY)
328  epics_set_num(StringByKey(roikey + "MinY", controls, "="), minY)
329  epics_set_num(StringByKey(roikey + "SizeY", controls, "="), sizeY)
330  endif
331  endif
332 
333  svar graphname = :view_image:prof_graphname
334  ad_update_ROI(graphname, iroi)
335 
336  setdatafolder savedf
337 };
338 
339 variable add_roi_controls(){
340  PopupMenu pm_set_roi mode=0,value="ROI 1;ROI 2;ROI 3;ROI 4",title="Set ROI"
341  PopupMenu pm_set_roi pos={400,0},bodyWidth=60,proc=PearlAreaLive#pmp_set_roi
342  PopupMenu pm_set_roi help={"Set a detector ROI to the current cursor selection"}
343 };
344 
345 
346 static variable pmp_set_roi(WMPopupAction* pa){
347  STRUCT WMPopupAction &pa
348 
349  switch( pa.eventCode )
350  case 2:// mouse up
351  variable popNum = pa.popNum
352  string imgname = StringFromList(0, ImageNameList(pa.win, ";"))
353  wave /z image = ImageNameToWaveRef(pa.win, imgname)
354  if (waveexists(image))
355  wave /z source = PearlAreaDisplay#get_source_image(image)
356  if (waveexists(source))
357  dfref sourcedf = GetWavesDataFolderDFR(source)
358  string nickname = GetDataFolder(0, sourcedf)
359  ad_set_ROI(nickname, popNum - 1, pcsr(A, pa.win), qcsr(A, pa.win), pcsr(B, pa.win), qcsr(B, pa.win), 1)
360  endif
361  endif
362  break
363  case -1:// control being killed
364  break
365  endswitch
366 
367  return 0
368 };
369 
static variable epics_connect()
connect the angle scan tracker to EPICS
variable ad_update_profiles(wave image)
update a profiles graph with new data.
version
static const string package_path
static const string prefs_objects
instant visualization of angle scan and manipulator position.
static wave get_source_image(wave view)
find the source image wave corresponding to the given view.
static const string package_name
variable add_roi_controls()
static const string imgname
static variable ad_update_ROI(string graphname, variable iroi)
variable ad_set_ROI(string nickname, variable iroi, variable p1, variable q1, variable p2, variable q2, variable enable)
static const string camname
variable ad_live_callback(variable chan)
variable ad_connect(string epicsname, string nickname)
static variable ad_update_ROI_rect(string graphname, variable iroi, variable x1, variable y1, variable x2, variable y2, variable enable)
static variable pmp_set_roi(WMPopupAction *pa)