1 Commits

Author SHA1 Message Date
29d4b6881f new angle-scan processing features, update documentation, bugfixes
new functions:
- voigt_fwhm_lor
- rotate_hemi_scan
- import_tpi_scan
- draw_diffraction_cone

updated functions:
- interpolate_hemi_scan
- display_hemi_scan
- duplicate_hemi_scan

updated documentation:
- installation instructions
- readme
2016-03-30 12:02:57 +02:00
6 changed files with 359 additions and 42 deletions

34
README.md Normal file
View File

@ -0,0 +1,34 @@
Introduction
============
PEARL Procedures is a suite of Igor Pro procedures developed for data acquisition and data processing at the PEARL beamline at the Swiss Light Source.
Installation
============
PEARL Procedures should be installed according to the regular Igor Pro guidelines. Please read the Igor help `About Igor Pro User Files` for details.
- Make a `pearl-procs` directory in your private or shared `User Procedures` folder, and copy the PEARL Procedures distribution there.
- Create shortcuts of the `pearl-arpes.ipf` and `pearl-menu.ipf` files, and move them to the `Igor Procedures` folder next to your `User Procedures` folder.
- Find the `HDF5.XOP` extension in the `Igor Pro Folder` under `More Extensions/File Loaders`, create a shortcut, and move the shortcut to the `Igor Extensions` folder next to your `User Procedures` folder.
- Find the `HDF5 Help.ihf` next to `HDF5.XOP`, create a shortcut, and move the shortcut to the `Igor Help Files` folder next to your `User Procedures` folder.
License
=======
The source code of PEARL Procedures is available under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) at <https://git.psi.ch/pearl-public/igor-procs>.
Users of PEARL Procedures are requested to coordinate and share the development of the code with the original author.
Please read and respect the respective license agreements.
Author
------
Matthias Muntwiler, <mailto:matthias.muntwiler@psi.ch>
Copyright
---------
Copyright 2009-2016 by [Paul Scherrer Institut](http://www.psi.ch)

View File

@ -758,7 +758,8 @@ WARN_LOGFILE =
# spaces. # spaces.
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = ../pearl INPUT = ../pearl \
src
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@ -778,7 +779,8 @@ INPUT_ENCODING = CP1252
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
# *.qsf, *.as and *.js. # *.qsf, *.as and *.js.
FILE_PATTERNS = *.ipf FILE_PATTERNS = *.ipf \
*.dox
# The RECURSIVE tag can be used to specify whether or not subdirectories should # The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well. # be searched for input files as well.
@ -863,7 +865,7 @@ IMAGE_PATH =
# code is scanned, but not when the output code is generated. If lines are added # code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly. # or removed, the anchors will not be placed correctly.
INPUT_FILTER = "gawk -f doxygen-filter-ipf.awk" INPUT_FILTER =
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis. Doxygen will compare the file name with each pattern and apply the # basis. Doxygen will compare the file name with each pattern and apply the
@ -872,7 +874,7 @@ INPUT_FILTER = "gawk -f doxygen-filter-ipf.awk"
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the # filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied. # patterns match the file name, INPUT_FILTER is applied.
FILTER_PATTERNS = FILTER_PATTERNS = "*.ipf=\"gawk -f doxygen-filter-ipf.awk\""
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will also be used to filter the input files that are used for # INPUT_FILTER) will also be used to filter the input files that are used for

View File

@ -11,6 +11,9 @@ DOX=doxygen
DOXOPTS= DOXOPTS=
LATEX_DIR=latex LATEX_DIR=latex
REVISION=$(shell git describe --always --tags --dirty --long)
export REVISION
all: docs all: docs
docs: doxygen pdf docs: doxygen pdf
@ -24,4 +27,3 @@ pdf: doxygen
clean: clean:
-rm latex/* -rm latex/*
-rm html/* -rm html/*

27
doc/src/mainpage.dox Normal file
View File

@ -0,0 +1,27 @@
/*! @mainpage Introduction
\section sec_intro Introduction
PEARL Procedures is a suite of Igor Pro procedures developed for data acquisition and data processing at the PEARL beamline at the Swiss Light Source.
\section sec_install Installation
PEARL Procedures should be installed according to the regular Igor Pro guidelines. Please read the Igor help `About Igor Pro User Files` for details.
- Make a `pearl-procs` directory in your private or shared `User Procedures` folder, and copy the PEARL Procedures distribution there.
- Create shortcuts of the `pearl-arpes.ipf` and `pearl-menu.ipf` files, and move them to the `Igor Procedures` folder next to your `User Procedures` folder.
- Find the `HDF5.XOP` extension in the `Igor Pro Folder` under `More Extensions/File Loaders`, create a shortcut, and move the shortcut to the `Igor Extensions` folder next to your `User Procedures` folder.
- Find the `HDF5 Help.ihf` next to `HDF5.XOP`, create a shortcut, and move the shortcut to the `Igor Help Files` folder next to your `User Procedures` folder.
\section sec_license License Information
An open distribution of PEARL Procedures is available under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) at <https://git.psi.ch/pearl-public/igor-procs>.
Users of PEARL Procedures are requested to coordinate and share the development of the code with the original author.
Please read and respect the respective license agreements.
\author Matthias Muntwiler, <mailto:matthias.muntwiler@psi.ch>
\version This documentation is compiled from revision $(REVISION).
\copyright 2009-2016 by [Paul Scherrer Institut](http://www.psi.ch)
\copyright Licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
*/

View File

@ -1204,6 +1204,7 @@ function duplicate_hemi_scan(source_nickname, dest_folder, dest_nickname, [xpdpl
string s_theta = s_prefix + "th" string s_theta = s_prefix + "th"
string s_tot = s_prefix + "tot" string s_tot = s_prefix + "tot"
string s_weight = s_prefix + "wt" string s_weight = s_prefix + "wt"
string s_matrix = s_prefix + "matrix"
wave theta1 = $s_theta wave theta1 = $s_theta
wave polar1 = $s_polar wave polar1 = $s_polar
@ -1211,6 +1212,7 @@ function duplicate_hemi_scan(source_nickname, dest_folder, dest_nickname, [xpdpl
wave tot1 = $s_tot wave tot1 = $s_tot
wave weight1 = $s_weight wave weight1 = $s_weight
wave values1 = $s_int wave values1 = $s_int
wave /z matrix1 = $s_matrix
variable npol = numpnts(theta1) variable npol = numpnts(theta1)
@ -1230,6 +1232,7 @@ function duplicate_hemi_scan(source_nickname, dest_folder, dest_nickname, [xpdpl
s_theta = s_prefix + "th" s_theta = s_prefix + "th"
s_tot = s_prefix + "tot" s_tot = s_prefix + "tot"
s_weight = s_prefix + "wt" s_weight = s_prefix + "wt"
s_matrix = s_prefix + "matrix"
wave theta2 = $s_theta wave theta2 = $s_theta
wave polar2 = $s_polar wave polar2 = $s_polar
@ -1241,6 +1244,9 @@ function duplicate_hemi_scan(source_nickname, dest_folder, dest_nickname, [xpdpl
tot2 = tot1 tot2 = tot1
weight2 = weight1 weight2 = weight1
values2 = values1 values2 = values1
if (waveexists(matrix1))
duplicate /o matrix1, $s_matrix
endif
if (!(NumberByKey("version", note(azim1), "=", "\r") >= 1.6)) if (!(NumberByKey("version", note(azim1), "=", "\r") >= 1.6))
azim2 += 180 // changed 151030 (v1.6) azim2 += 180 // changed 151030 (v1.6)
@ -1250,6 +1256,48 @@ function duplicate_hemi_scan(source_nickname, dest_folder, dest_nickname, [xpdpl
setdatafolder saveDF setdatafolder saveDF
end end
/// azimuthally rotate a hemispherical scan dataset.
///
/// this function works only for hemi scans created by make_hemi_grid() (or compatible functions).
///
/// @param nickname name prefix for waves. source data must be in current data folder.
/// @param angle azimuthal rotation angle in degrees.
///
function rotate_hemi_scan(nickname, angle)
string nickname
variable angle
dfref savedf = getdatafolderdfr()
if (strlen(nickname))
string s_prefix = nickname + "_"
string s_int = s_prefix + "i"
else
s_prefix = ""
s_int = "values"
endif
string s_polar = s_prefix + "pol"
string s_azim = s_prefix + "az"
string s_tot = s_prefix + "tot"
string s_weight = s_prefix + "wt"
wave polar = $s_polar
wave azim = $s_azim
wave tot = $s_tot
wave weight = $s_weight
wave values = $s_int
azim += angle
azim = azim < 0 ? azim + 360 : azim
azim = azim >= 360 ? azim - 360 : azim
duplicate /free polar, neg_polar
neg_polar = -polar
sort {neg_polar, azim}, polar, azim, tot, weight, values
setdatafolder saveDF
end
/// display a plot of a hemispherical angle scan. /// display a plot of a hemispherical angle scan.
/// ///
/// the scan data must exist in the current data folder. /// the scan data must exist in the current data folder.
@ -1264,10 +1312,29 @@ end
/// @arg 0 linear /// @arg 0 linear
/// @arg 1 stereographic (default) /// @arg 1 stereographic (default)
/// @arg 2 azimuthal /// @arg 2 azimuthal
/// @arg 3 gnomonic (0 <= polar < 90).
/// ///
/// @param graphtype type of graph /// @param graphtype type of graph
/// @arg 1 Igor "New Polar" (default) /// @arg 1 (pol, az) trace in Igor "New Polar" (default).
/// @arg 2 XPDplot (reserved, not implemented) /// @arg 2 XPDplot (reserved, not implemented).
/// @arg 3 matrix in Igor "New Polar".
/// the matrix wave is a 2D wave with X and Y scaling corresponding to the selected projection.
/// matrix waves can be created by interpolate_hemi_scan().
/// note: the pol and az waves are required as well.
///
/// @param do_ticks select which ticks to draw.
/// value must be the arithmetic OR of all selected items.
/// default: 3
/// @arg 0 none
/// @arg 1 major azimuthal
/// @arg 2 minor azimuthal
///S
/// @param do_grids select which grids to draw.
/// value must be the arithmetic OR of all selected items.
/// default: 3
/// @arg 0 none
/// @arg 1 radius at 0 and 90 degree azimuth
/// @arg 2 circle at 30 and 60 degree polar
/// ///
/// @param graphname name of graph window. default: nickname /// @param graphname name of graph window. default: nickname
/// if empty, a default name is assigned. /// if empty, a default name is assigned.
@ -1275,10 +1342,12 @@ end
/// ///
/// @returns the name of the graph window /// @returns the name of the graph window
/// ///
function /s display_hemi_scan(nickname, [projection, graphtype, graphname]) function /s display_hemi_scan(nickname, [projection, graphtype, do_ticks, do_grids, graphname])
string nickname string nickname
variable projection variable projection
variable graphtype variable graphtype
variable do_ticks
variable do_grids
string graphname string graphname
if (ParamIsDefault(projection)) if (ParamIsDefault(projection))
@ -1287,6 +1356,12 @@ function /s display_hemi_scan(nickname, [projection, graphtype, graphname])
if (ParamIsDefault(graphtype)) if (ParamIsDefault(graphtype))
graphtype = 1 graphtype = 1
endif endif
if (ParamIsDefault(do_ticks))
do_ticks = 3
endif
if (ParamIsDefault(do_grids))
do_grids = 3
endif
if (ParamIsDefault(graphname)) if (ParamIsDefault(graphname))
if (strlen(nickname) > 0) if (strlen(nickname) > 0)
graphname = nickname graphname = nickname
@ -1305,9 +1380,12 @@ function /s display_hemi_scan(nickname, [projection, graphtype, graphname])
endif endif
string s_polar = s_prefix + "pol" string s_polar = s_prefix + "pol"
string s_azim = s_prefix + "az" string s_azim = s_prefix + "az"
string s_matrix = s_prefix + "matrix"
wave /z values = $s_int wave /z values = $s_int
wave /z azim = $s_azim wave /z azim = $s_azim
wave /z polar = $s_polar wave /z polar = $s_polar
wave /z matrix = $s_matrix
string s_ster_rad = s_prefix + "ster_rad" string s_ster_rad = s_prefix + "ster_rad"
duplicate /o polar, $s_ster_rad /wave=ster_rad duplicate /o polar, $s_ster_rad /wave=ster_rad
@ -1325,11 +1403,12 @@ function /s display_hemi_scan(nickname, [projection, graphtype, graphname])
azim_offset = 180 // changed 151030 (v1.6) azim_offset = 180 // changed 151030 (v1.6)
endif endif
string s_trace
switch(graphtype) switch(graphtype)
case 1: case 1:
graphname = display_polar_graph(graphname, angle_offset=azim_offset) graphname = display_polar_graph(graphname, angle_offset=azim_offset, do_ticks=do_ticks)
string s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360) s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360)
ModifyGraph /W=$graphname mode($s_trace)=2, lsize($s_trace)=2 ModifyGraph /W=$graphname mode($s_trace)=2, lsize($s_trace)=2
ModifyGraph /W=$graphname zColor($s_trace)={values,*,*,BlueGreenOrange,0} ModifyGraph /W=$graphname zColor($s_trace)={values,*,*,BlueGreenOrange,0}
@ -1338,7 +1417,21 @@ function /s display_hemi_scan(nickname, [projection, graphtype, graphname])
ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50 ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50
SetWindow $graphname, userdata(projection)=num2str(projection) SetWindow $graphname, userdata(projection)=num2str(projection)
draw_hemi_axes(graphname) draw_hemi_axes(graphname, do_grids=do_grids)
break
case 3:
graphname = display_polar_graph(graphname, angle_offset=azim_offset, do_ticks=do_ticks)
s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360)
ModifyGraph /W=$graphname mode($s_trace)=0, lsize($s_trace)=0
AppendImage /L=VertCrossing /B=HorizCrossing matrix
ColorScale /W=$graphname /C /N=text0 /E=2 /F=0 /B=1 /A=RB /X=0.00 /Y=0.00 image=$s_matrix
ColorScale /W=$graphname /C /N=text0 side=2, width=5, heightPct=40, frame=0.50, lblMargin=0
ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50
SetWindow $graphname, userdata(projection)=num2str(projection)
draw_hemi_axes(graphname, do_grids=do_grids)
break break
endswitch endswitch
@ -1373,22 +1466,33 @@ end
/// for hemi grids created with earlier versions, /// for hemi grids created with earlier versions,
/// it should be set to 180 for correct orientation. /// it should be set to 180 for correct orientation.
/// ///
/// @param do_ticks select which ticks to draw.
/// value must be the arithmetic OR of all selected items.
/// default: 3
/// @arg 0 none
/// @arg 1 major azimuthal
/// @arg 2 minor azimuthal
///
/// @returns the name of the graph window. /// @returns the name of the graph window.
/// ///
/// @version 1.7 /// @version 1.7
/// interface change: the trace drawing code is moved to display_hemi_scan, /// interface change: the trace drawing code is moved to display_hemi_scan,
/// so that this function can be reused by other graph types, e.g. display_scanlines. /// so that this function can be reused by other graph types, e.g. display_scanlines.
/// ///
static function /s display_polar_graph(graphname, [angle_offset]) static function /s display_polar_graph(graphname, [angle_offset, do_ticks])
string graphname string graphname
variable angle_offset variable angle_offset
variable do_ticks
dfref savedf = GetDataFolderDFR() dfref savedf = GetDataFolderDFR()
if (ParamIsDefault(angle_offset)) if (ParamIsDefault(angle_offset))
angle_offset = 0 angle_offset = 0
endif endif
if (ParamIsDefault(do_ticks))
do_ticks = 3
endif
if ((strlen(graphname) == 0) || (wintype(graphname) == 0)) if ((strlen(graphname) == 0) || (wintype(graphname) == 0))
Display /k=1 /W=(10,45,360,345) Display /k=1 /W=(10,45,360,345)
@ -1408,15 +1512,28 @@ static function /s display_polar_graph(graphname, [angle_offset])
WMPolarGraphSetVar(graphname, "doPolarGrids", 0) WMPolarGraphSetVar(graphname, "doPolarGrids", 0)
WMPolarGraphSetVar(graphname, "doRadiusTickLabels", 0) WMPolarGraphSetVar(graphname, "doRadiusTickLabels", 0)
WMPolarGraphSetStr(graphname, "radiusAxisWhere", " Off ") WMPolarGraphSetStr(graphname, "radiusAxesWhere", " Off") // note the leading spaces, cf. WMPolarAnglesForRadiusAxes
WMPolarGraphSetStr(graphname, "radiusTicksLocation", "Off")
WMPolarGraphSetVar(graphname, "majorTickLength", 5) WMPolarGraphSetVar(graphname, "majorTickLength", 2)
WMPolarGraphSetVar(graphname, "majorTickThick", 0.5) WMPolarGraphSetVar(graphname, "majorTickThick", 0.5)
WMPolarGraphSetVar(graphname, "minorTickLength", 3) WMPolarGraphSetVar(graphname, "minorTickLength", 1)
WMPolarGraphSetVar(graphname, "minorTickThick", 0.5) WMPolarGraphSetVar(graphname, "minorTickThick", 0.5)
WMPolarGraphSetVar(graphname, "tickLabelOpaque", 0) WMPolarGraphSetVar(graphname, "tickLabelOpaque", 0)
WMPolarGraphSetVar(graphname, "tickLabelFontSize", 7) WMPolarGraphSetVar(graphname, "tickLabelFontSize", 7)
// changes
if (do_ticks & 1)
WMPolarGraphSetStr(graphname, "angleTicksLocation", "Outside")
else
WMPolarGraphSetStr(graphname, "angleTicksLocation", "Off")
endif
if (do_ticks & 2)
WMPolarGraphSetVar(graphname, "doMinorAngleTicks", 1)
else
WMPolarGraphSetVar(graphname, "doMinorAngleTicks", 0)
endif
DoWindow /T $graphname, graphname DoWindow /T $graphname, graphname
// cursor info in angles // cursor info in angles
@ -1452,11 +1569,11 @@ static function /s display_polar_graph(graphname, [angle_offset])
return graphname return graphname
end end
/// draw polar and azimuthal axes in an existing polar graph /// draw polar and azimuthal grids in an existing polar graph.
/// ///
/// the function adds the following draw objects to a polar graph: /// the function adds the following draw objects to a polar graph:
/// * concentric circles at polar angles 0, 30, 60, and 90 degrees with labels. /// * concentric circles at polar angles 0, 30, and 60 degrees with labels.
/// * labels for azimuthal angles at 0, 30, 60, and 90 degrees. /// * radial axes at 0 and 90 degree azimuth.
/// ///
/// the objects are added to the ProgFront drawing layer and will appear in front of the data trace. /// the objects are added to the ProgFront drawing layer and will appear in front of the data trace.
/// in interactive drawing mode, you can select the active drawing layer by clicking the tree icon /// in interactive drawing mode, you can select the active drawing layer by clicking the tree icon
@ -1467,12 +1584,24 @@ end
/// ///
/// @param graphname name of graph window. /// @param graphname name of graph window.
/// ///
/// @param do_grids select which optional grids to draw.
/// value must be the arithmetic OR of all selected items.
/// default: 3
/// @arg 0 none
/// @arg 1 radius at 0 and 90 degree azimuth
/// @arg 2 circle at 30 and 60 degree polar
///
/// @warning EXPERIMENTAL! /// @warning EXPERIMENTAL!
/// this function is under development. /// this function is under development.
/// the interface and behaviour of this function may change significantly in future versions. /// the interface and behaviour of this function may change significantly in future versions.
static function /s draw_hemi_axes(graphname) static function /s draw_hemi_axes(graphname, [do_grids])
string graphname string graphname
variable do_grids
if (ParamIsDefault(do_grids))
do_grids = 3
endif
dfref savedf = GetDataFolderDFR() dfref savedf = GetDataFolderDFR()
string sproj = GetUserData(graphname, "", "projection") string sproj = GetUserData(graphname, "", "projection")
@ -1490,26 +1619,96 @@ static function /s draw_hemi_axes(graphname)
//SetDrawEnv /W=$graphname linefgc=(65535,65535,65535) //SetDrawEnv /W=$graphname linefgc=(65535,65535,65535)
SetDrawEnv /W=$graphname save SetDrawEnv /W=$graphname save
variable radi if (do_grids & 1)
radi = calc_graph_radius(0.5, projection=projection) DrawLine /W=$graphname 0, -2, 0, 2
DrawOval /W=$graphname -radi, radi, radi, -radi DrawLine /W=$graphname -2, 0, 2, 0
radi = calc_graph_radius(30, projection=projection) endif
DrawOval /W=$graphname -radi, radi, radi, -radi
radi = calc_graph_radius(60, projection=projection)
DrawOval /W=$graphname -radi, radi, radi, -radi
DrawLine /W=$graphname 0, -2, 0, 2
DrawLine /W=$graphname -2, 0, 2, 0
SetDrawEnv /W=$graphname textxjust= 1,textyjust= 2 variable radi
SetDrawEnv /W=$graphname save if (do_grids & 2)
radi = calc_graph_radius(30, projection=projection) radi = calc_graph_radius(0.5, projection=projection)
DrawText /W=$graphname radi, -0.1, "30<33>" DrawOval /W=$graphname -radi, radi, radi, -radi
radi = calc_graph_radius(60, projection=projection) radi = calc_graph_radius(30, projection=projection)
DrawText /W=$graphname radi, -0.1, "60<36>" DrawOval /W=$graphname -radi, radi, radi, -radi
radi = calc_graph_radius(60, projection=projection)
DrawOval /W=$graphname -radi, radi, radi, -radi
SetDrawEnv /W=$graphname textxjust= 1,textyjust= 2
SetDrawEnv /W=$graphname save
radi = calc_graph_radius(30, projection=projection)
DrawText /W=$graphname radi, -0.1, "30<33>"
radi = calc_graph_radius(60, projection=projection)
DrawText /W=$graphname radi, -0.1, "60<36>"
endif
setdatafolder savedf setdatafolder savedf
end end
/// draw the circle of a diffraction cone in a stereographic polar graph.
///
/// the diffraction cone consists of a circle marking the diffraction ring, and a dot marking the axis.
/// the cone is drawn as a group of draw objects on the UserFront layer.
/// the objects can be edited interactively.
///
/// @param graphname name of graph window (not implemented yet).
///
/// @param groupname name of a drawing group.
/// if the group exists (from a previous cone) it is replaced.
/// if the group doesn't exist, a new one is created.
///
/// @param theta_axis polar angle of the cone axis in degrees.
///
/// @param theta_inner polar angle of the innermost point of the circle in degrees.
///
/// @param phi azimuthal angle of the cone axis in degrees.
///
/// @warning EXPERIMENTAL!
/// this function is under development.
/// the interface and behaviour of this function may change significantly in future versions.
///
function draw_diffraction_cone(graphname, groupname, theta_axis, theta_inner, phi)
string graphname
string groupname
variable theta_axis
variable theta_inner
variable phi
variable r_axis = calc_graph_radius(theta_axis)
variable r_inner = calc_graph_radius(theta_inner)
variable r_outer = calc_graph_radius(2 * theta_axis - theta_inner)
SetDrawEnv push
SetDrawLayer UserFront
DrawAction getgroup=$groupname, delete
SetDrawEnv gstart, gname=$groupname
variable xc, yc, xr, yr
// cone periphery
variable r_center = (r_outer + r_inner) / 2
variable r_radius = (r_outer - r_inner) / 2
xc = r_center * cos(phi * pi / 180)
yc = r_center * sin(phi * pi / 180)
xr = r_radius
yr = r_radius
SetDrawEnv xcoord=HorizCrossing, ycoord=VertCrossing
SetDrawEnv dash=11, fillpat=0
DrawOval xc - xr, yc - yr, xc + xr, yc + yr
// cone axis
xc = r_axis * cos(phi * pi / 180)
yc = r_axis * sin(phi * pi / 180)
r_radius = calc_graph_radius(2)
xr = r_radius
yr = r_radius
SetDrawEnv xcoord=HorizCrossing, ycoord=VertCrossing
SetDrawEnv fillfgc=(0,0,0)
DrawOval xc - xr, yc - yr, xc + xr, yc + yr
SetDrawEnv gstop
SetDrawEnv pop
end
/// display a polar graph with lines indicating the angles covered by an angle scan. /// display a polar graph with lines indicating the angles covered by an angle scan.
/// ///
/// @param nickname nick name for output data. /// @param nickname nick name for output data.
@ -2021,7 +2220,13 @@ function hemi_add_aziscan(nickname, values, polar, azi, [weights])
w_values[d1, d1 + nd - 1] = w_totals[p] / w_weights[p] w_values[d1, d1 + nd - 1] = w_totals[p] / w_weights[p]
end end
/// interpolate a hemispherical scan onto a rectangular grid
///
/// @warning experimental /// @warning experimental
/// this function has been tested for one specific set of scan parameters.
/// the interface and code may change at any time.
/// the function depends on the ster_x and ster_y waves that are created by display_hemi_scan.
///
function interpolate_hemi_scan(nickname) function interpolate_hemi_scan(nickname)
string nickname string nickname
@ -2044,21 +2249,26 @@ function interpolate_hemi_scan(nickname)
wave ster_x = $s_ster_x wave ster_x = $s_ster_x
wave ster_y = $s_ster_y wave ster_y = $s_ster_y
wavestats /q/m=0 ster_x variable min_ster_x = wavemin(ster_x)
variable x0 = v_min variable max_ster_x = wavemax(ster_x)
variable x0 = min_ster_x
variable xn = 181 variable xn = 181
variable dx = (v_max - v_min) / (xn - 1) variable dx = (max_ster_x - min_ster_x) / (xn - 1)
make /n=(v_npnts, 3) /free triplet make /n=(numpnts(ster_x), 3) /free triplet
triplet[][0] = ster_x[p] triplet[][0] = ster_x[p]
triplet[][1] = ster_y[p] triplet[][1] = ster_y[p]
triplet[][2] = values[p] triplet[][2] = values[p]
//ImageInterpolate /stw /s={x0, dx, xn, x0, dx, xn} voronoi triplet //ImageInterpolate /stw /s={x0, dx, xn, x0, dx, xn} voronoi triplet
make /n=(181, 181) /d /o $(s_prefix + "matrix") /wave=matrix variable size = 181
make /n=(181, 181) /free mnorm make /n=(size, size) /d /o $(s_prefix + "matrix") /wave=matrix
make /n=(size, size) /free mnorm
ImageFromXYZ /as {ster_x, ster_y, values}, matrix, mnorm ImageFromXYZ /as {ster_x, ster_y, values}, matrix, mnorm
matrix /= mnorm matrix /= mnorm
//matrixfilter NanZapMedian, matrix matrixfilter NanZapMedian, matrix
matrixfilter gauss, matrix
matrix = (x^2 + y^2) < 4 ? matrix : nan
end end
/// map angle scan data onto a rectangular grid in stereographic projection /// map angle scan data onto a rectangular grid in stereographic projection
@ -2234,3 +2444,44 @@ function load_hemi_scan(nickname, pathname, filename)
setdatafolder saveDF setdatafolder saveDF
end end
/// import a hemispherical scan from theta-phi-intensity waves and display it
///
/// @warning EXPERIMENTAL
/// the interface and behaviour of this function may change
///
function import_tpi_scan(nickname, theta, phi, intensity, [folding, npolar, nograph, xpdplot])
string nickname
wave theta
wave phi
wave intensity
variable folding
variable npolar
variable nograph
variable xpdplot
if (ParamIsDefault(npolar))
npolar = 91
endif
if (ParamIsDefault(nograph))
nograph = 0
endif
if (ParamIsDefault(folding))
folding = 1
endif
if (ParamIsDefault(xpdplot))
xpdplot = 0
endif
make_hemi_grid(npolar, nickname, xpdplot=xpdplot)
variable ifold
duplicate /free phi, fold_phi
for (ifold = 0; ifold < folding; ifold += 1)
hemi_add_anglescan(nickname, intensity, theta, fold_phi)
fold_phi = fold_phi >= 180 ? fold_phi + 360 / folding - fold_phi : fold_phi + 360 / folding
endfor
display_hemi_scan(nickname)
end

View File

@ -2,6 +2,7 @@
#pragma IgorVersion = 6.2 #pragma IgorVersion = 6.2
#pragma ModuleName = PearlFitFuncs #pragma ModuleName = PearlFitFuncs
#pragma version = 1.01 #pragma version = 1.01
#include "mm-physconst", version >= 1.05
// various fit functions for photoelectron spectroscopy // various fit functions for photoelectron spectroscopy
@ -682,7 +683,7 @@ function FermiGaussConv(pw, yw, xw) : FitFunc
variable xd = wavemin(xdw) / oversampling variable xd = wavemin(xdw) / oversampling
// calculate gausswave size based on pw[5] and precision variable // calculate gausswave size based on pw[5] and precision variable
variable x0g = pw[5] * precision_g variable x0g = abs(pw[5]) * precision_g
variable ng = 2 * floor(x0g / xd) + 1 variable ng = 2 * floor(x0g / xd) + 1
// calculate fermiwave size based on desired range for yw // calculate fermiwave size based on desired range for yw