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
190 epics_disconnect()
191 end
192
194 function ast_setup()
195 setup_data()
196 setup_detector()
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
245 update_data_graph()
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)
292 process_image_data()
293 update_data_graph()
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)
356 update_detector_graph()
357 end
358
360 function ast_close()
361 dfref savedf = getdatafolderdfr()
362 setdatafolder $(package_path)
363
364 epics_disconnect()
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
640 update_capture()
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
685 epics_disconnect()
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
848 epics_disconnect()
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:
1090 import_tracker_data()
1091 break
1092 case 2:
1093 export_tracker_data()
1094 break
1095 case 3:
1096 load_tracker_data()
1097 break
1098 case 4:
1099 save_tracker_data()
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
1199 pmp_parameters_mouseup(pa)
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:
1219 edit_reduction_params()
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
ast_set_processing
variable ast_set_processing(string reduction_func, string reduction_params)
set the data processing parameters
Definition: pearl-anglescan-tracker.ipf:261
ast_close
variable ast_close()
stop tracker, close graph, release data structures.
Definition: pearl-anglescan-tracker.ipf:360
normalize_strip_theta
variable normalize_strip_theta(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
divide the strip by the average polar distribution.
Definition: pearl-anglescan-process.ipf:366
epics_connect
static variable epics_connect()
connect the angle scan tracker to EPICS
Definition: pearl-anglescan-tracker.ipf:680
update_detector_graph
static variable update_detector_graph()
Definition: pearl-anglescan-tracker.ipf:657
bp_capture
static variable bp_capture(WMButtonAction *ba)
Definition: pearl-anglescan-tracker.ipf:1023
crop_strip
variable crop_strip(wave strip, variable xlo, variable xhi)
crop a strip at the sides.
Definition: pearl-anglescan-process.ipf:673
make_hemi_grid
variable make_hemi_grid(variable npol, string nickname, variable xpdplot=defaultValue)
create a hemispherical, constant solid angle grid
Definition: pearl-anglescan-process.ipf:1291
hemi_add_anglescan
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.
Definition: pearl-anglescan-process.ipf:2538
setup_detector
static variable setup_detector()
Definition: pearl-anglescan-tracker.ipf:434
pmp_parameters
static variable pmp_parameters(WMPopupAction *pa)
Definition: pearl-anglescan-tracker.ipf:1194
get_hemi_prefix
string get_hemi_prefix(wave w)
finds the prefix given any hemi wave
Definition: pearl-anglescan-process.ipf:1467
display_hemi_scan
string display_hemi_scan(string nickname, variable projection=defaultValue, variable graphtype=defaultValue, variable do_ticks=defaultValue, variable do_grids=defaultValue, string graphname=defaultValue)
display a plot of a hemispherical angle scan.
Definition: pearl-anglescan-process.ipf:1784
epics_disconnect
static variable epics_disconnect()
Definition: pearl-anglescan-tracker.ipf:806
update_data_graph
static variable update_data_graph()
Definition: pearl-anglescan-tracker.ipf:645
ast_setup
variable ast_setup()
set up data structures, display graph, and try to connect to analyser.
Definition: pearl-anglescan-tracker.ipf:194
convert_angles_ttpd2polar
variable convert_angles_ttpd2polar(wave theta, wave tilt, wave phi, wave data, wave polar, wave azi)
convert angles from TTPA (theta-tilt-phi-analyser) scheme to polar coordinates.
Definition: pearl-anglescan-process.ipf:1049
prefs_objects
static const string prefs_objects
semicolon-separated list of persistent variable, string, and wave names
Definition: pearl-anglescan-tracker.ipf:70
setup_graph
static variable setup_graph()
create the graph window.
Definition: pearl-anglescan-tracker.ipf:594
import_tracker_data
static variable import_tracker_data()
import tracker data (with prompt)
Definition: pearl-anglescan-tracker.ipf:1135
clear_hemi_grid
variable clear_hemi_grid(string nickname)
clear a hemispherical scan grid
Definition: pearl-anglescan-process.ipf:1532
extend_data
static variable extend_data(variable num_slices)
extend the data buffer for the next polar scan
Definition: pearl-anglescan-tracker.ipf:402
pmp_data_mouseup
static variable pmp_data_mouseup(WMPopupAction *pa)
Definition: pearl-anglescan-tracker.ipf:1085
ast_prepare
variable ast_prepare(variable theta_offset=defaultValue, variable tilt_offset=defaultValue, variable phi_offset=defaultValue)
prepare for new measurement and clear the data buffer.
Definition: pearl-anglescan-tracker.ipf:211
setup_data
static variable setup_data()
Definition: pearl-anglescan-tracker.ipf:372
int_linbg_reduction
threadsafe wave int_linbg_reduction(wave source, string *param)
linear-background subtracted integration reduction function.
Definition: pearl-scienta-preprocess.ipf:260
epics_disconnect_chid
static variable epics_disconnect_chid(string chid_var_name)
Definition: pearl-anglescan-tracker.ipf:792
version
version
Definition: pearl-anglescan-tracker.ipf:5
AfterCompiledHook
static variable AfterCompiledHook()
initialize package data once when the procedure is first loaded
Definition: pearl-anglescan-tracker.ipf:73
save_prefs
static variable save_prefs()
save persistent package data to the preferences file.
Definition: pearl-anglescan-tracker.ipf:139
edit_offsets
static variable edit_offsets()
Definition: pearl-anglescan-tracker.ipf:1244
add_image_data
static variable add_image_data(wave image, variable theta, variable tilt, variable phi)
reduce a detector image and add the result to the data buffer.
Definition: pearl-anglescan-tracker.ipf:453
package_path
static const string package_path
data folder path
Definition: pearl-anglescan-tracker.ipf:68
load_tracker_data
static variable load_tracker_data()
import tracker data from file (with prompt)
Definition: pearl-anglescan-tracker.ipf:1175
save_tracker_data
static variable save_tracker_data()
save tracker data to file (with prompt)
Definition: pearl-anglescan-tracker.ipf:1164
update_capture
static variable update_capture()
Definition: pearl-anglescan-tracker.ipf:1055
ast_export
variable ast_export(dfref folder, string nickname, variable xpdplot=defaultValue)
export tracker data to a separate, independent data set.
Definition: pearl-anglescan-tracker.ipf:307
ast_update_detector
variable ast_update_detector(variable theta, variable tilt, variable phi, variable range)
update the current position indicator.
Definition: pearl-anglescan-tracker.ipf:349
process_image_data
static variable process_image_data()
process the data buffer to generate the tracker dataset.
Definition: pearl-anglescan-tracker.ipf:507
save_hemi_scan
variable save_hemi_scan(string nickname, string pathname, string filename)
save a hemispherical scan to an Igor text file
Definition: pearl-anglescan-process.ipf:2903
IgorQuitHook
static variable IgorQuitHook(string app)
disconnect EPICS channels before Igor quits.
Definition: pearl-anglescan-tracker.ipf:188
adh5_default_reduction
threadsafe wave adh5_default_reduction(wave source, string *param)
function prototype for adh5_load_reduced_detector
Definition: pearl-area-import.ipf:1111
ast_callback_manip
variable ast_callback_manip(variable chan)
callback function for new manipulator position from EPICS.
Definition: pearl-anglescan-tracker.ipf:990
ast_callback_detector
variable ast_callback_detector(variable chan)
callback function for new detector state from EPICS.
Definition: pearl-anglescan-tracker.ipf:961
pmp_parameters_mouseup
static variable pmp_parameters_mouseup(WMPopupAction *pa)
Definition: pearl-anglescan-tracker.ipf:1208
prompt_func_params
variable prompt_func_params(string func_name, string *func_param)
Definition: pearl-data-explorer.ipf:1076
convert_angles_ttpa2polar
variable convert_angles_ttpa2polar(wave theta, wave tilt, wave phi, wave analyser, wave polar, wave azi)
convert angles from TTPA (theta-tilt-phi-analyser) scheme to polar coordinates.
Definition: pearl-anglescan-process.ipf:1088
ast_add_image
variable ast_add_image(wave image, variable theta, variable tilt, variable phi)
process and add a detector image to the tracker scan.
Definition: pearl-anglescan-tracker.ipf:285
pmp_data
static variable pmp_data(WMPopupAction *pa)
Definition: pearl-anglescan-tracker.ipf:1071
duplicate_hemi_scan
variable duplicate_hemi_scan(string source_nickname, dfref dest_folder, string dest_nickname, variable xpdplot=defaultValue)
duplicate a hemispherical scan dataset.
Definition: pearl-anglescan-process.ipf:1579
init_package
static variable init_package()
Definition: pearl-anglescan-tracker.ipf:98
ast_window_hook
static variable ast_window_hook(WMWinHookStruct *s)
window hook
Definition: pearl-anglescan-tracker.ipf:841
edit_reduction_params
static variable edit_reduction_params()
Definition: pearl-anglescan-tracker.ipf:1228
toggle_capture
static variable toggle_capture()
Definition: pearl-anglescan-tracker.ipf:1037
ast_callback_data
variable ast_callback_data(variable chan)
callback function for new analyser data from EPICS.
Definition: pearl-anglescan-tracker.ipf:856
ast_import
variable ast_import(string nickname)
import tracker data from an existing angle scan dataset.
Definition: pearl-anglescan-tracker.ipf:329
package_name
static const string package_name
package name is used as data folder name
Definition: pearl-anglescan-panel.ipf:45
load_prefs
static variable load_prefs()
load persistent package data from the preferences file.
Definition: pearl-anglescan-tracker.ipf:163
normalize_strip_x
variable normalize_strip_x(wave strip, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
divide the strip by the average X distribution.
Definition: pearl-anglescan-process.ipf:187
update_detector
static variable update_detector(variable theta, variable tilt, variable phi, variable range)
update the current position indicator.
Definition: pearl-anglescan-tracker.ipf:559
export_tracker_data
static variable export_tracker_data()
export tracker data (with prompt)
Definition: pearl-anglescan-tracker.ipf:1105