PEARL Procedures rev-distro-1.6.0-0-gcf1399e-dirty Igor procedures for the analysis of PEARL data

- Main Page
- Related Pages
- Packages
- Namespaces
- Files

- File List
- Globals

pearl-anglescan-process.ipf
Go to the documentation of this file.
1 #pragma rtGlobals=3// Use modern global access method and strict wave access.
2 #pragma version = 1.8
3 #pragma IgorVersion = 6.2
4 #pragma ModuleName = PearlAnglescanProcess
5 #include "pearl-vector-operations"
6 #include "pearl-polar-coordinates"
7 #include <New Polar Graphs>
8
9 // copyright (c) 2013-17 Paul Scherrer Institut
10 //
11 // Licensed under the Apache License, Version 2.0 (the "License");
12 // you may not use this file except in compliance with the License.
13 // You may obtain a copy of the License at
14 // http:///www.apache.org/licenses/LICENSE-2.0
15 //
16 // Please acknowledge the use of this code.
17
76
81
82
105 variable strip_delete_frames(wave strip, variable qlo, variable qhi, wave theta, wave tilt, wave phi){
106 wave strip// 2D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan
107 variable qlo
108 variable qhi
109 wave theta
110 wave tilt
111 wave phi
112
113 if (qlo > qhi)
114 return -1
115 endif
116
117 // source indices
118 variable snx = dimsize(strip, 0)
119 variable sny = dimsize(strip, 1)
120 variable sq1lo = 0
121 variable sq1hi = max(qlo-1, 0)
122 variable sq2lo = min(qhi+1, sny - 1)
123 variable sq2hi = dimsize(strip, 1) - 1
124
125 // dest indices
126 variable dnx = snx
127 variable dny = sny - (sq2lo - sq1hi + 1)
128 variable dq1lo = 0
129 variable dq1hi = sq1hi
130 variable dq2lo = dq1hi + 1
131 variable dq2hi = dny - 1
132 variable q1ofs = sq1lo - dq1lo
133 variable q2ofs = sq2lo - dq2lo
134
135 duplicate /free strip, strip_copy
136 redimension /n=(dnx,dny) strip
137 strip[][dq1lo,dq1hi] = strip_copy[p][q + q1ofs]
138 strip[][dq2lo,dq2hi] = strip_copy[p][q + q2ofs]
139
140 duplicate /free theta, theta_copy
141 redimension /n=(dny) theta
142 theta[dq1lo,dq1hi] = theta_copy[p + q1ofs]
143 theta[dq2lo,dq2hi] = theta_copy[p + q2ofs]
144
145 duplicate /free tilt, tilt_copy
146 redimension /n=(dny) tilt
147 tilt[dq1lo,dq1hi] = tilt_copy[p + q1ofs]
148 tilt[dq2lo,dq2hi] = tilt_copy[p + q2ofs]
149
150 duplicate /free phi, phi_copy
151 redimension /n=(dny) phi
152 phi[dq1lo,dq1hi] = phi_copy[p + q1ofs]
153 phi[dq2lo,dq2hi] = phi_copy[p + q2ofs]
154
155 return 0
156 };
157
185 variable normalize_strip_x(wave strip, variable smooth_method = defaultValue, variable smooth_factor = defaultValue, variable check = defaultValue){
186 wave strip
187 variable smooth_method
188 variable smooth_factor
189 variable check
190
191 if (ParamIsDefault(smooth_method))
192 smooth_method = 1
193 endif
194 if (ParamIsDefault(smooth_factor))
195 switch(smooth_method)
196 case 4:
197 smooth_factor = 0.5
198 break
199 default:
200 smooth_factor = 2
201 endswitch
202 endif
203 if (ParamIsDefault(check))
204 check = 0
205 endif
206
207 // average over all scan positions
208 wave dist = ad_profile_x(strip, -inf, inf, "")
209 variable div = mean(dist)
210 dist /= div
211
212 if (check)
213 duplicate /o dist, check_dist
214 endif
215
216 // smooth distribution function
217 switch(smooth_method)
218 case 1:
219 Smooth /B /E=3 smooth_factor, dist
220 break
221 case 2:
222 Smooth /E=3 smooth_factor, dist
223 break
224 case 3:
225 make /n=1 /d /free fit_params
226 fit_scienta_ang_transm(dist, fit_params)
227 dist = scienta_ang_transm(fit_params, x)
228 break
229 case 4:
230 loess /smth=(smooth_factor) srcWave=dist
231 break
232 endswitch
233
234 if (check)
235 duplicate /o dist, check_smoo
236 endif
237
238 // divide
239 if (check != 2)
240 strip /= dist[p]
241 endif
242 };
243
270 variable normalize_strip_phi(wave strip, wave theta, wave phi, variable theta_offset = defaultValue, variable theta_range = defaultValue, variable check = defaultValue){
271 wave strip
272 wave theta
273 wave phi
274 variable theta_offset
275 variable theta_range
276 variable check
277
278 if (ParamIsDefault(check))
279 check = 0
280 endif
281 if (ParamIsDefault(theta_offset))
282 theta_offset = 0
283 endif
284 if (ParamIsDefault(theta_range))
285 theta_offset = 10
286 endif
287
288 // average over analyser angles
289 wave dist = ad_profile_y(strip, -inf, inf, "")
290
291 // smooth distribution function
292 duplicate /free dist, dist_smoo
293 duplicate /free theta, theta_int
294 theta_int = theta - theta_offset
295 duplicate /free phi, phi_int
296 setscale /p x phi_int[0], phi_int[1] - phi_int[0], waveunits(phi, -1), dist, dist_smoo
297
298 extract /free /indx dist, red_idx, theta_int < theta_range
299 duplicate /free red_idx, red_dist, red_phi
300 red_dist = dist[red_idx]
301 red_phi = phi_int[red_idx]
302
303 variable wavg = mean(red_dist)
304 make /n=4 /d /free coef
305 coef[0] = {wavg, wavg/100, pi/180, 0}
306 CurveFit /q /h="0010" /g /w=2 sin, kwcWave=coef, red_dist /x=red_phi
307 dist_smoo = coef[0] + coef[1] * sin(coef[2] * phi_int[p] + coef[3])
308
309 // divide
310 if (check != 2)
311 strip = strip / dist_smoo[q] * coef[0]
312 endif
313
314 // check
315 if (check)
316 duplicate /o dist, check_dist
317 duplicate /o dist_smoo, check_smoo
318 setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
319 endif
320 };
321
353 variable normalize_strip_theta(wave strip, wave theta, variable theta_offset = defaultValue, variable smooth_method = defaultValue, variable smooth_factor = defaultValue, variable check = defaultValue){
354 wave strip
355 wave theta
356 variable theta_offset
357 variable smooth_method
358 variable smooth_factor
359 variable check
360
361 if (ParamIsDefault(check))
362 check = 0
363 endif
364 if (ParamIsDefault(theta_offset))
365 theta_offset = 0
366 endif
367 if (ParamIsDefault(smooth_method))
368 smooth_method = 4
369 endif
370 if (ParamIsDefault(smooth_factor))
371 smooth_factor = 0.5
372 endif
373
374 // average over analyser angles
375 wave dist = ad_profile_y(strip, -inf, inf, "")
376
377 // smooth distribution function
378 duplicate /free dist, dist_smoo
379 duplicate /free theta, theta_int
380 theta_int = theta - theta_offset
381 setscale /p x theta_int[0], theta_int[1] - theta_int[0], waveunits(theta,-1), dist, dist_smoo
382 variable nx = dimsize(strip, 0)
383 variable ix
384
385 switch(smooth_method)
386 case 1:
387 Smooth /B /E=3 smooth_factor, dist_smoo
388 break
389 case 2:
390 Smooth /E=3 smooth_factor, dist_smoo
391 break
392 case 4:
393 loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={theta_int}
394 break
395 case 3:
396 for (ix = 0; ix < nx; ix += 1)
397 dist = strip[ix][p]
398 if (smooth_factor > 1)
399 CurveFit /nthr=0 /q /w=2 poly smooth_factor+1, dist /x=theta_int /d=dist_smoo
400 else
401 CurveFit /nthr=0 /q /w=2 line, dist /x=theta_int /d=dist_smoo
402 endif
403 strip[ix,ix][] /= dist_smoo[q]
404 endfor
405 dist_smoo = 1
406 break
407 endswitch
408
409 // divide
410 if (check != 2)
411 strip /= dist_smoo[q]
412 endif
413
414 // check
415 if (check)
416 duplicate /o dist, check_dist
417 duplicate /o dist_smoo, check_smoo
418 setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
419 endif
420 };
421
435 variable normalize_strip_2d(wave strip, wave theta, variable theta_offset = defaultValue, variable smooth_method = defaultValue, variable smooth_factor = defaultValue, variable check = defaultValue){
436 wave strip
437 wave theta
438 variable theta_offset
439 variable smooth_method
440 variable smooth_factor
441 variable check
442
443 if (ParamIsDefault(check))
444 check = 0
445 endif
446 if (ParamIsDefault(theta_offset))
447 theta_offset = 0
448 endif
449 if (ParamIsDefault(smooth_method))
450 smooth_method = 4
451 endif
452 if (ParamIsDefault(smooth_factor))
453 smooth_factor = 0.5
454 endif
455
456 variable nx = dimsize(strip, 0)
457 variable ny = dimsize(strip, 1)
458
459 duplicate /free strip, dist, alpha_int, theta_int
460 theta_int = theta[q] - theta_offset
461 alpha_int = dimoffset(strip, 0) + p * dimdelta(strip, 0)
462 redimension /n=(nx * ny) dist, alpha_int, theta_int
463
464 switch(smooth_method)
465 case 4:
466 loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={alpha_int, theta_int}
467 redimension /n=(nx, ny) dist_smoo
468 break
469 default:
470 Abort "undefined smooth method"
471 break
472 endswitch
473
474 // divide
475 if (check != 2)
476 strip /= dist_smoo
477 endif
478
479 // check
480 if (check)
481 //duplicate /o dist, check_dist
482 duplicate /o dist_smoo, check_smoo
483 endif
484 };
485
495 variable crop_strip(wave strip, variable xlo, variable xhi){
496 wave strip
497 variable xlo
498 variable xhi
499
500 variable plo = round((xlo - dimoffset(strip, 0)) / dimdelta(strip, 0))
501 variable phi = round((xhi - dimoffset(strip, 0)) / dimdelta(strip, 0))
502 xlo = plo * dimdelta(strip, 0) + dimoffset(strip, 0)
503 xhi = phi * dimdelta(strip, 0) + dimoffset(strip, 0)
504 variable nx = phi - plo + 1
505 variable ny = dimsize(strip, 1)
506
507 duplicate /free strip, strip_copy
508 redimension /n=(nx,ny) strip
509 strip = strip_copy[p + plo][q]
510 setscale /i x xlo, xhi, waveunits(strip, 0), strip
511 };
512
555 variable pizza_service(wave data, string nickname, variable theta_offset, variable tilt_offset, variable phi_offset, variable npolar = defaultValue, variable nograph = defaultValue, variable folding = defaultValue, variable xpdplot = defaultValue){
556 wave data
557 string nickname
558 variable theta_offset
559 variable tilt_offset
560 variable phi_offset
561 variable npolar
562 variable nograph
563 variable folding
564 variable xpdplot
565
566 if (ParamIsDefault(npolar))
567 npolar = 91
568 endif
569 if (ParamIsDefault(nograph))
570 nograph = 0
571 endif
572 if (ParamIsDefault(folding))
573 folding = 1
574 endif
575 if (ParamIsDefault(xpdplot))
576 xpdplot = 0
577 endif
578
579 // sort out data folder structure
580 dfref saveDF = GetDataFolderDFR()
581 dfref dataDF = GetWavesDataFolderDFR(data)
582 setdatafolder dataDF
583 if (DataFolderExists(":attr"))
584 setdatafolder :attr
585 endif
586 dfref attrDF = GetDataFolderDFR()
587
588 wave /sdfr=attrDF ManipulatorTheta
589 wave /sdfr=attrDF ManipulatorTilt
590 wave /sdfr=attrDF ManipulatorPhi
591
592 if ((dimsize(ManipulatorTheta, 0) != dimsize(data, 1)) || (dimsize(ManipulatorTilt, 0) != dimsize(data, 1)) || (dimsize(ManipulatorPhi, 0) != dimsize(data, 1)))
593 Abort "Warning: The dimension size of the manipulator waves does not match the Y dimension of the data wave!\rIf you restructured the data wave, please use pizza_service_2 with properly scaled manipulator waves."
594 endif
595
596 duplicate /free ManipulatorTheta, m_theta
597 duplicate /free ManipulatorTilt, m_tilt
598 duplicate /free ManipulatorPhi, m_phi
599
600 m_theta -= theta_offset
601 m_tilt -= tilt_offset
602 m_phi -= phi_offset
603
604 pizza_service_2(data, nickname, m_theta, m_tilt, m_phi, npolar=npolar, nograph=nograph, folding=folding, xpdplot=xpdplot)
605
606 setdatafolder saveDF
607 };
608
648 variable pizza_service_2(wave data, string nickname, wave m_theta, wave m_tilt, wave m_phi, variable npolar = defaultValue, variable nograph = defaultValue, variable folding = defaultValue, variable xpdplot = defaultValue){
649 wave data
650 string nickname
651 wave m_theta
652 wave m_tilt
653 wave m_phi
654 variable npolar
655 variable nograph
656 variable folding
657 variable xpdplot
658
659 if (ParamIsDefault(npolar))
660 npolar = 91
661 endif
662 if (ParamIsDefault(nograph))
663 nograph = 0
664 endif
665 if (ParamIsDefault(folding))
666 folding = 1
667 endif
668 if (ParamIsDefault(xpdplot))
669 xpdplot = 0
670 endif
671
672 if ((dimsize(m_theta, 0) != dimsize(data, 1)) || (dimsize(m_tilt, 0) != dimsize(data, 1)) || (dimsize(m_phi, 0) != dimsize(data, 1)))
673 Abort "Warning: The dimension size of the manipulator waves does not match the Y dimension of the data wave!"
674 endif
675
676 string graphname = "graph_" + nickname
677 string outprefix = nickname
678
679 // sort out data folder structure
680 dfref saveDF = GetDataFolderDFR()
681 dfref dataDF = GetWavesDataFolderDFR(data)
682 setdatafolder dataDF
683
684 if (xpdplot)
685 setdatafolder root:
686 outprefix = nickname
687 else
688 setdatafolder dataDF
689 newdatafolder /s/o $nickname
690 outprefix = ""
691 endif
692 dfref destDF = GetDataFolderDFR()
693
694 // performance monitoring
695 variable timerRefNum
696 variable /g pol_perf_secs
697 timerRefNum = startMSTimer
698
699 duplicate /free m_tilt, corr_tilt
700 duplicate /free m_phi, corr_phi
701 corr_tilt = -m_tilt// checked 140702
702 corr_phi = m_phi// checked 140702
703
704 make /n=1/d/free d_polar, d_azi
705
706 convert_angles_ttpd2polar(m_theta, corr_tilt, corr_phi, data, d_polar, d_azi)
707 d_azi += 180// changed 151030 (v1.6)
708 make_hemi_grid(npolar, outprefix, xpdplot=xpdplot)
709 variable ifold
710 for (ifold = 0; ifold < folding; ifold += 1)
711 d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
712 hemi_add_anglescan(outprefix, data, d_polar, d_azi)
713 d_azi += 360 / folding
714 endfor
715
716 // normalize folding
717 if (strlen(outprefix))
718 string s_prefix = outprefix + "_"
719 string s_int = s_prefix + "i"
720 else
721 s_prefix = ""
722 s_int = "values"
723 endif
724 if (folding > 1)
725 wave values = $s_int
726 values /= folding
727 endif
728
729 if (!nograph)
730 display_hemi_scan(outprefix, graphname = graphname)
731 endif
732
733 if (timerRefNum >= 0)
734 pol_perf_secs = stopMSTimer(timerRefNum) / 1e6
735 endif
736
737 setdatafolder saveDF
738 };
739
765 variable show_analyser_line(variable theta, variable tilt, variable phi, variable theta_offset, variable tilt_offset, variable phi_offset, variable npolar = defaultValue, variable nograph = defaultValue, variable xpdplot = defaultValue){
766 variable theta
767 variable tilt
768 variable phi
769 variable theta_offset
770 variable tilt_offset
771 variable phi_offset
772 variable npolar
773 variable nograph
774 variable xpdplot
775
776 string nickname = "analyser"
777
778 if (ParamIsDefault(npolar))
779 npolar = 91
780 endif
781 if (ParamIsDefault(nograph))
782 nograph = 0
783 endif
784 if (ParamIsDefault(xpdplot))
785 xpdplot = 0
786 endif
787 string graphname = "graph_" + nickname
788 string outprefix = nickname
789
790 // sort out data folder structure
791 dfref saveDF = GetDataFolderDFR()
792 dfref dataDF = saveDF
793 if (xpdplot)
794 setdatafolder root:
795 outprefix = nickname
796 else
797 setdatafolder dataDF
798 newdatafolder /s/o $nickname
799 outprefix = ""
800 endif
801 dfref destDF = GetDataFolderDFR()
802
803 make /n=1 /free m_theta
804 make /n=1 /free m_tilt
805 make /n=1 /free m_phi
806 m_theta = theta - theta_offset
807 m_tilt = tilt - tilt_offset
808 m_tilt *= -1// checked 140702
809 m_phi = phi - phi_offset
810 //m_phi *= -1 // checked 140702
811
812 make /n=60 /free data
813 setscale /i x -30, 30, data
814 data = x
815 make /n=1/d/free d_polar, d_azi
816
817 convert_angles_ttpa2polar(m_theta, m_tilt, m_phi, data, d_polar, d_azi)
818 d_azi += 180// changed 151030 (v1.6)
819 d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
820 make_hemi_grid(npolar, outprefix, xpdplot=xpdplot)
821 hemi_add_anglescan(outprefix, data, d_polar, d_azi)
822
823 if (!nograph)
824 display_hemi_scan(outprefix, graphname = graphname)
825 endif
826
827 setdatafolder saveDF
828 };
829
834
835 variable convert_angles_ttpd2polar(wave theta, wave tilt, wave phi, wave data, wave polar, wave azi){
836 wave theta, tilt, phi// see convert_angles_ttpa2polar
837 wave data// in, 1D or 2D
838 // X-scale must be set to analyser angle scale
839 wave polar, azi// see convert_angles_ttpa2polar
840
841 make /n=(dimsize(data, 0)) /d /free ana
842 setscale /p x dimoffset(data, 0), dimdelta(data, 0), waveunits(data, 0), ana
843 ana = x
844 convert_angles_ttpa2polar(theta, tilt, phi, ana, polar, azi)
845 };
846
874 variable convert_angles_ttpa2polar(wave theta, wave tilt, wave phi, wave analyser, wave polar, wave azi){
875 wave theta
876 wave tilt
877 wave phi
878 wave analyser
879 wave polar, azi
880
881 variable nn = numpnts(theta)
882 variable na = numpnts(analyser)
883 redimension /n=(na, nn) polar, azi
884
885 variable radius = 1// don't need to specify - everything is scalable
886
887 // step 1: calculate cartesian detection vectors at normal emission
888 // this is simply a polar-cartesian mapping, independent of the manipulator
889 // phi=0 is in the polar rotation plane
890 make /n=(3,na) /d /free w_orig_polar, w_orig_cart, w_rot_cart, w_rot_polar
891 w_orig_polar[0][] = radius
892 w_orig_polar[1][] = analyser[q]
893 w_orig_polar[2][] = 0
894 polar2cart_wave(w_orig_polar, w_orig_cart)
895 // if the angle-dispersive axis was horizontal, we'd need to rotate the detector
896 //rotate_z_wave(w_orig_cart, 90)
897
898 variable ii
899 for (ii = 0; ii < nn; ii += 1)
900 // step 2: rotate the detection vectors according to the manipulator angles
901 // the order of rotations is important because we rotate about fixed axes
902 // y-axis = tilt rotation axis
903 // x-axis = polar rotation axis
904 // z-axis = normal emission = azimuthal rotation axis
905 w_rot_cart = w_orig_cart
906 rotate_y_wave(w_rot_cart, -tilt[ii])
907 rotate_x_wave(w_rot_cart, -theta[ii])
908 rotate_z_wave(w_rot_cart, -phi[ii] - 90)
909 // map the vectors back to the sample coordinate system
910 cart2polar_wave(w_rot_cart, w_rot_polar)
911 // copy to output
912 polar[][ii] = w_rot_polar[1][p]
913 azi[][ii] = w_rot_polar[2][p]
914 endfor
915 };
916
917 static variable line_average(wave source, wave dest){
918 // is this function used?
919 wave source
920 wave dest
921
922 variable ii
923 variable nn = dimsize(source, 1)
924 make /n=(dimsize(source, 0))/d/free line
925 for (ii = 0; ii < nn; ii += 1)
926 line = source[p][ii]
927 wavestats /q line
928 dest[][ii] = line[p] / v_max
929 endfor
930 };
931
935 static variable calc_nth(variable Theta_st, variable Theta_in, variable th, variable Phi_ran, variable Phi_ref, string Holomode){
936 Variable Theta_st, Theta_in, th, Phi_ran, Phi_ref
937 String Holomode
938 Variable The_step
939 Variable deg2rad=0.01745329
940
941 if ( cmpstr(Holomode, "Stereographic") == 0)
942 The_step =trunc( Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st )
943 if(th==90)
944 The_step =trunc( Phi_ran*sin(th*pi/180)*Phi_ref/Theta_st )
945 endif
946 else
947 if (cmpstr(Holomode, "Parallel") == 0)
948 The_step=trunc( Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st )
949 else
950 if ( cmpstr(Holomode, "h") == 0)
951 The_step=trunc( th/Theta_in*Phi_ran/Theta_st )
952 else
953 //altro
954 endif
955 endif
956 endif
957
958 return(The_step)
959 };
960
964 static variable calc_phi_step(variable Theta_in, variable th, variable Theta_st, variable Phi_ran, variable Phi_ref, string Holomode){
965 Variable Theta_in, th, Theta_st, Phi_ran, Phi_ref
966 String Holomode
967
968 Variable Phi_st
969 Variable deg2rad=0.01745329
970
971 if ( cmpstr(Holomode, "Stereographic") == 0 )
972 if ((th < 0.5) || (trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st) == 0))
973 Phi_st=0.0
974 else
975 Phi_st=Phi_ran/(trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st))
976 endif
977 if(th==90)
978 Phi_st=2.0
979 endif
980 endif
981
982 if ( cmpstr(Holomode, "Parallel") == 0 )
983 if((th < 0.5) || (trunc(Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st) == 0))
984 Phi_st=0.0
985 else
986 Phi_st=Phi_ran/(trunc(Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st))
987 endif
988 endif
989
990 if ( cmpstr(Holomode, "h") == 0 )
991 if((th < 0.5) || (trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st) == 0))
992 Phi_st=0.0
993 else
994 Phi_st=Phi_ran/trunc(th/Theta_in*Phi_ran/Theta_st)
995 endif
996 endif
997
998 if (Phi_st==0)
999 Phi_st=360
1000 endif
1001
1002 return(Phi_st)
1003 };
1004
1008 static variable Calc_The_step(variable th, variable Theta_st, string Holomode){
1009 String Holomode
1010 Variable th, Theta_st
1011
1012 Variable deg2rad=0.01745329, dt_loc,The_step
1013
1014 if ( (cmpstr(Holomode, "Stereographic")) ==0 )
1015 The_step=Theta_st
1016 endif
1017
1018 if ( (cmpstr(Holomode, "h")) ==0 )
1019 The_step=Theta_st
1020 endif
1021
1022 if ( cmpstr(Holomode, "Parallel") == 0 )
1023 if(th < 89.5)
1024 dt_loc = Theta_st/cos(th*deg2rad)
1025 if(dt_loc > 10)
1026 dt_loc=10
1027 endif
1028 The_step=dt_loc
1029 else
1030 The_step=10
1031 endif
1032 endif
1033 return(The_step)
1034 };
1035
1039 static variable CalcN_Theta(string HoloMode, variable Theta_in, variable Theta_ran, variable Theta_st){
1040 String HoloMode
1041 Variable Theta_in,Theta_ran,Theta_st
1042 Variable n_theta, aux, aux1,ii
1043
1044 aux = Theta_in
1045 aux1= Theta_in - Theta_ran
1046 ii = 0
1047 do
1048 aux = aux - Calc_The_step(aux, Theta_st, HoloMode)
1049 if(aux<=Theta_in-Theta_ran)
1050 aux=Theta_in-Theta_ran
1051 endif
1052 ii = ii+1
1053 while((aux>aux1)%&(Theta_in-aux<=Theta_ran))//
1054 n_theta=ii+1
1055 Return(n_theta)
1056 };
1057
1077 variable make_hemi_grid(variable npol, string nickname, variable xpdplot = defaultValue){
1078 variable npol
1079 string nickname
1080 variable xpdplot
1081
1082 if (ParamIsDefault(xpdplot))
1083 xpdplot = 0
1084 endif
1085
1086 string HoloMode = "h"
1087 variable Theta_in = 90
1088 variable Theta_ran = 90
1089 variable Theta_st = 90 / (npol - 1)
1090 variable Phi_ran = 360
1091 variable Phi_ref = 1
1092 variable Phi_in = 0
1093
1094 variable n_theta = CalcN_Theta(HoloMode, Theta_in, Theta_ran, Theta_st)
1095
1096 // wave names
1097 if (strlen(nickname))
1098 string s_prefix = nickname + "_"
1099 string s_int = s_prefix + "i"// Intensity wave (counts/sec)
1100 else
1101 s_prefix = ""
1102 s_int = "values"// "i" is not a valid wave name
1103 endif
1104 string s_polar = s_prefix + "pol"// thetas for each int-point of the holo
1105 string s_azim = s_prefix + "az"// phis for each int-point of the holo
1106
1107 string s_index = s_prefix + "index"// starting index for each theta
1108 string s_theta = s_prefix + "th"// theta values
1109 string s_dphi = s_prefix + "dphi"// delta phis at each theta
1110 string s_nphis = s_prefix + "nphis"// number of phis at each theta
1111
1112 string s_HoloData = s_prefix + "data"// All holo exp.- parameter information
1113 string s_HoloInfo = s_prefix + "info"
1114
1115 // the following two waves are used by the pearl-anglescan procedures but not by XPDplot
1116 string s_tot = s_prefix + "tot"// accumulated counts at each point
1117 string s_weight = s_prefix + "wt"// total accumulation time at each point (arb. units)
1118
1119 make /O/D/n=(n_theta) $s_index /wave=index
1120 make /O/D/n=(n_theta) $s_theta /wave=theta
1121 make /O/D/n=(n_theta) $s_dphi /wave=dphi
1122 make /O/D/n=(n_theta) $s_nphis /wave=nphis
1123
1124 //---------- calculate phi-step-size for this theta:
1125 variable aux = Calc_The_step(Theta_in, Theta_st, HoloMode)
1126 dphi[0] = calc_phi_step(Theta_in, Theta_in, aux, Phi_ran, Phi_ref, HoloMode)
1127 Theta[0] = Theta_in
1128 nphis[0] = calc_nth(aux, Theta_in, Theta_in, Phi_ran, Phi_ref, HoloMode)
1129 Index[0] = nphis[0]
1130
1131 //---------- calculate number of phis, phi-step, and starting-index for each theta:
1132 variable ii = 1
1133 do
1134 Theta[ii] = Theta[ii-1] - aux
1135 if(Theta[ii] <= Theta_in-Theta_ran)
1136 Theta[ii] = Theta_in-Theta_ran
1137 endif
1138 aux = Calc_The_step(Theta[ii], Theta_st, HoloMode)
1139 dphi[ii] = calc_phi_step(Theta_in, Theta[ii], aux, Phi_ran, Phi_ref, HoloMode)
1140 nphis[ii] = calc_nth(aux, Theta_in, Theta[ii], Phi_ran, Phi_ref, HoloMode)
1141 Index[ii] = Index[ii-1] + nphis[ii]
1142 ii=ii+1
1143 while(ii < n_theta)
1144
1145 if (Index[n_theta-1]==Index[n_theta-2])
1146 Index[n_theta-1]=Index[n_theta-2]+1
1147 nphis[n_theta-1]=1
1148 endif
1149
1150 variable NumPoints = sum(nphis, 0, numpnts(nphis))
1151
1152 //---------- calculate theta and phi for each data point:
1153 make /O/D/N=(NumPoints) $s_polar /wave=polar, $s_azim /wave=azim
1154 note azim, "version=1.6"
1155
1156 ii = 0
1157 variable StartIndex = 0
1158 variable EndIndex
1159 do
1160 EndIndex=Index[ii]
1161 Polar[StartIndex, EndIndex-1]=Theta[ii]
1162 Azim[StartIndex, EndIndex-1]= mod(Phi_ran+(x-StartIndex)*dphi[ii]+Phi_in,Phi_ran)
1163 ii = ii + 1
1164 StartIndex = EndIndex
1165 while(ii < n_theta)
1166
1167 duplicate /o azim, $s_int /wave=values
1168 duplicate /o azim, $s_tot /wave=totals
1169 duplicate /o azim, $s_weight /wave=weights
1170 values = nan
1171 totals = 0
1172 weights = 0
1173
1174 // XPDplot metadata
1175 if (xpdplot)
1176 string s_FileName = ""
1177 string s_Comment = "created by pearl-anglescan-process.ipf"
1178 string s_HoloMode = "Stereographic"
1179 variable /g gb_SpectraFile = 0
1180
1181 Make/O/D/n=22 $s_HoloData /wave=HoloData
1182 HoloData[0] = NaN// v_StartKE
1183 HoloData[1] = NaN// v_StoppKE
1184 HoloData[6] = NumPoints
1185 HoloData[7] = Theta_in
1186 HoloData[8] = Theta_ran
1187 HoloData[9] = Theta_st
1188 HoloData[11] = Phi_in
1189 HoloData[12] = Phi_ran
1190 HoloData[13] = Theta_st
1191 HoloData[15] = Phi_ref
1192 HoloData[16] = Phi_ran
1193 HoloData[17] = 0// v_HoloBit (stereographic)
1194
1195 Make/O/T/n=22 $s_HoloInfo /wave=HoloInfo
1196 HoloInfo[0] = s_FileName
1197 HoloInfo[1] = s_Comment
1198 HoloInfo[10] = s_HoloMode
1199 HoloInfo[11] = ""// s_MeasuringMode
1200
1201 // notebook for XPDplot
1202 if (WinType(NickName) == 5)
1203 Notebook $NickName selection={startOfFile, endOfFile}
1204 Notebook $NickName text=""
1205 else
1206 NewNotebook /F=0 /K=1 /N=$NickName /W=(5,40,341,260)
1207 Notebook $NickName defaultTab=140
1208 Notebook $NickName statusWidth=300
1209 Notebook $NickName backRGB=(56797,56797,56797)
1210 Notebook $NickName pageMargins={80,80,80,80}
1211 Notebook $NickName fSize=10
1212 Notebook $NickName fStyle=0,textRGB=(65535,0,26214)
1213 Notebook $NickName textRGB=(65535,0,26214)
1214 endif
1215 Notebook $NickName text = "File:\t" + s_FileName + "\r"
1216 Notebook $NickName text = "*** " + s_Comment + " ***\r\r"
1217 Notebook $NickName text = "Angle-Mode:\t" + s_HoloMode + "\r"
1218 Notebook $NickName text = "XPDplot Nickname:\t" + NickName + "\r"
1219 endif
1220 };
1221
1228 string get_hemi_nickname(wave w){
1229 wave w
1230
1231 string prefix = get_hemi_prefix(w)
1232 string wname = nameofwave(w)
1233 string nickname
1234
1235 if (strlen(prefix))
1236 nickname = prefix
1237 else
1238 string s_wave_df = GetWavesDataFolder(w, 1)
1239 dfref parent_df = $(s_wave_df + "::")
1240 nickname = GetDataFolder(0, parent_df)
1241 endif
1242
1243 return nickname
1244 };
1245
1253 string get_hemi_prefix(wave w){
1254 wave w
1255
1256 string wname = nameofwave(w)
1257 string prefix
1258 if (ItemsInList(wname, "_") >= 2)
1259 prefix = StringFromList(0, wname, "_")
1260 else
1261 prefix = ""
1262 endif
1263
1264 return prefix
1265 };
1266
1284 dfr find_hemi_data(string nickname, string* prefix, string* intwave){
1285 string nickname
1286 string &prefix
1287 string &intwave
1288
1289 dfref datadf
1290 prefix = ""
1291 intwave = "values"
1292 if (strlen(nickname))
1293 if (DataFolderExists(nickname))
1294 datadf = $nickname
1295 else
1296 datadf = getdatafolderdfr()
1297 prefix = nickname + "_"
1298 intwave = prefix + "i"
1299 if (exists(intwave) != 1)
1300 datadf = root:
1301 endif
1302 endif
1303 else
1304 datadf = getdatafolderdfr()
1305 prefix = ""
1306 intwave = "values"
1307 endif
1308 return datadf
1309 };
1310
1318 variable clear_hemi_grid(string nickname){
1319 string nickname
1320
1321 dfref datadf
1322 string s_prefix
1323 string s_int
1324 datadf = find_hemi_data(nickname, s_prefix, s_int)
1325
1326 string s_totals = s_prefix + "tot"
1327 string s_weights = s_prefix + "wt"
1328
1329 wave /sdfr=datadf /z w_values = $s_int
1330 wave /sdfr=datadf /z w_totals = $s_totals
1331 wave /sdfr=datadf /z w_weights = $s_weights
1332
1333 if (waveexists(w_totals))
1334 w_totals = 0
1335 endif
1336 if (waveexists(w_weights))
1337 w_weights = 0
1338 endif
1339 if (waveexists(w_values))
1340 w_values = nan
1341 endif
1342 };
1343
1365 variable duplicate_hemi_scan(string source_nickname, dfref dest_folder, string dest_nickname, variable xpdplot = defaultValue){
1366 string source_nickname
1367 dfref dest_folder
1368 string dest_nickname
1369 variable xpdplot
1370
1371 if (ParamIsDefault(xpdplot))
1372 xpdplot = 0
1373 endif
1374
1375 dfref savedf = getdatafolderdfr()
1376
1377 // source data
1378 string s_prefix = ""
1379 string s_int = "values"
1380 dfref source_df = find_hemi_data(source_nickname, s_prefix, s_int)
1381 string s_polar = s_prefix + "pol"
1382 string s_azim = s_prefix + "az"
1383 string s_theta = s_prefix + "th"
1384 string s_tot = s_prefix + "tot"
1385 string s_weight = s_prefix + "wt"
1386 string s_matrix = s_prefix + "matrix"
1387
1388 wave /sdfr=source_df theta1 = $s_theta
1389 wave /sdfr=source_df polar1 = $s_polar
1390 wave /sdfr=source_df azim1 = $s_azim
1391 wave /sdfr=source_df tot1 = $s_tot
1392 wave /sdfr=source_df weight1 = $s_weight
1393 wave /sdfr=source_df values1 = $s_int
1394 wave /sdfr=source_df /z matrix1 = $s_matrix
1395
1396 variable npol = numpnts(theta1)
1397
1398 setdatafolder dest_folder
1399 make_hemi_grid(npol, dest_nickname, xpdplot=xpdplot)
1400
1401 // dest data
1402 dfref dest_df = find_hemi_data(dest_nickname, s_prefix, s_int)
1403 s_polar = s_prefix + "pol"
1404 s_azim = s_prefix + "az"
1405 s_theta = s_prefix + "th"
1406 s_tot = s_prefix + "tot"
1407 s_weight = s_prefix + "wt"
1408 s_matrix = s_prefix + "matrix"
1409
1410 wave /sdfr=dest_df theta2 = $s_theta
1411 wave /sdfr=dest_df polar2 = $s_polar
1412 wave /sdfr=dest_df azim2 = $s_azim
1413 wave /sdfr=dest_df tot2 = $s_tot
1414 wave /sdfr=dest_df weight2 = $s_weight
1415 wave /sdfr=dest_df values2 = $s_int
1416
1417 tot2 = tot1
1418 weight2 = weight1
1419 values2 = values1
1420 if (waveexists(matrix1))
1421 setdatafolder dest_df
1422 duplicate /o matrix1, $s_matrix
1423 endif
1424
1425 if (!(NumberByKey("version", note(azim1), "=", "\r") >= 1.6))
1426 azim2 += 180// changed 151030 (v1.6)
1427 azim2 = azim2 >= 360 ? azim2 - 360 : azim2
1428 endif
1429
1430 setdatafolder saveDF
1431 };
1432
1440 variable rotate_hemi_scan(string nickname, variable angle){
1441 string nickname
1442 variable angle
1443
1444 dfref savedf = getdatafolderdfr()
1445
1446 string s_prefix = ""
1447 string s_int = "values"
1448 dfref df = find_hemi_data(nickname, s_prefix, s_int)
1449
1450 string s_polar = s_prefix + "pol"
1451 string s_azim = s_prefix + "az"
1452 string s_tot = s_prefix + "tot"
1453 string s_weight = s_prefix + "wt"
1454
1455 wave /sdfr=df polar = $s_polar
1456 wave /sdfr=df azim = $s_azim
1457 wave /sdfr=df tot = $s_tot
1458 wave /sdfr=df weight = $s_weight
1459 wave /sdfr=df values = $s_int
1460
1461 azim += angle
1462 azim = azim < 0 ? azim + 360 : azim
1463 azim = azim >= 360 ? azim - 360 : azim
1464
1465 duplicate /free polar, neg_polar
1466 neg_polar = -polar
1467 sort {neg_polar, azim}, polar, azim, tot, weight, values
1468
1469 setdatafolder saveDF
1470 };
1471
1516 string display_hemi_scan(string nickname, variable projection = defaultValue, variable graphtype = defaultValue, variable do_ticks = defaultValue, variable do_grids = defaultValue, string graphname = defaultValue){
1517 string nickname
1518 variable projection
1519 variable graphtype
1520 variable do_ticks
1521 variable do_grids
1522 string graphname
1523
1524 dfref savedf = getdatafolderdfr()
1525
1526 if (ParamIsDefault(projection))
1527 projection = 1
1528 endif
1529 if (ParamIsDefault(graphtype))
1530 graphtype = 1
1531 endif
1532 if (ParamIsDefault(do_ticks))
1533 do_ticks = 3
1534 endif
1535 if (ParamIsDefault(do_grids))
1536 do_grids = 3
1537 endif
1538 if (ParamIsDefault(graphname))
1539 if (strlen(nickname) > 0)
1540 graphname = nickname
1541 else
1542 graphname = GetDataFolder(0)
1543 endif
1544 endif
1545
1546 // hemi grid waves
1547 string s_prefix = ""
1548 string s_int = "values"
1549 dfref df = find_hemi_data(nickname, s_prefix, s_int)
1550
1551 string s_polar = s_prefix + "pol"
1552 string s_azim = s_prefix + "az"
1553 string s_matrix = s_prefix + "matrix"
1554
1555 wave /sdfr=df /z values = $s_int
1556 wave /sdfr=df /z azim = $s_azim
1557 wave /sdfr=df /z polar = $s_polar
1558 wave /sdfr=df /z matrix = $s_matrix
1559
1560 setdatafolder df
1561 string s_ster_rad = s_prefix + "ster_rad"
1562 duplicate /o polar, $s_ster_rad /wave=ster_rad
1563 ster_rad = calc_graph_radius(polar, projection=projection)
1564
1565 string s_ster_x = s_prefix + "ster_x"
1566 string s_ster_y = s_prefix + "ster_y"
1567 duplicate /o azim, $s_ster_x /wave=ster_x, $s_ster_y /wave=ster_y
1568 ster_x = ster_rad * cos(azim * pi / 180)
1569 ster_y = ster_rad * sin(azim * pi / 180)
1570
1571 variable azim_offset = 0
1572 if (!(NumberByKey("version", note(azim), "=", "\r") >= 1.6))
1573 DoAlert /T="display hemi scan" 0, "your dataset doesn't include the version 1.6 flag. if it was created with an earlier version that might be okay. please check that the orientation is correct!"
1574 azim_offset = 180// changed 151030 (v1.6)
1575 endif
1576
1577 string s_trace
1578 switch(graphtype)
1579 case 1:
1580 graphname = display_polar_graph(graphname, angle_offset=azim_offset, do_ticks=do_ticks)
1581
1582 s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360)
1583 ModifyGraph /W=$graphname mode($s_trace)=2, lsize($s_trace)=2
1584 ModifyGraph /W=$graphname zColor($s_trace)={values,*,*,BlueGreenOrange,0}
1585
1586 ColorScale /W=$graphname /C /N=text0 /E=2 /F=0 /B=1 /A=RB /X=0.00 /Y=0.00 trace=polarY0
1587 ColorScale /W=$graphname /C /N=text0 side=2, width=5, heightPct=40, frame=0.50, lblMargin=0
1588 ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50
1589
1590 SetWindow $graphname, userdata(projection)=num2str(projection)
1591 draw_hemi_axes(graphname, do_grids=do_grids)
1592 break
1593 case 3:
1594 graphname = display_polar_graph(graphname, angle_offset=azim_offset, do_ticks=do_ticks)
1595
1596 s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360)
1597 ModifyGraph /W=$graphname mode($s_trace)=0, lsize($s_trace)=0
1598 AppendImage /L=VertCrossing /B=HorizCrossing matrix
1599
1600 ColorScale /W=$graphname /C /N=text0 /E=2 /F=0 /B=1 /A=RB /X=0.00 /Y=0.00 image=$s_matrix
1601 ColorScale /W=$graphname /C /N=text0 side=2, width=5, heightPct=40, frame=0.50, lblMargin=0
1602 ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50
1603
1604 SetWindow $graphname, userdata(projection)=num2str(projection)
1605 draw_hemi_axes(graphname, do_grids=do_grids)
1606 break
1607 endswitch
1608
1609 setdatafolder savedf
1610 return graphname
1611 };
1612
1654 static string display_polar_graph(string graphname, variable angle_offset = defaultValue, variable do_ticks = defaultValue){
1655
1656 string graphname
1657 variable angle_offset
1658 variable do_ticks
1659
1660 dfref savedf = GetDataFolderDFR()
1661
1662 if (ParamIsDefault(angle_offset))
1663 angle_offset = 0
1664 endif
1665 if (ParamIsDefault(do_ticks))
1666 do_ticks = 3
1667 endif
1668
1669 if ((strlen(graphname) == 0) || (wintype(graphname) == 0))
1670 Display /k=1 /W=(10,45,360,345)
1671 DoWindow /C $graphname
1672 graphname = WMNewPolarGraph("", graphname)
1673 WMPolarGraphSetVar(graphname, "zeroAngleWhere", angle_offset)
1674
1675 WMPolarGraphSetVar(graphname, "angleAxisThick", 0.5)
1676 WMPolarGraphSetStr(graphname, "doMajorAngleTicks", "manual")
1677 WMPolarGraphSetVar(graphname, "majorAngleInc", 30)// major ticks in 30 deg steps
1678 WMPolarGraphSetVar(graphname, "minorAngleTicks", 2)// minor ticks in 10 deg steps
1679 WMPolarGraphSetStr(graphname, "angleTicksLocation", "Outside")
1680 WMPolarGraphSetVar(graphname, "doAngleTickLabelSubRange", 1)
1681 WMPolarGraphSetVar(graphname, "angleTickLabelRangeStart", 0)
1682 WMPolarGraphSetVar(graphname, "angleTickLabelRangeExtent", 90)
1683 WMPolarGraphSetStr(graphname, "angleTickLabelNotation", "%g")
1684
1685 WMPolarGraphSetVar(graphname, "doPolarGrids", 0)
1686 WMPolarGraphSetVar(graphname, "doRadiusTickLabels", 0)
1687 WMPolarGraphSetStr(graphname, "radiusAxesWhere", " Off")// note the leading spaces, cf. WMPolarAnglesForRadiusAxes
1688 WMPolarGraphSetStr(graphname, "radiusTicksLocation", "Off")
1689
1690 WMPolarGraphSetVar(graphname, "majorTickLength", 2)
1691 WMPolarGraphSetVar(graphname, "majorTickThick", 0.5)
1692 WMPolarGraphSetVar(graphname, "minorTickLength", 1)
1693 WMPolarGraphSetVar(graphname, "minorTickThick", 0.5)
1694 WMPolarGraphSetVar(graphname, "tickLabelOpaque", 0)
1695 WMPolarGraphSetVar(graphname, "tickLabelFontSize", 7)
1696
1697 // changes
1698 if (do_ticks & 1)
1699 WMPolarGraphSetStr(graphname, "angleTicksLocation", "Outside")
1700 else
1701 WMPolarGraphSetStr(graphname, "angleTicksLocation", "Off")
1702 endif
1703 if (do_ticks & 2)
1704 WMPolarGraphSetVar(graphname, "doMinorAngleTicks", 1)
1705 else
1706 WMPolarGraphSetVar(graphname, "doMinorAngleTicks", 0)
1707 endif
1708
1709 DoWindow /T $graphname, graphname
1710
1711 // cursor info in angles
1712 string graphdf = "root:packages:WMPolarGraphs:" + graphname
1713 setdatafolder graphdf
1714 // current theta, phi coordinates are stored in global variables in the package folder of the graph
1715 variable /g csrA_theta
1716 variable /g csrA_phi
1717 variable /g csrB_theta
1718 variable /g csrB_phi
1719 // the text box is hidden initially. it shows up and hides with the cursor info box.
1720 string tb
1721 tb = "\\{"
1722 tb = tb + "\"A = (%.1f, %.1f)\","
1723 tb = tb + graphdf + ":csrA_theta,"
1724 tb = tb + graphdf + ":csrA_phi"
1725 tb = tb + "}"
1726 TextBox /W=$graphname /A=LT /B=1 /E=2 /F=0 /N=tb_angles /X=1 /Y=1 /V=0 tb
1727 tb = "\\{"
1728 tb = tb + "\"B = (%.1f, %.1f)\","
1729 tb = tb + graphdf + ":csrB_theta,"
1730 tb = tb + graphdf + ":csrB_phi"
1731 tb = tb + "}"
1732 AppendText /W=$graphname /N=tb_angles tb
1733 // updates are triggered by a window hook
1734 SetWindow $graphname, hook(polar_graph_hook)=PearlAnglescanProcess#polar_graph_hook
1735 else
1736 // graph window exists
1737 DoWindow /F $graphname
1738 endif
1739
1740 setdatafolder savedf
1741 return graphname
1742 };
1743
1769 static string draw_hemi_axes(string graphname, variable do_grids = defaultValue){
1770 string graphname
1771 variable do_grids
1772
1773 if (ParamIsDefault(do_grids))
1774 do_grids = 3
1775 endif
1776
1777 dfref savedf = GetDataFolderDFR()
1778
1779 string sproj = GetUserData(graphname, "", "projection")
1780 variable projection = str2num("0" + sproj)
1781
1782 SetDrawLayer /W=$graphname ProgFront
1783
1784 // polar axis
1785 SetDrawEnv /W=$graphname xcoord=HorizCrossing, ycoord=VertCrossing
1786 SetDrawEnv /W=$graphname linethick= 0.5
1787 SetDrawEnv /W=$graphname dash=2
1788 SetDrawEnv /W=$graphname fillpat=0
1789 SetDrawEnv /W=$graphname fname="default", fsize=7
1790 SetDrawEnv /W=$graphname textxjust=1, textyjust=1
1791 //SetDrawEnv /W=$graphname linefgc=(65535,65535,65535)
1792 SetDrawEnv /W=$graphname save
1793
1794 if (do_grids & 1)
1795 DrawLine /W=$graphname 0, -2, 0, 2
1796 DrawLine /W=$graphname -2, 0, 2, 0
1797 endif
1798
1799 variable radi
1800 if (do_grids & 2)
1801 radi = calc_graph_radius(0.5, projection=projection)
1802 DrawOval /W=$graphname -radi, radi, radi, -radi
1803 radi = calc_graph_radius(30, projection=projection)
1804 DrawOval /W=$graphname -radi, radi, radi, -radi
1805 radi = calc_graph_radius(60, projection=projection)
1806 DrawOval /W=$graphname -radi, radi, radi, -radi
1807
1808 SetDrawEnv /W=$graphname textxjust= 1,textyjust= 2
1809 SetDrawEnv /W=$graphname save
1810 radi = calc_graph_radius(30, projection=projection)
1811 DrawText /W=$graphname radi, -0.1, "30"
1812 radi = calc_graph_radius(60, projection=projection)
1813 DrawText /W=$graphname radi, -0.1, "60"
1814 endif
1815
1816 setdatafolder savedf
1817 };
1818
1841 variable draw_diffraction_cone(string graphname, string groupname, variable theta_axis, variable theta_inner, variable phi){
1842 string graphname
1843 string groupname
1844
1845 variable theta_axis
1846 variable theta_inner
1847 variable phi
1848
1849 variable r_axis = calc_graph_radius(theta_axis)
1850 variable r_inner = calc_graph_radius(theta_inner)
1851 variable r_outer = calc_graph_radius(2 * theta_axis - theta_inner)
1852
1853 SetDrawEnv push
1854 SetDrawLayer UserFront
1855 DrawAction getgroup=$groupname, delete
1856 SetDrawEnv gstart, gname=$groupname
1857 variable xc, yc, xr, yr
1858
1859 // cone periphery
1860 variable r_center = (r_outer + r_inner) / 2
1861 variable r_radius = (r_outer - r_inner) / 2
1862 xc = r_center * cos(phi * pi / 180)
1863 yc = r_center * sin(phi * pi / 180)
1864 xr = r_radius
1865 yr = r_radius
1866 SetDrawEnv xcoord=HorizCrossing, ycoord=VertCrossing
1867 SetDrawEnv dash=11, fillpat=0
1868 DrawOval xc - xr, yc - yr, xc + xr, yc + yr
1869
1870 // cone axis
1871 xc = r_axis * cos(phi * pi / 180)
1872 yc = r_axis * sin(phi * pi / 180)
1873 r_radius = calc_graph_radius(2)
1874 xr = r_radius
1875 yr = r_radius
1876 SetDrawEnv xcoord=HorizCrossing, ycoord=VertCrossing
1877 SetDrawEnv fillfgc=(0,0,0)
1878 DrawOval xc - xr, yc - yr, xc + xr, yc + yr
1879
1880 SetDrawEnv gstop
1881 SetDrawEnv pop
1882 };
1883
1905 string display_scanlines(string nickname, variable alpha_lo, variable alpha_hi, wave m_theta, wave m_tilt, wave m_phi, variable folding = defaultValue, variable projection = defaultValue){
1906 string nickname
1907 variable alpha_lo
1908 variable alpha_hi
1909 wave m_theta
1910 wave m_tilt
1911 wave m_phi
1912 variable folding
1913 variable projection
1914
1915 if (ParamIsDefault(folding))
1916 folding = 1
1917 endif
1918 if (ParamIsDefault(projection))
1919 projection = 1
1920 endif
1921
1922 // sort out data folder structure
1923 dfref saveDF = GetDataFolderDFR()
1924 newdatafolder /s/o $nickname
1925 string graphname = "graph_" + nickname
1926
1927 duplicate /free m_tilt, loc_m_tilt
1928 loc_m_tilt = -m_tilt
1929
1930 make /n=1 /d /free d_polar, d_azi
1931 variable n_alpha = round(alpha_hi - alpha_lo) + 1
1932 make /n=(n_alpha) /d /free analyser
1933 setscale /i x alpha_lo, alpha_hi, "", analyser
1934 analyser = x
1935
1936 convert_angles_ttpa2polar(m_theta, loc_m_tilt, m_phi, analyser, d_polar, d_azi)
1937 duplicate /free d_polar, d_radius
1938 d_radius = calc_graph_radius(d_polar, projection=projection)
1939 d_azi += 180// changed 151030 (v1.6)
1940
1941 graphname = display_polar_graph(graphname)
1942 SetWindow $graphname, userdata(projection)=num2str(projection)
1943
1944 variable ifold
1945 variable iang
1946 variable nang = numpnts(m_theta)
1947 string s_rad
1948 string s_azi
1949 string s_trace
1950 for (ifold = 0; ifold < folding; ifold += 1)
1951 d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
1952 for (iang = 0; iang < nang; iang += 1)
1953 sprintf s_rad, "rad_%d_%d", ifold, iang
1954 duplicate /o analyser, $s_rad
1955 wave w_rad = $s_rad
1956 w_rad = d_radius[p][iang]
1957
1958 sprintf s_azi, "azi_%d_%d", ifold, iang
1959 duplicate /o analyser, $s_azi
1960 wave w_azi = $s_azi
1961 w_azi = d_azi[p][iang]
1962
1963 if (numtype(sum(w_rad)) == 0)
1964 s_trace = WMPolarAppendTrace(graphname, w_rad, w_azi, 360)
1965 ModifyGraph /w=$graphname mode($s_trace)=0, lsize($s_trace)=0.5
1966 endif
1967 endfor
1968 d_azi += 360 / folding
1969 endfor
1970
1971 draw_hemi_axes(graphname)
1972
1973 setdatafolder saveDF
1974 return graphname
1975 };
1976
1993 const variable kProjDist = 0;
1994 const variable kProjStereo = 1;
1995 const variable kProjArea = 2;
1996 const variable kProjGnom = 3;
1997 const variable kProjOrtho = 4;
1998
1999 static const variable kProjScaleDist = 2;
2000 static const variable kProjScaleStereo = 2;
2001 static const variable kProjScaleArea = 2;
2002 // scaled so that radius(gnom) = radius(stereo) for polar = 88
2003 static const variable kProjScaleGnom = 0.06744519021;
2004 static const variable kProjScaleOrtho = 2;
2005
2020 threadsafe variable calc_graph_radius(variable polar, variable projection = defaultValue){
2021 variable polar
2022 variable projection
2023
2024 if (ParamIsDefault(projection))
2025 projection = 1
2026 endif
2027
2028 variable radius
2029 switch(projection)
2030 case kProjStereo:// stereographic
2031 radius = kProjScaleStereo * tan(polar / 2 * pi / 180)
2032 break
2033 case kProjArea:// equal area
2034 radius = kProjScaleArea * sin(polar / 2 * pi / 180)
2035 break
2036 case kProjGnom:// gnomonic
2037 radius = polar < 90 ? kProjScaleGnom * tan(polar * pi / 180) : inf
2038 break
2039 case kProjOrtho:// orthographic
2040 radius = kProjScaleOrtho * sin(polar * pi / 180)
2041 break
2042 default:// equidistant
2043 radius = kProjScaleDist * polar / 90
2044 endswitch
2045
2046 return radius
2047 };
2048
2065 threadsafe variable calc_graph_polar(variable x, variable y, variable projection = defaultValue){
2066 variable x
2067 variable y
2068 variable projection
2069
2070 if (ParamIsDefault(projection))
2071 projection = 1
2072 endif
2073
2074 variable radius
2075 variable polar
2076
2077 radius = sqrt(x^2 + y^2)
2078 switch(projection)
2079 case kProjStereo:// stereographic
2080 polar = 2 * atan(radius / kProjScaleStereo) * 180 / pi
2081 break
2082 case kProjArea:// equal area
2083 polar = 2 * asin(radius / kProjScaleArea) * 180 / pi
2084 break
2085 case kProjGnom:// gnomonic
2086 polar = atan(radius / kProjScaleGnom) * 180 / pi
2087 break
2088 case kProjOrtho:// orthographic
2089 polar = asin(radius / kProjScaleOrtho) * 180 / pi
2090 break
2091 default:// equidistant
2092 polar = 90 * radius / kProjScaleDist
2093 endswitch
2094
2095 return polar
2096 };
2097
2118 threadsafe variable calc_graph_azi(variable x, variable y, variable projection = defaultValue, variable zeroAngle = defaultValue){
2119 variable x
2120 variable y
2121 variable projection
2122 variable zeroAngle
2123
2124 if (ParamIsDefault(projection))
2125 projection = 1
2126 endif
2127 if (ParamIsDefault(zeroAngle))
2128 zeroAngle = 0
2129 endif
2130
2131 variable azi
2132 if (x > 0)
2133 azi = atan(y / x) * 180 / pi
2134 else
2135 azi = atan(y / x) * 180 / pi + 180
2136 endif
2137
2138 azi += zeroAngle
2139 if (azi < 0)
2140 azi += 360
2141 endif
2142 if (azi >= 360)
2143 azi -= 360
2144 endif
2145 if (numtype(azi) != 0)
2146 azi = 0
2147 endif
2148
2149 return azi
2150 };
2151
2163 static variable update_polar_info(string graphname){
2164 string graphname
2165
2166 dfref savedf = GetDataFolderDFR()
2167
2168 string graphdf = "root:packages:WMPolarGraphs:" + graphname
2169 setdatafolder graphdf
2170
2171 nvar csrA_theta
2172 nvar csrA_phi
2173 nvar csrB_theta
2174 nvar csrB_phi
2175
2176 string sproj = GetUserData(graphname, "", "projection")
2177 variable projection = str2num("0" + sproj)
2178 nvar zeroAngleWhere
2179
2180 variable x = hcsr(A, graphname)
2181 variable y = vcsr(A, graphname)
2182 csrA_theta = calc_graph_polar(x, y, projection=projection)
2183 csrA_phi = calc_graph_azi(x, y, projection=projection, zeroAngle=zeroAngleWhere)
2184
2185 x = hcsr(B, graphname)
2186 y = vcsr(B, graphname)
2187 csrB_theta = calc_graph_polar(x, y, projection=projection)
2188 csrB_phi = calc_graph_azi(x, y, projection=projection, zeroAngle=zeroAngleWhere)
2189
2190 setdatafolder savedf
2191 };
2192
2198 static variable polar_graph_hook(WMWinHookStruct* s){
2199 STRUCT WMWinHookStruct &s
2200
2201 Variable hookResult = 0
2202
2203 switch(s.eventCode)
2204 case 7:// cursor moved
2205 update_polar_info(s.winname)
2206 break
2207 case 20:// show info
2208 TextBox /W=$s.winname /N=tb_angles /C /V=1
2209 break
2210 case 21:// hide info
2211 TextBox /W=$s.winname /N=tb_angles /C /V=0
2212 break
2213 endswitch
2214
2215 return hookResult// 0 if nothing done, else 1
2216 };
2217
2218 variable set_polar_graph_cursor(string nickname, string cursorname, variable polar_angle, variable azim_angle, string graphname = defaultValue){
2219 string nickname
2220 string cursorname
2221 variable polar_angle
2222 variable azim_angle
2223 string graphname
2224
2225 if (ParamIsDefault(graphname))
2226 if (strlen(nickname) > 0)
2227 graphname = nickname
2228 else
2229 graphname = GetDataFolder(0)
2230 endif
2231 endif
2232
2233 string s_prefix = ""
2234 string s_int = "values"
2235 dfref df = find_hemi_data(nickname, s_prefix, s_int)
2236
2237 string s_polar = s_prefix + "pol"
2238 string s_azim = s_prefix + "az"
2239 wave /sdfr=df /z azim = $s_azim
2240 wave /sdfr=df /z polar = $s_polar
2241
2242 FindLevel /P /Q polar, polar_angle
2243 if (v_flag == 0)
2244 variable polar_level = floor(v_levelx)
2245 FindLevel /P /Q /R=[polar_level] azim, azim_angle
2246 if (v_flag == 0)
2247 variable azim_level = round(v_levelx)
2248 string tracename = "polarY0"
2249 Cursor /W=$graphname /P $cursorname $traceName azim_level
2250 endif
2251 endif
2252 };
2253
2263 variable hemi_add_anglescan(string nickname, wave values, wave polar, wave azi, wave weights = defaultValue){
2264 string nickname// name prefix of holo waves.
2265 // may be empty.
2266 wave values// intensity values
2267 // the wave can be one- or two-dimensional.
2268 // no specific order required, the function sorts the arrays internally
2269 wave polar// polar coordinates. allowed range 0 <= theta <= 90
2270 // dimensions corresponding to value.
2271 wave azi// azimuthal coordinates. allowed range -360 <= phi < +360
2272 // dimensions corresponding to value.
2273 wave weights// total accumulation time of each point of values. default = 1
2274
2275 if (ParamIsDefault(weights))
2276 duplicate /free values, weights
2277 weights = 1
2278 endif
2279
2280 // quick check whether hemi grid is existing
2281 string s_prefix = ""
2282 string s_int = "values"
2283 dfref df = find_hemi_data(nickname, s_prefix, s_int)
2284
2285 string s_polar = s_prefix + "pol"
2286 string s_azim = s_prefix + "az"
2287 string s_theta = s_prefix + "th"
2288
2289 wave /sdfr=df /z w_values = $s_int
2290 wave /sdfr=df /z w_azim = $s_azim
2291 wave /sdfr=df /z w_polar = $s_polar
2292 wave /sdfr=df /z w_theta = $s_theta
2293 if (!waveexists(w_values) || !waveexists(w_azim) || !waveexists(w_polar))
2294 abort "Missing hemispherical scan grid. Please call make_hemi_grid() first."
2295 endif
2296
2297 // make internal copies, one-dimensional, ordered in theta
2298 duplicate /free values, values_copy
2299 duplicate /free polar, polar_copy
2300 duplicate /free azi, azi_copy
2301 duplicate /free weights, weights_copy
2302 variable nn = dimsize(values, 0) * max(dimsize(values, 1), 1)
2303 redimension /n=(nn) values_copy, polar_copy, azi_copy, weights_copy
2304 sort /r polar_copy, polar_copy, azi_copy, values_copy, weights_copy
2305
2306 variable pol
2307 variable pol_st = abs(w_theta[1] - w_theta[0])
2308 variable pol1, pol2
2309
2310 duplicate /free azi_copy, azi_slice
2311 duplicate /free values_copy, values_slice
2312 duplicate /free weights_copy, weights_slice
2313 for (pol = 90; pol >= 0; pol -= pol_st)
2314 pol1 = pol - pol_st / 2
2315 pol2 = pol + pol_st / 2
2316 extract /free /indx polar_copy, sel, (pol1 < polar_copy) && (polar_copy <= pol2)
2317 if (numpnts(sel) > 0)
2318 redimension /n=(numpnts(sel)) azi_slice, values_slice, weights_slice
2319 azi_slice = azi_copy[sel]
2320 values_slice = values_copy[sel]
2321 weights_slice = weights_copy[sel]
2322 hemi_add_aziscan(nickname, values_slice, pol, azi_slice, weights=weights_slice)
2323 endif
2324 endfor
2325 };
2326
2333 variable hemi_add_aziscan(string nickname, wave values, variable polar, wave azi, wave weights = defaultValue){
2334 string nickname// name prefix of holo waves.
2335 // may be empty.
2336 wave values// intensity values of the azimuthal scan at the positions given in the azi parameter
2337 variable polar// polar angle where to add the azi scan
2338 wave azi// angle positions of the azimuthal scan
2339 // acceptable range: >= -360 and < +360
2340 // no specific order required, the function sorts the array internally
2341 wave weights// total accumulation time of each point of values. default = 1
2342
2343 if (ParamIsDefault(weights))
2344 duplicate /free values, weights
2345 weights = 1
2346 endif
2347
2348 // hemi grid waves
2349 string s_prefix = ""
2350 string s_int = "values"
2351 dfref df = find_hemi_data(nickname, s_prefix, s_int)
2352
2353 string s_totals = s_prefix + "tot"
2354 string s_weights = s_prefix + "wt"
2355 string s_polar = s_prefix + "pol"
2356 string s_azim = s_prefix + "az"
2357 string s_index = s_prefix + "index"
2358 string s_theta = s_prefix + "th"
2359 string s_dphi = s_prefix + "dphi"
2360 string s_nphis = s_prefix + "nphis"
2361
2362 wave /sdfr=df w_polar = $s_polar
2363 wave /sdfr=df w_azim = $s_azim
2364 wave /sdfr=df w_values = $s_int
2365 wave /sdfr=df w_totals = $s_totals
2366 wave /sdfr=df w_weights = $s_weights
2367 wave /sdfr=df w_index = $s_index
2368 wave /sdfr=df w_theta = $s_theta
2369 wave /sdfr=df w_dphi = $s_dphi
2370 wave /sdfr=df w_nphis = $s_nphis
2371
2372 // destination slice coordinates
2373 //polar = round(polar)
2374 //variable ipol = 90 - polar
2375 variable ipol = BinarySearch(w_theta, polar)
2376 if (ipol < 0)
2377 abort "assertion failed in hemi_add_aziscan(): polar angle not found in grid."
2378 endif
2379
2380 variable d1, d2
2381 if (ipol >= 1)
2382 d1 = w_index[ipol - 1]
2383 else
2384 d1 = 0
2385 endif
2386 d2 = w_index[ipol] - 1
2387 variable nd = d2 - d1 + 1
2388 variable dphi = w_dphi[ipol]
2389 variable az1, az2
2390
2391 // source slice coordinates
2392 // order the slice from -dphi/2 to 360-dphi/2
2393 azi = azi < 0 ? azi + 360 : azi
2394 azi = azi >= 360 - dphi/2 ? azi - 360 : azi
2395 duplicate /free values, sel_values
2396 duplicate /free weights, sel_weights
2397
2398 // loop over destination
2399 variable id
2400 variable v1, v2, w1, w2
2401 for (id = 0; id < nd; id += 1)
2402 az1 = (id - 0.5) * dphi
2403 az2 = (id + 0.5) * dphi
2404 extract /free /indx azi, sel, (az1 <= azi) && (azi < az2)
2405 if (numpnts(sel) > 0)
2406 redimension /n=(numpnts(sel)) sel_values, sel_weights
2407 sel_values = values[sel]
2408 sel_weights = weights[sel]
2409 v1 = w_totals[d1 + id]
2410 w1 = w_weights[d1 + id]
2411 if ((numtype(v1) == 2) || (w1 <= 0))
2412 v1 = 0
2413 w1 = 0
2414 endif
2415 v2 = sum(sel_values)
2416 w2 = sum(sel_weights)
2417 w_totals[d1 + id] = v1 + v2
2418 w_weights[d1 + id] = w1 + w2
2419 endif
2420 endfor
2421 w_values[d1, d1 + nd - 1] = w_totals[p] / w_weights[p]
2422 };
2423
2439 variable interpolate_hemi_scan(string nickname){
2440 string nickname
2441
2442 dfref savedf = GetDataFolderDFR()
2443
2444 string s_prefix = ""
2445 string s_int = "values"
2446 dfref df = find_hemi_data(nickname, s_prefix, s_int)
2447
2448 string s_polar = s_prefix + "pol"
2449 string s_azim = s_prefix + "az"
2450 string s_ster_x = s_prefix + "ster_x"
2451 string s_ster_y = s_prefix + "ster_y"
2452
2453 wave /sdfr=df values = $s_int
2454 wave /sdfr=df azim = $s_azim
2455 wave /sdfr=df polar = $s_polar
2456 wave /sdfr=df ster_x = $s_ster_x
2457 wave /sdfr=df ster_y = $s_ster_y
2458
2459 variable min_ster_x = wavemin(ster_x)
2460 variable max_ster_x = wavemax(ster_x)
2461 variable x0 = min_ster_x
2462 variable xn = 181
2463 variable dx = (max_ster_x - min_ster_x) / (xn - 1)
2464 make /n=(numpnts(ster_x), 3) /free triplet
2465 triplet[][0] = ster_x[p]
2466 triplet[][1] = ster_y[p]
2467 triplet[][2] = values[p]
2468
2469 variable size = 181
2470 setdatafolder df
2471 make /n=(size, size) /d /o $(s_prefix + "matrix") /wave=matrix
2472 make /n=(size, size) /free mnorm
2473 ImageFromXYZ /as {ster_x, ster_y, values}, matrix, mnorm
2474 matrix /= mnorm
2475 matrixfilter NanZapMedian, matrix
2476 matrixfilter gauss, matrix
2477
2478 duplicate /free values, ster_finite
2479 ster_finite = (numtype(values) == 0) * (ster_x^2 + ster_y^2)
2480 variable ster_max = wavemax(ster_finite)
2481 matrix = (x^2 + y^2) <= ster_max ? matrix : nan
2482
2483 setdatafolder savedf
2484 };
2485
2496 variable quick_pizza_image(wave data, string nickname, variable theta_offset, variable tilt_offset, variable phi_offset, variable npolar = defaultValue, variable nograph = defaultValue, variable folding = defaultValue){
2497 wave data// 2D intensity wave, see requirements above
2498 string nickname// nick name for output data
2499 // in default mode, this will be the name of a child folder containing the output
2500 // in XPDplot mode, this will be a prefix of the generated data in the root folder
2501 variable theta_offset// manipulator theta angle corresponding to normal emission
2502 variable tilt_offset// manipulator tilt angle corresponding to normal emission
2503 variable phi_offset// manipulator phi angle corresponding to phi_result = 0
2504 variable npolar// number of polar angles, determines polar and azimuthal step size
2505 // default = 91 (1 degree steps)
2506 variable nograph// 0 (default) = display a new polar graph
2507 // 1 = don't display a new graph (if a graph is existing from a previous call, it will update)
2508 variable folding// rotational averaging, default = 1
2509
2510 if (ParamIsDefault(npolar))
2511 npolar = 91
2512 endif
2513 if (ParamIsDefault(nograph))
2514 nograph = 0
2515 endif
2516 if (ParamIsDefault(folding))
2517 folding = 1
2518 endif
2519 string graphname = "graph_" + nickname
2520 string s_prefix = ""
2521
2522 // sort out data folder structure
2523 dfref saveDF = GetDataFolderDFR()
2524 dfref dataDF = GetWavesDataFolderDFR(data)
2525 setdatafolder dataDF
2526 if (DataFolderExists(":attr"))
2527 setdatafolder :attr
2528 endif
2529 dfref attrDF = GetDataFolderDFR()
2530 setdatafolder dataDF
2531 newdatafolder /s/o $nickname
2532 dfref destDF = GetDataFolderDFR()
2533
2534 // performance monitoring
2535 variable timerRefNum
2536 variable /g xyz_perf_secs
2537 timerRefNum = startMSTimer
2538
2539 wave /sdfr=attrDF ManipulatorTheta
2540 wave /sdfr=attrDF ManipulatorTilt
2541 wave /sdfr=attrDF ManipulatorPhi
2542 duplicate /free ManipulatorTheta, m_theta
2543 duplicate /free ManipulatorTilt, m_tilt
2544 duplicate /free ManipulatorPhi, m_phi
2545 m_theta -= theta_offset
2546 m_tilt -= tilt_offset
2547 m_tilt *= -1// checked 140702
2548 m_phi -= phi_offset
2549 //m_phi *= -1 // checked 140702
2550
2551 make /n=1/d/free d_polar, d_azi
2552 convert_angles_ttpd2polar(m_theta, m_tilt, m_phi, data, d_polar, d_azi)
2553 d_azi += 180// changed 151030 (v1.6)
2554 d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
2555
2556 duplicate /free data, values
2557 variable nn = dimsize(values, 0) * max(dimsize(values, 1), 1)
2558 redimension /n=(nn) values, d_polar, d_azi
2559 duplicate /o d_polar, ster_rad, ster_x, ster_y
2560
2561 variable projection = 1
2562 switch(projection)
2563 case 1:// stereographic
2564 ster_rad = 2 * tan(d_polar / 2 * pi / 180)
2565 break
2566 case 2:// azimuthal
2567 ster_rad = 2 * cos((180 - d_polar) / 2 * pi / 180)
2568 break
2569 endswitch
2570 string s_ster_x = s_prefix + "ster_x"
2571 string s_ster_y = s_prefix + "ster_y"
2572
2573 nn = 401
2574 make /n=(nn, nn) /d /o matrix
2575 make /n=(nn, nn) /free mnorm
2576 setscale /i x -2, +2, matrix, mnorm
2577 setscale /i y -2, +2, matrix, mnorm
2578 matrix = 0
2579 mnorm = 0
2580
2581 variable ifold
2582 for (ifold = 0; ifold < folding; ifold += 1)
2583 ster_x = ster_rad * cos(d_azi * pi / 180)
2584 ster_y = ster_rad * sin(d_azi * pi / 180)
2585 ImageFromXYZ {ster_x, ster_y, values}, matrix, mnorm
2586 d_azi = d_azi >= 180 ? d_azi + 360 / folding - 180 : d_azi + 360 / folding
2587 endfor
2588
2589 matrix /= mnorm
2590 matrixfilter /n=5 NanZapMedian matrix
2591 matrixfilter /n=3 gauss matrix
2592
2593 if (!nograph)
2594 display /k=1
2595 appendimage matrix
2596 modifygraph width={Plan,1,bottom,left}
2597 endif
2598
2599 if (timerRefNum >= 0)
2600 xyz_perf_secs = stopMSTimer(timerRefNum) / 1e6
2601 endif
2602
2603 setdatafolder saveDF
2604 };
2605
2607 variable save_hemi_scan(string nickname, string pathname, string filename){
2608 string nickname
2609 string pathname
2610 string filename
2611
2612 dfref savedf = getdatafolderdfr()
2613
2614 // source data
2615 string s_prefix = ""
2616 string s_int = "values"
2617 dfref df = find_hemi_data(nickname, s_prefix, s_int)
2618
2619 string s_polar = s_prefix + "pol"
2620 string s_azim = s_prefix + "az"
2621 string s_theta = s_prefix + "th"
2622 string s_tot = s_prefix + "tot"
2623 string s_weight = s_prefix + "wt"
2624
2625 wave /sdfr=df theta1 = $s_theta
2626 wave /sdfr=df polar1 = $s_polar
2627 wave /sdfr=df azim1 = $s_azim
2628 wave /sdfr=df tot1 = $s_tot
2629 wave /sdfr=df weight1 = $s_weight
2630 wave /sdfr=df values1 = $s_int
2631
2632 save /m="\r\n" /o /p=$pathname /t theta1, polar1, azim1, tot1, weight1, values1 as filename
2633
2634 setdatafolder saveDF
2635 };
2636
2640 variable load_hemi_scan(string nickname, string pathname, string filename){
2641 string nickname
2642 string pathname
2643 string filename
2644
2645 dfref savedf = getdatafolderdfr()
2646
2647 //loadwave /p=$pathname /t theta1, polar1, azim1, tot1, weight1, values1 as filename
2648 //LoadWave /t/p=pearl_explorer_filepath/q filename
2649 //svar waves = s_wavenames
2650 //if (v_flag > 0)
2651 // string /g pearl_explorer_import = "load_itx_file"
2652 //endif
2653
2654 setdatafolder saveDF
2655 };
2656
2689 variable import_tpi_scan(string nickname, wave theta, wave phi, wave intensity, variable folding = defaultValue, variable npolar = defaultValue, variable nograph = defaultValue, variable xpdplot = defaultValue){
2690 string nickname
2691 wave theta
2692 wave phi
2693 wave intensity
2694
2695 variable folding
2696 variable npolar
2697 variable nograph
2698 variable xpdplot
2699
2700 if (ParamIsDefault(npolar))
2701 npolar = 91
2702 endif
2703 if (ParamIsDefault(nograph))
2704 nograph = 0
2705 endif
2706 if (ParamIsDefault(folding))
2707 folding = 1
2708 endif
2709 if (ParamIsDefault(xpdplot))
2710 xpdplot = 0
2711 endif
2712
2713 make_hemi_grid(npolar, nickname, xpdplot=xpdplot)
2714
2715 variable ifold
2716 duplicate /free phi, fold_phi
2717 for (ifold = 0; ifold < folding; ifold += 1)
2718 hemi_add_anglescan(nickname, intensity, theta, fold_phi)
2719 fold_phi = fold_phi >= 180 ? fold_phi + 360 / folding - fold_phi : fold_phi + 360 / folding
2720 endfor
2721
2722 if (nograph==0)
2723 display_hemi_scan(nickname)
2724 endif
2725 };
2726
2738 variable trim_hemi_scan(string nickname, variable theta_max){
2739 string nickname
2740 variable theta_max
2741
2742 string s_prefix = ""
2743 string s_int = "values"
2744 dfref df = find_hemi_data(nickname, s_prefix, s_int)
2745
2746 string s_totals = s_prefix + "tot"
2747 string s_weights = s_prefix + "wt"
2748 string s_polar = s_prefix + "pol"
2749
2750 wave /sdfr=df w_polar = $s_polar
2751 wave /sdfr=df w_values = $s_int
2752 wave /sdfr=df w_totals = $s_totals
2753 wave /sdfr=df w_weights = $s_weights
2754
2755 w_values = w_polar <= theta_max ? w_totals / w_weights : nan
2756 };
2757
2777 wave hemi_polar_cut(string nickname, variable azim){
2778 string nickname
2779 variable azim
2780
2781 dfref savedf = getdatafolderdfr()
2782 string s_prefix = ""
2783 string s_int = "values"
2784 dfref df = find_hemi_data(nickname, s_prefix, s_int)
2785
2786 string s_totals = s_prefix + "tot"
2787 string s_weights = s_prefix + "wt"
2788 string s_polar = s_prefix + "pol"
2789 string s_azim = s_prefix + "az"
2790 string s_index = s_prefix + "index"
2791 string s_theta = s_prefix + "th"
2792 string s_dphi = s_prefix + "dphi"
2793 string s_nphis = s_prefix + "nphis"
2794 string s_cut
2795 sprintf s_cut, "%s_azi%03u", s_int, round(azim)
2796
2797 wave /sdfr=df w_polar = $s_polar
2798 wave /sdfr=df w_azim = $s_azim
2799 wave /sdfr=df w_values = $s_int
2800 wave /sdfr=df w_totals = $s_totals
2801 wave /sdfr=df w_weights = $s_weights
2802 wave /sdfr=df w_index = $s_index
2803 wave /sdfr=df w_theta = $s_theta
2804 wave /sdfr=df w_dphi = $s_dphi
2805 wave /sdfr=df w_nphis = $s_nphis
2806
2807 variable npol = numpnts(w_theta)
2808 variable ipol
2809 variable pol_st = abs(w_theta[1] - w_theta[0])
2810 variable pol
2811 variable pol1, pol2
2812 variable nsel
2813
2814 setdatafolder df
2815 make /n=(npol) /o $s_cut
2816 wave w_cut = $s_cut
2817 setscale /i x w_theta[0], w_theta[numpnts(w_theta)-1], "deg", w_cut
2818 make /n=1 /free azi_slice
2819 make /n=1 /free values_slice
2820
2821 for (ipol = 0; ipol < npol; ipol += 1)
2822 pol = w_theta[ipol]
2823 pol1 = pol - pol_st / 2
2824 pol2 = pol + pol_st / 2
2825 extract /free /indx w_polar, sel, (pol1 < w_polar) && (w_polar <= pol2)
2826 nsel = numpnts(sel)
2827 if (nsel > 0)
2828 redimension /n=(nsel+2) azi_slice, values_slice
2829 azi_slice[1, nsel] = w_azim[sel[p-1]]
2830 azi_slice[0] = azi_slice[nsel] - 360
2831 azi_slice[nsel+1] = azi_slice[1] + 360
2832 values_slice[1, nsel] = w_values[sel[p-1]]
2833 values_slice[0] = values_slice[nsel]
2834 values_slice[nsel+1] = values_slice[1]
2835 w_cut[ipol] = interp(azim, azi_slice, values_slice)
2836 else
2837 w_cut[ipol] = nan
2838 endif
2839 endfor
2840
2841 setdatafolder savedf
2842 return w_cut
2843 };
2844
2863 wave hemi_azi_cut(string nickname, variable pol){
2864 string nickname
2865 variable pol
2866
2867 dfref savedf = getdatafolderdfr()
2868 string s_prefix = ""
2869 string s_int = "values"
2870 dfref df = find_hemi_data(nickname, s_prefix, s_int)
2871
2872 string s_totals = s_prefix + "tot"
2873 string s_weights = s_prefix + "wt"
2874 string s_polar = s_prefix + "pol"
2875 string s_azim = s_prefix + "az"
2876 string s_index = s_prefix + "index"
2877 string s_theta = s_prefix + "th"
2878 string s_dphi = s_prefix + "dphi"
2879 string s_nphis = s_prefix + "nphis"
2880 string s_cut
2881 sprintf s_cut, "%s_pol%03u", s_int, round(pol)
2882
2883 wave /sdfr=df w_polar = $s_polar
2884 wave /sdfr=df w_azim = $s_azim
2885 wave /sdfr=df w_values = $s_int
2886 wave /sdfr=df w_totals = $s_totals
2887 wave /sdfr=df w_weights = $s_weights
2888 wave /sdfr=df w_index = $s_index
2889 wave /sdfr=df w_theta = $s_theta
2890 wave /sdfr=df w_dphi = $s_dphi
2891 wave /sdfr=df w_nphis = $s_nphis
2892
2893 variable pol_st = abs(w_theta[1] - w_theta[0])
2894 variable pol1, pol2
2895 variable nsel
2896
2897 pol1 = pol - pol_st / 2
2898 pol2 = pol + pol_st / 2
2899 extract /free /indx w_polar, sel, (pol1 < w_polar) && (w_polar <= pol2)
2900 nsel = numpnts(sel)
2901 if (nsel > 0)
2902 setdatafolder df
2903 make /n=(nsel) /o $s_cut
2904 wave w_cut = $s_cut
2905 w_cut = w_values[sel]
2906 setscale /i x w_azim[sel[0]], w_azim[sel[nsel-1]], "", w_cut
2907 setdatafolder savedf
2908 return w_cut
2909 else
2910 setdatafolder savedf
2911 return $""
2912 endif
2913 setdatafolder savedf
2914 };
2915
2916 static variable check_contrast(wave values, variable pcmin, variable pcmax, variable* vmin, variable* vmax){
2917 wave values
2918 variable pcmin
2919 variable pcmax
2920 variable &vmin
2921 variable &vmax
2922
2923 dfref save_df = GetDataFolderDFR()
2924 dfref dfr = NewFreeDataFolder()
2925 setdatafolder dfr
2926 StatsQuantiles /inan /iw /q /z values
2927 wave index = w_quantilesindex
2928 variable imin = round(numpnts(index) * pcmin / 100)
2929 variable imax = round(numpnts(index) * (100 - pcmax) / 100)
2930 vmin = values[index[imin]]
2931 vmax = values[index[imax]]
2932 KillDataFolder dfr
2933 setdatafolder save_df
2934 };
2935
2952 variable set_contrast(variable pcmin, variable pcmax, string graphname = defaultValue, string colortable = defaultValue){
2953 variable pcmin
2954 variable pcmax
2955 string graphname
2956 string colortable
2957
2958 if (ParamIsDefault(graphname))
2959 graphname = ""
2960 endif
2961 if (ParamIsDefault(colortable))
2962 colortable = ""
2963 endif
2964
2965 dfref save_df = GetDataFolderDFR()
2966
2967 string objname
2968 string info
2969 string wname
2970 string ctab
2971 variable rev
2972 variable n
2973 variable i
2974 variable vmin
2975 variable vmax
2976
2977 string traces = TraceNameList(graphname, ";", 1+4)
2978 n = ItemsInList(traces, ";")
2979 for (i = 0; i < n; i += 1)
2980 objname = StringFromList(i, traces, ";")
2981 info = TraceInfo(graphname, objname, 0)
2982 if (strlen(info) > 0)
2983 info = StringByKey("RECREATION", info, ":", ";")
2984 info = StringByKey("zColor(x)", info, "=", ";")
2985 if (strlen(info) > 2)
2986 info = info[1,strlen(info)-2]
2987 wname = StringFromList(0, info, ",")
2988 wave w = $wname
2989 ctab = StringFromList(3, info, ",")
2990 rev = str2num("0" + StringFromList(4, info, ","))
2991 if (strlen(colortable) > 0)
2992 ctab = colortable
2993 endif
2994 check_contrast(w, pcmin, pcmax, vmin, vmax)
2995 ModifyGraph /w=$graphname zColor($objname)={w, vmin, vmax, $ctab, rev}
2996 endif
2997 endif
2998 endfor
2999
3000 string images = ImageNameList(graphname, ";")
3001 n = ItemsInList(images, ";")
3002 for (i = 0; i < n; i += 1)
3003 objname = StringFromList(i, images, ";")
3004 wave w = ImageNameToWaveRef(graphname, objname)
3005 info = ImageInfo(graphname, objname, 0)
3006 if (strlen(info) > 0)
3007 info = StringByKey("RECREATION", info, ":", ";")
3008 info = StringByKey("ctab", info, "=", ";")
3009 if (strlen(info) > 2)
3010 info = info[1,strlen(info)-2]
3011 ctab = StringFromList(2, info, ",")
3012 rev = str2num("0" + StringFromList(3, info, ","))
3013 if (strlen(colortable) > 0)
3014 ctab = colortable
3015 endif
3016 check_contrast(w, pcmin, pcmax, vmin, vmax)
3017 ModifyImage /w=$graphname $objname ctab={vmin, vmax, $ctab, rev}
3018 endif
3019 endif
3020 endfor
3021
3022 setdatafolder save_df
3023 };
3024
fit_scienta_ang_transm
wave fit_scienta_ang_transm(wave data, wave params)
Definition: pearl-scienta-preprocess.ipf:551
hemi_polar_cut
wave hemi_polar_cut(string nickname, variable azim)
extract a polar cut from a hemispherical scan.
Definition: pearl-anglescan-process.ipf:2777
trim_hemi_scan
variable trim_hemi_scan(string nickname, variable theta_max)
trim a hemispherical scan at grazing angle
Definition: pearl-anglescan-process.ipf:2738
pizza_service_2
variable pizza_service_2(wave data, string nickname, wave m_theta, wave m_tilt, wave m_phi, variable npolar=defaultValue, variable nograph=defaultValue, variable folding=defaultValue, variable xpdplot=defaultValue)
create a pizza plot from a measured (energy-integrated) data strip
Definition: pearl-anglescan-process.ipf:648
kProjScaleOrtho
static const variable kProjScaleOrtho
Definition: pearl-anglescan-process.ipf:2004
polar2cart_wave
variable polar2cart_wave(wave in, wave out)
Definition: pearl-polar-coordinates.ipf:58
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:353
normalize_strip_2d
variable normalize_strip_2d(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
divide the strip by a two-dimensional normalization function.
Definition: pearl-anglescan-process.ipf:435
crop_strip
variable crop_strip(wave strip, variable xlo, variable xhi)
crop a strip at the sides.
Definition: pearl-anglescan-process.ipf:495
kProjGnom
const variable kProjGnom
Definition: pearl-anglescan-process.ipf:1996
ad_profile_y
threadsafe wave ad_profile_y(wave dataset, variable p1, variable p2, string destname, variable noavg=defaultValue)
1D cut through 2D dataset along Y dimension, new destination wave.
Definition: pearl-area-profiles.ipf:542
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:1077
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:2263
get_hemi_nickname
string get_hemi_nickname(wave w)
finds the nick name given any hemi wave
Definition: pearl-anglescan-process.ipf:1228
interpolate_hemi_scan
variable interpolate_hemi_scan(string nickname)
interpolate a hemispherical scan onto a rectangular grid
Definition: pearl-anglescan-process.ipf:2439
get_hemi_prefix
string get_hemi_prefix(wave w)
finds the prefix given any hemi wave
Definition: pearl-anglescan-process.ipf:1253
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:1516
CalcN_Theta
static variable CalcN_Theta(string HoloMode, variable Theta_in, variable Theta_ran, variable Theta_st)
calculate the number of thetas for a pattern
Definition: pearl-anglescan-process.ipf:1039
find_hemi_data
dfr find_hemi_data(string nickname, string *prefix, string *intwave)
finds the folder, prefix and name of holo waves given their nick name
Definition: pearl-anglescan-process.ipf:1284
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:835
clear_hemi_grid
variable clear_hemi_grid(string nickname)
clear a hemispherical scan grid
Definition: pearl-anglescan-process.ipf:1318
kProjScaleDist
static const variable kProjScaleDist
Definition: pearl-anglescan-process.ipf:1999
calc_graph_polar
threadsafe variable calc_graph_polar(variable x, variable y, variable projection=defaultValue)
calculate polar angle from Cartesian coordinate
Definition: pearl-anglescan-process.ipf:2065
check_contrast
static variable check_contrast(wave values, variable pcmin, variable pcmax, variable *vmin, variable *vmax)
Definition: pearl-anglescan-process.ipf:2916
Calc_The_step
static variable Calc_The_step(variable th, variable Theta_st, string Holomode)
calculate delta-theta for a given theta
Definition: pearl-anglescan-process.ipf:1008
kProjArea
const variable kProjArea
Definition: pearl-anglescan-process.ipf:1995
line_average
static variable line_average(wave source, wave dest)
Definition: pearl-anglescan-process.ipf:917
calc_graph_radius
threadsafe variable calc_graph_radius(variable polar, variable projection=defaultValue)
calculate the projected polar angle
Definition: pearl-anglescan-process.ipf:2020
scienta_ang_transm
threadsafe variable scienta_ang_transm(wave w, variable x)
Definition: pearl-scienta-preprocess.ipf:578
pizza_service
variable pizza_service(wave data, string nickname, variable theta_offset, variable tilt_offset, variable phi_offset, variable npolar=defaultValue, variable nograph=defaultValue, variable folding=defaultValue, variable xpdplot=defaultValue)
create a pizza plot from a measured (energy-integrated) data strip
Definition: pearl-anglescan-process.ipf:555
rotate_x_wave
variable rotate_x_wave(wave inout, variable angle)
Definition: pearl-vector-operations.ipf:83
cart2polar_wave
variable cart2polar_wave(wave in, wave out)
Definition: pearl-polar-coordinates.ipf:36
display_scanlines
string display_scanlines(string nickname, variable alpha_lo, variable alpha_hi, wave m_theta, wave m_tilt, wave m_phi, variable folding=defaultValue, variable projection=defaultValue)
display a polar graph with lines indicating the angles covered by an angle scan.
Definition: pearl-anglescan-process.ipf:1905
hemi_azi_cut
wave hemi_azi_cut(string nickname, variable pol)
extract an azimuthal cut from a hemispherical scan
Definition: pearl-anglescan-process.ipf:2863
draw_diffraction_cone
variable draw_diffraction_cone(string graphname, string groupname, variable theta_axis, variable theta_inner, variable phi)
draw the circle of a diffraction cone in a stereographic polar graph.
Definition: pearl-anglescan-process.ipf:1841
hemi_add_aziscan
variable hemi_add_aziscan(string nickname, wave values, variable polar, wave azi, wave weights=defaultValue)
add an azimuthal scan to a hemispherical scan grid.
Definition: pearl-anglescan-process.ipf:2333
kProjScaleGnom
static const variable kProjScaleGnom
Definition: pearl-anglescan-process.ipf:2003
rotate_y_wave
variable rotate_y_wave(wave inout, variable angle)
Definition: pearl-vector-operations.ipf:101
rotate_hemi_scan
variable rotate_hemi_scan(string nickname, variable angle)
azimuthally rotate a hemispherical scan dataset.
Definition: pearl-anglescan-process.ipf:1440
kProjScaleStereo
static const variable kProjScaleStereo
Definition: pearl-anglescan-process.ipf:2000
PearlAnglescanProcess
processing and holographic mapping of angle scanned XPD data.
display_polar_graph
static string display_polar_graph(string graphname, variable angle_offset=defaultValue, variable do_ticks=defaultValue)
displays an empty polar graph
Definition: pearl-anglescan-process.ipf:1654
kProjOrtho
const variable kProjOrtho
Definition: pearl-anglescan-process.ipf:1997
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:2607
normalize_strip_phi
variable normalize_strip_phi(wave strip, wave theta, wave phi, variable theta_offset=defaultValue, variable theta_range=defaultValue, variable check=defaultValue)
divide the strip by a sine function in phi (wobble correction).
Definition: pearl-anglescan-process.ipf:270
kProjStereo
const variable kProjStereo
Definition: pearl-anglescan-process.ipf:1994
quick_pizza_image
variable quick_pizza_image(wave data, string nickname, variable theta_offset, variable tilt_offset, variable phi_offset, variable npolar=defaultValue, variable nograph=defaultValue, variable folding=defaultValue)
map angle scan data onto a rectangular grid in stereographic projection
Definition: pearl-anglescan-process.ipf:2496
polar_graph_hook
static variable polar_graph_hook(WMWinHookStruct *s)
polar graph window hook
Definition: pearl-anglescan-process.ipf:2198
kProjDist
const variable kProjDist
Definition: pearl-anglescan-process.ipf:1993
calc_graph_azi
threadsafe variable calc_graph_azi(variable x, variable y, variable projection=defaultValue, variable zeroAngle=defaultValue)
calculate azimuthal angle from Cartesian coordinate
Definition: pearl-anglescan-process.ipf:2118
set_contrast
variable set_contrast(variable pcmin, variable pcmax, string graphname=defaultValue, string colortable=defaultValue)
set the pseudocolor contrast by percentile.
Definition: pearl-anglescan-process.ipf:2952
strip_delete_frames
variable strip_delete_frames(wave strip, variable qlo, variable qhi, wave theta, wave tilt, wave phi)
delete a contiguous range of frames from a strip.
Definition: pearl-anglescan-process.ipf:105
rotate_z_wave
variable rotate_z_wave(wave inout, variable angle)
Definition: pearl-vector-operations.ipf:119
calc_nth
static variable calc_nth(variable Theta_st, variable Theta_in, variable th, variable Phi_ran, variable Phi_ref, string Holomode)
calculate the number of phis for a given theta
Definition: pearl-anglescan-process.ipf:935
kProjScaleArea
static const variable kProjScaleArea
Definition: pearl-anglescan-process.ipf:2001
show_analyser_line
variable show_analyser_line(variable theta, variable tilt, variable phi, variable theta_offset, variable tilt_offset, variable phi_offset, variable npolar=defaultValue, variable nograph=defaultValue, variable xpdplot=defaultValue)
calculate and display the line seen by the analyser for a specific emission angle ...
Definition: pearl-anglescan-process.ipf:765
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:874
draw_hemi_axes
static string draw_hemi_axes(string graphname, variable do_grids=defaultValue)
draw polar and azimuthal grids in an existing polar graph.
Definition: pearl-anglescan-process.ipf:1769
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:1365
set_polar_graph_cursor
variable set_polar_graph_cursor(string nickname, string cursorname, variable polar_angle, variable azim_angle, string graphname=defaultValue)
Definition: pearl-anglescan-process.ipf:2218
update_polar_info
static variable update_polar_info(string graphname)
update the angles info based on cursors A and B of a given polar graph window
Definition: pearl-anglescan-process.ipf:2163
import_tpi_scan
variable import_tpi_scan(string nickname, wave theta, wave phi, wave intensity, variable folding=defaultValue, variable npolar=defaultValue, variable nograph=defaultValue, variable xpdplot=defaultValue)
import a hemispherical scan from theta-phi-intensity waves and display it
Definition: pearl-anglescan-process.ipf:2689
load_hemi_scan
variable load_hemi_scan(string nickname, string pathname, string filename)
load a hemispherical scan from an Igor text file
Definition: pearl-anglescan-process.ipf:2640
ad_profile_x
threadsafe wave ad_profile_x(wave dataset, variable q1, variable q2, string destname, variable noavg=defaultValue)
1D cut through 2D dataset along X dimension, new destination wave.
Definition: pearl-area-profiles.ipf:480
calc_phi_step
static variable calc_phi_step(variable Theta_in, variable th, variable Theta_st, variable Phi_ran, variable Phi_ref, string Holomode)
calculate delta-phi for a given theta
Definition: pearl-anglescan-process.ipf:964
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:185