PEARL Procedures  rev-distro-2.1.1-1-gf419e92-dirty
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 
809  if (DataFolderExists(package_path))
810  SetDataFolder $(package_path)
811  else
812  return nan
813  endif
814 
815  nvar connected
816  if (connected)
817  connected = 0
818  epics_disconnect_chid("chidDetectorState")
819  epics_disconnect_chid("chidArrayData")
820  epics_disconnect_chid("chidXScale")
821  epics_disconnect_chid("chidYScale")
822  epics_disconnect_chid("chidNDimensions")
823  epics_disconnect_chid("chidArraySize0")
824  epics_disconnect_chid("chidArraySize1")
825  epics_disconnect_chid("chidDataType")
826  epics_disconnect_chid("chidColorMode")
827  epics_disconnect_chid("chidLensMode")
828  epics_disconnect_chid("chidTheta")
829  epics_disconnect_chid("chidTilt")
830  epics_disconnect_chid("chidPhi")
831  print "angle scan tracker: offline"
832  endif
833 
834  setdatafolder savedf
835 end
836 
841 static function ast_window_hook(s)
842  STRUCT WMWinHookStruct &s
843 
844  Variable hookResult = 0
845 
846  switch(s.eventCode)
847  case 2: // kill
849  break
850  endswitch
851 
852  return hookResult
853 End
854 
856 function ast_callback_data(chan)
857  variable chan
858 
859  nvar capturing = $(package_path + "capturing")
860  if (!capturing)
861  return 0
862  endif
863 
864  dfref savedf = GetDataFolderDFR()
865  setdatafolder $(package_path)
866  #if exists("pvGetWave")
867 
868  // retrieve data
869  nvar chidArrayData
870  nvar chidXScale
871  nvar chidYScale
872  nvar chidNDimensions
873  nvar chidArraySize0
874  nvar chidArraySize1
875  nvar chidDataType
876  nvar chidColorMode
877  nvar chidTheta
878  nvar chidTilt
879  nvar chidPhi
880  nvar acqTheta
881  nvar acqTilt
882  nvar acqPhi
883 
884  wave arraydata
885  wave image
886  wave xscale
887  wave yscale
888  variable ndimensions
889  variable arraysize0
890  variable arraysize1
891  variable datatype
892  variable colormode
893 
894  //printf "array callback: acqtheta = %.1f, acqtilt = %.1f, acqphi = %.1f\r", acqTheta, acqTilt, acqPhi
895 
896  pvGet chidNDimensions, ndimensions
897  pvGet chidArraySize0, arraysize0
898  pvGet chidArraySize1, arraysize1
899  pvGet chidDataType, datatype
900  pvGet chidColorMode, colormode
901 
902  // sanity checks
903  if (ndimensions != 2)
904  return -2
905  endif
906  if (colormode != 0)
907  return -3
908  endif
909 
910  redimension /n=(arraysize0 * arraysize1) arraydata
911  redimension /n=(arraysize0, arraysize1) image
912  redimension /n=(arraysize0) xscale
913  redimension /n=(arraysize1) yscale
914 
915  switch(datatype)
916  case 0: // int8
917  redimension /b arraydata, image
918  break
919  case 1: // uint8
920  redimension /b/u arraydata, image
921  break
922  case 2: // int16
923  redimension /w arraydata, image
924  break
925  case 3: // uint16
926  redimension /w/u arraydata, image
927  break
928  case 4: // int32
929  redimension /i arraydata, image
930  break
931  case 5: // uint32
932  redimension /i/u arraydata, image
933  break
934  case 6: // float32
935  redimension /s arraydata, image
936  break
937  case 7: // float64
938  redimension /d arraydata, image
939  break
940  endswitch
941 
942  pvGetWave chidArrayData, arraydata
943  pvGetWave chidXScale, xscale
944  pvGetWave chidYScale, yscale
945 
946  image = arraydata[p + q * arraysize0]
947  setscale /i x xscale[0], xscale[numpnts(xscale)-1], image
948  setscale /i y yscale[0], yscale[numpnts(yscale)-1], image
949 
950  ast_add_image(image, acqTheta, acqTilt, acqPhi)
951 
952  #endif
953  setdatafolder savedf
954  return 0
955 end
956 
961 function ast_callback_detector(chan)
962  variable chan
963 
964  dfref savedf = GetDataFolderDFR()
965  setdatafolder $(package_path)
966 
967  // retrieve data
968  nvar curDetectorState
969  nvar curTheta
970  nvar curTilt
971  nvar curPhi
972 
973  nvar acqTheta
974  nvar acqTilt
975  nvar acqPhi
976 
977  if (curDetectorState == 1)
978  acqTheta = curTheta
979  acqTilt = curTilt
980  acqPhi = curPhi
981  endif
982 
983  //printf "detector callback: acqtheta = %.1f, acqtilt = %.1f, acqphi = %.1f, detstate = %d\r", acqTheta, acqTilt, acqPhi, curDetectorState
984 
985  setdatafolder savedf
986  return 0
987 end
988 
990 function ast_callback_manip(chan)
991  variable chan
992 
993  dfref savedf = GetDataFolderDFR()
994  setdatafolder $(package_path)
995 
996  // retrieve data
997  nvar lensmode = curLensMode
998  nvar theta = curTheta
999  nvar tilt = curTilt
1000  nvar phi = curPhi
1001 
1002  //printf "manipulator callback: curtheta = %.1f, curtilt = %.1f, curphi = %.1f, lensmode = %d\r", theta, tilt, phi, lensmode
1003 
1004  variable range
1005  switch(lensmode)
1006  case 1:
1007  range = 45 // angular 45
1008  break
1009  case 2:
1010  range = 60 // angular 60
1011  break
1012  default:
1013  range = 2 // transmission or error
1014  endswitch
1015  ast_update_detector(theta, tilt, phi, range)
1016 
1017  setdatafolder savedf
1018  return 0
1019 end
1020 
1021 // GUI functions
1022 
1023 static function bp_capture(ba) : ButtonControl
1024  STRUCT WMButtonAction &ba
1025 
1026  switch( ba.eventCode )
1027  case 2: // mouse up
1028  toggle_capture()
1029  break
1030  case -1: // control being killed
1031  break
1032  endswitch
1033 
1034  return 0
1035 end
1036 
1037 static function toggle_capture()
1038  dfref savedf = getdatafolderdfr()
1039  setdatafolder $(package_path)
1040 
1041  nvar capturing
1042  svar graphname
1043 
1044  capturing = !capturing
1045  if (capturing)
1046  ast_prepare()
1047  Button b_capture win=$graphname, title="stop"
1048  else
1049  Button b_capture win=$graphname, title="start"
1050  endif
1051 
1052  setdatafolder saveDF
1053 end
1054 
1055 static function update_capture()
1056  dfref savedf = getdatafolderdfr()
1057  setdatafolder $(package_path)
1058 
1059  nvar capturing
1060  svar graphname
1061 
1062  if (capturing)
1063  Button b_capture win=$graphname, title="stop"
1064  else
1065  Button b_capture win=$graphname, title="start"
1066  endif
1067 
1068  setdatafolder saveDF
1069 end
1070 
1071 static function pmp_data(pa) : PopupMenuControl
1072  STRUCT WMPopupAction &pa
1073 
1074  switch( pa.eventCode )
1075  case 2: // mouse up
1076  pmp_data_mouseup(pa)
1077  break
1078  case -1: // control being killed
1079  break
1080  endswitch
1081 
1082  return 0
1083 end
1084 
1085 static function pmp_data_mouseup(pa)
1086  STRUCT WMPopupAction &pa
1087 
1088  switch(pa.popNum)
1089  case 1:
1091  break
1092  case 2:
1094  break
1095  case 3:
1097  break
1098  case 4:
1100  break
1101  endswitch
1102 end
1103 
1105 static function export_tracker_data()
1106  dfref savedf = getdatafolderdfr()
1107  setdatafolder $(package_path)
1108 
1109  svar export_folderpath
1110  nvar export_format
1111 
1112  string folderpath = export_folderpath
1113  string nickname = ""
1114  variable format = export_format
1115 
1116  prompt folderpath, "Folder Path"
1117  prompt nickname, "Nick Name"
1118  prompt format, "Format", popup, "PEARL;XPDplot"
1119 
1120  doprompt "Export Parameters", folderpath, nickname, format
1121 
1122  if (v_flag == 0)
1123  export_folderpath = folderpath
1124  export_format = format
1125  // note: if a full or partial path is used, all data folders except for the last in the path must already exist.
1126  newdatafolder /o $folderpath
1127  variable xpdplot = format == 2
1128  ast_export($folderpath, nickname, xpdplot=xpdplot)
1129  endif
1130 
1131  setdatafolder saveDF
1132 end
1133 
1135 static function import_tracker_data()
1136  dfref savedf = getdatafolderdfr()
1137  setdatafolder $(package_path)
1138 
1139  svar export_folderpath
1140  string folderpath = export_folderpath
1141  string nickname = ""
1142 
1143  dfref dfBefore = GetDataFolderDFR()
1144  Execute /q/z "CreateBrowser prompt=\"Select wave from dataset\", showWaves=1, showVars=0, showStrs=0"
1145  dfref dfAfter = GetDataFolderDFR()
1146  SetDataFolder dfBefore
1147 
1148  SVAR list = S_BrowserList
1149  NVAR flag = V_Flag
1150 
1151  if ((flag != 0) && (ItemsInList(list) >= 1))
1152  string wname = StringFromList(0, list)
1153  wave w = $wname
1154  string prefix = get_hemi_prefix(w)
1155  dfref df = GetWavesDataFolderDFR(w)
1156  setdatafolder df
1157  ast_import(prefix)
1158  endif
1159 
1160  setdatafolder saveDF
1161 end
1162 
1164 static function save_tracker_data()
1165  dfref savedf = getdatafolderdfr()
1166  setdatafolder $(package_path)
1167 
1168  svar dataname
1169  save_hemi_scan(dataname, "", "")
1170 
1171  setdatafolder saveDF
1172 end
1173 
1175 static function load_tracker_data()
1176  dfref savedf = getdatafolderdfr()
1177  setdatafolder $(package_path)
1178 
1179  NewDataFolder /O/S load_data
1180  LoadWave /t /q
1181  if (v_flag > 0)
1182  string wname = StringFromList(0, s_wavenames, ";")
1183  wave w = $wname
1184  string prefix = get_hemi_prefix(w)
1185  ast_import(prefix)
1186  endif
1187 
1188  setdatafolder $(package_path)
1189  KillDataFolder /Z load_data
1190 
1191  setdatafolder saveDF
1192 end
1193 
1194 static function pmp_parameters(pa) : PopupMenuControl
1195  STRUCT WMPopupAction &pa
1196 
1197  switch( pa.eventCode )
1198  case 2: // mouse up
1200  break
1201  case -1: // control being killed
1202  break
1203  endswitch
1204 
1205  return 0
1206 end
1207 
1208 static function pmp_parameters_mouseup(pa)
1209  STRUCT WMPopupAction &pa
1210 
1211  switch(pa.popNum)
1212  case 1:
1213  load_prefs()
1214  break
1215  case 2:
1216  save_prefs()
1217  break
1218  case 3:
1220  break
1221  case 4:
1222  edit_offsets()
1223  break
1224  endswitch
1225 
1226 end
1227 
1228 static function edit_reduction_params()
1229  dfref savedf = getdatafolderdfr()
1230  setdatafolder $(package_path)
1231 
1232  svar pref_func = reduction_func
1233  svar pref_params = reduction_params
1234 
1235  string loc_func = pref_func
1236  string loc_params = pref_params
1237  if (prompt_func_params(loc_func, loc_params) == 0)
1238  ast_set_processing(loc_func, loc_params)
1239  endif
1240 
1241  setdatafolder saveDF
1242 end
1243 
1244 static function edit_offsets()
1245  dfref savedf = getdatafolderdfr()
1246  setdatafolder $(package_path)
1247 
1248  nvar theta_offset
1249  nvar tilt_offset
1250  nvar phi_offset
1251 
1252  variable loc_theta = theta_offset
1253  variable loc_tilt = tilt_offset
1254  variable loc_phi = phi_offset
1255 
1256  prompt loc_theta, "theta offset"
1257  prompt loc_tilt, "tilt offset"
1258  prompt loc_phi, "phi offset"
1259 
1260  doprompt "manipulator offsets", loc_theta, loc_tilt, loc_phi
1261  if (v_flag == 0)
1262  theta_offset = loc_theta
1263  tilt_offset = loc_tilt
1264  phi_offset = loc_phi
1265  endif
1266 
1267  setdatafolder saveDF
1268 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)
display the angle scan tracker window
Definition: pearl-menu.ipf:242
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)