PEARL Procedures  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
pearl-anglescan-tracker.ipf
Go to the documentation of this file.
1 #pragma TextEncoding = "Windows-1252"
2 #pragma rtGlobals=3
3 #pragma version = 1.4
4 #pragma IgorVersion = 6.2
5 #pragma ModuleName = PearlAnglescanTracker
6 #include "pearl-area-profiles", version > 1.04
7 #include "pearl-area-import", version > 1.05
8 #include "pearl-scienta-preprocess", version > 1.00
9 #include "pearl-anglescan-process", version >= 1.6
10 #include <New Polar Graphs>
11 
12 // $Id$
13 //
14 // author: matthias.muntwiler@psi.ch
15 // Copyright (c) 2014-15 Paul Scherrer Institut
16 //
17 // Licensed under the Apache License, Version 2.0 (the "License");
18 // you may not use this file except in compliance with the License.
19 // You may obtain a copy of the License at
20 // http://www.apache.org/licenses/LICENSE-2.0
21 
59 
65 
67 static strconstant package_name = "pearl_anglescan_tracker"
69 static strconstant package_path = "root:packages:pearl_anglescan_tracker:"
71 static strconstant prefs_objects = "projection;theta_offset;tilt_offset;phi_offset;reduction_func;reduction_params"
72 
74 static function AfterCompiledHook()
75 
76  dfref savedf = GetDataFolderDFR()
77  variable do_init = 1
78  if (DataFolderExists(package_path))
79  setdatafolder $(package_path)
80  nvar /z init_done
81  if (nvar_exists(init_done))
82  if (init_done)
83  do_init = 0
84  endif
85  endif
86  endif
87 
88  if (do_init)
89  init_package()
90  load_prefs()
91  setdatafolder $(package_path)
92  variable /g init_done = 1
93  endif
94 
95  setdatafolder savedf
96  return 0
97 end
98 
99 static function init_package()
100  dfref savedf = getdatafolderdfr()
101  setdatafolder root:
102  newdatafolder /o/s packages
103  newdatafolder /o/s $package_name
104 
105  // configuration (persistent)
106  string /g graphname = "graph_anglescan_tracker"
107  string /g dataname = "tracker"
108  string /g projection = "stereographic"
109 
110  // recently used (persistent)
111  variable /g theta_offset = 0
112  variable /g tilt_offset = 0
113  variable /g phi_offset = 0
114  string /g reduction_func = "int_linbg_reduction"
115  string /g reduction_params = "Lcrop=0.1;Hcrop=0.1;Lsize=0.2;Hsize=0.2;Cpos=0.5;Csize=0.4"
116 
117  // recently used (volatile)
118  string /g export_folderpath = "root:"
119  variable /g export_format = 1
120 
121  // run-time variables (volatile)
122  string /g detector_tracename
123  variable /g capturing = 0
124  variable /g buf_size = 0 // number of measurements that fit into the data buffer
125  variable /g buf_count = 0 // number of measurements contained in the data buffer
126  variable /g buf_width = 0 // number of slices that fit into the data buffer
127 
128  // load icon of sample holder
129  string path = FunctionPath("")
130  path = ParseFilePath(1, path, ":", 1, 0) + "tracker-sample-picture.png"
131  LoadPict /O/Q path, pict_tracker_sample
132 
133  setdatafolder savedf
134 end
135 
140 static function save_prefs()
141  dfref saveDF = GetDataFolderDFR()
142 
143  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
144  fullPath += package_name
145  NewPath/O/C/Q tempPackagePrefsPath, fullPath
146  fullPath += ":preferences.pxp"
147 
148  SetDataFolder root:packages
149  SetDataFolder $package_name
150  SaveData /O /Q /J=prefs_objects fullPath
151 
152  KillPath/Z tempPackagePrefsPath
153 
154  SetDataFolder saveDF
155 end
156 
164 static function load_prefs()
165  dfref saveDF = GetDataFolderDFR()
166 
167  variable result = -1
168  setdatafolder root:
169  NewDataFolder /O/S packages
170  NewDataFolder /O/S $package_name
171  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
172  fullPath += package_name
173 
174  GetFileFolderInfo /Q /Z fullPath
175  if (V_Flag == 0) // Disk directory exists?
176  fullPath += ":preferences.pxp"
177  GetFileFolderInfo /Q /Z fullPath
178  if (V_Flag == 0) // Preference file exist?
179  LoadData /O /R /Q fullPath
180  result = 0
181  endif
182  endif
183 
184  SetDataFolder saveDF
185  return result
186 end
187 
189 static function IgorQuitHook(app)
190  string app
192 end
193 
195 function ast_setup()
196  setup_data()
198  setup_graph()
199  epics_connect()
200 end
201 
212 function ast_prepare([theta_offset, tilt_offset, phi_offset])
213  variable theta_offset
214  variable tilt_offset
215  variable phi_offset
216 
217  dfref savedf = getdatafolderdfr()
218  setdatafolder $(package_path)
219 
220  if (!ParamIsDefault(theta_offset))
221  nvar v_theta_offset = theta_offset
222  v_theta_offset = theta_offset
223  endif
224  if (!ParamIsDefault(tilt_offset))
225  nvar v_tilt_offset = tilt_offset
226  v_tilt_offset = tilt_offset
227  endif
228  if (!ParamIsDefault(phi_offset))
229  nvar v_phi_offset = phi_offset
230  v_phi_offset = phi_offset
231  endif
232 
233  nvar buf_count
234  nvar buf_size
235  nvar buf_width
236  buf_count = 0
237  buf_size = 0
238  buf_width = 0
239 
240  svar dataname
241  clear_hemi_grid(dataname)
242  // work-around: set one point to a real number to make the rest of the trace in the graph transparent
243  wave values = $(dataname + "_i")
244  values[numpnts(values) - 1] = 0
245 
247 
248  setdatafolder saveDF
249 end
250 
262 function ast_set_processing(reduction_func, reduction_params)
263  string reduction_func
264  string reduction_params
265 
266  dfref savedf = getdatafolderdfr()
267  setdatafolder $(package_path)
268 
269  svar red_func = reduction_func
270  svar red_params = reduction_params
271 
272  red_func = reduction_func
273  red_params = reduction_params
274 
275  setdatafolder saveDF
276 end
277 
286 function ast_add_image(image, theta, tilt, phi)
287  wave image
288  variable theta
289  variable tilt
290  variable phi
291 
292  add_image_data(image, theta, tilt, phi)
295 end
296 
308 function ast_export(folder, nickname, [xpdplot])
309  dfref folder
310  string nickname
311  variable xpdplot
312 
313  if (ParamIsDefault(xpdplot))
314  xpdplot = 0
315  endif
316 
317  dfref savedf = getdatafolderdfr()
318  setdatafolder $(package_path)
319 
320  svar dataname
321  duplicate_hemi_scan(dataname, folder, nickname, xpdplot=xpdplot)
322 
323  setdatafolder saveDF
324 end
325 
330 function ast_import(nickname)
331  string nickname
332 
333  dfref savedf = getdatafolderdfr()
334 
335  svar /sdfr=$(package_path) dataname
336  duplicate_hemi_scan(nickname, $(package_path), dataname)
337 
338  setdatafolder saveDF
339 end
340 
350 function ast_update_detector(theta, tilt, phi, range)
351  variable theta
352  variable tilt
353  variable phi
354  variable range
355 
356  update_detector(theta, tilt, phi, range)
358 end
359 
361 function ast_close()
362  dfref savedf = getdatafolderdfr()
363  setdatafolder $(package_path)
364 
366 
367  svar graphname
368  KillWindow $graphname
369 
370  setdatafolder saveDF
371 end
372 
373 static function setup_data()
374  dfref savedf = getdatafolderdfr()
375  setdatafolder $(package_path)
376 
377  nvar buf_size
378  nvar buf_count
379  nvar buf_width
380  buf_size = 0
381  buf_count = 0
382  buf_width = 0
383  make /n=(1,1) /o buf_i
384  make /n=(1) /o buf_th, buf_ph, buf_ti
385 
386  svar dataname
387  variable npolar = 91
388  make_hemi_grid(npolar, dataname)
389 
390  // work-around: set one point to a real number to make the rest of the trace in the graph transparent
391  wave values = $(dataname + "_i")
392  values[numpnts(values) - 1] = 0
393 
394  setdatafolder saveDF
395 end
396 
403 static function extend_data(num_slices)
404  variable num_slices
405 
406  dfref savedf = getdatafolderdfr()
407  setdatafolder $(package_path)
408 
409  nvar buf_size
410  nvar buf_count
411  nvar buf_width
412 
413  variable new_size = buf_size + 91
414  buf_width = num_slices
415 
416  wave buf_i
417  wave buf_th
418  wave buf_ti
419  wave buf_ph
420 
421  redimension /n=(buf_width,new_size) buf_i
422  redimension /n=(new_size) buf_th, buf_ph, buf_ti
423 
424  buf_i[][buf_size, new_size-1] = nan
425  buf_th[buf_size, new_size-1] = nan
426  buf_ph[buf_size, new_size-1] = nan
427  buf_ti[buf_size, new_size-1] = nan
428 
429  buf_size = new_size
430 
431  setdatafolder saveDF
432  return buf_count
433 end
434 
435 static function setup_detector()
436  dfref savedf = getdatafolderdfr()
437  setdatafolder $(package_path)
438 
439  make /n=31 /o detector_angle, detector_pol, detector_az, detector_rad
440  setscale /i x -30, 30, "°", detector_angle, detector_pol, detector_az, detector_rad
441  detector_angle = x
442 
443  setdatafolder saveDF
444 end
445 
454 static function add_image_data(image, theta, tilt, phi)
455  wave image
456  variable theta
457  variable tilt
458  variable phi
459 
460  dfref savedf = getdatafolderdfr()
461  setdatafolder $(package_path)
462  svar dataname
463  nvar theta_offset
464  nvar tilt_offset
465  nvar phi_offset
466 
467  // extract angle distribution from image using reduction function mechanism from area-import
468  svar red_func_name = reduction_func
469  svar red_params = reduction_params
470  funcref adh5_default_reduction red_func = $red_func_name
471  variable nx = dimsize(image, 0)
472  string loc_params = red_params
473  wave /wave red_results = red_func(image, loc_params)
474  if (numpnts(red_results) < 1)
475  setdatafolder saveDF
476  return 0
477  endif
478 
479  wave profile1 = red_results[0]
480  nx = numpnts(profile1)
481 
482  // write the result to the buffer
483  nvar buf_count
484  nvar buf_size
485  nvar buf_width
486  wave buf_i
487  wave buf_th
488  wave buf_ph
489  wave buf_ti
490 
491  if ((buf_count >= buf_size) || (nx > buf_width))
492  extend_data(nx)
493  setscale /p x dimoffset(profile1,0), dimdelta(profile1,0), waveunits(profile1,0), buf_i
494  endif
495 
496  buf_i[][buf_count] = profile1[p]
497  buf_th[buf_count] = theta - theta_offset
498  buf_ti[buf_count] = -(tilt - tilt_offset)
499  buf_ph[buf_count] = phi - phi_offset
500 
501  buf_count += 1
502 
503  setdatafolder saveDF
504 end
505 
508 static function process_image_data()
509  wave image
510  variable theta
511  variable tilt
512  variable phi
513 
514  dfref savedf = getdatafolderdfr()
515  setdatafolder $(package_path)
516  svar dataname
517 
518  nvar buf_count
519  nvar buf_size
520  nvar buf_width
521 
522  wave buf_i
523  wave buf_th
524  wave buf_ph
525  wave buf_ti
526 
527  duplicate /free /R=[0,buf_width-1][0,buf_count-1] buf_i, buf_n
528  duplicate /free /R=[0,buf_count-1] buf_th, w_th
529  duplicate /free /R=[0,buf_count-1] buf_ti, w_ti
530  duplicate /free /R=[0,buf_count-1] buf_ph, w_ph
531 
532  normalize_strip_x(buf_n, smooth_method=4)
533  if (buf_count >= 10)
534  normalize_strip_theta(buf_n, w_th, smooth_method=4)
535  endif
536  if (dimoffset(buf_i,0) < -20)
537  crop_strip(buf_n, -25, 25)
538  else
539  crop_strip(buf_n, -15, 15)
540  endif
541 
542  make /n=1 /free d_polar, d_azi
543  convert_angles_ttpd2polar(w_th, w_ti, w_ph, buf_n, d_polar, d_azi)
544  d_azi += 180 // changed 151030 (v1.4)
545  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
546  hemi_add_anglescan(dataname, buf_n, d_polar, d_azi)
547 
548  setdatafolder saveDF
549 end
550 
560 static function update_detector(theta, tilt, phi, range)
561  variable theta
562  variable tilt
563  variable phi
564  variable range
565 
566  dfref savedf = getdatafolderdfr()
567  setdatafolder $(package_path)
568  nvar theta_offset
569  nvar tilt_offset
570  nvar phi_offset
571 
572  make /n=1 /free m_theta
573  make /n=1 /free m_tilt
574  make /n=1 /free m_phi
575  m_theta = theta - theta_offset
576  m_tilt = tilt - tilt_offset
577  m_tilt *= -1 // checked 140702
578  m_phi = phi - phi_offset
579  //m_phi *= -1 // checked 140702
580 
581  wave detector_angle, detector_pol, detector_az, detector_rad
582  setscale /i x -range/2, +range/2, "°", detector_angle
583  detector_angle = x
584 
585  convert_angles_ttpa2polar(m_theta, m_tilt, m_phi, detector_angle, detector_pol, detector_az)
586  redimension /n=(numpnts(detector_pol)) detector_rad
587  detector_rad = 2 * tan(detector_pol / 2 * pi / 180)
588  detector_az += 180 // changed 151030 (v1.4)
589  detector_az = detector_az >= 360 ? detector_az - 360 : detector_az
590 
591  setdatafolder saveDF
592 end
593 
595 static function setup_graph()
596  dfref savedf = getdatafolderdfr()
597  setdatafolder $(package_path)
598 
599  svar dataname
600  svar graphname
601  wave detector_az
602  wave detector_rad
603  wave detector_angle
604  svar tracename = detector_tracename
605 
606  graphname = display_hemi_scan(dataname, graphname=graphname)
607  tracename = WMPolarAppendTrace(graphname, detector_rad, detector_az, 360)
608  ModifyGraph /w=$graphname lstyle($tracename)=0
609  ModifyGraph /w=$graphname lsize($tracename)=1.5
610  ModifyGraph /w=$graphname zColor($tracename)={detector_angle,*,*,RedWhiteBlue,0}
611  ColorScale /w=$graphname /C /N=text1 trace=$tracename
612  ColorScale /w=$graphname /C /N=text1 /F=0 /B=1 /A=LB /X=0.00 /Y=0.00
613  ColorScale /w=$graphname /C /N=text1 width=1.5, heightPct=20, frame=0.00
614  ColorScale /w=$graphname /C /N=text1 lblMargin=0
615  ColorScale /w=$graphname /C /N=text1 nticks=2, tickLen=2.00, tickThick=0.50
616 
617  TextBox /w=$graphname /C /N=tb_manip /F=0 /B=1 /X=0.00 /Y=0.00 /E=2 "\\{\"manip = (%.1f, %.1f, %.1f)\", "
618  AppendText /w=$graphname /N=tb_manip /NOCR "root:packages:pearl_anglescan_tracker:curTheta, "
619  AppendText /w=$graphname /N=tb_manip /NOCR "root:packages:pearl_anglescan_tracker:curTilt, "
620  AppendText /w=$graphname /N=tb_manip /NOCR "root:packages:pearl_anglescan_tracker:curPhi}"
621 
622  // the window hook releases the EPICS variables when the window is killed
623  DoWindow /T $graphname, "Angle Scan Tracker"
624  SetWindow $graphname, hook(ast_hook) = ast_window_hook
625 
626  ControlBar /w=$graphname 21
627  Button b_capture win=$graphname, title="start", pos={0,0}, size={40,21}, proc=PearlAnglescanTracker#bp_capture
628  Button b_capture win=$graphname, fColor=(65535,65535,65535), fSize=10
629  Button b_capture win=$graphname, help={"Start/stop capturing."}
630  PopupMenu pm_params win=$graphname, mode=0, value="load preferences;save preferences;reduction parameters;manipulator offsets", title="parameters"
631  PopupMenu pm_params win=$graphname, pos={70,0}, bodyWidth=80, proc=PearlAnglescanTracker#pmp_parameters
632  PopupMenu pm_params win=$graphname, help={"Load/save/edit data processing parameters"}
633  PopupMenu pm_data win=$graphname, mode=0, value="import;export;load file;save file", title="data"
634  PopupMenu pm_data win=$graphname, pos={120,0}, proc=PearlAnglescanTracker#pmp_data
635  PopupMenu pm_data win=$graphname, help={"Load/save data from/to independent dataset or file"}
636 
637  SetDrawLayer /w=$graphname ProgFront
638  SetDrawEnv /w=$graphname xcoord=rel, ycoord=rel
639  DrawPict /w=$graphname 0, 0, 1, 1, pict_tracker_sample
640 
642 
643  setdatafolder saveDF
644 end
645 
646 static function update_data_graph()
647  dfref savedf = getdatafolderdfr()
648  setdatafolder $(package_path)
649 
650  svar dataname
651  svar graphname
652 
653  // nothing to do - trace is updated automatically
654 
655  setdatafolder saveDF
656 end
657 
658 static function update_detector_graph()
659  dfref savedf = getdatafolderdfr()
660  setdatafolder $(package_path)
661 
662  svar dataname
663  svar graphname
664 
665  // nothing to do - trace is updated automatically
666 
667  setdatafolder saveDF
668 end
669 
681 static function epics_connect()
682  dfref savedf = getdatafolderdfr()
683  setdatafolder $(package_path)
684 
685  // close PVs which may be open from a previous call
687 
688  // create variables and waves
689  make /n=(1)/o arraydata, xscale, yscale
690  make /n=(1,1)/o image
691  variable /g ndimensions
692  variable /g arraysize0, arraysize1
693  variable /g datatype
694  variable /g colormode
695  string /g controls, monitors
696  string /g xunits, yunits
697 
698  // channel ID variables
699  variable /g chidDetectorState = 0
700  variable /g chidArrayData = 0
701  variable /g chidXScale = 0
702  variable /g chidYScale = 0
703  variable /g chidNDimensions = 0
704  variable /g chidArraySize0 = 0
705  variable /g chidArraySize1 = 0
706  variable /g chidDataType = 0
707  variable /g chidColorMode = 0
708  variable /g chidLensMode = 0
709  variable /g chidTheta = 0
710  variable /g chidTilt = 0
711  variable /g chidPhi = 0
712  variable /g curDetectorState = 0
713  variable /g curLensMode = 0
714  variable /g curTheta = 0
715  variable /g curTilt = 0
716  variable /g curPhi = 0
717  variable /g acqTheta = 0
718  variable /g acqTilt = 0
719  variable /g acqPhi = 0
720  variable /g connected = 0
721 
722  string epicsname = "X03DA-SCIENTA:"
723  string imagename = epicsname + "image1:"
724  string camname = epicsname + "cam1:"
725  string manipname = "X03DA-ES2-MA:"
726  variable timeout = 5 // seconds
727 
728  #if exists("pvWait")
729  // EPICS.XOP version 0.3.0 or later
730  pvOpen /Q chidDetectorState, camname + "DetectorState_RBV" // 0 = idle
731  pvOpen /Q chidLensMode, camname + "LENS_MODE_RBV"
732  pvOpen /Q chidXScale, camname + "CHANNEL_SCALE_RBV"
733  pvOpen /Q chidYScale, camname + "SLICE_SCALE_RBV"
734  pvOpen /Q chidArrayData, imagename + "ArrayData"
735  pvOpen /Q chidNDimensions, imagename + "NDimensions_RBV"
736  pvOpen /Q chidArraySize0, imagename + "ArraySize0_RBV"
737  pvOpen /Q chidArraySize1, imagename + "ArraySize1_RBV"
738  pvOpen /Q chidDataType, imagename + "DataType_RBV"
739  pvOpen /Q chidColorMode, imagename + "ColorMode_RBV"
740 
741  pvOpen /Q chidTheta, manipname + "THT.RBV"
742  pvOpen /Q chidTilt, manipname + "TLT.RBV"
743  pvOpen /Q chidPhi, manipname + "PHI.RBV"
744 
745  pvWait timeout
746 
747  if (!GetRTError(1))
748  connected = 1
749  endif
750  #elif exists("pvOpen")
751  // EPICS.XOP version < 0.3.0
752  pvOpen /T=(timeout) chidDetectorState, camname + "DetectorState_RBV" // 0 = idle
753  pvOpen /T=(timeout) chidLensMode, camname + "LENS_MODE_RBV"
754  pvOpen /T=(timeout) chidXScale, camname + "CHANNEL_SCALE_RBV"
755  pvOpen /T=(timeout) chidYScale, camname + "SLICE_SCALE_RBV"
756  pvOpen /T=(timeout) chidArrayData, imagename + "ArrayData"
757  pvOpen /T=(timeout) chidNDimensions, imagename + "NDimensions_RBV"
758  pvOpen /T=(timeout) chidArraySize0, imagename + "ArraySize0_RBV"
759  pvOpen /T=(timeout) chidArraySize1, imagename + "ArraySize1_RBV"
760  pvOpen /T=(timeout) chidDataType, imagename + "DataType_RBV"
761  pvOpen /T=(timeout) chidColorMode, imagename + "ColorMode_RBV"
762 
763  pvOpen /T=(timeout) chidTheta, manipname + "THT.RBV"
764  pvOpen /T=(timeout) chidTilt, manipname + "TLT.RBV"
765  pvOpen /T=(timeout) chidPhi, manipname + "PHI.RBV"
766 
767  if (!GetRTError(1))
768  connected = 1
769  endif
770  #endif
771 
772  #if exists("pvMonitor")
773  if (connected)
774  pvMonitor /F=ast_callback_detector chidDetectorState, curDetectorState
775  pvMonitor /F=ast_callback_manip chidTheta, curTheta
776  pvMonitor /F=ast_callback_manip chidTilt, curTilt
777  pvMonitor /F=ast_callback_manip chidPhi, curPhi
778  pvMonitor /F=ast_callback_manip chidLensMode, curLensMode
779  pvMonitor /F=ast_callback_data chidArrayData
780  endif
781  #endif
782 
783  if (connected)
784  print "angle scan tracker: online"
785  else
786  print "angle scan tracker: offline"
787  endif
788 
789  setdatafolder saveDF
790  return !connected
791 end
792 
793 static function epics_disconnect_chid(chid_var_name)
794  string chid_var_name
795 
796  #if exists("pvClose")
797  nvar /z chid = $chid_var_name
798  if (nvar_exists(chid))
799  if (chid != 0)
800  pvClose chid
801  endif
802  chid = 0
803  endif
804  #endif
805 end
806 
807 static function epics_disconnect()
808  dfref savedf = GetDataFolderDFR()
809 
810  if (DataFolderExists(package_path))
811  SetDataFolder $(package_path)
812  else
813  return nan
814  endif
815 
816  nvar connected
817  if (connected)
818  connected = 0
819  epics_disconnect_chid("chidDetectorState")
820  epics_disconnect_chid("chidArrayData")
821  epics_disconnect_chid("chidXScale")
822  epics_disconnect_chid("chidYScale")
823  epics_disconnect_chid("chidNDimensions")
824  epics_disconnect_chid("chidArraySize0")
825  epics_disconnect_chid("chidArraySize1")
826  epics_disconnect_chid("chidDataType")
827  epics_disconnect_chid("chidColorMode")
828  epics_disconnect_chid("chidLensMode")
829  epics_disconnect_chid("chidTheta")
830  epics_disconnect_chid("chidTilt")
831  epics_disconnect_chid("chidPhi")
832  print "angle scan tracker: offline"
833  endif
834 
835  setdatafolder savedf
836 end
837 
842 static function ast_window_hook(s)
843  STRUCT WMWinHookStruct &s
844 
845  Variable hookResult = 0
846 
847  switch(s.eventCode)
848  case 2: // kill
850  break
851  endswitch
852 
853  return hookResult
854 End
855 
857 function ast_callback_data(chan)
858  variable chan
859 
860  nvar capturing = $(package_path + "capturing")
861  if (!capturing)
862  return 0
863  endif
864 
865  dfref savedf = GetDataFolderDFR()
866  setdatafolder $(package_path)
867  #if exists("pvGetWave")
868 
869  // retrieve data
870  nvar chidArrayData
871  nvar chidXScale
872  nvar chidYScale
873  nvar chidNDimensions
874  nvar chidArraySize0
875  nvar chidArraySize1
876  nvar chidDataType
877  nvar chidColorMode
878  nvar chidTheta
879  nvar chidTilt
880  nvar chidPhi
881  nvar acqTheta
882  nvar acqTilt
883  nvar acqPhi
884 
885  wave arraydata
886  wave image
887  wave xscale
888  wave yscale
889  variable ndimensions
890  variable arraysize0
891  variable arraysize1
892  variable datatype
893  variable colormode
894 
895  //printf "array callback: acqtheta = %.1f, acqtilt = %.1f, acqphi = %.1f\r", acqTheta, acqTilt, acqPhi
896 
897  pvGet chidNDimensions, ndimensions
898  pvGet chidArraySize0, arraysize0
899  pvGet chidArraySize1, arraysize1
900  pvGet chidDataType, datatype
901  pvGet chidColorMode, colormode
902 
903  // sanity checks
904  if (ndimensions != 2)
905  return -2
906  endif
907  if (colormode != 0)
908  return -3
909  endif
910 
911  redimension /n=(arraysize0 * arraysize1) arraydata
912  redimension /n=(arraysize0, arraysize1) image
913  redimension /n=(arraysize0) xscale
914  redimension /n=(arraysize1) yscale
915 
916  switch(datatype)
917  case 0: // int8
918  redimension /b arraydata, image
919  break
920  case 1: // uint8
921  redimension /b/u arraydata, image
922  break
923  case 2: // int16
924  redimension /w arraydata, image
925  break
926  case 3: // uint16
927  redimension /w/u arraydata, image
928  break
929  case 4: // int32
930  redimension /i arraydata, image
931  break
932  case 5: // uint32
933  redimension /i/u arraydata, image
934  break
935  case 6: // float32
936  redimension /s arraydata, image
937  break
938  case 7: // float64
939  redimension /d arraydata, image
940  break
941  endswitch
942 
943  pvGetWave chidArrayData, arraydata
944  pvGetWave chidXScale, xscale
945  pvGetWave chidYScale, yscale
946 
947  image = arraydata[p + q * arraysize0]
948  setscale /i x xscale[0], xscale[numpnts(xscale)-1], image
949  setscale /i y yscale[0], yscale[numpnts(yscale)-1], image
950 
951  ast_add_image(image, acqTheta, acqTilt, acqPhi)
952 
953  #endif
954  setdatafolder savedf
955  return 0
956 end
957 
962 function ast_callback_detector(chan)
963  variable chan
964 
965  dfref savedf = GetDataFolderDFR()
966  setdatafolder $(package_path)
967 
968  // retrieve data
969  nvar curDetectorState
970  nvar curTheta
971  nvar curTilt
972  nvar curPhi
973 
974  nvar acqTheta
975  nvar acqTilt
976  nvar acqPhi
977 
978  if (curDetectorState == 1)
979  acqTheta = curTheta
980  acqTilt = curTilt
981  acqPhi = curPhi
982  endif
983 
984  //printf "detector callback: acqtheta = %.1f, acqtilt = %.1f, acqphi = %.1f, detstate = %d\r", acqTheta, acqTilt, acqPhi, curDetectorState
985 
986  setdatafolder savedf
987  return 0
988 end
989 
991 function ast_callback_manip(chan)
992  variable chan
993 
994  dfref savedf = GetDataFolderDFR()
995  setdatafolder $(package_path)
996 
997  // retrieve data
998  nvar lensmode = curLensMode
999  nvar theta = curTheta
1000  nvar tilt = curTilt
1001  nvar phi = curPhi
1002 
1003  //printf "manipulator callback: curtheta = %.1f, curtilt = %.1f, curphi = %.1f, lensmode = %d\r", theta, tilt, phi, lensmode
1004 
1005  variable range
1006  switch(lensmode)
1007  case 1:
1008  range = 45 // angular 45
1009  break
1010  case 2:
1011  range = 60 // angular 60
1012  break
1013  default:
1014  range = 2 // transmission or error
1015  endswitch
1016  ast_update_detector(theta, tilt, phi, range)
1017 
1018  setdatafolder savedf
1019  return 0
1020 end
1021 
1022 // GUI functions
1023 
1024 static function bp_capture(ba) : ButtonControl
1025  STRUCT WMButtonAction &ba
1026 
1027  switch( ba.eventCode )
1028  case 2: // mouse up
1029  toggle_capture()
1030  break
1031  case -1: // control being killed
1032  break
1033  endswitch
1034 
1035  return 0
1036 end
1037 
1038 static function toggle_capture()
1039  dfref savedf = getdatafolderdfr()
1040  setdatafolder $(package_path)
1041 
1042  nvar capturing
1043  svar graphname
1044 
1045  capturing = !capturing
1046  if (capturing)
1047  ast_prepare()
1048  Button b_capture win=$graphname, title="stop"
1049  else
1050  Button b_capture win=$graphname, title="start"
1051  endif
1052 
1053  setdatafolder saveDF
1054 end
1055 
1056 static function update_capture()
1057  dfref savedf = getdatafolderdfr()
1058  setdatafolder $(package_path)
1059 
1060  nvar capturing
1061  svar graphname
1062 
1063  if (capturing)
1064  Button b_capture win=$graphname, title="stop"
1065  else
1066  Button b_capture win=$graphname, title="start"
1067  endif
1068 
1069  setdatafolder saveDF
1070 end
1071 
1072 static function pmp_data(pa) : PopupMenuControl
1073  STRUCT WMPopupAction &pa
1074 
1075  switch( pa.eventCode )
1076  case 2: // mouse up
1077  pmp_data_mouseup(pa)
1078  break
1079  case -1: // control being killed
1080  break
1081  endswitch
1082 
1083  return 0
1084 end
1085 
1086 static function pmp_data_mouseup(pa)
1087  STRUCT WMPopupAction &pa
1088 
1089  switch(pa.popNum)
1090  case 1:
1092  break
1093  case 2:
1095  break
1096  case 3:
1098  break
1099  case 4:
1101  break
1102  endswitch
1103 end
1104 
1106 static function export_tracker_data()
1107  dfref savedf = getdatafolderdfr()
1108  setdatafolder $(package_path)
1109 
1110  svar export_folderpath
1111  nvar export_format
1112 
1113  string folderpath = export_folderpath
1114  string nickname = ""
1115  variable format = export_format
1116 
1117  prompt folderpath, "Folder Path"
1118  prompt nickname, "Nick Name"
1119  prompt format, "Format", popup, "PEARL;XPDplot"
1120 
1121  doprompt "Export Parameters", folderpath, nickname, format
1122 
1123  if (v_flag == 0)
1124  export_folderpath = folderpath
1125  export_format = format
1126  // note: if a full or partial path is used, all data folders except for the last in the path must already exist.
1127  newdatafolder /o $folderpath
1128  variable xpdplot = format == 2
1129  ast_export($folderpath, nickname, xpdplot=xpdplot)
1130  endif
1131 
1132  setdatafolder saveDF
1133 end
1134 
1136 static function import_tracker_data()
1137  dfref savedf = getdatafolderdfr()
1138  setdatafolder $(package_path)
1139 
1140  svar export_folderpath
1141  string folderpath = export_folderpath
1142  string nickname = ""
1143 
1144  dfref dfBefore = GetDataFolderDFR()
1145  Execute /q/z "CreateBrowser prompt=\"Select wave from dataset\", showWaves=1, showVars=0, showStrs=0"
1146  dfref dfAfter = GetDataFolderDFR()
1147  SetDataFolder dfBefore
1148 
1149  SVAR list = S_BrowserList
1150  NVAR flag = V_Flag
1151 
1152  if ((flag != 0) && (ItemsInList(list) >= 1))
1153  string wname = StringFromList(0, list)
1154  wave w = $wname
1155  string prefix = get_hemi_prefix(w)
1156  dfref df = GetWavesDataFolderDFR(w)
1157  setdatafolder df
1158  ast_import(prefix)
1159  endif
1160 
1161  setdatafolder saveDF
1162 end
1163 
1165 static function save_tracker_data()
1166  dfref savedf = getdatafolderdfr()
1167  setdatafolder $(package_path)
1168 
1169  svar dataname
1170  save_hemi_scan(dataname, "", "")
1171 
1172  setdatafolder saveDF
1173 end
1174 
1176 static function load_tracker_data()
1177  dfref savedf = getdatafolderdfr()
1178  setdatafolder $(package_path)
1179 
1180  NewDataFolder /O/S load_data
1181  LoadWave /t /q
1182  if (v_flag > 0)
1183  string wname = StringFromList(0, s_wavenames, ";")
1184  wave w = $wname
1185  string prefix = get_hemi_prefix(w)
1186  ast_import(prefix)
1187  endif
1188 
1189  setdatafolder $(package_path)
1190  KillDataFolder /Z load_data
1191 
1192  setdatafolder saveDF
1193 end
1194 
1195 static function pmp_parameters(pa) : PopupMenuControl
1196  STRUCT WMPopupAction &pa
1197 
1198  switch( pa.eventCode )
1199  case 2: // mouse up
1201  break
1202  case -1: // control being killed
1203  break
1204  endswitch
1205 
1206  return 0
1207 end
1208 
1209 static function pmp_parameters_mouseup(pa)
1210  STRUCT WMPopupAction &pa
1211 
1212  switch(pa.popNum)
1213  case 1:
1214  load_prefs()
1215  break
1216  case 2:
1217  save_prefs()
1218  break
1219  case 3:
1221  break
1222  case 4:
1223  edit_offsets()
1224  break
1225  endswitch
1226 
1227 end
1228 
1229 static function edit_reduction_params()
1230  dfref savedf = getdatafolderdfr()
1231  setdatafolder $(package_path)
1232 
1233  svar pref_func = reduction_func
1234  svar pref_params = reduction_params
1235 
1236  string loc_func = pref_func
1237  string loc_params = pref_params
1238  if (prompt_func_params(loc_func, loc_params) == 0)
1239  ast_set_processing(loc_func, loc_params)
1240  endif
1241 
1242  setdatafolder saveDF
1243 end
1244 
1245 static function edit_offsets()
1246  dfref savedf = getdatafolderdfr()
1247  setdatafolder $(package_path)
1248 
1249  nvar theta_offset
1250  nvar tilt_offset
1251  nvar phi_offset
1252 
1253  variable loc_theta = theta_offset
1254  variable loc_tilt = tilt_offset
1255  variable loc_phi = phi_offset
1256 
1257  prompt loc_theta, "theta offset"
1258  prompt loc_tilt, "tilt offset"
1259  prompt loc_phi, "phi offset"
1260 
1261  doprompt "manipulator offsets", loc_theta, loc_tilt, loc_phi
1262  if (v_flag == 0)
1263  theta_offset = loc_theta
1264  tilt_offset = loc_tilt
1265  phi_offset = loc_phi
1266  endif
1267 
1268  setdatafolder saveDF
1269 end
crop_strip
variable crop_strip(wave strip, variable xlo, variable xhi)
crop a strip at the sides.
Definition: pearl-anglescan-process.ipf:747
hemi_add_anglescan
variable hemi_add_anglescan(string nickname, wave values, wave polar, wave azi, wave weights=defaultValue)
add arbitrary angle scan data to a hemispherical scan grid.
Definition: pearl-anglescan-process.ipf:2637
ast_callback_manip
variable ast_callback_manip(variable chan)
callback function for new manipulator position from EPICS.
Definition: pearl-anglescan-tracker.ipf:991
save_prefs
static variable save_prefs()
save persistent package data to the preferences file.
Definition: pearl-anglescan-tracker.ipf:140
normalize_strip_theta
variable normalize_strip_theta(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
divide the strip by the average polar distribution.
Definition: pearl-anglescan-process.ipf:433
setup_detector
static variable setup_detector()
Definition: pearl-anglescan-tracker.ipf:435
update_capture
static variable update_capture()
Definition: pearl-anglescan-tracker.ipf:1056
epics_disconnect
static variable epics_disconnect()
Definition: pearl-anglescan-tracker.ipf:807
ast_update_detector
variable ast_update_detector(variable theta, variable tilt, variable phi, variable range)
update the current position indicator.
Definition: pearl-anglescan-tracker.ipf:350
int_linbg_reduction
threadsafe wave int_linbg_reduction(wave source, string *param)
linear-background subtracted integration reduction function.
Definition: pearl-scienta-preprocess.ipf:262
normalize_strip_x
variable normalize_strip_x(wave strip, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
divide the strip by the average X distribution.
Definition: pearl-anglescan-process.ipf:252
convert_angles_ttpd2polar
variable convert_angles_ttpd2polar(wave theta, wave tilt, wave phi, wave data, wave polar, wave azi)
convert angles from TTPA (theta-tilt-phi-analyser) scheme to polar coordinates.
Definition: pearl-anglescan-process.ipf:1123
ast_export
variable ast_export(dfref folder, string nickname, variable xpdplot=defaultValue)
export tracker data to a separate, independent data set.
Definition: pearl-anglescan-tracker.ipf:308
get_hemi_prefix
string get_hemi_prefix(wave w)
finds the prefix given any hemi wave
Definition: pearl-anglescan-process.ipf:1541
make_hemi_grid
variable make_hemi_grid(variable npol, string nickname, variable xpdplot=defaultValue)
create a hemispherical, constant solid angle grid
Definition: pearl-anglescan-process.ipf:1365
clear_hemi_grid
variable clear_hemi_grid(string nickname)
clear a hemispherical scan grid
Definition: pearl-anglescan-process.ipf:1606
bp_capture
static variable bp_capture(WMButtonAction *ba)
Definition: pearl-anglescan-tracker.ipf:1024
ast_set_processing
variable ast_set_processing(string reduction_func, string reduction_params)
set the data processing parameters
Definition: pearl-anglescan-tracker.ipf:262
pmp_parameters_mouseup
static variable pmp_parameters_mouseup(WMPopupAction *pa)
Definition: pearl-anglescan-tracker.ipf:1209
ast_callback_detector
variable ast_callback_detector(variable chan)
callback function for new detector state from EPICS.
Definition: pearl-anglescan-tracker.ipf:962
AfterCompiledHook
static variable AfterCompiledHook()
initialize package data once when the procedure is first loaded
Definition: pearl-anglescan-tracker.ipf:74
setup_graph
static variable setup_graph()
create the graph window.
Definition: pearl-anglescan-tracker.ipf:595
IgorQuitHook
static variable IgorQuitHook(string app)
disconnect EPICS channels before Igor quits.
Definition: pearl-anglescan-tracker.ipf:189
pmp_data
static variable pmp_data(WMPopupAction *pa)
Definition: pearl-anglescan-tracker.ipf:1072
init_package
static variable init_package()
Definition: pearl-anglescan-tracker.ipf:99
setup_data
static variable setup_data()
Definition: pearl-anglescan-tracker.ipf:373
export_tracker_data
static variable export_tracker_data()
export tracker data (with prompt)
Definition: pearl-anglescan-tracker.ipf:1106
pmp_parameters
static variable pmp_parameters(WMPopupAction *pa)
Definition: pearl-anglescan-tracker.ipf:1195
toggle_capture
static variable toggle_capture()
Definition: pearl-anglescan-tracker.ipf:1038
ast_close
variable ast_close()
stop tracker, close graph, release data structures.
Definition: pearl-anglescan-tracker.ipf:361
ast_add_image
variable ast_add_image(wave image, variable theta, variable tilt, variable phi)
process and add a detector image to the tracker scan.
Definition: pearl-anglescan-tracker.ipf:286
ast_callback_data
variable ast_callback_data(variable chan)
callback function for new analyser data from EPICS.
Definition: pearl-anglescan-tracker.ipf:857
update_detector_graph
static variable update_detector_graph()
Definition: pearl-anglescan-tracker.ipf:658
update_detector
static variable update_detector(variable theta, variable tilt, variable phi, variable range)
update the current position indicator.
Definition: pearl-anglescan-tracker.ipf:560
ast_import
variable ast_import(string nickname)
import tracker data from an existing angle scan dataset.
Definition: pearl-anglescan-tracker.ipf:330
PearlAnglescanTracker
variable PearlAnglescanTracker(string epicsname, string wbRGB)
display the angle scan tracker window
Definition: pearl-menu.ipf:243
prefs_objects
static const string prefs_objects
semicolon-separated list of persistent variable, string, and wave names
Definition: pearl-anglescan-tracker.ipf:71
ast_setup
variable ast_setup()
set up data structures, display graph, and try to connect to analyser.
Definition: pearl-anglescan-tracker.ipf:195
process_image_data
static variable process_image_data()
process the data buffer to generate the tracker dataset.
Definition: pearl-anglescan-tracker.ipf:508
import_tracker_data
static variable import_tracker_data()
import tracker data (with prompt)
Definition: pearl-anglescan-tracker.ipf:1136
save_tracker_data
static variable save_tracker_data()
save tracker data to file (with prompt)
Definition: pearl-anglescan-tracker.ipf:1165
adh5_default_reduction
threadsafe wave adh5_default_reduction(wave source, string *param)
function prototype for adh5_load_reduced_detector
Definition: pearl-area-import.ipf:1115
convert_angles_ttpa2polar
variable convert_angles_ttpa2polar(wave theta, wave tilt, wave phi, wave analyser, wave polar, wave azi)
convert angles from TTPA (theta-tilt-phi-analyser) scheme to polar coordinates.
Definition: pearl-anglescan-process.ipf:1162
ast_prepare
variable ast_prepare(variable theta_offset=defaultValue, variable tilt_offset=defaultValue, variable phi_offset=defaultValue)
prepare for new measurement and clear the data buffer.
Definition: pearl-anglescan-tracker.ipf:212
pmp_data_mouseup
static variable pmp_data_mouseup(WMPopupAction *pa)
Definition: pearl-anglescan-tracker.ipf:1086
save_hemi_scan
variable save_hemi_scan(string nickname, string pathname, string filename)
save a hemispherical scan to an Igor text file
Definition: pearl-anglescan-process.ipf:3097
load_prefs
static variable load_prefs()
load persistent package data from the preferences file.
Definition: pearl-anglescan-tracker.ipf:164
prompt_func_params
variable prompt_func_params(string func_name, string *func_param)
Definition: pearl-data-explorer.ipf:1136
duplicate_hemi_scan
variable duplicate_hemi_scan(string source_nickname, dfref dest_folder, string dest_nickname, variable xpdplot=defaultValue)
duplicate a hemispherical scan dataset.
Definition: pearl-anglescan-process.ipf:1653
ast_window_hook
static variable ast_window_hook(WMWinHookStruct *s)
window hook
Definition: pearl-anglescan-tracker.ipf:842
update_data_graph
static variable update_data_graph()
Definition: pearl-anglescan-tracker.ipf:646
edit_reduction_params
static variable edit_reduction_params()
Definition: pearl-anglescan-tracker.ipf:1229
epics_connect
static variable epics_connect()
connect the angle scan tracker to EPICS
Definition: pearl-anglescan-tracker.ipf:681
edit_offsets
static variable edit_offsets()
Definition: pearl-anglescan-tracker.ipf:1245
epics_disconnect_chid
static variable epics_disconnect_chid(string chid_var_name)
Definition: pearl-anglescan-tracker.ipf:793
version
version
Definition: pearl-anglescan-tracker.ipf:6
package_path
static const string package_path
data folder path
Definition: pearl-anglescan-tracker.ipf:69
package_name
static const string package_name
package name is used as data folder name
Definition: pearl-anglescan-panel.ipf:48
extend_data
static variable extend_data(variable num_slices)
extend the data buffer for the next polar scan
Definition: pearl-anglescan-tracker.ipf:403
load_tracker_data
static variable load_tracker_data()
import tracker data from file (with prompt)
Definition: pearl-anglescan-tracker.ipf:1176
display_hemi_scan
string display_hemi_scan(string nickname, variable projection=defaultValue, variable graphtype=defaultValue, variable do_ticks=defaultValue, variable do_grids=defaultValue, string graphname=defaultValue)
display a plot of a hemispherical angle scan.
Definition: pearl-anglescan-process.ipf:1858
add_image_data
static variable add_image_data(wave image, variable theta, variable tilt, variable phi)
reduce a detector image and add the result to the data buffer.
Definition: pearl-anglescan-tracker.ipf:454