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