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