PEARL Procedures  rev-distro-1.6.0-0-gcf1399e-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 const string package_name = "pearl_anglescan_tracker";
68 static const string package_path = "root:packages:pearl_anglescan_tracker:";
70 static const string prefs_objects = "projection;theta_offset;tilt_offset;phi_offset;reduction_func;reduction_params";
71 
73 static variable 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 };
97 
98 static variable 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 };
134 
139 static variable 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 };
155 
163 static variable 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 };
186 
188 static variable IgorQuitHook(string app){
189  string app
191 };
192 
194 variable ast_setup(){
195  setup_data()
197  setup_graph()
198  epics_connect()
199 };
200 
211 variable ast_prepare(variable theta_offset = defaultValue, variable tilt_offset = defaultValue, variable phi_offset = defaultValue){
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 };
249 
261 variable ast_set_processing(string reduction_func, string 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 };
276 
285 variable ast_add_image(wave image, variable theta, variable tilt, variable phi){
286  wave image
287  variable theta
288  variable tilt
289  variable phi
290 
291  add_image_data(image, theta, tilt, phi)
294 };
295 
307 variable ast_export(dfref folder, string nickname, variable xpdplot = defaultValue){
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 };
324 
329 variable ast_import(string 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 };
339 
349 variable ast_update_detector(variable theta, variable tilt, variable phi, variable range){
350  variable theta
351  variable tilt
352  variable phi
353  variable range
354 
355  update_detector(theta, tilt, phi, range)
357 };
358 
360 variable ast_close(){
361  dfref savedf = getdatafolderdfr()
362  setdatafolder $(package_path)
363 
365 
366  svar graphname
367  KillWindow $graphname
368 
369  setdatafolder saveDF
370 };
371 
372 static variable 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 };
395 
402 static variable extend_data(variable 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 };
433 
434 static variable 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 };
444 
453 static variable add_image_data(wave image, variable theta, variable tilt, variable 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  make /n=(nx) /free profile1, profile2
472  string loc_params = red_params
473  red_func(image, profile1, profile2, loc_params)
474  nx = numpnts(profile1)
475 
476  // write the result to the buffer
477  nvar buf_count
478  nvar buf_size
479  nvar buf_width
480  wave buf_i
481  wave buf_th
482  wave buf_ph
483  wave buf_ti
484 
485  if ((buf_count >= buf_size) || (nx > buf_width))
486  extend_data(nx)
487  setscale /p x dimoffset(profile1,0), dimdelta(profile1,0), waveunits(profile1,0), buf_i
488  endif
489 
490  buf_i[][buf_count] = profile1[p]
491  buf_th[buf_count] = theta - theta_offset
492  buf_ti[buf_count] = -(tilt - tilt_offset)
493  buf_ph[buf_count] = phi - phi_offset
494 
495  buf_count += 1
496 
497  setdatafolder saveDF
498 };
499 
502 static variable process_image_data(){
503  wave image
504  variable theta
505  variable tilt
506  variable phi
507 
508  dfref savedf = getdatafolderdfr()
509  setdatafolder $(package_path)
510  svar dataname
511 
512  nvar buf_count
513  nvar buf_size
514  nvar buf_width
515 
516  wave buf_i
517  wave buf_th
518  wave buf_ph
519  wave buf_ti
520 
521  duplicate /free /R=[0,buf_width-1][0,buf_count-1] buf_i, buf_n
522  duplicate /free /R=[0,buf_count-1] buf_th, w_th
523  duplicate /free /R=[0,buf_count-1] buf_ti, w_ti
524  duplicate /free /R=[0,buf_count-1] buf_ph, w_ph
525 
526  normalize_strip_x(buf_n, smooth_method=4)
527  if (buf_count >= 10)
528  normalize_strip_theta(buf_n, w_th, smooth_method=4)
529  endif
530  if (dimoffset(buf_i,0) < -20)
531  crop_strip(buf_n, -25, 25)
532  else
533  crop_strip(buf_n, -15, 15)
534  endif
535 
536  make /n=1 /free d_polar, d_azi
537  convert_angles_ttpd2polar(w_th, w_ti, w_ph, buf_n, d_polar, d_azi)
538  d_azi += 180// changed 151030 (v1.4)
539  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
540  hemi_add_anglescan(dataname, buf_n, d_polar, d_azi)
541 
542  setdatafolder saveDF
543 };
544 
554 static variable update_detector(variable theta, variable tilt, variable phi, variable range){
555  variable theta
556  variable tilt
557  variable phi
558  variable range
559 
560  dfref savedf = getdatafolderdfr()
561  setdatafolder $(package_path)
562  nvar theta_offset
563  nvar tilt_offset
564  nvar phi_offset
565 
566  make /n=1 /free m_theta
567  make /n=1 /free m_tilt
568  make /n=1 /free m_phi
569  m_theta = theta - theta_offset
570  m_tilt = tilt - tilt_offset
571  m_tilt *= -1// checked 140702
572  m_phi = phi - phi_offset
573  //m_phi *= -1 // checked 140702
574 
575  wave detector_angle, detector_pol, detector_az, detector_rad
576  setscale /i x -range/2, +range/2, "°", detector_angle
577  detector_angle = x
578 
579  convert_angles_ttpa2polar(m_theta, m_tilt, m_phi, detector_angle, detector_pol, detector_az)
580  redimension /n=(numpnts(detector_pol)) detector_rad
581  detector_rad = 2 * tan(detector_pol / 2 * pi / 180)
582  detector_az += 180// changed 151030 (v1.4)
583  detector_az = detector_az >= 360 ? detector_az - 360 : detector_az
584 
585  setdatafolder saveDF
586 };
587 
589 static variable setup_graph(){
590  dfref savedf = getdatafolderdfr()
591  setdatafolder $(package_path)
592 
593  svar dataname
594  svar graphname
595  wave detector_az
596  wave detector_rad
597  wave detector_angle
598  svar tracename = detector_tracename
599 
600  graphname = display_hemi_scan(dataname, graphname=graphname)
601  tracename = WMPolarAppendTrace(graphname, detector_rad, detector_az, 360)
602  ModifyGraph /w=$graphname lstyle($tracename)=0
603  ModifyGraph /w=$graphname lsize($tracename)=1.5
604  ModifyGraph /w=$graphname zColor($tracename)={detector_angle,*,*,RedWhiteBlue,0}
605  ColorScale /w=$graphname /C /N=text1 trace=$tracename
606  ColorScale /w=$graphname /C /N=text1 /F=0 /B=1 /A=LB /X=0.00 /Y=0.00
607  ColorScale /w=$graphname /C /N=text1 width=1.5, heightPct=20, frame=0.00
608  ColorScale /w=$graphname /C /N=text1 lblMargin=0
609  ColorScale /w=$graphname /C /N=text1 nticks=2, tickLen=2.00, tickThick=0.50
610 
611  TextBox /w=$graphname /C /N=tb_manip /F=0 /B=1 /X=0.00 /Y=0.00 /E=2 "\\{\"manip = (%.1f, %.1f, %.1f)\", "
612  AppendText /w=$graphname /N=tb_manip /NOCR "root:packages:pearl_anglescan_tracker:curTheta, "
613  AppendText /w=$graphname /N=tb_manip /NOCR "root:packages:pearl_anglescan_tracker:curTilt, "
614  AppendText /w=$graphname /N=tb_manip /NOCR "root:packages:pearl_anglescan_tracker:curPhi}"
615 
616  // the window hook releases the EPICS variables when the window is killed
617  DoWindow /T $graphname, "Angle Scan Tracker"
618  SetWindow $graphname, hook(ast_hook) = ast_window_hook
619 
620  ControlBar /w=$graphname 21
621  Button b_capture win=$graphname, title="start", pos={0,0}, size={40,21}, proc=PearlAnglescanTracker#bp_capture
622  Button b_capture win=$graphname, fColor=(65535,65535,65535), fSize=10
623  Button b_capture win=$graphname, help={"Start/stop capturing."}
624  PopupMenu pm_params win=$graphname, mode=0, value="load preferences;save preferences;reduction parameters;manipulator offsets", title="parameters"
625  PopupMenu pm_params win=$graphname, pos={70,0}, bodyWidth=80, proc=PearlAnglescanTracker#pmp_parameters
626  PopupMenu pm_params win=$graphname, help={"Load/save/edit data processing parameters"}
627  PopupMenu pm_data win=$graphname, mode=0, value="import;export;load file;save file", title="data"
628  PopupMenu pm_data win=$graphname, pos={120,0}, proc=PearlAnglescanTracker#pmp_data
629  PopupMenu pm_data win=$graphname, help={"Load/save data from/to independent dataset or file"}
630 
631  SetDrawLayer /w=$graphname ProgFront
632  SetDrawEnv /w=$graphname xcoord=rel, ycoord=rel
633  DrawPict /w=$graphname 0, 0, 1, 1, pict_tracker_sample
634 
636 
637  setdatafolder saveDF
638 };
639 
640 static variable update_data_graph(){
641  dfref savedf = getdatafolderdfr()
642  setdatafolder $(package_path)
643 
644  svar dataname
645  svar graphname
646 
647  // nothing to do - trace is updated automatically
648 
649  setdatafolder saveDF
650 };
651 
652 static variable update_detector_graph(){
653  dfref savedf = getdatafolderdfr()
654  setdatafolder $(package_path)
655 
656  svar dataname
657  svar graphname
658 
659  // nothing to do - trace is updated automatically
660 
661  setdatafolder saveDF
662 };
663 
675 static variable epics_connect(){
676  dfref savedf = getdatafolderdfr()
677  setdatafolder $(package_path)
678 
679  // close PVs which may be open from a previous call
681 
682  // create variables and waves
683  make /n=(1)/o arraydata, xscale, yscale
684  make /n=(1,1)/o image
685  variable /g ndimensions
686  variable /g arraysize0, arraysize1
687  variable /g datatype
688  variable /g colormode
689  string /g controls, monitors
690  string /g xunits, yunits
691 
692  // channel ID variables
693  variable /g chidDetectorState = 0
694  variable /g chidArrayData = 0
695  variable /g chidXScale = 0
696  variable /g chidYScale = 0
697  variable /g chidNDimensions = 0
698  variable /g chidArraySize0 = 0
699  variable /g chidArraySize1 = 0
700  variable /g chidDataType = 0
701  variable /g chidColorMode = 0
702  variable /g chidLensMode = 0
703  variable /g chidTheta = 0
704  variable /g chidTilt = 0
705  variable /g chidPhi = 0
706  variable /g curDetectorState = 0
707  variable /g curLensMode = 0
708  variable /g curTheta = 0
709  variable /g curTilt = 0
710  variable /g curPhi = 0
711  variable /g acqTheta = 0
712  variable /g acqTilt = 0
713  variable /g acqPhi = 0
714  variable /g connected = 0
715 
716  string epicsname = "X03DA-SCIENTA:"
717  string imagename = epicsname + "image1:"
718  string camname = epicsname + "cam1:"
719  string manipname = "X03DA-ES2-MA:"
720  variable timeout = 5// seconds
721 
722  #if exists("pvWait")
723  // EPICS.XOP version 0.3.0 or later
724  pvOpen /Q chidDetectorState, camname + "DetectorState_RBV"// 0 = idle
725  pvOpen /Q chidLensMode, camname + "LENS_MODE_RBV"
726  pvOpen /Q chidXScale, camname + "CHANNEL_SCALE_RBV"
727  pvOpen /Q chidYScale, camname + "SLICE_SCALE_RBV"
728  pvOpen /Q chidArrayData, imagename + "ArrayData"
729  pvOpen /Q chidNDimensions, imagename + "NDimensions_RBV"
730  pvOpen /Q chidArraySize0, imagename + "ArraySize0_RBV"
731  pvOpen /Q chidArraySize1, imagename + "ArraySize1_RBV"
732  pvOpen /Q chidDataType, imagename + "DataType_RBV"
733  pvOpen /Q chidColorMode, imagename + "ColorMode_RBV"
734 
735  pvOpen /Q chidTheta, manipname + "THT.RBV"
736  pvOpen /Q chidTilt, manipname + "TLT.RBV"
737  pvOpen /Q chidPhi, manipname + "PHI.RBV"
738 
739  pvWait timeout
740 
741  if (!GetRTError(1))
742  connected = 1
743  endif
744  #elif exists("pvOpen")
745  // EPICS.XOP version < 0.3.0
746  pvOpen /T=(timeout) chidDetectorState, camname + "DetectorState_RBV"// 0 = idle
747  pvOpen /T=(timeout) chidLensMode, camname + "LENS_MODE_RBV"
748  pvOpen /T=(timeout) chidXScale, camname + "CHANNEL_SCALE_RBV"
749  pvOpen /T=(timeout) chidYScale, camname + "SLICE_SCALE_RBV"
750  pvOpen /T=(timeout) chidArrayData, imagename + "ArrayData"
751  pvOpen /T=(timeout) chidNDimensions, imagename + "NDimensions_RBV"
752  pvOpen /T=(timeout) chidArraySize0, imagename + "ArraySize0_RBV"
753  pvOpen /T=(timeout) chidArraySize1, imagename + "ArraySize1_RBV"
754  pvOpen /T=(timeout) chidDataType, imagename + "DataType_RBV"
755  pvOpen /T=(timeout) chidColorMode, imagename + "ColorMode_RBV"
756 
757  pvOpen /T=(timeout) chidTheta, manipname + "THT.RBV"
758  pvOpen /T=(timeout) chidTilt, manipname + "TLT.RBV"
759  pvOpen /T=(timeout) chidPhi, manipname + "PHI.RBV"
760 
761  if (!GetRTError(1))
762  connected = 1
763  endif
764  #endif
765 
766  #if exists("pvMonitor")
767  if (connected)
768  pvMonitor /F=ast_callback_detector chidDetectorState, curDetectorState
769  pvMonitor /F=ast_callback_manip chidTheta, curTheta
770  pvMonitor /F=ast_callback_manip chidTilt, curTilt
771  pvMonitor /F=ast_callback_manip chidPhi, curPhi
772  pvMonitor /F=ast_callback_manip chidLensMode, curLensMode
773  pvMonitor /F=ast_callback_data chidArrayData
774  endif
775  #endif
776 
777  if (connected)
778  print "angle scan tracker: online"
779  else
780  print "angle scan tracker: offline"
781  endif
782 
783  setdatafolder saveDF
784  return !connected
785 };
786 
787 static variable epics_disconnect_chid(string chid_var_name){
788  string chid_var_name
789 
790  #if exists("pvClose")
791  nvar /z chid = $chid_var_name
792  if (nvar_exists(chid))
793  if (chid != 0)
794  pvClose chid
795  endif
796  chid = 0
797  endif
798  #endif
799 };
800 
801 static variable epics_disconnect(){
802  dfref savedf = GetDataFolderDFR()
803  setdatafolder $(package_path)
804 
805  nvar connected
806  if (connected)
807  connected = 0
808  epics_disconnect_chid("chidDetectorState")
809  epics_disconnect_chid("chidArrayData")
810  epics_disconnect_chid("chidXScale")
811  epics_disconnect_chid("chidYScale")
812  epics_disconnect_chid("chidNDimensions")
813  epics_disconnect_chid("chidArraySize0")
814  epics_disconnect_chid("chidArraySize1")
815  epics_disconnect_chid("chidDataType")
816  epics_disconnect_chid("chidColorMode")
817  epics_disconnect_chid("chidLensMode")
818  epics_disconnect_chid("chidTheta")
819  epics_disconnect_chid("chidTilt")
820  epics_disconnect_chid("chidPhi")
821  print "angle scan tracker: offline"
822  endif
823 
824  setdatafolder savedf
825 };
826 
831 static variable ast_window_hook(WMWinHookStruct* s){
832  STRUCT WMWinHookStruct &s
833 
834  Variable hookResult = 0
835 
836  switch(s.eventCode)
837  case 2:// kill
839  break
840  endswitch
841 
842  return hookResult
843 };
844 
846 variable ast_callback_data(variable chan){
847  variable chan
848 
849  nvar capturing = $(package_path + "capturing")
850  if (!capturing)
851  return 0
852  endif
853 
854  dfref savedf = GetDataFolderDFR()
855  setdatafolder $(package_path)
856  #if exists("pvGetWave")
857 
858  // retrieve data
859  nvar chidArrayData
860  nvar chidXScale
861  nvar chidYScale
862  nvar chidNDimensions
863  nvar chidArraySize0
864  nvar chidArraySize1
865  nvar chidDataType
866  nvar chidColorMode
867  nvar chidTheta
868  nvar chidTilt
869  nvar chidPhi
870  nvar acqTheta
871  nvar acqTilt
872  nvar acqPhi
873 
874  wave arraydata
875  wave image
876  wave xscale
877  wave yscale
878  variable ndimensions
879  variable arraysize0
880  variable arraysize1
881  variable datatype
882  variable colormode
883 
884  //printf "array callback: acqtheta = %.1f, acqtilt = %.1f, acqphi = %.1f\r", acqTheta, acqTilt, acqPhi
885 
886  pvGet chidNDimensions, ndimensions
887  pvGet chidArraySize0, arraysize0
888  pvGet chidArraySize1, arraysize1
889  pvGet chidDataType, datatype
890  pvGet chidColorMode, colormode
891 
892  // sanity checks
893  if (ndimensions != 2)
894  return -2
895  endif
896  if (colormode != 0)
897  return -3
898  endif
899 
900  redimension /n=(arraysize0 * arraysize1) arraydata
901  redimension /n=(arraysize0, arraysize1) image
902  redimension /n=(arraysize0) xscale
903  redimension /n=(arraysize1) yscale
904 
905  switch(datatype)
906  case 0:// int8
907  redimension /b arraydata, image
908  break
909  case 1:// uint8
910  redimension /b/u arraydata, image
911  break
912  case 2:// int16
913  redimension /w arraydata, image
914  break
915  case 3:// uint16
916  redimension /w/u arraydata, image
917  break
918  case 4:// int32
919  redimension /i arraydata, image
920  break
921  case 5:// uint32
922  redimension /i/u arraydata, image
923  break
924  case 6:// float32
925  redimension /s arraydata, image
926  break
927  case 7:// float64
928  redimension /d arraydata, image
929  break
930  endswitch
931 
932  pvGetWave chidArrayData, arraydata
933  pvGetWave chidXScale, xscale
934  pvGetWave chidYScale, yscale
935 
936  image = arraydata[p + q * arraysize0]
937  setscale /i x xscale[0], xscale[numpnts(xscale)-1], image
938  setscale /i y yscale[0], yscale[numpnts(yscale)-1], image
939 
940  ast_add_image(image, acqTheta, acqTilt, acqPhi)
941 
942  #endif
943  setdatafolder savedf
944  return 0
945 };
946 
951 variable ast_callback_detector(variable chan){
952  variable chan
953 
954  dfref savedf = GetDataFolderDFR()
955  setdatafolder $(package_path)
956 
957  // retrieve data
958  nvar curDetectorState
959  nvar curTheta
960  nvar curTilt
961  nvar curPhi
962 
963  nvar acqTheta
964  nvar acqTilt
965  nvar acqPhi
966 
967  if (curDetectorState == 1)
968  acqTheta = curTheta
969  acqTilt = curTilt
970  acqPhi = curPhi
971  endif
972 
973  //printf "detector callback: acqtheta = %.1f, acqtilt = %.1f, acqphi = %.1f, detstate = %d\r", acqTheta, acqTilt, acqPhi, curDetectorState
974 
975  setdatafolder savedf
976  return 0
977 };
978 
980 variable ast_callback_manip(variable chan){
981  variable chan
982 
983  dfref savedf = GetDataFolderDFR()
984  setdatafolder $(package_path)
985 
986  // retrieve data
987  nvar lensmode = curLensMode
988  nvar theta = curTheta
989  nvar tilt = curTilt
990  nvar phi = curPhi
991 
992  //printf "manipulator callback: curtheta = %.1f, curtilt = %.1f, curphi = %.1f, lensmode = %d\r", theta, tilt, phi, lensmode
993 
994  variable range
995  switch(lensmode)
996  case 1:
997  range = 45// angular 45
998  break
999  case 2:
1000  range = 60// angular 60
1001  break
1002  default:
1003  range = 2// transmission or error
1004  endswitch
1005  ast_update_detector(theta, tilt, phi, range)
1006 
1007  setdatafolder savedf
1008  return 0
1009 };
1010 
1011 // GUI functions
1012 
1013 static variable bp_capture(WMButtonAction* ba){
1014  STRUCT WMButtonAction &ba
1015 
1016  switch( ba.eventCode )
1017  case 2:// mouse up
1018  toggle_capture()
1019  break
1020  case -1:// control being killed
1021  break
1022  endswitch
1023 
1024  return 0
1025 };
1026 
1027 static variable toggle_capture(){
1028  dfref savedf = getdatafolderdfr()
1029  setdatafolder $(package_path)
1030 
1031  nvar capturing
1032  svar graphname
1033 
1034  capturing = !capturing
1035  if (capturing)
1036  ast_prepare()
1037  Button b_capture win=$graphname, title="stop"
1038  else
1039  Button b_capture win=$graphname, title="start"
1040  endif
1041 
1042  setdatafolder saveDF
1043 };
1044 
1045 static variable update_capture(){
1046  dfref savedf = getdatafolderdfr()
1047  setdatafolder $(package_path)
1048 
1049  nvar capturing
1050  svar graphname
1051 
1052  if (capturing)
1053  Button b_capture win=$graphname, title="stop"
1054  else
1055  Button b_capture win=$graphname, title="start"
1056  endif
1057 
1058  setdatafolder saveDF
1059 };
1060 
1061 static variable pmp_data(WMPopupAction* pa){
1062  STRUCT WMPopupAction &pa
1063 
1064  switch( pa.eventCode )
1065  case 2:// mouse up
1066  pmp_data_mouseup(pa)
1067  break
1068  case -1:// control being killed
1069  break
1070  endswitch
1071 
1072  return 0
1073 };
1074 
1075 static variable pmp_data_mouseup(WMPopupAction* pa){
1076  STRUCT WMPopupAction &pa
1077 
1078  switch(pa.popNum)
1079  case 1:
1081  break
1082  case 2:
1084  break
1085  case 3:
1087  break
1088  case 4:
1090  break
1091  endswitch
1092 };
1093 
1095 static variable export_tracker_data(){
1096  dfref savedf = getdatafolderdfr()
1097  setdatafolder $(package_path)
1098 
1099  svar export_folderpath
1100  nvar export_format
1101 
1102  string folderpath = export_folderpath
1103  string nickname = ""
1104  variable format = export_format
1105 
1106  prompt folderpath, "Folder Path"
1107  prompt nickname, "Nick Name"
1108  prompt format, "Format", popup, "PEARL;XPDplot"
1109 
1110  doprompt "Export Parameters", folderpath, nickname, format
1111 
1112  if (v_flag == 0)
1113  export_folderpath = folderpath
1114  export_format = format
1115  // note: if a full or partial path is used, all data folders except for the last in the path must already exist.
1116  newdatafolder /o $folderpath
1117  variable xpdplot = format == 2
1118  ast_export($folderpath, nickname, xpdplot=xpdplot)
1119  endif
1120 
1121  setdatafolder saveDF
1122 };
1123 
1125 static variable import_tracker_data(){
1126  dfref savedf = getdatafolderdfr()
1127  setdatafolder $(package_path)
1128 
1129  svar export_folderpath
1130  string folderpath = export_folderpath
1131  string nickname = ""
1132 
1133  dfref dfBefore = GetDataFolderDFR()
1134  Execute /q/z "CreateBrowser prompt=\"Select wave from dataset\", showWaves=1, showVars=0, showStrs=0"
1135  dfref dfAfter = GetDataFolderDFR()
1136  SetDataFolder dfBefore
1137 
1138  SVAR list = S_BrowserList
1139  NVAR flag = V_Flag
1140 
1141  if ((flag != 0) && (ItemsInList(list) >= 1))
1142  string wname = StringFromList(0, list)
1143  wave w = $wname
1144  string prefix = get_hemi_prefix(w)
1145  dfref df = GetWavesDataFolderDFR(w)
1146  setdatafolder df
1147  ast_import(prefix)
1148  endif
1149 
1150  setdatafolder saveDF
1151 };
1152 
1154 static variable save_tracker_data(){
1155  dfref savedf = getdatafolderdfr()
1156  setdatafolder $(package_path)
1157 
1158  svar dataname
1159  save_hemi_scan(dataname, "", "")
1160 
1161  setdatafolder saveDF
1162 };
1163 
1165 static variable load_tracker_data(){
1166  dfref savedf = getdatafolderdfr()
1167  setdatafolder $(package_path)
1168 
1169  NewDataFolder /O/S load_data
1170  LoadWave /t /q
1171  if (v_flag > 0)
1172  string wname = StringFromList(0, s_wavenames, ";")
1173  wave w = $wname
1174  string prefix = get_hemi_prefix(w)
1175  ast_import(prefix)
1176  endif
1177 
1178  setdatafolder $(package_path)
1179  KillDataFolder /Z load_data
1180 
1181  setdatafolder saveDF
1182 };
1183 
1184 static variable pmp_parameters(WMPopupAction* pa){
1185  STRUCT WMPopupAction &pa
1186 
1187  switch( pa.eventCode )
1188  case 2:// mouse up
1190  break
1191  case -1:// control being killed
1192  break
1193  endswitch
1194 
1195  return 0
1196 };
1197 
1198 static variable pmp_parameters_mouseup(WMPopupAction* pa){
1199  STRUCT WMPopupAction &pa
1200 
1201  switch(pa.popNum)
1202  case 1:
1203  load_prefs()
1204  break
1205  case 2:
1206  save_prefs()
1207  break
1208  case 3:
1210  break
1211  case 4:
1212  edit_offsets()
1213  break
1214  endswitch
1215 
1216 };
1217 
1218 static variable edit_reduction_params(){
1219  dfref savedf = getdatafolderdfr()
1220  setdatafolder $(package_path)
1221 
1222  svar pref_func = reduction_func
1223  svar pref_params = reduction_params
1224 
1225  string loc_func = pref_func
1226  string loc_params = pref_params
1227  if (prompt_func_params(loc_func, loc_params) == 0)
1228  ast_set_processing(loc_func, loc_params)
1229  endif
1230 
1231  setdatafolder saveDF
1232 };
1233 
1234 static variable edit_offsets(){
1235  dfref savedf = getdatafolderdfr()
1236  setdatafolder $(package_path)
1237 
1238  nvar theta_offset
1239  nvar tilt_offset
1240  nvar phi_offset
1241 
1242  variable loc_theta = theta_offset
1243  variable loc_tilt = tilt_offset
1244  variable loc_phi = phi_offset
1245 
1246  prompt loc_theta, "theta offset"
1247  prompt loc_tilt, "tilt offset"
1248  prompt loc_phi, "phi offset"
1249 
1250  doprompt "manipulator offsets", loc_theta, loc_tilt, loc_phi
1251  if (v_flag == 0)
1252  theta_offset = loc_theta
1253  tilt_offset = loc_tilt
1254  phi_offset = loc_phi
1255  endif
1256 
1257  setdatafolder saveDF
1258 };
1259 
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:182
static variable setup_data()
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 const string package_name
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.
threadsafe variable adh5_default_reduction(wave source, wave dest1, wave dest2, string *param)
function prototype for adh5_load_reduced_detector
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.
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 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)