From 43689ef16280f4e944721733871fd9d93e347397 Mon Sep 17 00:00:00 2001 From: matthias muntwiler Date: Tue, 1 Mar 2022 15:33:15 +0100 Subject: [PATCH] compile documentation for release 3.0.0 --- doc/html/_page_projections.html | 56 +- doc/html/anglescan-processing_8dox.html | 24 +- doc/html/annotated.html | 24 +- doc/html/classes.html | 34 +- .../dir_fe5dc42579d4b99403482a3a637d9f7d.html | 29 +- doc/html/doxygen.css | 303 +- doc/html/dynsections.js | 29 +- doc/html/fermi-edge-analysis_8ipf.html | 103 +- doc/html/fermi-edge-analysis_8ipf.js | 1 - doc/html/fermi-edge-analysis_8ipf_source.html | 328 +- doc/html/files.html | 28 +- doc/html/files.js | 26 - doc/html/functions.html | 24 +- doc/html/functions_vars.html | 24 +- doc/html/globals.html | 38 +- doc/html/globals_b.html | 58 +- doc/html/globals_c.html | 31 +- doc/html/globals_d.html | 29 +- doc/html/globals_e.html | 27 +- doc/html/globals_f.html | 33 +- doc/html/globals_func.html | 38 +- doc/html/globals_func_b.html | 58 +- doc/html/globals_func_c.html | 31 +- doc/html/globals_func_d.html | 29 +- doc/html/globals_func_e.html | 27 +- doc/html/globals_func_f.html | 33 +- doc/html/globals_func_g.html | 36 +- doc/html/globals_func_h.html | 48 +- doc/html/globals_func_i.html | 24 +- doc/html/globals_func_k.html | 27 +- doc/html/globals_func_l.html | 42 +- doc/html/globals_func_m.html | 31 +- doc/html/globals_func_n.html | 24 +- doc/html/globals_func_o.html | 24 +- doc/html/globals_func_p.html | 137 +- doc/html/globals_func_q.html | 24 +- doc/html/globals_func_r.html | 26 +- doc/html/globals_func_s.html | 44 +- doc/html/globals_func_t.html | 24 +- doc/html/globals_func_u.html | 36 +- doc/html/globals_func_w.html | 24 +- doc/html/globals_g.html | 36 +- doc/html/globals_h.html | 48 +- doc/html/globals_i.html | 24 +- doc/html/globals_k.html | 75 +- doc/html/globals_l.html | 42 +- doc/html/globals_m.html | 31 +- doc/html/globals_n.html | 24 +- doc/html/globals_o.html | 24 +- doc/html/globals_p.html | 144 +- doc/html/globals_q.html | 24 +- doc/html/globals_r.html | 26 +- doc/html/globals_s.html | 44 +- doc/html/globals_t.html | 24 +- doc/html/globals_u.html | 36 +- doc/html/globals_v.html | 25 +- doc/html/globals_vars.html | 80 +- doc/html/globals_w.html | 24 +- doc/html/group___arpes_package.html | 47 +- doc/html/group___arpes_package.js | 3 +- doc/html/index.html | 41 +- doc/html/jquery.js | 94 +- doc/html/mainpage_8dox.html | 24 +- doc/html/menu.js | 26 +- doc/html/menudata.js | 22 + doc/html/modules.html | 24 +- doc/html/namespace_pearl_anglescan_panel.html | 28 +- .../namespace_pearl_anglescan_process.html | 28 +- doc/html/namespace_pearl_area_display.html | 38 +- doc/html/namespace_pearl_area_import.html | 28 +- doc/html/namespace_pearl_area_profiles.html | 26 +- doc/html/namespace_pearl_arpes.html | 28 +- doc/html/namespace_pearl_compat.html | 28 +- doc/html/namespace_pearl_data_explorer.html | 106 - doc/html/namespace_pearl_elog.html | 28 +- doc/html/namespace_pearl_fit_funcs.html | 28 +- doc/html/namespace_pearl_matrix_import.html | 28 +- doc/html/namespace_pearl_p_shell_import.html | 28 +- doc/html/namespace_pearl_pmsco_import.html | 28 +- .../namespace_pearl_scienta_countrate.html | 106 - .../namespace_pearl_scienta_preprocess.html | 28 +- .../namespace_pearl_vector_operations.html | 28 +- doc/html/namespaces.html | 41 +- doc/html/namespaces.js | 19 - doc/html/navtree.css | 2 +- doc/html/navtree.js | 67 +- doc/html/navtreedata.js | 34 +- doc/html/navtreeindex0.js | 166 +- doc/html/navtreeindex1.js | 134 +- doc/html/navtreeindex2.js | 184 +- doc/html/pag_anglescan_processing.html | 243 +- doc/html/pages.html | 26 +- doc/html/pearl-anglescan-panel_8ipf.html | 204 +- .../pearl-anglescan-panel_8ipf_source.html | 1659 +++++++++- doc/html/pearl-anglescan-process_8ipf.html | 591 +++- doc/html/pearl-anglescan-process_8ipf.js | 7 +- .../pearl-anglescan-process_8ipf_source.html | 2769 ++++++++++++++++- doc/html/pearl-anglescan-tracker_8ipf.html | 197 +- .../pearl-anglescan-tracker_8ipf_source.html | 1253 +++++++- doc/html/pearl-area-display_8ipf.html | 199 +- doc/html/pearl-area-display_8ipf_source.html | 1623 +++++++++- doc/html/pearl-area-import_8ipf.html | 143 +- doc/html/pearl-area-import_8ipf_source.html | 1834 ++++++++++- doc/html/pearl-area-profiles_8ipf.html | 84 +- doc/html/pearl-area-profiles_8ipf_source.html | 612 +++- doc/html/pearl-arpes_8ipf.html | 36 +- doc/html/pearl-arpes_8ipf_source.html | 66 +- doc/html/pearl-compat_8ipf.html | 26 +- doc/html/pearl-compat_8ipf_source.html | 68 +- doc/html/pearl-data-explorer_8ipf.html | 2209 ++++++++----- doc/html/pearl-data-explorer_8ipf.js | 56 +- doc/html/pearl-data-explorer_8ipf_source.html | 2274 +++++++++++++- doc/html/pearl-elog_8ipf.html | 246 +- doc/html/pearl-elog_8ipf_source.html | 1785 ++++++++++- doc/html/pearl-fitfuncs_8ipf.html | 231 +- doc/html/pearl-fitfuncs_8ipf.js | 6 +- doc/html/pearl-fitfuncs_8ipf_source.html | 894 +++++- doc/html/pearl-gui-tools_8ipf.html | 30 +- doc/html/pearl-gui-tools_8ipf_source.html | 83 +- doc/html/pearl-matrix-import_8ipf.html | 112 +- doc/html/pearl-matrix-import_8ipf_source.html | 730 ++++- doc/html/pearl-menu_8ipf.html | 58 +- doc/html/pearl-menu_8ipf_source.html | 286 +- doc/html/pearl-otf-import_8ipf.html | 24 +- doc/html/pearl-otf-import_8ipf_source.html | 360 ++- doc/html/pearl-pmsco-import_8ipf.html | 163 +- doc/html/pearl-pmsco-import_8ipf.js | 2 + doc/html/pearl-pmsco-import_8ipf_source.html | 236 +- doc/html/pearl-polar-coordinates_8ipf.html | 34 +- .../pearl-polar-coordinates_8ipf_source.html | 120 +- doc/html/pearl-pshell-import_8ipf.html | 2194 +++++++------ doc/html/pearl-pshell-import_8ipf.js | 73 +- doc/html/pearl-pshell-import_8ipf_source.html | 2011 +++++++++++- doc/html/pearl-scienta-countrate_8ipf.html | 235 -- doc/html/pearl-scienta-countrate_8ipf.js | 5 - .../pearl-scienta-countrate_8ipf_source.html | 105 - doc/html/pearl-scienta-preprocess_8ipf.html | 111 +- doc/html/pearl-scienta-preprocess_8ipf.js | 1 + .../pearl-scienta-preprocess_8ipf_source.html | 1344 +++++++- doc/html/pearl-tools_8ipf.html | 36 +- doc/html/pearl-tools_8ipf_source.html | 178 +- doc/html/pearl-vector-operations_8ipf.html | 66 +- .../pearl-vector-operations_8ipf_source.html | 175 +- doc/html/resize.js | 29 +- doc/html/search/all_0.html | 8 +- doc/html/search/all_0.js | 198 +- doc/html/search/all_1.html | 8 +- doc/html/search/all_1.js | 92 +- doc/html/search/all_10.html | 8 +- doc/html/search/all_10.js | 24 +- doc/html/search/all_11.html | 8 +- doc/html/search/all_11.js | 70 +- doc/html/search/all_12.html | 8 +- doc/html/search/all_12.js | 12 +- doc/html/search/all_13.html | 8 +- doc/html/search/all_13.js | 28 +- doc/html/search/all_14.html | 8 +- doc/html/search/all_14.js | 2 +- doc/html/search/all_15.html | 8 +- doc/html/search/all_15.js | 6 +- doc/html/search/all_16.html | 8 +- doc/html/search/all_16.js | 4 +- doc/html/search/all_17.html | 8 +- doc/html/search/all_17.js | 2 +- doc/html/search/all_2.html | 8 +- doc/html/search/all_2.js | 63 +- doc/html/search/all_3.html | 8 +- doc/html/search/all_3.js | 61 +- doc/html/search/all_4.html | 8 +- doc/html/search/all_4.js | 47 +- doc/html/search/all_5.html | 8 +- doc/html/search/all_5.js | 17 +- doc/html/search/all_6.html | 8 +- doc/html/search/all_6.js | 36 +- doc/html/search/all_7.html | 8 +- doc/html/search/all_7.js | 18 +- doc/html/search/all_8.html | 8 +- doc/html/search/all_8.js | 34 +- doc/html/search/all_9.html | 8 +- doc/html/search/all_9.js | 74 +- doc/html/search/all_a.html | 8 +- doc/html/search/all_a.js | 32 +- doc/html/search/all_b.html | 8 +- doc/html/search/all_b.js | 51 +- doc/html/search/all_c.html | 8 +- doc/html/search/all_c.js | 18 +- doc/html/search/all_d.html | 8 +- doc/html/search/all_d.js | 20 +- doc/html/search/all_e.html | 8 +- doc/html/search/all_e.js | 259 +- doc/html/search/all_f.html | 8 +- doc/html/search/all_f.js | 2 +- doc/html/search/classes_0.html | 8 +- doc/html/search/classes_0.js | 2 +- doc/html/search/classes_1.html | 8 +- doc/html/search/classes_1.js | 2 +- doc/html/search/files_0.html | 8 +- doc/html/search/files_0.js | 2 +- doc/html/search/files_1.html | 8 +- doc/html/search/files_1.js | 2 +- doc/html/search/files_2.html | 8 +- doc/html/search/files_2.js | 2 +- doc/html/search/files_3.html | 8 +- doc/html/search/files_3.js | 44 +- doc/html/search/functions_0.html | 8 +- doc/html/search/functions_0.js | 190 +- doc/html/search/functions_1.html | 8 +- doc/html/search/functions_1.js | 90 +- doc/html/search/functions_10.html | 8 +- doc/html/search/functions_10.js | 24 +- doc/html/search/functions_11.html | 8 +- doc/html/search/functions_11.js | 68 +- doc/html/search/functions_12.html | 8 +- doc/html/search/functions_12.js | 10 +- doc/html/search/functions_13.html | 8 +- doc/html/search/functions_13.js | 26 +- doc/html/search/functions_14.html | 8 +- doc/html/search/functions_14.js | 2 +- doc/html/search/functions_2.html | 8 +- doc/html/search/functions_2.js | 61 +- doc/html/search/functions_3.html | 8 +- doc/html/search/functions_3.js | 59 +- doc/html/search/functions_4.html | 8 +- doc/html/search/functions_4.js | 39 +- doc/html/search/functions_5.html | 8 +- doc/html/search/functions_5.js | 13 +- doc/html/search/functions_6.html | 8 +- doc/html/search/functions_6.js | 36 +- doc/html/search/functions_7.html | 8 +- doc/html/search/functions_7.js | 16 +- doc/html/search/functions_8.html | 8 +- doc/html/search/functions_8.js | 28 +- doc/html/search/functions_9.html | 8 +- doc/html/search/functions_9.js | 3 +- doc/html/search/functions_a.html | 8 +- doc/html/search/functions_a.js | 32 +- doc/html/search/functions_b.html | 8 +- doc/html/search/functions_b.js | 41 +- doc/html/search/functions_c.html | 8 +- doc/html/search/functions_c.js | 14 +- doc/html/search/functions_d.html | 8 +- doc/html/search/functions_d.js | 18 +- doc/html/search/functions_e.html | 8 +- doc/html/search/functions_e.js | 173 +- doc/html/search/functions_f.html | 8 +- doc/html/search/functions_f.js | 2 +- doc/html/search/groups_0.html | 8 +- doc/html/search/groups_0.js | 2 +- doc/html/search/mag_sel.png | Bin 563 -> 465 bytes doc/html/search/namespaces_0.html | 8 +- doc/html/search/namespaces_0.js | 31 +- doc/html/search/nomatches.html | 2 +- doc/html/search/pages_0.html | 8 +- doc/html/search/pages_0.js | 2 +- doc/html/search/pages_1.html | 8 +- doc/html/search/pages_1.js | 2 +- doc/html/search/pages_2.html | 8 +- doc/html/search/pages_2.js | 2 +- doc/html/search/pages_3.html | 8 +- doc/html/search/pages_3.js | 2 +- doc/html/search/search.js | 25 +- doc/html/search/search_l.png | Bin 604 -> 567 bytes doc/html/search/search_r.png | Bin 612 -> 553 bytes doc/html/search/variables_0.html | 8 +- doc/html/search/variables_0.js | 2 +- doc/html/search/variables_1.html | 8 +- doc/html/search/variables_1.js | 2 +- doc/html/search/variables_10.html | 8 +- doc/html/search/variables_10.js | 4 +- doc/html/search/variables_11.html | 8 +- doc/html/search/variables_11.js | 2 +- doc/html/search/variables_2.html | 8 +- doc/html/search/variables_2.js | 2 +- doc/html/search/variables_3.html | 8 +- doc/html/search/variables_3.js | 6 +- doc/html/search/variables_4.html | 8 +- doc/html/search/variables_4.js | 2 +- doc/html/search/variables_5.html | 8 +- doc/html/search/variables_5.js | 2 +- doc/html/search/variables_6.html | 8 +- doc/html/search/variables_6.js | 4 +- doc/html/search/variables_7.html | 8 +- doc/html/search/variables_7.js | 71 +- doc/html/search/variables_8.html | 8 +- doc/html/search/variables_8.js | 8 +- doc/html/search/variables_9.html | 8 +- doc/html/search/variables_9.js | 4 +- doc/html/search/variables_a.html | 8 +- doc/html/search/variables_a.js | 2 +- doc/html/search/variables_b.html | 8 +- doc/html/search/variables_b.js | 10 +- doc/html/search/variables_c.html | 8 +- doc/html/search/variables_c.js | 2 +- doc/html/search/variables_d.html | 8 +- doc/html/search/variables_d.js | 2 +- doc/html/search/variables_e.html | 8 +- doc/html/search/variables_e.js | 2 +- doc/html/search/variables_f.html | 8 +- doc/html/search/variables_f.js | 4 +- doc/html/struct_doniach_sunjic_struct.html | 44 +- doc/html/structerror_code.html | 48 +- doc/html/tabs.css | 2 +- doc/html/todo.html | 47 +- doc/latex/refman.pdf | Bin 713498 -> 0 bytes 304 files changed, 28296 insertions(+), 7262 deletions(-) delete mode 100644 doc/html/files.js delete mode 100644 doc/html/namespace_pearl_data_explorer.html delete mode 100644 doc/html/namespace_pearl_scienta_countrate.html delete mode 100644 doc/html/namespaces.js delete mode 100644 doc/html/pearl-scienta-countrate_8ipf.html delete mode 100644 doc/html/pearl-scienta-countrate_8ipf.js delete mode 100644 doc/html/pearl-scienta-countrate_8ipf_source.html delete mode 100644 doc/latex/refman.pdf diff --git a/doc/html/_page_projections.html b/doc/html/_page_projections.html index a61ea07..9021cd6 100644 --- a/doc/html/_page_projections.html +++ b/doc/html/_page_projections.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Projections @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@ - + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -80,36 +82,36 @@ $(document).ready(function(){initNavTree('_page_projections.html','');});
-
+
Projections
-

the functions of the anglescan package support the following map projections.

-

for a description of the different projections, see, for example, https://en.wikipedia.org/wiki/Map_projection

- - - - - - - - - - - - - +

the functions of the anglescan package support the following map projections. for a description of the different projections, see, for example, https://en.wikipedia.org/wiki/Map_projection

+
Selector Projection Function Properties
kProjDist = 0 azimuthal equidistant r = c * theta radius is proportional to polar angle.
kProjStereo = 1 stereographic r = c * tan theta/2 circles on sphere map to circles.
kProjArea = 2 azimuthal equal-area r = c * sin theta/2 preserves area measure.
kProjGnom = 3 gnomonic r = c * tan theta great circles map to straight lines.
kProjOrtho = 4 orthographic r = c * sin theta k-space mapping in ARPES and LEED.
+ + + + + + + + + + + +
Selector Projection Function Properties
kProjDist = 0 azimuthal equidistant r = c * theta radius is proportional to polar angle.
kProjStereo = 1 stereographic r = c * tan theta/2 circles on sphere map to circles.
kProjArea = 2 azimuthal equal-area r = c * sin theta/2 preserves area measure.
kProjGnom = 3 gnomonic r = c * tan theta great circles map to straight lines.
kProjOrtho = 4 orthographic r = c * sin theta k-space mapping in ARPES and LEED.

the projections in this package are defined for 0 <= theta < 90.

+
diff --git a/doc/html/anglescan-processing_8dox.html b/doc/html/anglescan-processing_8dox.html index 65e6759..d21e881 100644 --- a/doc/html/anglescan-processing_8dox.html +++ b/doc/html/anglescan-processing_8dox.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: anglescan-processing.dox File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@ - + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -91,9 +93,9 @@ $(document).ready(function(){initNavTree('anglescan-processing_8dox.html','');}) diff --git a/doc/html/annotated.html b/doc/html/annotated.html index baf2e44..8f4a839 100644 --- a/doc/html/annotated.html +++ b/doc/html/annotated.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Data Structures @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@
- + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -96,9 +98,9 @@ $(document).ready(function(){initNavTree('annotated.html','');}); diff --git a/doc/html/classes.html b/doc/html/classes.html index c6bc203..81d3e92 100644 --- a/doc/html/classes.html +++ b/doc/html/classes.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Data Structure Index @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@
- + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -88,10 +90,14 @@ $(document).ready(function(){initNavTree('classes.html','');});
d | e
+ + + - + + +
  d  
-
  e  
-
  e  
+
DoniachSunjicStruct   errorCode   
DoniachSunjicStruct   errorCode   
d | e
@@ -100,9 +106,9 @@ $(document).ready(function(){initNavTree('classes.html','');}); diff --git a/doc/html/dir_fe5dc42579d4b99403482a3a637d9f7d.html b/doc/html/dir_fe5dc42579d4b99403482a3a637d9f7d.html index 97cdf41..9243214 100644 --- a/doc/html/dir_fe5dc42579d4b99403482a3a637d9f7d.html +++ b/doc/html/dir_fe5dc42579d4b99403482a3a637d9f7d.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl Directory Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@
- + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -115,7 +117,6 @@ Files  compatibility procedures for igor 8
  file  pearl-data-explorer.ipf [code] - preview and import panel for PEARL data
  file  pearl-elog.ipf [code]  interface for writing ELOG entries with Igor graphs as attachment.
@@ -140,8 +141,8 @@ Files file  pearl-pshell-import.ipf [code]  import data from PShell
  -file  pearl-scienta-countrate.ipf [code] - count rate functions for Scienta detector images.
+file  pearl-scienta-live.ipf [code] + utility functions for operating the Scienta analyser.
  file  pearl-scienta-preprocess.ipf [code]  preprocessing functions for Scienta detector images.
@@ -158,9 +159,9 @@ Files diff --git a/doc/html/doxygen.css b/doc/html/doxygen.css index 4f1ab91..73ecbb2 100644 --- a/doc/html/doxygen.css +++ b/doc/html/doxygen.css @@ -1,4 +1,4 @@ -/* The standard CSS for doxygen 1.8.13 */ +/* The standard CSS for doxygen 1.8.17 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; @@ -53,17 +53,24 @@ dt { font-weight: bold; } -div.multicol { +ul.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; + column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; + column-count: 3; } p.startli, p.startdd { margin-top: 2px; } +th p.starttd, p.intertd, p.endtd { + font-size: 100%; + font-weight: 700; +} + p.starttd { margin-top: 0px; } @@ -80,6 +87,15 @@ p.endtd { margin-bottom: 2px; } +p.interli { +} + +p.interdd { +} + +p.intertd { +} + /* @end */ caption { @@ -134,12 +150,12 @@ a.qindex { a.qindexHL { font-weight: bold; background-color: #9CAFD4; - color: #ffffff; + color: #FFFFFF; border: 1px double #869DCA; } .contents a.qindexHL:visited { - color: #ffffff; + color: #FFFFFF; } a.el { @@ -163,6 +179,25 @@ dl.el { margin-left: -1cm; } +ul { + overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; @@ -177,8 +212,8 @@ pre.fragment { } div.fragment { - padding: 0px; - margin: 4px 8px 4px 2px; + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; background-color: #FBFCFD; border: 1px solid #C4CFE5; } @@ -248,7 +283,7 @@ span.lineno a:hover { div.ah, span.ah { background-color: black; font-weight: bold; - color: #ffffff; + color: #FFFFFF; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; @@ -324,7 +359,7 @@ img.formulaDsp { } -img.formulaInl { +img.formulaInl, img.inline { vertical-align: middle; } @@ -402,6 +437,13 @@ blockquote { padding: 0 12px 0 16px; } +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #9CAFD4; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + /* @end */ /* @@ -498,7 +540,7 @@ table.memberdecls { white-space: nowrap; } -.memItemRight { +.memItemRight, .memTemplItemRight { width: 100%; } @@ -666,17 +708,17 @@ dl.reflist dd { padding-left: 0px; } -.params .paramname, .retval .paramname { +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { font-weight: bold; vertical-align: top; } -.params .paramtype { +.params .paramtype, .tparams .paramtype { font-style: italic; vertical-align: top; } -.params .paramdir { +.params .paramdir, .tparams .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } @@ -1081,72 +1123,143 @@ div.headertitle padding: 5px 5px 5px 10px; } -dl -{ - padding: 0 0 0 10px; +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; } -/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ -dl.section -{ +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { margin-left: 0px; padding-left: 0px; } -dl.note -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #D0C000; +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; } -dl.warning, dl.attention -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #FF0000; +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; } -dl.pre, dl.post, dl.invariant -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00D000; +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; } -dl.deprecated -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #505050; +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; } -dl.todo -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00C0E0; +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; } -dl.test -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #3030E0; +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; } -dl.bug -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #C08050; +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; } dl.section dd { @@ -1263,6 +1376,11 @@ div.toc { width: 200px; } +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; @@ -1271,6 +1389,12 @@ div.toc li { padding-top: 2px; } +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #4665A2; @@ -1300,6 +1424,26 @@ div.toc li.level4 { margin-left: 45px; } +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + .inherit_header { font-weight: bold; color: gray; @@ -1413,7 +1557,7 @@ tr.heading h2 { } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { - border-top-color: #ffffff; + border-top-color: #FFFFFF; border-width: 10px; margin: 0px -10px; } @@ -1441,7 +1585,7 @@ tr.heading h2 { } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { - border-bottom-color: #ffffff; + border-bottom-color: #FFFFFF; border-width: 10px; margin: 0px -10px; } @@ -1468,7 +1612,7 @@ tr.heading h2 { left: 100%; } #powerTip.e:after { - border-left-color: #ffffff; + border-left-color: #FFFFFF; border-width: 10px; top: 50%; margin-top: -10px; @@ -1484,7 +1628,7 @@ tr.heading h2 { right: 100%; } #powerTip.w:after { - border-right-color: #ffffff; + border-right-color: #FFFFFF; border-width: 10px; top: 50%; margin-top: -10px; @@ -1592,5 +1736,36 @@ th.markdownTableHeadCenter, td.markdownTableBodyCenter { text-align: center } +.DocNodeRTL { + text-align: right; + direction: rtl; +} +.DocNodeLTR { + text-align: left; + direction: ltr; +} + +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; +} + +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; +} + +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; +} /* @end */ + +u { + text-decoration: underline; +} + diff --git a/doc/html/dynsections.js b/doc/html/dynsections.js index 1e6bf07..c8e84aa 100644 --- a/doc/html/dynsections.js +++ b/doc/html/dynsections.js @@ -1,3 +1,26 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); @@ -15,7 +38,7 @@ function toggleVisibility(linkObj) summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); - } + } return false; } @@ -94,11 +117,11 @@ function toggleInherit(id) $(img).attr('src',src.substring(0,src.length-10)+'open.png'); } } - +/* @license-end */ $(document).ready(function() { $('.code,.codeRef').each(function() { - $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html()); + $(this).data('powertip',$('#a'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html()); $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true }); }); }); diff --git a/doc/html/fermi-edge-analysis_8ipf.html b/doc/html/fermi-edge-analysis_8ipf.html index 61f8cc0..8fd4166 100644 --- a/doc/html/fermi-edge-analysis_8ipf.html +++ b/doc/html/fermi-edge-analysis_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: fermi-edge-analysis.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@
- + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -111,23 +113,20 @@ Functions   variable show_shift (wave data)   -variable analyser_energy_resolution (variable epass, variable slit) - calculate the energy resolution of the analyser More...
-  - + - + - + - +

Variables

static const variable mcp_radius_pix = 555
 MCP radius seen by the camera in pixels. More...
 MCP radius seen by the camera in pixels. More...
 
static const variable mcp_radius_mm = 20
 physical size (radius) of the MCP in mm More...
 physical size (radius) of the MCP in mm More...
 
static const variable hemi_radius_mm = 200
 physical size (radius) of the hemisphere in mm More...
 physical size (radius) of the hemisphere in mm More...
 
static const variable mcp_radius_epass = 0.04
 energy range imaged on MCP relative to the pass energy More...
 energy range imaged on MCP relative to the pass energy More...
 

Detailed Description

@@ -142,9 +141,9 @@ Variables
Author
matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
thomas dienel
-
-

Definition at line 27 of file fermi-edge-analysis.ipf.

- -
- - -

◆ analyser_energy_resolution()

- -
-
- - - - - - - - - - - - - - - - - - -
variable analyser_energy_resolution (variable epass,
variable slit 
)
-
- -

calculate the energy resolution of the analyser

-
Parameters
- - - -
epasspass energy in eV
slitanalyser entrance slit in mm
-
-
-
Returns
energy resolution (FWHM)
- -

Definition at line 306 of file fermi-edge-analysis.ipf.

+

Definition at line 28 of file fermi-edge-analysis.ipf.

@@ -241,7 +200,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
-

Definition at line 216 of file fermi-edge-analysis.ipf.

+

Definition at line 217 of file fermi-edge-analysis.ipf.

@@ -271,7 +230,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
-

Definition at line 116 of file fermi-edge-analysis.ipf.

+

Definition at line 117 of file fermi-edge-analysis.ipf.

@@ -291,7 +250,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
-

Definition at line 98 of file fermi-edge-analysis.ipf.

+

Definition at line 99 of file fermi-edge-analysis.ipf.

@@ -311,7 +270,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
-

Definition at line 284 of file fermi-edge-analysis.ipf.

+

Definition at line 285 of file fermi-edge-analysis.ipf.

@@ -347,7 +306,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
-

Definition at line 173 of file fermi-edge-analysis.ipf.

+

Definition at line 174 of file fermi-edge-analysis.ipf.

@@ -377,7 +336,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
-

Definition at line 267 of file fermi-edge-analysis.ipf.

+

Definition at line 268 of file fermi-edge-analysis.ipf.

@@ -404,7 +363,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

physical size (radius) of the hemisphere in mm

-

Definition at line 263 of file fermi-edge-analysis.ipf.

+

Definition at line 264 of file fermi-edge-analysis.ipf.

@@ -430,7 +389,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

energy range imaged on MCP relative to the pass energy

-

Definition at line 265 of file fermi-edge-analysis.ipf.

+

Definition at line 266 of file fermi-edge-analysis.ipf.

@@ -456,7 +415,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

physical size (radius) of the MCP in mm

-

Definition at line 261 of file fermi-edge-analysis.ipf.

+

Definition at line 262 of file fermi-edge-analysis.ipf.

@@ -482,7 +441,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

MCP radius seen by the camera in pixels.

-

Definition at line 259 of file fermi-edge-analysis.ipf.

+

Definition at line 260 of file fermi-edge-analysis.ipf.

@@ -492,9 +451,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/doc/html/fermi-edge-analysis_8ipf.js b/doc/html/fermi-edge-analysis_8ipf.js index eea1f88..8af98dd 100644 --- a/doc/html/fermi-edge-analysis_8ipf.js +++ b/doc/html/fermi-edge-analysis_8ipf.js @@ -1,7 +1,6 @@ var fermi_edge_analysis_8ipf = [ [ "analyse_curved_edge", "fermi-edge-analysis_8ipf.html#a1c4a805435a1d43c2b6dfb6deb633894", null ], - [ "analyser_energy_resolution", "fermi-edge-analysis_8ipf.html#ad23de34bb698589e2576ce2836b89d55", null ], [ "FermiFuncLinDOS2D_corr", "fermi-edge-analysis_8ipf.html#a520d8de9fbc4276c19fb417861f05b0d", null ], [ "integrate_curved_edge", "fermi-edge-analysis_8ipf.html#a2a1d7b49c1f88f29ee6d49f6a6f4fbf8", null ], [ "record_results", "fermi-edge-analysis_8ipf.html#aac6bac1ee0582caa0676bdc9c2d254f0", null ], diff --git a/doc/html/fermi-edge-analysis_8ipf_source.html b/doc/html/fermi-edge-analysis_8ipf_source.html index 2e68d7d..0b5aebd 100644 --- a/doc/html/fermi-edge-analysis_8ipf_source.html +++ b/doc/html/fermi-edge-analysis_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: fermi-edge-analysis.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@ - + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -85,29 +87,305 @@ $(document).ready(function(){initNavTree('fermi-edge-analysis_8ipf_source.html',
fermi-edge-analysis.ipf
-Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #include "pearl-area-profiles"
3 
4 // $Id$
5 
25 
26 
27 function analyse_curved_edge(data)
28  wave data // 2D counts data, x-scale = kinetic energy, y-scale = analyser angle
29  variable guess_EF // initial guess of the Fermi level
30 
31  dfref savedf = GetDataFolderDFR()
32  dfref datadf = GetWavesDataFolderDFR(data)
33  setdatafolder datadf
34 
35  make /n=5 /d /o w_coef_int
36  make /n=7 /d /o w_coef_curved
37 
38  // 1) integrate data
39  wave xint = ad_profile_x(data, -inf, inf, "", noavg=1)
40  duplicate /free xint, xint_sig
41  xint_sig = sqrt(xint * 4) / 4
42  variable xmin = wavemin(xint)
43  variable xmax = wavemax(xint)
44  variable xmean = mean(xint)
45 
46  // 2) fit integrated data for reference
47  w_coef_int[0] = xmin
48  w_coef_int[1] = 0
49  w_coef_int[2] = xmax - xmin
50  w_coef_int[3] = dimoffset(xint, 0) + dimdelta(xint, 0) * dimsize(xint, 0) / 2
51  w_coef_int[4] = 100
52  FuncFit /NTHR=0 FermiFuncLinDOS w_coef_int xint /D /I=1 /W=xint_sig
53  wave w_sigma
54  duplicate /o w_sigma, w_sigma_int
55 
56  // 3) normalize data
57  wave yavg = ad_profile_y(data, -inf, inf, "")
58  variable ymean = mean(yavg)
59 
60  duplicate /o data, data_norm, data_sig
61  data_sig = sqrt(data * 4) / 4
62  data_norm = data_norm * ymean / yavg[q]
63  data_sig = data_sig * ymean / yavg[q]
64 
65  // 4) fit normalized data
66  wave xavg = ad_profile_x(data, -inf, inf, "")
67  xmin = wavemin(xavg)
68  xmax = wavemax(xavg)
69  xmean = mean(xavg)
70 
71  w_coef_curved[0] = {0, 0, 1, 95.5, 100, 0, -0.0001}
72  w_coef_curved[0] = xmin
73  w_coef_curved[2] = xmax - xmin
74  w_coef_curved[3] = w_coef_int[3]
75  w_coef_curved[4] = w_coef_int[4]
76 
77  //variable box = min(11, numpnts(xavg) / 5)
78  //FindLevel /B=(box) /EDGE=2 /Q xavg, (xmin + xmax) / 2
79  //if (v_flag == 0)
80  // w_coef_curved[3] = v_levelx
81  //else
82  // w_coef_curved[3] = dimoffset(data, 0) + dimdelta(data, 0) * dimsize(data, 0) / 2
83  //endif
84 
85  duplicate /o data_norm, fit_data_norm
86  FuncFitMD /X=1 /NTHR=0 FermiFuncLinDOS_2Dcorr w_coef_curved data_norm /D=fit_data_norm /I=1 /W=data_sig
87  wave w_sigma
88  duplicate /o w_sigma, w_sigma_curved
89 
90  display /k=1; appendimage data_norm
91  ModifyImage data_norm ctab= {xmin,xmax,Grays,0}
92  AppendMatrixContour fit_data_norm
93 
94  setdatafolder savedf
95  return 0
96 end
97 
98 function record_results(index)
99  variable index
100 
101  dfref savedf = GetDataFolderDFR()
102  wave /sdfr=root: Tint, Tint_sig, Tcurv, Tcurv_sig, EFcurv, EFcurv_sig
103  wave w_coef_int, w_coef_curved
104  wave w_sigma_int, w_sigma_curved
105 
106  Tint[index] = w_coef_int[4]
107  Tint_sig[index] = w_sigma_int[4]
108  Tcurv[index] = w_coef_curved[4]
109  Tcurv_sig[index] = w_sigma_curved[4]
110  EFcurv[index] = w_coef_curved[3]
111  EFcurv_sig[index] = w_sigma_curved[3]
112 
113  setdatafolder savedf
114 end
115 
116 function integrate_curved_edge(data, data_sig)
117  wave data
118  wave /z data_sig
119  //wave coef
120 
121  string name = nameofwave(data)
122 
123  duplicate /o data, data_out
124  redimension /n=(dimsize(data,0)) data_out
125  data_out = 0
126 
127  if (waveexists(data_sig))
128  duplicate /o data_sig, sig_out
129  redimension /n=(dimsize(data,0)) sig_out
130  sig_out = 0
131  endif
132 
133  wave ywgt = ad_profile_y(data, -inf, inf, "", noavg=1)
134  ywgt = 1 / ywgt / 4
135  //ywgt = 1 / 4
136  variable sum_ywgt = sum(ywgt)
137 
138  variable nx = dimsize(data, 0)
139  variable ny = dimsize(data, 1)
140  variable iy
141  variable yy
142  variable dx
143  variable dy
144  variable dp
145  variable dp_min = 0
146 
147  wave PassEnergy = :attr:PassEnergy
148  wave NumSlices = :attr:NumSlices
149 
150  for (iy = 0; iy < ny; iy += 1)
151  dy = dimoffset(data, 1) + dimdelta(data, 1) * iy
152  dy = dy / dimdelta(data, 1)
153  dx = slit_shift(dy * 902 / NumSlices[0], PassEnergy[0])
154  dp = round(dx / dimdelta(data, 0)) // <= 0
155  dp_min = min(dp_min, dp)
156 
157  data_out[] = p+dp >= 0 ? data_out + data[p+dp][iy] * ywgt[iy] : data_out
158 
159  if (waveexists(data_sig))
160  sig_out = p+dp >= 0 ? sig_out + data_sig[p+dp][iy] * ywgt[iy] : sig_out
161  endif
162  endfor
163 
164  data_out /= sum_ywgt
165  data_out[0, -dp_min][] = nan
166 
167  if (waveexists(sig_out))
168  sig_out /= sum_ywgt
169  //sig_out[0, -dp_min] = nan
170  endif
171 end
172 
173 function slit_correction(data, data_out, epass)
174  wave data // must be image with original dimensions (no cropping!)
175  wave /z data_out // 2D or 1D wave to receive the result
176  // X dimension must be identical to the one of data
177  // if 2D, Y dimension must be either identical to the one of data
178  // if 1D, the result will be the sum of the corrected slices
179  variable epass // pass energy
180 
181  if (!WaveExists(data_out))
182  string name = nameofwave(data) + "_corr"
183  duplicate /o data, $name
184  wave data_out = $name
185  //redimension /n=(dimsize(data,0)) data_out
186  endif
187  data_out = 0
188 
189  variable nx = dimsize(data, 0)
190  variable ny = dimsize(data, 1)
191  variable iy
192  variable yy
193  variable dx
194  variable dy
195  variable dp
196  variable dp_min = 0
197 
198  for (iy = 0; iy < ny; iy += 1)
199  dy = dimoffset(data, 1) + dimdelta(data, 1) * iy
200  dy = dy / dimdelta(data, 1)
201  dx = slit_shift(dy * 902 / ny, epass)
202  dp = round(dx / dimdelta(data, 0)) // <= 0
203  dp_min = min(dp_min, dp)
204 
205  if (wavedims(data_out) >= 2)
206  data_out[][iy] = p+dp >= 0 ? data_out + data[p+dp][iy] : data_out
207  else
208  data_out = p+dp >= 0 ? data_out + data[p+dp][iy] : data_out
209  endif
210  endfor
211 
212  data_out[0, -dp_min][] = nan
213 end
214 
215 //------------------------------------------------------------------------------
216 threadsafe Function FermiFuncLinDOS2D_corr(w,x,y) : FitFunc
217 // linear density of states below Fermi level
218 // 2D data with corrections:
219 // - straight slit (slit shift)
220 // - transmission function (polynomial)
221 //------------------------------------------------------------------------------
222  Wave w; Variable x; variable y
223  // w[0] = background far above the fermi level
224  // w[1] = slope of the linear background
225  // w[2] = amplitude
226  // w[3] = fermi level in eV
227  // w[4] = temperature in K
228  // w[5] = transmission - linear term
229  // w[6] = transmission - quadratic term
230  // w[7] = transmission - cubic term
231  // w[8] = pass energy (hold this value)
232  // w[9] = y scale: pixels / unit of y
233 
234  variable pos = w[3] + slit_shift(y * w[9], w[8])
235  variable transm = 1 + w[5] * y + w[6] * y^2 + w[7] * y^3
236  variable fermi = (w[1] * min(x - pos, 0) + w[2]) / ( exp( (x - pos) / (kBoltzmann * w[4]) ) + 1.0 )
237  return transm * (fermi + w[0])
238 end
239 
240 //------------------------------------------------------------------------------
241 threadsafe Function FermiFuncLinDOS_2Dcorr_old(w,x,y) : FitFunc
242 // linear density of states below Fermi level
243 // 2D data with a polynomial shift of the Fermi level in the second dimension
244 //------------------------------------------------------------------------------
245  Wave w; Variable x; variable y
246  // w[0] = background far above the fermi level
247  // w[1] = slope of the linear background
248  // w[2] = amplitude
249  // w[3] = fermi level in eV
250  // w[4] = temperature in K
251  // w[5] = shift - linear term
252  // w[6] = shift - quadratic term
253 
254  variable pos = w[3] + w[5] * y + w[6] * y^2
255  return w[0] + (w[1] * min(x - pos, 0) + w[2]) / ( exp( (x - pos) / (kBoltzmann * w[4]) ) + 1.0 )
256 end
257 
259 static constant mcp_radius_pix = 555
261 static constant mcp_radius_mm = 20
263 static constant hemi_radius_mm = 200
265 static constant mcp_radius_epass = 0.04
266 
267 threadsafe function slit_shift(ypix, epass)
268  // calculates the energy shift due to straight slit
269  // the radius of the curve is 1/2 of the hemisphere radius
270  variable ypix // vertical (angle/position) pixels distance from center
271  // = slice coordinate * 902 / number of slices
272  variable epass // pass energy
273 
274  variable rpix = mcp_radius_pix * hemi_radius_mm / mcp_radius_mm
275  //variable rpix = mcp_radius_pix * hemi_radius_mm / 2 / mcp_radius_mm
276  variable rene = epass * mcp_radius_epass * hemi_radius_mm / 2 / mcp_radius_mm
277 
278  variable isin = asin(ypix / rpix)
279  variable dene = rene * (cos(isin) - 1)
280 
281  return dene
282 end
283 
284 function show_shift(data)
285  wave data
286  variable epass
287 
288  variable ny = dimsize(data, 1)
289  make /o /n=(ny) shift_x
290  setscale /i x -ny/2, ny/2, "", shift_x
291  wave PassEnergy = :attr:PassEnergy
292  wave NumSlices = :attr:NumSlices
293 
294  shift_x = slit_shift(x * 902 / NumSlices[0], PassEnergy[0])
295 
296  variable ecenter = dimoffset(data, 0) + dimdelta(data, 0) * dimsize(data, 0) / 2
297  shift_x += ecenter
298 end
299 
306 function analyser_energy_resolution(epass, slit)
307  variable epass
308  variable slit
309 
310  variable respow
311  if (epass < 4)
312  respow = 1110
313  elseif (epass < 8)
314  respow = 1400
315  else
316  respow = 1750
317  endif
318 
319  return epass * max(0.2, slit) / 0.2 / respow
320 end
threadsafe variable FermiFuncLinDOS2D_corr(variable w, threadsafe x, wave y)
-
threadsafe variable slit_shift(variable ypix, variable epass)
-
static const variable mcp_radius_pix
MCP radius seen by the camera in pixels.
-
static const variable mcp_radius_mm
physical size (radius) of the MCP in mm
-
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.
-
variable analyse_curved_edge(wave data)
-
static const variable hemi_radius_mm
physical size (radius) of the hemisphere in mm
-
variable analyser_energy_resolution(variable epass, variable slit)
calculate the energy resolution of the analyser
-
variable slit_correction(wave data, wave data_out, variable epass)
-
static const variable mcp_radius_epass
energy range imaged on MCP relative to the pass energy
-
variable integrate_curved_edge(wave data, wave data_sig)
-
variable show_shift(wave data)
-
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.
-
variable record_results(variable index)
+Go to the documentation of this file.
1 #pragma TextEncoding = "UTF-8"
+
2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
+
3 #include "pearl-area-profiles"
+
4 
+
5 // $Id$
+
6 
+
26 
+
27 
+
28 function analyse_curved_edge(data)
+
29  wave data // 2D counts data, x-scale = kinetic energy, y-scale = analyser angle
+
30  variable guess_EF // initial guess of the Fermi level
+
31 
+
32  dfref savedf = GetDataFolderDFR()
+
33  dfref datadf = GetWavesDataFolderDFR(data)
+
34  setdatafolder datadf
+
35 
+
36  make /n=5 /d /o w_coef_int
+
37  make /n=7 /d /o w_coef_curved
+
38 
+
39  // 1) integrate data
+
40  wave xint = ad_profile_x(data, -inf, inf, "", noavg=1)
+
41  duplicate /free xint, xint_sig
+
42  xint_sig = sqrt(xint * 4) / 4
+
43  variable xmin = wavemin(xint)
+
44  variable xmax = wavemax(xint)
+
45  variable xmean = mean(xint)
+
46 
+
47  // 2) fit integrated data for reference
+
48  w_coef_int[0] = xmin
+
49  w_coef_int[1] = 0
+
50  w_coef_int[2] = xmax - xmin
+
51  w_coef_int[3] = dimoffset(xint, 0) + dimdelta(xint, 0) * dimsize(xint, 0) / 2
+
52  w_coef_int[4] = 100
+
53  FuncFit /NTHR=0 FermiFuncLinDOS w_coef_int xint /D /I=1 /W=xint_sig
+
54  wave w_sigma
+
55  duplicate /o w_sigma, w_sigma_int
+
56 
+
57  // 3) normalize data
+
58  wave yavg = ad_profile_y(data, -inf, inf, "")
+
59  variable ymean = mean(yavg)
+
60 
+
61  duplicate /o data, data_norm, data_sig
+
62  data_sig = sqrt(data * 4) / 4
+
63  data_norm = data_norm * ymean / yavg[q]
+
64  data_sig = data_sig * ymean / yavg[q]
+
65 
+
66  // 4) fit normalized data
+
67  wave xavg = ad_profile_x(data, -inf, inf, "")
+
68  xmin = wavemin(xavg)
+
69  xmax = wavemax(xavg)
+
70  xmean = mean(xavg)
+
71 
+
72  w_coef_curved[0] = {0, 0, 1, 95.5, 100, 0, -0.0001}
+
73  w_coef_curved[0] = xmin
+
74  w_coef_curved[2] = xmax - xmin
+
75  w_coef_curved[3] = w_coef_int[3]
+
76  w_coef_curved[4] = w_coef_int[4]
+
77 
+
78  //variable box = min(11, numpnts(xavg) / 5)
+
79  //FindLevel /B=(box) /EDGE=2 /Q xavg, (xmin + xmax) / 2
+
80  //if (v_flag == 0)
+
81  // w_coef_curved[3] = v_levelx
+
82  //else
+
83  // w_coef_curved[3] = dimoffset(data, 0) + dimdelta(data, 0) * dimsize(data, 0) / 2
+
84  //endif
+
85 
+
86  duplicate /o data_norm, fit_data_norm
+
87  FuncFitMD /X=1 /NTHR=0 FermiFuncLinDOS_2Dcorr w_coef_curved data_norm /D=fit_data_norm /I=1 /W=data_sig
+
88  wave w_sigma
+
89  duplicate /o w_sigma, w_sigma_curved
+
90 
+
91  display /k=1; appendimage data_norm
+
92  ModifyImage data_norm ctab= {xmin,xmax,Grays,0}
+
93  AppendMatrixContour fit_data_norm
+
94 
+
95  setdatafolder savedf
+
96  return 0
+
97 end
+
98 
+
99 function record_results(index)
+
100  variable index
+
101 
+
102  dfref savedf = GetDataFolderDFR()
+
103  wave /sdfr=root: Tint, Tint_sig, Tcurv, Tcurv_sig, EFcurv, EFcurv_sig
+
104  wave w_coef_int, w_coef_curved
+
105  wave w_sigma_int, w_sigma_curved
+
106 
+
107  Tint[index] = w_coef_int[4]
+
108  Tint_sig[index] = w_sigma_int[4]
+
109  Tcurv[index] = w_coef_curved[4]
+
110  Tcurv_sig[index] = w_sigma_curved[4]
+
111  EFcurv[index] = w_coef_curved[3]
+
112  EFcurv_sig[index] = w_sigma_curved[3]
+
113 
+
114  setdatafolder savedf
+
115 end
+
116 
+
117 function integrate_curved_edge(data, data_sig)
+
118  wave data
+
119  wave /z data_sig
+
120  //wave coef
+
121 
+
122  string name = nameofwave(data)
+
123 
+
124  duplicate /o data, data_out
+
125  redimension /n=(dimsize(data,0)) data_out
+
126  data_out = 0
+
127 
+
128  if (waveexists(data_sig))
+
129  duplicate /o data_sig, sig_out
+
130  redimension /n=(dimsize(data,0)) sig_out
+
131  sig_out = 0
+
132  endif
+
133 
+
134  wave ywgt = ad_profile_y(data, -inf, inf, "", noavg=1)
+
135  ywgt = 1 / ywgt / 4
+
136  //ywgt = 1 / 4
+
137  variable sum_ywgt = sum(ywgt)
+
138 
+
139  variable nx = dimsize(data, 0)
+
140  variable ny = dimsize(data, 1)
+
141  variable iy
+
142  variable yy
+
143  variable dx
+
144  variable dy
+
145  variable dp
+
146  variable dp_min = 0
+
147 
+
148  wave PassEnergy = :attr:PassEnergy
+
149  wave NumSlices = :attr:NumSlices
+
150 
+
151  for (iy = 0; iy < ny; iy += 1)
+
152  dy = dimoffset(data, 1) + dimdelta(data, 1) * iy
+
153  dy = dy / dimdelta(data, 1)
+
154  dx = slit_shift(dy * 902 / NumSlices[0], PassEnergy[0])
+
155  dp = round(dx / dimdelta(data, 0)) // <= 0
+
156  dp_min = min(dp_min, dp)
+
157 
+
158  data_out[] = p+dp >= 0 ? data_out + data[p+dp][iy] * ywgt[iy] : data_out
+
159 
+
160  if (waveexists(data_sig))
+
161  sig_out = p+dp >= 0 ? sig_out + data_sig[p+dp][iy] * ywgt[iy] : sig_out
+
162  endif
+
163  endfor
+
164 
+
165  data_out /= sum_ywgt
+
166  data_out[0, -dp_min][] = nan
+
167 
+
168  if (waveexists(sig_out))
+
169  sig_out /= sum_ywgt
+
170  //sig_out[0, -dp_min] = nan
+
171  endif
+
172 end
+
173 
+
174 function slit_correction(data, data_out, epass)
+
175  wave data // must be image with original dimensions (no cropping!)
+
176  wave /z data_out // 2D or 1D wave to receive the result
+
177  // X dimension must be identical to the one of data
+
178  // if 2D, Y dimension must be either identical to the one of data
+
179  // if 1D, the result will be the sum of the corrected slices
+
180  variable epass // pass energy
+
181 
+
182  if (!WaveExists(data_out))
+
183  string name = nameofwave(data) + "_corr"
+
184  duplicate /o data, $name
+
185  wave data_out = $name
+
186  //redimension /n=(dimsize(data,0)) data_out
+
187  endif
+
188  data_out = 0
+
189 
+
190  variable nx = dimsize(data, 0)
+
191  variable ny = dimsize(data, 1)
+
192  variable iy
+
193  variable yy
+
194  variable dx
+
195  variable dy
+
196  variable dp
+
197  variable dp_min = 0
+
198 
+
199  for (iy = 0; iy < ny; iy += 1)
+
200  dy = dimoffset(data, 1) + dimdelta(data, 1) * iy
+
201  dy = dy / dimdelta(data, 1)
+
202  dx = slit_shift(dy * 902 / ny, epass)
+
203  dp = round(dx / dimdelta(data, 0)) // <= 0
+
204  dp_min = min(dp_min, dp)
+
205 
+
206  if (wavedims(data_out) >= 2)
+
207  data_out[][iy] = p+dp >= 0 ? data_out + data[p+dp][iy] : data_out
+
208  else
+
209  data_out = p+dp >= 0 ? data_out + data[p+dp][iy] : data_out
+
210  endif
+
211  endfor
+
212 
+
213  data_out[0, -dp_min][] = nan
+
214 end
+
215 
+
216 //------------------------------------------------------------------------------
+
217 threadsafe Function FermiFuncLinDOS2D_corr(w,x,y) : FitFunc
+
218 // linear density of states below Fermi level
+
219 // 2D data with corrections:
+
220 // - straight slit (slit shift)
+
221 // - transmission function (polynomial)
+
222 //------------------------------------------------------------------------------
+
223  Wave w; Variable x; variable y
+
224  // w[0] = background far above the fermi level
+
225  // w[1] = slope of the linear background
+
226  // w[2] = amplitude
+
227  // w[3] = fermi level in eV
+
228  // w[4] = temperature in K
+
229  // w[5] = transmission - linear term
+
230  // w[6] = transmission - quadratic term
+
231  // w[7] = transmission - cubic term
+
232  // w[8] = pass energy (hold this value)
+
233  // w[9] = y scale: pixels / unit of y
+
234 
+
235  variable pos = w[3] + slit_shift(y * w[9], w[8])
+
236  variable transm = 1 + w[5] * y + w[6] * y^2 + w[7] * y^3
+
237  variable fermi = (w[1] * min(x - pos, 0) + w[2]) / ( exp( (x - pos) / (kBoltzmann * w[4]) ) + 1.0 )
+
238  return transm * (fermi + w[0])
+
239 end
+
240 
+
241 //------------------------------------------------------------------------------
+
242 threadsafe Function FermiFuncLinDOS_2Dcorr_old(w,x,y) : FitFunc
+
243 // linear density of states below Fermi level
+
244 // 2D data with a polynomial shift of the Fermi level in the second dimension
+
245 //------------------------------------------------------------------------------
+
246  Wave w; Variable x; variable y
+
247  // w[0] = background far above the fermi level
+
248  // w[1] = slope of the linear background
+
249  // w[2] = amplitude
+
250  // w[3] = fermi level in eV
+
251  // w[4] = temperature in K
+
252  // w[5] = shift - linear term
+
253  // w[6] = shift - quadratic term
+
254 
+
255  variable pos = w[3] + w[5] * y + w[6] * y^2
+
256  return w[0] + (w[1] * min(x - pos, 0) + w[2]) / ( exp( (x - pos) / (kBoltzmann * w[4]) ) + 1.0 )
+
257 end
+
258 
+
260 static constant mcp_radius_pix = 555
+
262 static constant mcp_radius_mm = 20
+
264 static constant hemi_radius_mm = 200
+
266 static constant mcp_radius_epass = 0.04
+
267 
+
268 threadsafe function slit_shift(ypix, epass)
+
269  // calculates the energy shift due to straight slit
+
270  // the radius of the curve is 1/2 of the hemisphere radius
+
271  variable ypix // vertical (angle/position) pixels distance from center
+
272  // = slice coordinate * 902 / number of slices
+
273  variable epass // pass energy
+
274 
+
275  variable rpix = mcp_radius_pix * hemi_radius_mm / mcp_radius_mm
+
276  //variable rpix = mcp_radius_pix * hemi_radius_mm / 2 / mcp_radius_mm
+
277  variable rene = epass * mcp_radius_epass * hemi_radius_mm / 2 / mcp_radius_mm
+
278 
+
279  variable isin = asin(ypix / rpix)
+
280  variable dene = rene * (cos(isin) - 1)
+
281 
+
282  return dene
+
283 end
+
284 
+
285 function show_shift(data)
+
286  wave data
+
287  variable epass
+
288 
+
289  variable ny = dimsize(data, 1)
+
290  make /o /n=(ny) shift_x
+
291  setscale /i x -ny/2, ny/2, "", shift_x
+
292  wave PassEnergy = :attr:PassEnergy
+
293  wave NumSlices = :attr:NumSlices
+
294 
+
295  shift_x = slit_shift(x * 902 / NumSlices[0], PassEnergy[0])
+
296 
+
297  variable ecenter = dimoffset(data, 0) + dimdelta(data, 0) * dimsize(data, 0) / 2
+
298  shift_x += ecenter
+
299 end
+
300 
+
threadsafe variable FermiFuncLinDOS2D_corr(variable w, threadsafe x, wave y)
+
variable integrate_curved_edge(wave data, wave data_sig)
+
static const variable hemi_radius_mm
physical size (radius) of the hemisphere in mm
+
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.
+
variable slit_correction(wave data, wave data_out, variable epass)
+
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.
+
static const variable mcp_radius_mm
physical size (radius) of the MCP in mm
+
variable show_shift(wave data)
+
variable analyse_curved_edge(wave data)
+
threadsafe variable slit_shift(variable ypix, variable epass)
+
variable record_results(variable index)
+
static const variable mcp_radius_pix
MCP radius seen by the camera in pixels.
+
static const variable mcp_radius_epass
energy range imaged on MCP relative to the pass energy
diff --git a/doc/html/files.html b/doc/html/files.html index 237447c..c1502b7 100644 --- a/doc/html/files.html +++ b/doc/html/files.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: File List @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@ - + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -96,7 +98,7 @@ $(document).ready(function(){initNavTree('files.html','');});  pearl-area-profiles.ipfProfile extraction for multi-dimensional datasets acquired from area detectors  pearl-arpes.ipfData acquisition and analysis package for ARPES at PEARL  pearl-compat.ipfCompatibility procedures for igor 8 - pearl-data-explorer.ipfPreview and import panel for PEARL data + pearl-data-explorer.ipf  pearl-elog.ipfInterface for writing ELOG entries with Igor graphs as attachment  pearl-fitfuncs.ipfVarious fit functions for photoelectron spectroscopy  pearl-gui-tools.ipf @@ -106,7 +108,7 @@ $(document).ready(function(){initNavTree('files.html','');});  pearl-pmsco-import.ipfData import/export procedures for multiple scattering calculations  pearl-polar-coordinates.ipf  pearl-pshell-import.ipfImport data from PShell - pearl-scienta-countrate.ipfCount rate functions for Scienta detector images + pearl-scienta-live.ipfUtility functions for operating the Scienta analyser  pearl-scienta-preprocess.ipfPreprocessing functions for Scienta detector images  pearl-tools.ipf  pearl-vector-operations.ipfBasic vector geometry operations @@ -117,9 +119,9 @@ $(document).ready(function(){initNavTree('files.html','');}); diff --git a/doc/html/files.js b/doc/html/files.js deleted file mode 100644 index 97bd86e..0000000 --- a/doc/html/files.js +++ /dev/null @@ -1,26 +0,0 @@ -var files = -[ - [ "fermi-edge-analysis.ipf", "fermi-edge-analysis_8ipf.html", "fermi-edge-analysis_8ipf" ], - [ "pearl-anglescan-panel.ipf", "pearl-anglescan-panel_8ipf.html", "pearl-anglescan-panel_8ipf" ], - [ "pearl-anglescan-process.ipf", "pearl-anglescan-process_8ipf.html", "pearl-anglescan-process_8ipf" ], - [ "pearl-anglescan-tracker.ipf", "pearl-anglescan-tracker_8ipf.html", "pearl-anglescan-tracker_8ipf" ], - [ "pearl-area-display.ipf", "pearl-area-display_8ipf.html", "pearl-area-display_8ipf" ], - [ "pearl-area-import.ipf", "pearl-area-import_8ipf.html", "pearl-area-import_8ipf" ], - [ "pearl-area-profiles.ipf", "pearl-area-profiles_8ipf.html", "pearl-area-profiles_8ipf" ], - [ "pearl-arpes.ipf", "pearl-arpes_8ipf.html", "pearl-arpes_8ipf" ], - [ "pearl-compat.ipf", "pearl-compat_8ipf.html", "pearl-compat_8ipf" ], - [ "pearl-data-explorer.ipf", "pearl-data-explorer_8ipf.html", "pearl-data-explorer_8ipf" ], - [ "pearl-elog.ipf", "pearl-elog_8ipf.html", "pearl-elog_8ipf" ], - [ "pearl-fitfuncs.ipf", "pearl-fitfuncs_8ipf.html", "pearl-fitfuncs_8ipf" ], - [ "pearl-gui-tools.ipf", "pearl-gui-tools_8ipf.html", "pearl-gui-tools_8ipf" ], - [ "pearl-matrix-import.ipf", "pearl-matrix-import_8ipf.html", "pearl-matrix-import_8ipf" ], - [ "pearl-menu.ipf", "pearl-menu_8ipf.html", "pearl-menu_8ipf" ], - [ "pearl-otf-import.ipf", "pearl-otf-import_8ipf.html", "pearl-otf-import_8ipf" ], - [ "pearl-pmsco-import.ipf", "pearl-pmsco-import_8ipf.html", "pearl-pmsco-import_8ipf" ], - [ "pearl-polar-coordinates.ipf", "pearl-polar-coordinates_8ipf.html", "pearl-polar-coordinates_8ipf" ], - [ "pearl-pshell-import.ipf", "pearl-pshell-import_8ipf.html", "pearl-pshell-import_8ipf" ], - [ "pearl-scienta-countrate.ipf", "pearl-scienta-countrate_8ipf.html", "pearl-scienta-countrate_8ipf" ], - [ "pearl-scienta-preprocess.ipf", "pearl-scienta-preprocess_8ipf.html", "pearl-scienta-preprocess_8ipf" ], - [ "pearl-tools.ipf", "pearl-tools_8ipf.html", "pearl-tools_8ipf" ], - [ "pearl-vector-operations.ipf", "pearl-vector-operations_8ipf.html", "pearl-vector-operations_8ipf" ] -]; \ No newline at end of file diff --git a/doc/html/functions.html b/doc/html/functions.html index 4fdf653..0216f8f 100644 --- a/doc/html/functions.html +++ b/doc/html/functions.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Data Fields @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@
- + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -148,9 +150,9 @@ $(document).ready(function(){initNavTree('functions.html','');}); diff --git a/doc/html/functions_vars.html b/doc/html/functions_vars.html index 11eda08..c01633f 100644 --- a/doc/html/functions_vars.html +++ b/doc/html/functions_vars.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Data Fields - Variables @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@
- + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -148,9 +150,9 @@ $(document).ready(function(){initNavTree('functions_vars.html','');}); diff --git a/doc/html/globals.html b/doc/html/globals.html index 1d709a8..9813a08 100644 --- a/doc/html/globals.html +++ b/doc/html/globals.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
@@ -38,18 +35,21 @@
- + +/* @license-end */
@@ -63,7 +63,9 @@ $(function() {
@@ -204,6 +206,12 @@ $(document).ready(function(){initNavTree('globals.html','');});
  • ad_update_profiles() : pearl-area-display.ipf
  • +
  • add_anglescan_worker() +: pearl-anglescan-process.ipf +
  • +
  • add_aziscan_core() +: pearl-anglescan-process.ipf +
  • add_image_data() : pearl-anglescan-tracker.ipf
  • @@ -265,9 +273,9 @@ $(document).ready(function(){initNavTree('globals.html','');}); : pearl-area-import.ipf
  • AfterCompiledHook() -: pearl-arpes.ipf -, pearl-anglescan-panel.ipf +: pearl-anglescan-panel.ipf , pearl-anglescan-tracker.ipf +, pearl-arpes.ipf
  • AfterFileOpenHook() : pearl-elog.ipf @@ -277,7 +285,7 @@ $(document).ready(function(){initNavTree('globals.html','');}); : fermi-edge-analysis.ipf
  • analyser_energy_resolution() -: fermi-edge-analysis.ipf +: pearl-scienta-live.ipf
  • AngleToK() : pearl-anglescan-process.ipf @@ -358,7 +366,7 @@ $(document).ready(function(){initNavTree('globals.html','');}); : pearl-anglescan-tracker.ipf
  • attributes_notebook() -: pearl-data-explorer.ipf +: pearl-data-explorer.ipf
  • Au4f() : pearl-fitfuncs.ipf @@ -375,9 +383,9 @@ $(document).ready(function(){initNavTree('globals.html','');}); diff --git a/doc/html/globals_b.html b/doc/html/globals_b.html index b466b85..ded6e9d 100644 --- a/doc/html/globals_b.html +++ b/doc/html/globals_b.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
  • - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -115,17 +117,11 @@ $(document).ready(function(){initNavTree('globals_b.html','');});
  • bp_crop_preview() : pearl-anglescan-panel.ipf
  • -
  • bp_dataset_display() -: pearl-data-explorer.ipf +
  • bp_display_dataset() +: pearl-data-explorer.ipf
  • -
  • bp_dataset_folder() -: pearl-data-explorer.ipf -
  • -
  • bp_dataset_next() -: pearl-data-explorer.ipf -
  • -
  • bp_dataset_prev() -: pearl-data-explorer.ipf +
  • bp_elog() +: pearl-data-explorer.ipf
  • bp_extract_slice() : pearl-area-display.ipf @@ -136,17 +132,17 @@ $(document).ready(function(){initNavTree('globals_b.html','');});
  • bp_file_prev() : pearl-data-explorer.ipf
  • +
  • bp_goto_dataset() +: pearl-data-explorer.ipf +
  • bp_graph_png() : pearl-anglescan-panel.ipf
  • bp_graph_update() : pearl-anglescan-panel.ipf
  • -
  • bp_load_files() -: pearl-data-explorer.ipf -
  • -
  • bp_load_files_opt() -: pearl-data-explorer.ipf +
  • bp_load_options() +: pearl-data-explorer.ipf
  • bp_load_prefs() : pearl-anglescan-panel.ipf @@ -200,6 +196,9 @@ $(document).ready(function(){initNavTree('globals_b.html','');});
  • bp_output_itx() : pearl-anglescan-panel.ipf
  • +
  • bp_reduction_params() +: pearl-data-explorer.ipf +
  • bp_reset_cursors() : pearl-area-display.ipf
  • @@ -207,8 +206,8 @@ $(document).ready(function(){initNavTree('globals_b.html','');}); : pearl-elog.ipf
  • bp_save_prefs() -: pearl-anglescan-panel.ipf -, pearl-data-explorer.ipf +: pearl-data-explorer.ipf +, pearl-anglescan-panel.ipf
  • bp_source_select() : pearl-anglescan-panel.ipf @@ -219,9 +218,6 @@ $(document).ready(function(){initNavTree('globals_b.html','');});
  • bp_submit() : pearl-elog.ipf
  • -
  • bp_update_datasets() -: pearl-data-explorer.ipf -
  • bp_update_filelist() : pearl-data-explorer.ipf
  • @@ -231,9 +227,9 @@ $(document).ready(function(){initNavTree('globals_b.html','');}); diff --git a/doc/html/globals_c.html b/doc/html/globals_c.html index efa6318..4ca53b4 100644 --- a/doc/html/globals_c.html +++ b/doc/html/globals_c.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -121,10 +123,10 @@ $(document).ready(function(){initNavTree('globals_c.html','');}); : pearl-polar-coordinates.ipf
  • check_contrast() -: pearl-anglescan-process.ipf +: pearl-anglescan-process.ipf
  • check_exposure_opt() -: pearl-scienta-countrate.ipf +: pearl-scienta-live.ipf
  • check_norm_alpha() : pearl-anglescan-panel.ipf @@ -153,6 +155,9 @@ $(document).ready(function(){initNavTree('globals_c.html','');});
  • convert_angles_ttpd2polar() : pearl-anglescan-process.ipf
  • +
  • create_attributes_notebook() +: pearl-data-explorer.ipf +
  • create_cmd_file() : pearl-elog.ipf
  • @@ -180,9 +185,9 @@ $(document).ready(function(){initNavTree('globals_c.html','');}); diff --git a/doc/html/globals_d.html b/doc/html/globals_d.html index 30bf151..b74ee4d 100644 --- a/doc/html/globals_d.html +++ b/doc/html/globals_d.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -84,6 +86,9 @@ $(document).ready(function(){initNavTree('globals_d.html','');});
    Here is a list of all functions, variables, defines, enums, and typedefs with links to the files they belong to:

    - d -

    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -144,6 +146,9 @@ $(document).ready(function(){initNavTree('globals_e.html','');});
  • extend_data() : pearl-anglescan-tracker.ipf
  • +
  • extract_attributes() +: pearl-data-explorer.ipf +
  • extract_preview_image() : pearl-data-explorer.ipf
  • @@ -153,9 +158,9 @@ $(document).ready(function(){initNavTree('globals_e.html','');}); diff --git a/doc/html/globals_f.html b/doc/html/globals_f.html index 69a1736..2c438bd 100644 --- a/doc/html/globals_f.html +++ b/doc/html/globals_f.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -90,18 +92,9 @@ $(document).ready(function(){initNavTree('globals_f.html','');});
  • FermiGaussConv() : pearl-fitfuncs.ipf
  • -
  • find_attr_folder() -: pearl-pshell-import.ipf -
  • find_hemi_data() : pearl-anglescan-process.ipf
  • -
  • find_scale_wave() -: pearl-pshell-import.ipf -
  • -
  • find_scan_folder() -: pearl-pshell-import.ipf -
  • Fit_DoniachSunjicBroad() : pearl-fitfuncs.ipf
  • @@ -114,9 +107,9 @@ $(document).ready(function(){initNavTree('globals_f.html','');}); diff --git a/doc/html/globals_func.html b/doc/html/globals_func.html index 3720e2a..67861ed 100644 --- a/doc/html/globals_func.html +++ b/doc/html/globals_func.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -204,6 +206,12 @@ $(document).ready(function(){initNavTree('globals_func.html','');});
  • ad_update_profiles() : pearl-area-display.ipf
  • +
  • add_anglescan_worker() +: pearl-anglescan-process.ipf +
  • +
  • add_aziscan_core() +: pearl-anglescan-process.ipf +
  • add_image_data() : pearl-anglescan-tracker.ipf
  • @@ -265,9 +273,9 @@ $(document).ready(function(){initNavTree('globals_func.html','');}); : pearl-area-import.ipf
  • AfterCompiledHook() -: pearl-arpes.ipf -, pearl-anglescan-panel.ipf +: pearl-anglescan-panel.ipf , pearl-anglescan-tracker.ipf +, pearl-arpes.ipf
  • AfterFileOpenHook() : pearl-elog.ipf @@ -277,7 +285,7 @@ $(document).ready(function(){initNavTree('globals_func.html','');}); : fermi-edge-analysis.ipf
  • analyser_energy_resolution() -: fermi-edge-analysis.ipf +: pearl-scienta-live.ipf
  • AngleToK() : pearl-anglescan-process.ipf @@ -358,7 +366,7 @@ $(document).ready(function(){initNavTree('globals_func.html','');}); : pearl-anglescan-tracker.ipf
  • attributes_notebook() -: pearl-data-explorer.ipf +: pearl-data-explorer.ipf
  • Au4f() : pearl-fitfuncs.ipf @@ -375,9 +383,9 @@ $(document).ready(function(){initNavTree('globals_func.html','');}); diff --git a/doc/html/globals_func_b.html b/doc/html/globals_func_b.html index e9c2e4b..1c97a26 100644 --- a/doc/html/globals_func_b.html +++ b/doc/html/globals_func_b.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
  • - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -115,17 +117,11 @@ $(document).ready(function(){initNavTree('globals_func_b.html','');});
  • bp_crop_preview() : pearl-anglescan-panel.ipf
  • -
  • bp_dataset_display() -: pearl-data-explorer.ipf +
  • bp_display_dataset() +: pearl-data-explorer.ipf
  • -
  • bp_dataset_folder() -: pearl-data-explorer.ipf -
  • -
  • bp_dataset_next() -: pearl-data-explorer.ipf -
  • -
  • bp_dataset_prev() -: pearl-data-explorer.ipf +
  • bp_elog() +: pearl-data-explorer.ipf
  • bp_extract_slice() : pearl-area-display.ipf @@ -136,17 +132,17 @@ $(document).ready(function(){initNavTree('globals_func_b.html','');});
  • bp_file_prev() : pearl-data-explorer.ipf
  • +
  • bp_goto_dataset() +: pearl-data-explorer.ipf +
  • bp_graph_png() : pearl-anglescan-panel.ipf
  • bp_graph_update() : pearl-anglescan-panel.ipf
  • -
  • bp_load_files() -: pearl-data-explorer.ipf -
  • -
  • bp_load_files_opt() -: pearl-data-explorer.ipf +
  • bp_load_options() +: pearl-data-explorer.ipf
  • bp_load_prefs() : pearl-anglescan-panel.ipf @@ -200,6 +196,9 @@ $(document).ready(function(){initNavTree('globals_func_b.html','');});
  • bp_output_itx() : pearl-anglescan-panel.ipf
  • +
  • bp_reduction_params() +: pearl-data-explorer.ipf +
  • bp_reset_cursors() : pearl-area-display.ipf
  • @@ -207,8 +206,8 @@ $(document).ready(function(){initNavTree('globals_func_b.html','');}); : pearl-elog.ipf
  • bp_save_prefs() -: pearl-anglescan-panel.ipf -, pearl-data-explorer.ipf +: pearl-data-explorer.ipf +, pearl-anglescan-panel.ipf
  • bp_source_select() : pearl-anglescan-panel.ipf @@ -219,9 +218,6 @@ $(document).ready(function(){initNavTree('globals_func_b.html','');});
  • bp_submit() : pearl-elog.ipf
  • -
  • bp_update_datasets() -: pearl-data-explorer.ipf -
  • bp_update_filelist() : pearl-data-explorer.ipf
  • @@ -231,9 +227,9 @@ $(document).ready(function(){initNavTree('globals_func_b.html','');}); diff --git a/doc/html/globals_func_c.html b/doc/html/globals_func_c.html index afc5251..20818d5 100644 --- a/doc/html/globals_func_c.html +++ b/doc/html/globals_func_c.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -121,10 +123,10 @@ $(document).ready(function(){initNavTree('globals_func_c.html','');}); : pearl-polar-coordinates.ipf
  • check_contrast() -: pearl-anglescan-process.ipf +: pearl-anglescan-process.ipf
  • check_exposure_opt() -: pearl-scienta-countrate.ipf +: pearl-scienta-live.ipf
  • check_norm_alpha() : pearl-anglescan-panel.ipf @@ -153,6 +155,9 @@ $(document).ready(function(){initNavTree('globals_func_c.html','');});
  • convert_angles_ttpd2polar() : pearl-anglescan-process.ipf
  • +
  • create_attributes_notebook() +: pearl-data-explorer.ipf +
  • create_cmd_file() : pearl-elog.ipf
  • @@ -180,9 +185,9 @@ $(document).ready(function(){initNavTree('globals_func_c.html','');}); diff --git a/doc/html/globals_func_d.html b/doc/html/globals_func_d.html index d98a3b5..686b57c 100644 --- a/doc/html/globals_func_d.html +++ b/doc/html/globals_func_d.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -84,6 +86,9 @@ $(document).ready(function(){initNavTree('globals_func_d.html','');});  

    - d -

    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -138,6 +140,9 @@ $(document).ready(function(){initNavTree('globals_func_e.html','');});
  • extend_data() : pearl-anglescan-tracker.ipf
  • +
  • extract_attributes() +: pearl-data-explorer.ipf +
  • extract_preview_image() : pearl-data-explorer.ipf
  • @@ -147,9 +152,9 @@ $(document).ready(function(){initNavTree('globals_func_e.html','');}); diff --git a/doc/html/globals_func_f.html b/doc/html/globals_func_f.html index eb2a066..cd3f6cd 100644 --- a/doc/html/globals_func_f.html +++ b/doc/html/globals_func_f.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -90,18 +92,9 @@ $(document).ready(function(){initNavTree('globals_func_f.html','');});
  • FermiGaussConv() : pearl-fitfuncs.ipf
  • -
  • find_attr_folder() -: pearl-pshell-import.ipf -
  • find_hemi_data() : pearl-anglescan-process.ipf
  • -
  • find_scale_wave() -: pearl-pshell-import.ipf -
  • -
  • find_scan_folder() -: pearl-pshell-import.ipf -
  • Fit_DoniachSunjicBroad() : pearl-fitfuncs.ipf
  • @@ -114,9 +107,9 @@ $(document).ready(function(){initNavTree('globals_func_f.html','');}); diff --git a/doc/html/globals_func_g.html b/doc/html/globals_func_g.html index 02b5547..2dce7d5 100644 --- a/doc/html/globals_func_g.html +++ b/doc/html/globals_func_g.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -90,12 +92,18 @@ $(document).ready(function(){initNavTree('globals_func_g.html','');});
  • gauss4_reduction() : pearl-scienta-preprocess.ipf
  • +
  • gauss6_reduction() +: pearl-scienta-preprocess.ipf +
  • get_default_panel_name() : pearl-elog.ipf
  • get_elog_df() : pearl-elog.ipf
  • +
  • get_file_info() +: pearl-data-explorer.ipf +
  • get_hemi_nickname() : pearl-anglescan-process.ipf
  • @@ -114,6 +122,9 @@ $(document).ready(function(){initNavTree('globals_func_g.html','');});
  • get_panel_message() : pearl-elog.ipf
  • +
  • get_pshell_info() +: pearl-data-explorer.ipf +
  • get_source_image() : pearl-area-display.ipf
  • @@ -129,6 +140,9 @@ $(document).ready(function(){initNavTree('globals_func_g.html','');});
  • GetAttrDataFolderDFR() : pearl-area-import.ipf
  • +
  • goto_dataset_folder() +: pearl-data-explorer.ipf +
  • graphname_from_dfref() : pearl-area-display.ipf
  • @@ -138,9 +152,9 @@ $(document).ready(function(){initNavTree('globals_func_g.html','');}); diff --git a/doc/html/globals_func_h.html b/doc/html/globals_func_h.html index c263e0c..713bfeb 100644 --- a/doc/html/globals_func_h.html +++ b/doc/html/globals_func_h.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -96,15 +98,39 @@ $(document).ready(function(){initNavTree('globals_func_h.html','');});
  • hemi_polar_cut() : pearl-anglescan-process.ipf
  • +
  • hl_add_objects() +: pearl-data-explorer.ipf +
  • +
  • hl_contents_clear() +: pearl-data-explorer.ipf +
  • +
  • hl_contents_update() +: pearl-data-explorer.ipf +
  • +
  • hl_default_selection() +: pearl-data-explorer.ipf +
  • +
  • hl_expand_scans() +: pearl-data-explorer.ipf +
  • +
  • hlp_contents_open() +: pearl-data-explorer.ipf +
  • +
  • hlp_contents_selection() +: pearl-data-explorer.ipf +
  • +
  • hlp_setup() +: pearl-data-explorer.ipf +
  • diff --git a/doc/html/globals_func_i.html b/doc/html/globals_func_i.html index ef53849..ecd5117 100644 --- a/doc/html/globals_func_i.html +++ b/doc/html/globals_func_i.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -137,9 +139,9 @@ $(document).ready(function(){initNavTree('globals_func_i.html','');}); diff --git a/doc/html/globals_func_k.html b/doc/html/globals_func_k.html index 904cba7..6686839 100644 --- a/doc/html/globals_func_k.html +++ b/doc/html/globals_func_k.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -84,6 +86,9 @@ $(document).ready(function(){initNavTree('globals_func_k.html','');});  

    - k -

    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -84,9 +86,6 @@ $(document).ready(function(){initNavTree('globals_func_l.html','');});  

    - l -

    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -133,7 +135,7 @@ $(document).ready(function(){initNavTree('globals_func_m.html','');}); : pearl-matrix-import.ipf
  • MultiDoniachSunjicLinBG() -: pearl-fitfuncs.ipf +: pearl-fitfuncs.ipf
  • MultiGaussLinBG() : pearl-fitfuncs.ipf @@ -142,7 +144,10 @@ $(document).ready(function(){initNavTree('globals_func_m.html','');}); : pearl-fitfuncs.ipf
  • MultiVoigtLinBG() -: pearl-fitfuncs.ipf +: pearl-fitfuncs.ipf +
  • +
  • MultiVoigtLinBG_AO() +: pearl-fitfuncs.ipf
  • @@ -150,9 +155,9 @@ $(document).ready(function(){initNavTree('globals_func_m.html','');}); diff --git a/doc/html/globals_func_n.html b/doc/html/globals_func_n.html index 05293f3..af55ead 100644 --- a/doc/html/globals_func_n.html +++ b/doc/html/globals_func_n.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -111,9 +113,9 @@ $(document).ready(function(){initNavTree('globals_func_n.html','');}); diff --git a/doc/html/globals_func_o.html b/doc/html/globals_func_o.html index a607eef..116f1c7 100644 --- a/doc/html/globals_func_o.html +++ b/doc/html/globals_func_o.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -117,9 +119,9 @@ $(document).ready(function(){initNavTree('globals_func_o.html','');}); diff --git a/doc/html/globals_func_p.html b/doc/html/globals_func_p.html index 8b24454..d2930a4 100644 --- a/doc/html/globals_func_p.html +++ b/doc/html/globals_func_p.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -126,6 +128,9 @@ $(document).ready(function(){initNavTree('globals_func_p.html','');});
  • pizza_service_2() : pearl-anglescan-process.ipf
  • +
  • pm_reduction_values() +: pearl-data-explorer.ipf +
  • pmp_data() : pearl-anglescan-tracker.ipf
  • @@ -162,6 +167,9 @@ $(document).ready(function(){initNavTree('globals_func_p.html','');});
  • pmp_parameters_mouseup() : pearl-anglescan-tracker.ipf
  • +
  • pmp_reduction_func() +: pearl-data-explorer.ipf +
  • pmsco_load_xyz() : pearl-pmsco-import.ipf
  • @@ -189,18 +197,12 @@ $(document).ready(function(){initNavTree('globals_func_p.html','');});
  • prepare_hemi_scan_display() : pearl-anglescan-process.ipf
  • -
  • preview_attributes() -: pearl-data-explorer.ipf -
  • preview_crop() : pearl-anglescan-panel.ipf
  • preview_datafolder() : pearl-data-explorer.ipf
  • -
  • preview_dataset() -: pearl-data-explorer.ipf -
  • preview_file() : pearl-data-explorer.ipf
  • @@ -213,9 +215,6 @@ $(document).ready(function(){initNavTree('globals_func_p.html','');});
  • preview_matrix_file() : pearl-matrix-import.ipf
  • -
  • preview_mtrx_file() -: pearl-data-explorer.ipf -
  • preview_norm_alpha() : pearl-anglescan-panel.ipf
  • @@ -259,7 +258,19 @@ $(document).ready(function(){initNavTree('globals_func_p.html','');}); : pearl-scienta-preprocess.ipf
  • ps_detect_scale() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf +
  • +
  • ps_find_attr_folder() +: pearl-pshell-import.ipf +
  • +
  • ps_find_scale_wave() +: pearl-pshell-import.ipf +
  • +
  • ps_find_scan_folder() +: pearl-pshell-import.ipf +
  • +
  • ps_fix_folder_name() +: pearl-pshell-import.ipf
  • ps_scale_dataset() : pearl-pshell-import.ipf @@ -268,7 +279,7 @@ $(document).ready(function(){initNavTree('globals_func_p.html','');}); : pearl-pshell-import.ipf
  • ps_scale_datasets() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf
  • ps_set_dimlabels() : pearl-pshell-import.ipf @@ -277,67 +288,67 @@ $(document).ready(function(){initNavTree('globals_func_p.html','');}); : pearl-pshell-import.ipf
  • psh5_close_file() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf
  • -
  • psh5_list_scan_datasets() -: pearl-pshell-import.ipf +
  • psh5_create_folders() +: pearl-pshell-import.ipf
  • -
  • psh5_list_scan_regions() -: pearl-pshell-import.ipf +
  • psh5_dataset_to_folder() +: pearl-pshell-import.ipf +
  • +
  • psh5_extract_region_paths() +: pearl-pshell-import.ipf +
  • +
  • psh5_extract_scan_paths() +: pearl-pshell-import.ipf +
  • +
  • psh5_filter_datasets_rank() +: pearl-pshell-import.ipf +
  • +
  • psh5_list_all_datasets() +: pearl-pshell-import.ipf +
  • +
  • psh5_list_dataset_info() +: pearl-pshell-import.ipf
  • psh5_list_scans() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf
  • -
  • psh5_load_complete() -: pearl-pshell-import.ipf +
  • psh5_load() +: pearl-pshell-import.ipf
  • psh5_load_dataset() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf
  • psh5_load_dataset_meta() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf
  • psh5_load_dataset_reduced() -: pearl-pshell-import.ipf -
  • -
  • psh5_load_dataset_slab() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf
  • psh5_load_dataset_slabs() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf
  • -
  • psh5_load_info() -: pearl-pshell-import.ipf +
  • psh5_load_datasets() +: pearl-pshell-import.ipf
  • -
  • psh5_load_preview() -: pearl-pshell-import.ipf -
  • -
  • psh5_load_reduced() -: pearl-pshell-import.ipf -
  • -
  • psh5_load_scan_attrs() -: pearl-pshell-import.ipf -
  • -
  • psh5_load_scan_complete() -: pearl-pshell-import.ipf -
  • -
  • psh5_load_scan_data() -: pearl-pshell-import.ipf -
  • -
  • psh5_load_scan_info() -: pearl-pshell-import.ipf +
  • psh5_load_general_group() +: pearl-pshell-import.ipf
  • psh5_load_scan_meta() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf
  • -
  • psh5_load_scan_preview() -: pearl-pshell-import.ipf -
  • -
  • psh5_load_scan_section() -: pearl-pshell-import.ipf +
  • psh5_match_dataset_classes() +: pearl-pshell-import.ipf
  • psh5_open_file() -: pearl-pshell-import.ipf +: pearl-pshell-import.ipf +
  • +
  • psh5_preview() +: pearl-pshell-import.ipf +
  • +
  • psh_load_general_string() +: pearl-pshell-import.ipf
  • @@ -345,9 +356,9 @@ $(document).ready(function(){initNavTree('globals_func_p.html','');}); diff --git a/doc/html/globals_func_q.html b/doc/html/globals_func_q.html index e0f0876..3562189 100644 --- a/doc/html/globals_func_q.html +++ b/doc/html/globals_func_q.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -93,9 +95,9 @@ $(document).ready(function(){initNavTree('globals_func_q.html','');}); diff --git a/doc/html/globals_func_r.html b/doc/html/globals_func_r.html index 76943f1..f6377a1 100644 --- a/doc/html/globals_func_r.html +++ b/doc/html/globals_func_r.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -98,7 +100,7 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');});
  • reduce_slab_image() : pearl-area-import.ipf -, pearl-pshell-import.ipf +, pearl-pshell-import.ipf
  • reduce_slab_worker() : pearl-pshell-import.ipf @@ -128,9 +130,9 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); diff --git a/doc/html/globals_func_s.html b/doc/html/globals_func_s.html index 3f7497b..682a223 100644 --- a/doc/html/globals_func_s.html +++ b/doc/html/globals_func_s.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
  • - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -100,13 +102,19 @@ $(document).ready(function(){initNavTree('globals_func_s.html','');}); : pearl-anglescan-tracker.ipf
  • ScientaLiveDisplay() -: pearl-scienta-countrate.ipf +: pearl-scienta-live.ipf
  • -
  • select_dataset() -: pearl-pshell-import.ipf +
  • selected_file() +: pearl-data-explorer.ipf +
  • +
  • send_to_elog() +: pearl-data-explorer.ipf
  • set_contrast() -: pearl-anglescan-process.ipf +: pearl-anglescan-process.ipf +
  • +
  • set_elog_attributes() +: pearl-data-explorer.ipf
  • set_panel_attributes() : pearl-elog.ipf @@ -144,6 +152,9 @@ $(document).ready(function(){initNavTree('globals_func_s.html','');});
  • ShirleyBG() : pearl-fitfuncs.ipf
  • +
  • shorten_filepath() +: pearl-data-explorer.ipf +
  • show_analyser_line() : pearl-anglescan-process.ipf
  • @@ -168,6 +179,9 @@ $(document).ready(function(){initNavTree('globals_func_s.html','');});
  • slp_slice_position() : pearl-area-display.ipf
  • +
  • strip_append() +: pearl-anglescan-process.ipf +
  • strip_delete_frames() : pearl-anglescan-process.ipf
  • @@ -189,9 +203,9 @@ $(document).ready(function(){initNavTree('globals_func_s.html','');}); diff --git a/doc/html/globals_func_t.html b/doc/html/globals_func_t.html index 2549aba..2e2e07a 100644 --- a/doc/html/globals_func_t.html +++ b/doc/html/globals_func_t.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -105,9 +107,9 @@ $(document).ready(function(){initNavTree('globals_func_t.html','');}); diff --git a/doc/html/globals_func_u.html b/doc/html/globals_func_u.html index e7e6c2b..8d15fe8 100644 --- a/doc/html/globals_func_u.html +++ b/doc/html/globals_func_u.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -84,6 +86,9 @@ $(document).ready(function(){initNavTree('globals_func_u.html','');});  

    - u -

    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -93,9 +95,9 @@ $(document).ready(function(){initNavTree('globals_func_w.html','');}); diff --git a/doc/html/globals_g.html b/doc/html/globals_g.html index 3e51dc1..ba7e22d 100644 --- a/doc/html/globals_g.html +++ b/doc/html/globals_g.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -90,12 +92,18 @@ $(document).ready(function(){initNavTree('globals_g.html','');});
  • gauss4_reduction() : pearl-scienta-preprocess.ipf
  • +
  • gauss6_reduction() +: pearl-scienta-preprocess.ipf +
  • get_default_panel_name() : pearl-elog.ipf
  • get_elog_df() : pearl-elog.ipf
  • +
  • get_file_info() +: pearl-data-explorer.ipf +
  • get_hemi_nickname() : pearl-anglescan-process.ipf
  • @@ -114,6 +122,9 @@ $(document).ready(function(){initNavTree('globals_g.html','');});
  • get_panel_message() : pearl-elog.ipf
  • +
  • get_pshell_info() +: pearl-data-explorer.ipf +
  • get_source_image() : pearl-area-display.ipf
  • @@ -129,6 +140,9 @@ $(document).ready(function(){initNavTree('globals_g.html','');});
  • GetAttrDataFolderDFR() : pearl-area-import.ipf
  • +
  • goto_dataset_folder() +: pearl-data-explorer.ipf +
  • graphname_from_dfref() : pearl-area-display.ipf
  • @@ -138,9 +152,9 @@ $(document).ready(function(){initNavTree('globals_g.html','');}); diff --git a/doc/html/globals_h.html b/doc/html/globals_h.html index 62a531a..21a9b31 100644 --- a/doc/html/globals_h.html +++ b/doc/html/globals_h.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -99,15 +101,39 @@ $(document).ready(function(){initNavTree('globals_h.html','');});
  • hemi_radius_mm : fermi-edge-analysis.ipf
  • +
  • hl_add_objects() +: pearl-data-explorer.ipf +
  • +
  • hl_contents_clear() +: pearl-data-explorer.ipf +
  • +
  • hl_contents_update() +: pearl-data-explorer.ipf +
  • +
  • hl_default_selection() +: pearl-data-explorer.ipf +
  • +
  • hl_expand_scans() +: pearl-data-explorer.ipf +
  • +
  • hlp_contents_open() +: pearl-data-explorer.ipf +
  • +
  • hlp_contents_selection() +: pearl-data-explorer.ipf +
  • +
  • hlp_setup() +: pearl-data-explorer.ipf +
  • diff --git a/doc/html/globals_i.html b/doc/html/globals_i.html index cc2dfc8..8f1febe 100644 --- a/doc/html/globals_i.html +++ b/doc/html/globals_i.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -137,9 +139,9 @@ $(document).ready(function(){initNavTree('globals_i.html','');}); diff --git a/doc/html/globals_k.html b/doc/html/globals_k.html index e61c603..225d55b 100644 --- a/doc/html/globals_k.html +++ b/doc/html/globals_k.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -99,9 +101,6 @@ $(document).ready(function(){initNavTree('globals_k.html','');});
  • kDataDimLabel : pearl-pshell-import.ipf
  • -
  • kDetectorSensitivity -: pearl-pshell-import.ipf -
  • kdfPersistent : pearl-elog.ipf
  • @@ -114,9 +113,54 @@ $(document).ready(function(){initNavTree('globals_k.html','');});
  • kdfVolatile : pearl-elog.ipf
  • +
  • kDSCAll +: pearl-pshell-import.ipf +
  • +
  • kDSCAttrs +: pearl-pshell-import.ipf +
  • +
  • kDSCDetectors +: pearl-pshell-import.ipf +
  • +
  • kDSCDiags +: pearl-pshell-import.ipf +
  • +
  • kDSCEssentialDiags +: pearl-pshell-import.ipf +
  • +
  • kDSCMeta +: pearl-pshell-import.ipf +
  • +
  • kDSCMonitors +: pearl-pshell-import.ipf +
  • +
  • kDSCOther +: pearl-pshell-import.ipf +
  • +
  • kDSCPositioners +: pearl-pshell-import.ipf +
  • +
  • kDSCPreview +: pearl-pshell-import.ipf +
  • +
  • kDSCRegions +: pearl-pshell-import.ipf +
  • +
  • kDSCScientaScaling +: pearl-pshell-import.ipf +
  • +
  • kDSCSnaps +: pearl-pshell-import.ipf +
  • kEnergyDimLabel : pearl-pshell-import.ipf
  • +
  • kEssentialDiagnostics +: pearl-pshell-import.ipf +
  • +
  • kill_matching_waves() +: pearl-pshell-import.ipf +
  • kill_progress_panel() : pearl-gui-tools.ipf
  • @@ -160,8 +204,7 @@ $(document).ready(function(){initNavTree('globals_k.html','');}); : pearl-data-explorer.ipf
  • ks_filematch_mtrx -: pearl-data-explorer.ipf -, pearl-matrix-import.ipf +: pearl-matrix-import.ipf
  • ks_filematch_pshell : pearl-data-explorer.ipf @@ -181,9 +224,9 @@ $(document).ready(function(){initNavTree('globals_k.html','');}); diff --git a/doc/html/globals_l.html b/doc/html/globals_l.html index 4870d5e..c407e42 100644 --- a/doc/html/globals_l.html +++ b/doc/html/globals_l.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
  • - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -84,9 +86,6 @@ $(document).ready(function(){initNavTree('globals_l.html','');});
    Here is a list of all functions, variables, defines, enums, and typedefs with links to the files they belong to:

    - l -

    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -142,7 +144,7 @@ $(document).ready(function(){initNavTree('globals_m.html','');}); : pearl-matrix-import.ipf
  • MultiDoniachSunjicLinBG() -: pearl-fitfuncs.ipf +: pearl-fitfuncs.ipf
  • MultiGaussLinBG() : pearl-fitfuncs.ipf @@ -151,7 +153,10 @@ $(document).ready(function(){initNavTree('globals_m.html','');}); : pearl-fitfuncs.ipf
  • MultiVoigtLinBG() -: pearl-fitfuncs.ipf +: pearl-fitfuncs.ipf +
  • +
  • MultiVoigtLinBG_AO() +: pearl-fitfuncs.ipf
  • @@ -159,9 +164,9 @@ $(document).ready(function(){initNavTree('globals_m.html','');}); diff --git a/doc/html/globals_n.html b/doc/html/globals_n.html index 10277b0..03f1326 100644 --- a/doc/html/globals_n.html +++ b/doc/html/globals_n.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -111,9 +113,9 @@ $(document).ready(function(){initNavTree('globals_n.html','');}); diff --git a/doc/html/globals_o.html b/doc/html/globals_o.html index c1aa57d..e38a142 100644 --- a/doc/html/globals_o.html +++ b/doc/html/globals_o.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -117,9 +119,9 @@ $(document).ready(function(){initNavTree('globals_o.html','');}); diff --git a/doc/html/globals_p.html b/doc/html/globals_p.html index 742585c..4e5eb3e 100644 --- a/doc/html/globals_p.html +++ b/doc/html/globals_p.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -86,16 +88,15 @@ $(document).ready(function(){initNavTree('globals_p.html','');});

    - p -

    @@ -361,9 +371,9 @@ $(document).ready(function(){initNavTree('globals_p.html','');}); diff --git a/doc/html/globals_q.html b/doc/html/globals_q.html index 2bc509d..7daba7e 100644 --- a/doc/html/globals_q.html +++ b/doc/html/globals_q.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -93,9 +95,9 @@ $(document).ready(function(){initNavTree('globals_q.html','');}); diff --git a/doc/html/globals_r.html b/doc/html/globals_r.html index 74fe313..b229ca4 100644 --- a/doc/html/globals_r.html +++ b/doc/html/globals_r.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -98,7 +100,7 @@ $(document).ready(function(){initNavTree('globals_r.html','');});
  • reduce_slab_image() : pearl-area-import.ipf -, pearl-pshell-import.ipf +, pearl-pshell-import.ipf
  • reduce_slab_worker() : pearl-pshell-import.ipf @@ -128,9 +130,9 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); diff --git a/doc/html/globals_s.html b/doc/html/globals_s.html index 635ef12..ee21d49 100644 --- a/doc/html/globals_s.html +++ b/doc/html/globals_s.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
  • - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -100,13 +102,19 @@ $(document).ready(function(){initNavTree('globals_s.html','');}); : pearl-anglescan-tracker.ipf
  • ScientaLiveDisplay() -: pearl-scienta-countrate.ipf +: pearl-scienta-live.ipf
  • -
  • select_dataset() -: pearl-pshell-import.ipf +
  • selected_file() +: pearl-data-explorer.ipf +
  • +
  • send_to_elog() +: pearl-data-explorer.ipf
  • set_contrast() -: pearl-anglescan-process.ipf +: pearl-anglescan-process.ipf +
  • +
  • set_elog_attributes() +: pearl-data-explorer.ipf
  • set_panel_attributes() : pearl-elog.ipf @@ -144,6 +152,9 @@ $(document).ready(function(){initNavTree('globals_s.html','');});
  • ShirleyBG() : pearl-fitfuncs.ipf
  • +
  • shorten_filepath() +: pearl-data-explorer.ipf +
  • show_analyser_line() : pearl-anglescan-process.ipf
  • @@ -168,6 +179,9 @@ $(document).ready(function(){initNavTree('globals_s.html','');});
  • slp_slice_position() : pearl-area-display.ipf
  • +
  • strip_append() +: pearl-anglescan-process.ipf +
  • strip_delete_frames() : pearl-anglescan-process.ipf
  • @@ -189,9 +203,9 @@ $(document).ready(function(){initNavTree('globals_s.html','');}); diff --git a/doc/html/globals_t.html b/doc/html/globals_t.html index 699431f..24e5b1b 100644 --- a/doc/html/globals_t.html +++ b/doc/html/globals_t.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -105,9 +107,9 @@ $(document).ready(function(){initNavTree('globals_t.html','');}); diff --git a/doc/html/globals_u.html b/doc/html/globals_u.html index dfeddb6..6d9cef9 100644 --- a/doc/html/globals_u.html +++ b/doc/html/globals_u.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -84,6 +86,9 @@ $(document).ready(function(){initNavTree('globals_u.html','');});
    Here is a list of all functions, variables, defines, enums, and typedefs with links to the files they belong to:

    - u -

    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -86,6 +88,7 @@ $(document).ready(function(){initNavTree('globals_v.html','');});

    - v -

    @@ -93,9 +96,9 @@ $(document).ready(function(){initNavTree('globals_v.html','');}); diff --git a/doc/html/globals_vars.html b/doc/html/globals_vars.html index 364f33d..7c8270e 100644 --- a/doc/html/globals_vars.html +++ b/doc/html/globals_vars.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -116,9 +118,6 @@ $(document).ready(function(){initNavTree('globals_vars.html','');});
  • kDataDimLabel : pearl-pshell-import.ipf
  • -
  • kDetectorSensitivity -: pearl-pshell-import.ipf -
  • kdfPersistent : pearl-elog.ipf
  • @@ -131,9 +130,51 @@ $(document).ready(function(){initNavTree('globals_vars.html','');});
  • kdfVolatile : pearl-elog.ipf
  • +
  • kDSCAll +: pearl-pshell-import.ipf +
  • +
  • kDSCAttrs +: pearl-pshell-import.ipf +
  • +
  • kDSCDetectors +: pearl-pshell-import.ipf +
  • +
  • kDSCDiags +: pearl-pshell-import.ipf +
  • +
  • kDSCEssentialDiags +: pearl-pshell-import.ipf +
  • +
  • kDSCMeta +: pearl-pshell-import.ipf +
  • +
  • kDSCMonitors +: pearl-pshell-import.ipf +
  • +
  • kDSCOther +: pearl-pshell-import.ipf +
  • +
  • kDSCPositioners +: pearl-pshell-import.ipf +
  • +
  • kDSCPreview +: pearl-pshell-import.ipf +
  • +
  • kDSCRegions +: pearl-pshell-import.ipf +
  • +
  • kDSCScientaScaling +: pearl-pshell-import.ipf +
  • +
  • kDSCSnaps +: pearl-pshell-import.ipf +
  • kEnergyDimLabel : pearl-pshell-import.ipf
  • +
  • kEssentialDiagnostics +: pearl-pshell-import.ipf +
  • kPreviewDatasets : pearl-pshell-import.ipf
  • @@ -174,8 +215,7 @@ $(document).ready(function(){initNavTree('globals_vars.html','');}); : pearl-data-explorer.ipf
  • ks_filematch_mtrx -: pearl-data-explorer.ipf -, pearl-matrix-import.ipf +: pearl-matrix-import.ipf
  • ks_filematch_pshell : pearl-data-explorer.ipf @@ -208,16 +248,15 @@ $(document).ready(function(){initNavTree('globals_vars.html','');});

    - p -

  • @@ -235,9 +275,9 @@ $(document).ready(function(){initNavTree('globals_vars.html','');}); diff --git a/doc/html/globals_w.html b/doc/html/globals_w.html index 9c80c0e..bfb714e 100644 --- a/doc/html/globals_w.html +++ b/doc/html/globals_w.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Globals @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -93,9 +95,9 @@ $(document).ready(function(){initNavTree('globals_w.html','');}); diff --git a/doc/html/group___arpes_package.html b/doc/html/group___arpes_package.html index 9693791..044fbba 100644 --- a/doc/html/group___arpes_package.html +++ b/doc/html/group___arpes_package.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: ARPES package @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -114,9 +116,6 @@ Files file  pearl-compat.ipf  compatibility procedures for igor 8
      -file  pearl-data-explorer.ipf - preview and import panel for PEARL data
    -  file  pearl-elog.ipf  interface for writing ELOG entries with Igor graphs as attachment.
      @@ -129,8 +128,8 @@ Files file  pearl-pshell-import.ipf  import data from PShell
      -file  pearl-scienta-countrate.ipf - count rate functions for Scienta detector images.
    +file  pearl-scienta-live.ipf + utility functions for operating the Scienta analyser.
      file  pearl-scienta-preprocess.ipf  preprocessing functions for Scienta detector images.
    @@ -143,15 +142,15 @@ Files

    data acquisition and analysis package for ARPES at PEARL.

    The purpose of a package is to load a bunch of dependent procedure files. The ARPES package loads the following files which are helpful when working with ARPES data (any data from the Scienta analyser, that is) from PEARL.

    Most of these files require the HDF5.XOP. The following files are loaded if the EPICS.XOP is present:

    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -80,7 +82,7 @@ $(document).ready(function(){initNavTree('index.html','');});
    -
    +
    Introduction
    @@ -96,29 +98,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 are tested on Igor Pro 8.04, 64-bit. Compatibility with earlier versions of Igor has been dropped. Please make sure to use the latest release version of Igor Pro.

    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.
    • +
    • 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.
    • +
    +

    Igor Pro 9 imports the HDF5 library by default. For earlier versions:

    +
      +
    • Find the HDF5.XOP (HDF5-64.xop for 64-bit) extension in the Igor Pro Folder under More Extensions/File Loaders (More Extensions (64-bit)/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 Information

    An open distribution of PEARL Procedures is available under the Apache License, Version 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, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -
    Version
    This documentation is compiled from version rev-distro-2.1.1-1-gf419e92-dirty.
    -
    + + diff --git a/doc/html/jquery.js b/doc/html/jquery.js index f5343ed..103c32d 100644 --- a/doc/html/jquery.js +++ b/doc/html/jquery.js @@ -1,71 +1,26 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
    "),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
    ").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
    "),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
    "),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element +},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** + * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.2 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
    a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
    ";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
    t
    ";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
    ";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

    ";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
    ";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
    ","
    "]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
    ").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! - * jQuery UI 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI - */ -(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! - * jQuery UI Widget 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Widget - */ -(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! - * jQuery UI Mouse 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Mouse - * - * Depends: - * jquery.ui.widget.js - */ -(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
    ').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
    ');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! - * jQuery hashchange event - v1.3 - 7/21/2010 - * http://benalman.com/projects/jquery-hashchange-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' - - -
    -
    -
    PearlDataExplorer Namespace Reference
    -
    -
    - -

    preview and import panel for PEARL data -More...

    -

    Detailed Description

    -

    preview and import panel for PEARL data

    -

    PearlDataExplorer is declared in pearl-data-explorer.ipf.

    -
    - - - - - diff --git a/doc/html/namespace_pearl_elog.html b/doc/html/namespace_pearl_elog.html index 6e5edce..9c795bb 100644 --- a/doc/html/namespace_pearl_elog.html +++ b/doc/html/namespace_pearl_elog.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: PearlElog Namespace Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    @@ -38,18 +35,21 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -87,19 +89,19 @@ $(document).ready(function(){initNavTree('namespace_pearl_elog.html','');});

    interface for writing ELOG entries with Igor graphs as attachment. -More...

    +More...

    Detailed Description

    interface for writing ELOG entries with Igor graphs as attachment.

    -

    PearlElog is declared in pearl-elog.ipf.

    +

    PearlElog is declared in pearl-elog.ipf.

    diff --git a/doc/html/namespace_pearl_fit_funcs.html b/doc/html/namespace_pearl_fit_funcs.html index 8cfcb96..a8d490a 100644 --- a/doc/html/namespace_pearl_fit_funcs.html +++ b/doc/html/namespace_pearl_fit_funcs.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: PearlFitFuncs Namespace Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -87,19 +89,19 @@ $(document).ready(function(){initNavTree('namespace_pearl_fit_funcs.html','');})

    various fit functions for photoelectron spectroscopy. -More...

    +More...

    Detailed Description

    various fit functions for photoelectron spectroscopy.

    -

    PearlFitFuncs is declared in pearl-fitfuncs.ipf.

    +

    PearlFitFuncs is declared in pearl-fitfuncs.ipf.

    diff --git a/doc/html/namespace_pearl_matrix_import.html b/doc/html/namespace_pearl_matrix_import.html index 28db93d..e5f5f40 100644 --- a/doc/html/namespace_pearl_matrix_import.html +++ b/doc/html/namespace_pearl_matrix_import.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: PearlMatrixImport Namespace Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -87,19 +89,19 @@ $(document).ready(function(){initNavTree('namespace_pearl_matrix_import.html',''

    data file import for omicron matrix (STM) files -More...

    +More...

    Detailed Description

    data file import for omicron matrix (STM) files

    -

    PearlMatrixImport is declared in pearl-matrix-import.ipf.

    +

    PearlMatrixImport is declared in pearl-matrix-import.ipf.

    diff --git a/doc/html/namespace_pearl_p_shell_import.html b/doc/html/namespace_pearl_p_shell_import.html index 486b589..4051559 100644 --- a/doc/html/namespace_pearl_p_shell_import.html +++ b/doc/html/namespace_pearl_p_shell_import.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: PearlPShellImport Namespace Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -87,19 +89,19 @@ $(document).ready(function(){initNavTree('namespace_pearl_p_shell_import.html','

    import data from PShell -More...

    +More...

    Detailed Description

    import data from PShell

    -

    PearlPShellImport is declared in pearl-pshell-import.ipf.

    +

    PearlPShellImport is declared in pearl-pshell-import.ipf.

    diff --git a/doc/html/namespace_pearl_pmsco_import.html b/doc/html/namespace_pearl_pmsco_import.html index 929a71d..0f4fc84 100644 --- a/doc/html/namespace_pearl_pmsco_import.html +++ b/doc/html/namespace_pearl_pmsco_import.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: PearlPmscoImport Namespace Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -87,19 +89,19 @@ $(document).ready(function(){initNavTree('namespace_pearl_pmsco_import.html','')

    data import/export procedures for multiple scattering calculations. -More...

    +More...

    Detailed Description

    data import/export procedures for multiple scattering calculations.

    -

    PearlPmscoImport is declared in pearl-pmsco-import.ipf.

    +

    PearlPmscoImport is declared in pearl-pmsco-import.ipf.

    diff --git a/doc/html/namespace_pearl_scienta_countrate.html b/doc/html/namespace_pearl_scienta_countrate.html deleted file mode 100644 index 79a88bb..0000000 --- a/doc/html/namespace_pearl_scienta_countrate.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - -PEARL Procedures: PearlScientaCountrate Namespace Reference - - - - - - - - - - - - - - -
    -
    - - - - - - -
    -
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty -
    -
    Igor procedures for the analysis of PEARL data
    -
    -
    - - - - - - - -
    -
    - -
    -
    -
    - -
    - -
    -
    - - -
    - -
    - -
    -
    -
    PearlScientaCountrate Namespace Reference
    -
    -
    - -

    count rate functions for Scienta detector images. -More...

    -

    Detailed Description

    -

    count rate functions for Scienta detector images.

    -

    PearlScientaCountrate is declared in pearl-scienta-countrate.ipf.

    -
    -
    - - - - diff --git a/doc/html/namespace_pearl_scienta_preprocess.html b/doc/html/namespace_pearl_scienta_preprocess.html index c4cddfc..b35f252 100644 --- a/doc/html/namespace_pearl_scienta_preprocess.html +++ b/doc/html/namespace_pearl_scienta_preprocess.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: PearlScientaPreprocess Namespace Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -87,19 +89,19 @@ $(document).ready(function(){initNavTree('namespace_pearl_scienta_preprocess.htm

    preprocessing functions for Scienta detector images. -More...

    +More...

    Detailed Description

    preprocessing functions for Scienta detector images.

    -

    PearlScientaPreprocess is declared in pearl-scienta-preprocess.ipf.

    +

    PearlScientaPreprocess is declared in pearl-scienta-preprocess.ipf.

    diff --git a/doc/html/namespace_pearl_vector_operations.html b/doc/html/namespace_pearl_vector_operations.html index 175f3ac..505643c 100644 --- a/doc/html/namespace_pearl_vector_operations.html +++ b/doc/html/namespace_pearl_vector_operations.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: PearlVectorOperations Namespace Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -87,19 +89,19 @@ $(document).ready(function(){initNavTree('namespace_pearl_vector_operations.html

    basic vector geometry operations. -More...

    +More...

    Detailed Description

    basic vector geometry operations.

    -

    PearlVectorOperations is declared in pearl-vector-operations.ipf.

    +

    PearlVectorOperations is declared in pearl-vector-operations.ipf.

    diff --git a/doc/html/namespaces.html b/doc/html/namespaces.html index c36d291..55c4249 100644 --- a/doc/html/namespaces.html +++ b/doc/html/namespaces.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Namespace List @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -94,15 +96,14 @@ $(document).ready(function(){initNavTree('namespaces.html','');});  NPearlAreaProfilesProfile extraction for multi-dimensional datasets acquired from area detectors  NPearlArpesData acquisition and analysis package for ARPES at PEARL  NPearlCompatCompatibility procedures for igor 8 - NPearlDataExplorerPreview and import panel for PEARL data - NPearlElogInterface for writing ELOG entries with Igor graphs as attachment - NPearlFitFuncsVarious fit functions for photoelectron spectroscopy - NPearlMatrixImportData file import for omicron matrix (STM) files - NPearlPmscoImportData import/export procedures for multiple scattering calculations - NPearlPShellImportImport data from PShell - NPearlScientaCountrateCount rate functions for Scienta detector images - NPearlScientaPreprocessPreprocessing functions for Scienta detector images - NPearlVectorOperationsBasic vector geometry operations + NPearlElogInterface for writing ELOG entries with Igor graphs as attachment + NPearlFitFuncsVarious fit functions for photoelectron spectroscopy + NPearlMatrixImportData file import for omicron matrix (STM) files + NPearlPmscoImportData import/export procedures for multiple scattering calculations + NPearlPShellImportImport data from PShell + NPearlScientaLiveUtility functions for operating the Scienta analyser + NPearlScientaPreprocessPreprocessing functions for Scienta detector images + NPearlVectorOperationsBasic vector geometry operations
    @@ -110,9 +111,9 @@ $(document).ready(function(){initNavTree('namespaces.html','');}); diff --git a/doc/html/namespaces.js b/doc/html/namespaces.js deleted file mode 100644 index cf1e66a..0000000 --- a/doc/html/namespaces.js +++ /dev/null @@ -1,19 +0,0 @@ -var namespaces = -[ - [ "PearlAnglescanPanel", "namespace_pearl_anglescan_panel.html", null ], - [ "PearlAnglescanProcess", "namespace_pearl_anglescan_process.html", null ], - [ "PearlAreaDisplay", "namespace_pearl_area_display.html", null ], - [ "PearlAreaImport", "namespace_pearl_area_import.html", null ], - [ "PearlAreaProfiles", "namespace_pearl_area_profiles.html", null ], - [ "PearlArpes", "namespace_pearl_arpes.html", null ], - [ "PearlCompat", "namespace_pearl_compat.html", null ], - [ "PearlDataExplorer", "namespace_pearl_data_explorer.html", null ], - [ "PearlElog", "namespace_pearl_elog.html", null ], - [ "PearlFitFuncs", "namespace_pearl_fit_funcs.html", null ], - [ "PearlMatrixImport", "namespace_pearl_matrix_import.html", null ], - [ "PearlPmscoImport", "namespace_pearl_pmsco_import.html", null ], - [ "PearlPShellImport", "namespace_pearl_p_shell_import.html", null ], - [ "PearlScientaCountrate", "namespace_pearl_scienta_countrate.html", null ], - [ "PearlScientaPreprocess", "namespace_pearl_scienta_preprocess.html", null ], - [ "PearlVectorOperations", "namespace_pearl_vector_operations.html", null ] -]; \ No newline at end of file diff --git a/doc/html/navtree.css b/doc/html/navtree.css index 0cc7e77..33341a6 100644 --- a/doc/html/navtree.css +++ b/doc/html/navtree.css @@ -96,7 +96,7 @@ .ui-resizable-e { background-image:url("splitbar.png"); background-size:100%; - background-repeat:no-repeat; + background-repeat:repeat-y; background-attachment: scroll; cursor:ew-resize; height:100%; diff --git a/doc/html/navtree.js b/doc/html/navtree.js index e6d31b0..edc31ef 100644 --- a/doc/html/navtree.js +++ b/doc/html/navtree.js @@ -1,3 +1,25 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2019 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ var navTreeSubIndices = new Array(); var arrowDown = '▼'; var arrowRight = '►'; @@ -47,7 +69,6 @@ function localStorageSupported() } } - function storeLink(link) { if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { @@ -79,15 +100,7 @@ function getScript(scriptName,func,show) script.type = 'text/javascript'; script.onload = func; script.src = scriptName+'.js'; - if ($.browser.msie && $.browser.version<=8) { - // script.onload does not work with older versions of IE - script.onreadystatechange = function() { - if (script.readyState=='complete' || script.readyState=='loaded') { - func(); if (show) showRoot(); - } - } - } - head.appendChild(script); + head.appendChild(script); } function createIndent(o,domNode,node,level) @@ -130,6 +143,7 @@ function gotoAnchor(anchor,aname,updateLocation) var pos, docContent = $('#doc-content'); var ancParent = $(anchor.parent()); if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('memtitle') || ancParent.hasClass('fieldname') || ancParent.hasClass('fieldtype') || ancParent.is(':header')) @@ -242,7 +256,7 @@ function showRoot() (function (){ // retry until we can scroll to the selected item try { var navtree=$('#nav-tree'); - navtree.scrollTo('#selected',0,{offset:-windowHeight/2}); + navtree.scrollTo('#selected',100,{offset:-windowHeight/2}); } catch (err) { setTimeout(arguments.callee, 0); } @@ -261,12 +275,8 @@ function expandNode(o, node, imm, showRoot) } else { if (!node.childrenVisited) { getNode(o, node); - } if (imm || ($.browser.msie && $.browser.version>8)) { - // somehow slideDown jumps to the start of tree for IE9 :-( - $(node.getChildrenUL()).show(); - } else { - $(node.getChildrenUL()).slideDown("fast"); } + $(node.getChildrenUL()).slideDown("fast"); node.plus_img.innerHTML = arrowDown; node.expanded = true; } @@ -296,7 +306,6 @@ function highlightAnchor() } else { glowEffect(anchor.next(),1000); // normal member } - gotoAnchor(anchor,aname,false); } function selectAndHighlight(hash,n) @@ -458,6 +467,18 @@ function toggleSyncButton(relpath) } } +var loadTriggered = false; +var readyTriggered = false; +var loadObject,loadToRoot,loadUrl,loadRelPath; + +$(window).on('load',function(){ + if (readyTriggered) { // ready first + navTo(loadObject,loadToRoot,loadUrl,loadRelPath); + showRoot(); + } + loadTriggered=true; +}); + function initNavTree(toroot,relpath) { var o = new Object(); @@ -488,10 +509,16 @@ function initNavTree(toroot,relpath) navSync.click(function(){ toggleSyncButton(relpath); }); } - $(window).load(function(){ + if (loadTriggered) { // load before ready navTo(o,toroot,hashUrl(),relpath); showRoot(); - }); + } else { // ready before load + loadObject = o; + loadToRoot = toroot; + loadUrl = hashUrl(); + loadRelPath = relpath; + readyTriggered=true; + } $(window).bind('hashchange', function(){ if (window.location.hash && window.location.hash.length>1){ @@ -514,4 +541,4 @@ function initNavTree(toroot,relpath) } }) } - +/* @license-end */ diff --git a/doc/html/navtreedata.js b/doc/html/navtreedata.js index 8fe4ef3..0014aba 100644 --- a/doc/html/navtreedata.js +++ b/doc/html/navtreedata.js @@ -1,3 +1,25 @@ +/* +@licstart The following is the entire license notice for the +JavaScript code in this file. + +Copyright (C) 1997-2019 by Dimitri van Heesch + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as published by +the Free Software Foundation + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +@licend The above is the entire license notice +for the JavaScript code in this file +*/ var NAVTREE = [ [ "PEARL Procedures", "index.html", [ @@ -36,8 +58,8 @@ var NAVTREE = ] ], [ "Todo List", "todo.html", null ], [ "Packages", "modules.html", "modules" ], - [ "Namespaces", null, [ - [ "Namespace List", "namespaces.html", "namespaces" ] + [ "Namespaces", "namespaces.html", [ + [ "Namespace List", "namespaces.html", "namespaces_dup" ] ] ], [ "Data Structures", "annotated.html", "annotated" ], [ "Data Structure Index", "classes.html", null ], @@ -45,8 +67,8 @@ var NAVTREE = [ "All", "functions.html", null ], [ "Variables", "functions_vars.html", null ] ] ], - [ "Files", null, [ - [ "File List", "files.html", "files" ], + [ "Files", "files.html", [ + [ "File List", "files.html", "files_dup" ], [ "Globals", "globals.html", [ [ "All", "globals.html", "globals_dup" ], [ "Functions", "globals_func.html", "globals_func" ], @@ -59,8 +81,8 @@ var NAVTREE = var NAVTREEINDEX = [ "_page_projections.html", -"pearl-anglescan-tracker_8ipf.html#a35a5cd8a21b48be8d726c69eb5fca134", -"pearl-elog_8ipf_source.html" +"pearl-anglescan-tracker_8ipf.html#a33e84ae8e13f405d466b28e83f608cb9", +"pearl-elog_8ipf.html#acbba78d869a543edf7c2b80d7a8d2344" ]; var SYNCONMSG = 'click to disable panel synchronisation'; diff --git a/doc/html/navtreeindex0.js b/doc/html/navtreeindex0.js index 796ac0c..cb355ae 100644 --- a/doc/html/navtreeindex0.js +++ b/doc/html/navtreeindex0.js @@ -4,18 +4,17 @@ var NAVTREEINDEX0 = "annotated.html":[6], "classes.html":[7], "fermi-edge-analysis_8ipf.html":[9,0,0], -"fermi-edge-analysis_8ipf.html#a09f26b0a0fd940a3d8c6f92aa769c8bc":[9,0,0,11], -"fermi-edge-analysis_8ipf.html#a0cb8da36beae05c79fe5b1da918d3897":[9,0,0,8], +"fermi-edge-analysis_8ipf.html#a09f26b0a0fd940a3d8c6f92aa769c8bc":[9,0,0,10], +"fermi-edge-analysis_8ipf.html#a0cb8da36beae05c79fe5b1da918d3897":[9,0,0,7], "fermi-edge-analysis_8ipf.html#a1c4a805435a1d43c2b6dfb6deb633894":[9,0,0,0], -"fermi-edge-analysis_8ipf.html#a27f000c3a3ea74c49db31716be3396d4":[9,0,0,7], -"fermi-edge-analysis_8ipf.html#a2a1d7b49c1f88f29ee6d49f6a6f4fbf8":[9,0,0,3], -"fermi-edge-analysis_8ipf.html#a4749b9bce3e1d0381bd9daeb97c9754c":[9,0,0,9], -"fermi-edge-analysis_8ipf.html#a4cec596c8fd2b21953cb45d6d347211d":[9,0,0,6], -"fermi-edge-analysis_8ipf.html#a4dcc00b93822f1663be2908b10d2ad3e":[9,0,0,10], -"fermi-edge-analysis_8ipf.html#a520d8de9fbc4276c19fb417861f05b0d":[9,0,0,2], -"fermi-edge-analysis_8ipf.html#aac6bac1ee0582caa0676bdc9c2d254f0":[9,0,0,4], -"fermi-edge-analysis_8ipf.html#acf72d644b8d37b6c26b1e070edba4e30":[9,0,0,5], -"fermi-edge-analysis_8ipf.html#ad23de34bb698589e2576ce2836b89d55":[9,0,0,1], +"fermi-edge-analysis_8ipf.html#a27f000c3a3ea74c49db31716be3396d4":[9,0,0,6], +"fermi-edge-analysis_8ipf.html#a2a1d7b49c1f88f29ee6d49f6a6f4fbf8":[9,0,0,2], +"fermi-edge-analysis_8ipf.html#a4749b9bce3e1d0381bd9daeb97c9754c":[9,0,0,8], +"fermi-edge-analysis_8ipf.html#a4cec596c8fd2b21953cb45d6d347211d":[9,0,0,5], +"fermi-edge-analysis_8ipf.html#a4dcc00b93822f1663be2908b10d2ad3e":[9,0,0,9], +"fermi-edge-analysis_8ipf.html#a520d8de9fbc4276c19fb417861f05b0d":[9,0,0,1], +"fermi-edge-analysis_8ipf.html#aac6bac1ee0582caa0676bdc9c2d254f0":[9,0,0,3], +"fermi-edge-analysis_8ipf.html#acf72d644b8d37b6c26b1e070edba4e30":[9,0,0,4], "fermi-edge-analysis_8ipf_source.html":[9,0,0], "files.html":[9,0], "functions.html":[8,0], @@ -80,15 +79,14 @@ var NAVTREEINDEX0 = "namespace_pearl_area_profiles.html":[5,0,4], "namespace_pearl_arpes.html":[5,0,5], "namespace_pearl_compat.html":[5,0,6], -"namespace_pearl_data_explorer.html":[5,0,7], -"namespace_pearl_elog.html":[5,0,8], -"namespace_pearl_fit_funcs.html":[5,0,9], -"namespace_pearl_matrix_import.html":[5,0,10], -"namespace_pearl_p_shell_import.html":[5,0,12], -"namespace_pearl_pmsco_import.html":[5,0,11], -"namespace_pearl_scienta_countrate.html":[5,0,13], -"namespace_pearl_scienta_preprocess.html":[5,0,14], -"namespace_pearl_vector_operations.html":[5,0,15], +"namespace_pearl_elog.html":[5,0,7], +"namespace_pearl_fit_funcs.html":[5,0,8], +"namespace_pearl_matrix_import.html":[5,0,9], +"namespace_pearl_p_shell_import.html":[5,0,11], +"namespace_pearl_pmsco_import.html":[5,0,10], +"namespace_pearl_scienta_live.html":[5,0,12], +"namespace_pearl_scienta_preprocess.html":[5,0,13], +"namespace_pearl_vector_operations.html":[5,0,14], "namespaces.html":[5,0], "pag_anglescan_processing.html":[2], "pag_anglescan_processing.html#sec_anglescan_intro":[2,0], @@ -177,67 +175,70 @@ var NAVTREEINDEX0 = "pearl-anglescan-panel_8ipf.html#af83bfcf48723e7f6eeb78b4e0d84277d":[9,0,1,47], "pearl-anglescan-panel_8ipf_source.html":[9,0,1], "pearl-anglescan-process_8ipf.html":[9,0,2], -"pearl-anglescan-process_8ipf.html#a01bac9e7d4ba743c3c34177a05070466":[9,0,2,47], -"pearl-anglescan-process_8ipf.html#a04e75675884236b6ed8244d7575d3a13":[9,0,2,56], -"pearl-anglescan-process_8ipf.html#a0b9e2b025e1d55d2a064edccf6c1c3e3":[9,0,2,42], -"pearl-anglescan-process_8ipf.html#a13e0d37ae23f68cdc5da3d84cb4beed8":[9,0,2,48], -"pearl-anglescan-process_8ipf.html#a1442bc23122d52ba9c77e0f9baaad1da":[9,0,2,22], -"pearl-anglescan-process_8ipf.html#a1baaa3ffd9495ed427b43cbfe6e1edf8":[9,0,2,50], -"pearl-anglescan-process_8ipf.html#a1f4f74a8ae557c56e1e3aacd0b45f3f1":[9,0,2,16], -"pearl-anglescan-process_8ipf.html#a1fb6aa7870dfbf0ed92660b7aae579e0":[9,0,2,6], -"pearl-anglescan-process_8ipf.html#a207c56ac03cc18bf1bfde88dbfe2666f":[9,0,2,51], -"pearl-anglescan-process_8ipf.html#a229770447193d4fd12032b235aab4d28":[9,0,2,39], -"pearl-anglescan-process_8ipf.html#a2b38c6c9b6e60593ba69d3773b6bc779":[9,0,2,11], -"pearl-anglescan-process_8ipf.html#a2e1ed05781f9eb4be5e77695ef049962":[9,0,2,8], -"pearl-anglescan-process_8ipf.html#a3b3bd11c35d5f850b34937ab6c45f659":[9,0,2,54], -"pearl-anglescan-process_8ipf.html#a3cc7eddf5c6b0658260cfb32dd2c026d":[9,0,2,10], -"pearl-anglescan-process_8ipf.html#a3ec6935a5903d0974c93a2072d743013":[9,0,2,9], -"pearl-anglescan-process_8ipf.html#a4641c716180d737700c6df87f5f8974e":[9,0,2,24], -"pearl-anglescan-process_8ipf.html#a46fd99d35a43601c39af6096d4e4f770":[9,0,2,15], -"pearl-anglescan-process_8ipf.html#a48b7d774ed8d3f4329e9923e18e580e8":[9,0,2,37], -"pearl-anglescan-process_8ipf.html#a48cbd596656bc6d849c53afb4c58b90d":[9,0,2,44], -"pearl-anglescan-process_8ipf.html#a4952bc53e3d6d272d25b5e35e91696b5":[9,0,2,23], -"pearl-anglescan-process_8ipf.html#a4a40c73c0e03545e0050ea370e9c57d3":[9,0,2,53], -"pearl-anglescan-process_8ipf.html#a4fc744e24e3e9c5efb17f14ab622bcae":[9,0,2,1], -"pearl-anglescan-process_8ipf.html#a5162488b366e217195d8f8bd7cdde0ce":[9,0,2,43], -"pearl-anglescan-process_8ipf.html#a5265fd61f86eb72dd877e4190bfb4adf":[9,0,2,27], -"pearl-anglescan-process_8ipf.html#a5dc0cc7db9d3d7a6b3fa3f1b04d84a5e":[9,0,2,49], -"pearl-anglescan-process_8ipf.html#a666dab03bb2e97ffef81cea450184d42":[9,0,2,45], -"pearl-anglescan-process_8ipf.html#a70b0e243bcbd549e2b1da74aab605629":[9,0,2,46], -"pearl-anglescan-process_8ipf.html#a75219b38ea58012abcffc848d536faa4":[9,0,2,3], -"pearl-anglescan-process_8ipf.html#a89f73edcd51a675f4c3933cd0242484e":[9,0,2,30], -"pearl-anglescan-process_8ipf.html#a902ac3a24e33f651e83ee03d31707da7":[9,0,2,31], -"pearl-anglescan-process_8ipf.html#a9624070f3e938378631432430d47a389":[9,0,2,4], -"pearl-anglescan-process_8ipf.html#a987811346894d8d81fc590b2f5ccec49":[9,0,2,21], -"pearl-anglescan-process_8ipf.html#a992920d621023e6b483ff51eee68b508":[9,0,2,35], -"pearl-anglescan-process_8ipf.html#a999a9cd7d00d3e1ec8e768228a664ad1":[9,0,2,5], -"pearl-anglescan-process_8ipf.html#a9b56897bd92d926d65f4c67bef1d41bb":[9,0,2,34], -"pearl-anglescan-process_8ipf.html#aa26c9ed4c4d703e07788d980edc2406d":[9,0,2,20], -"pearl-anglescan-process_8ipf.html#aa486e16909d01e2251eeb4d635b972b1":[9,0,2,26], -"pearl-anglescan-process_8ipf.html#aa5487fdee22e0da61a511c14239262f5":[9,0,2,58], -"pearl-anglescan-process_8ipf.html#aa54a550eccad2c8ccd82d2b4167f7a92":[9,0,2,29], -"pearl-anglescan-process_8ipf.html#aa5b1e2ab1dd43a73b7157406b803887e":[9,0,2,19], -"pearl-anglescan-process_8ipf.html#aa79c0ff6073bd42e202b9fa3f8c00b9f":[9,0,2,13], -"pearl-anglescan-process_8ipf.html#aaa734fddecdd75c7cabe20ba777b41b9":[9,0,2,33], -"pearl-anglescan-process_8ipf.html#aae45cc49d67f79dcedc4420f82acea4c":[9,0,2,52], -"pearl-anglescan-process_8ipf.html#ab65d25af7476ed18f7bf7359614a912b":[9,0,2,12], -"pearl-anglescan-process_8ipf.html#ab6670abb621d01994c0b9974f58be843":[9,0,2,57], -"pearl-anglescan-process_8ipf.html#ab6ac1268de338040028dca8d0ddc967c":[9,0,2,25], -"pearl-anglescan-process_8ipf.html#ac0def1ded61f9cd758df0c99f4ff9470":[9,0,2,7], -"pearl-anglescan-process_8ipf.html#ac151c6f989d6a568fdef0acb791f84db":[9,0,2,60], -"pearl-anglescan-process_8ipf.html#ac15ebd5a19c558dde666ab36aeb9906f":[9,0,2,41], -"pearl-anglescan-process_8ipf.html#ac4dbd1ece37b2cf22fa976a153977288":[9,0,2,40], -"pearl-anglescan-process_8ipf.html#ac617c3b400488b656493af8ca08f1791":[9,0,2,32], -"pearl-anglescan-process_8ipf.html#acca0130cccf2286863bbf5b7f91c5b3b":[9,0,2,28], -"pearl-anglescan-process_8ipf.html#acf6fddb73624fe2d21429e38c4994088":[9,0,2,0], -"pearl-anglescan-process_8ipf.html#ad0a93367d2e9b66bb7b81697e87adfaf":[9,0,2,36], -"pearl-anglescan-process_8ipf.html#ae2b036a06ffac8d2bb292a65401f8a9a":[9,0,2,2], -"pearl-anglescan-process_8ipf.html#ae57302acfc822c4817f2b7eef55efea2":[9,0,2,14], -"pearl-anglescan-process_8ipf.html#aed66bda9701d8a69b2174fac974aa665":[9,0,2,59], -"pearl-anglescan-process_8ipf.html#af00d9061e410ad033a9fd1f0ca561e0d":[9,0,2,18], -"pearl-anglescan-process_8ipf.html#afa14187803f5b428a96c8234e04ab217":[9,0,2,55], -"pearl-anglescan-process_8ipf.html#afed227ae79873fd32c96afbf606d1965":[9,0,2,38], -"pearl-anglescan-process_8ipf.html#afedad38a418cee5d1fb9e08aae2160a0":[9,0,2,17], +"pearl-anglescan-process_8ipf.html#a01bac9e7d4ba743c3c34177a05070466":[9,0,2,49], +"pearl-anglescan-process_8ipf.html#a04e75675884236b6ed8244d7575d3a13":[9,0,2,59], +"pearl-anglescan-process_8ipf.html#a0b9e2b025e1d55d2a064edccf6c1c3e3":[9,0,2,44], +"pearl-anglescan-process_8ipf.html#a13e0d37ae23f68cdc5da3d84cb4beed8":[9,0,2,51], +"pearl-anglescan-process_8ipf.html#a1442bc23122d52ba9c77e0f9baaad1da":[9,0,2,24], +"pearl-anglescan-process_8ipf.html#a1baaa3ffd9495ed427b43cbfe6e1edf8":[9,0,2,53], +"pearl-anglescan-process_8ipf.html#a1f4f74a8ae557c56e1e3aacd0b45f3f1":[9,0,2,18], +"pearl-anglescan-process_8ipf.html#a1fb6aa7870dfbf0ed92660b7aae579e0":[9,0,2,8], +"pearl-anglescan-process_8ipf.html#a207c56ac03cc18bf1bfde88dbfe2666f":[9,0,2,54], +"pearl-anglescan-process_8ipf.html#a229770447193d4fd12032b235aab4d28":[9,0,2,41], +"pearl-anglescan-process_8ipf.html#a2b38c6c9b6e60593ba69d3773b6bc779":[9,0,2,13], +"pearl-anglescan-process_8ipf.html#a3b3bd11c35d5f850b34937ab6c45f659":[9,0,2,57], +"pearl-anglescan-process_8ipf.html#a3cc7eddf5c6b0658260cfb32dd2c026d":[9,0,2,12], +"pearl-anglescan-process_8ipf.html#a3ec6935a5903d0974c93a2072d743013":[9,0,2,11], +"pearl-anglescan-process_8ipf.html#a4641c716180d737700c6df87f5f8974e":[9,0,2,26], +"pearl-anglescan-process_8ipf.html#a46fd99d35a43601c39af6096d4e4f770":[9,0,2,17], +"pearl-anglescan-process_8ipf.html#a48b7d774ed8d3f4329e9923e18e580e8":[9,0,2,39], +"pearl-anglescan-process_8ipf.html#a48cbd596656bc6d849c53afb4c58b90d":[9,0,2,46], +"pearl-anglescan-process_8ipf.html#a4952bc53e3d6d272d25b5e35e91696b5":[9,0,2,25], +"pearl-anglescan-process_8ipf.html#a4a40c73c0e03545e0050ea370e9c57d3":[9,0,2,56], +"pearl-anglescan-process_8ipf.html#a4fc744e24e3e9c5efb17f14ab622bcae":[9,0,2,3], +"pearl-anglescan-process_8ipf.html#a5162488b366e217195d8f8bd7cdde0ce":[9,0,2,45], +"pearl-anglescan-process_8ipf.html#a5265fd61f86eb72dd877e4190bfb4adf":[9,0,2,29], +"pearl-anglescan-process_8ipf.html#a5dc0cc7db9d3d7a6b3fa3f1b04d84a5e":[9,0,2,52], +"pearl-anglescan-process_8ipf.html#a67d53a1c362d7e5bbeccf1c9c12ae0c2":[9,0,2,10], +"pearl-anglescan-process_8ipf.html#a70b0e243bcbd549e2b1da74aab605629":[9,0,2,48], +"pearl-anglescan-process_8ipf.html#a75219b38ea58012abcffc848d536faa4":[9,0,2,5], +"pearl-anglescan-process_8ipf.html#a89f73edcd51a675f4c3933cd0242484e":[9,0,2,32], +"pearl-anglescan-process_8ipf.html#a8c83a187e371783dea62c9f2bc97c52c":[9,0,2,0], +"pearl-anglescan-process_8ipf.html#a8eabc7feca73f9e0db2109a78ee382cb":[9,0,2,1], +"pearl-anglescan-process_8ipf.html#a902ac3a24e33f651e83ee03d31707da7":[9,0,2,33], +"pearl-anglescan-process_8ipf.html#a9624070f3e938378631432430d47a389":[9,0,2,6], +"pearl-anglescan-process_8ipf.html#a987811346894d8d81fc590b2f5ccec49":[9,0,2,23], +"pearl-anglescan-process_8ipf.html#a992920d621023e6b483ff51eee68b508":[9,0,2,37], +"pearl-anglescan-process_8ipf.html#a999a9cd7d00d3e1ec8e768228a664ad1":[9,0,2,7], +"pearl-anglescan-process_8ipf.html#a9b56897bd92d926d65f4c67bef1d41bb":[9,0,2,36], +"pearl-anglescan-process_8ipf.html#aa26c9ed4c4d703e07788d980edc2406d":[9,0,2,22], +"pearl-anglescan-process_8ipf.html#aa486e16909d01e2251eeb4d635b972b1":[9,0,2,28], +"pearl-anglescan-process_8ipf.html#aa5487fdee22e0da61a511c14239262f5":[9,0,2,61], +"pearl-anglescan-process_8ipf.html#aa54a550eccad2c8ccd82d2b4167f7a92":[9,0,2,31], +"pearl-anglescan-process_8ipf.html#aa5b1e2ab1dd43a73b7157406b803887e":[9,0,2,21], +"pearl-anglescan-process_8ipf.html#aa79c0ff6073bd42e202b9fa3f8c00b9f":[9,0,2,15], +"pearl-anglescan-process_8ipf.html#aaa734fddecdd75c7cabe20ba777b41b9":[9,0,2,35], +"pearl-anglescan-process_8ipf.html#aae45cc49d67f79dcedc4420f82acea4c":[9,0,2,55], +"pearl-anglescan-process_8ipf.html#ab65d25af7476ed18f7bf7359614a912b":[9,0,2,14], +"pearl-anglescan-process_8ipf.html#ab6670abb621d01994c0b9974f58be843":[9,0,2,60], +"pearl-anglescan-process_8ipf.html#ab6ac1268de338040028dca8d0ddc967c":[9,0,2,27], +"pearl-anglescan-process_8ipf.html#ab97a936bc0fa6137b6d0b43cb61d39a1":[9,0,2,50], +"pearl-anglescan-process_8ipf.html#ac0def1ded61f9cd758df0c99f4ff9470":[9,0,2,9], +"pearl-anglescan-process_8ipf.html#ac151c6f989d6a568fdef0acb791f84db":[9,0,2,63], +"pearl-anglescan-process_8ipf.html#ac15ebd5a19c558dde666ab36aeb9906f":[9,0,2,43], +"pearl-anglescan-process_8ipf.html#ac4dbd1ece37b2cf22fa976a153977288":[9,0,2,42], +"pearl-anglescan-process_8ipf.html#ac617c3b400488b656493af8ca08f1791":[9,0,2,34], +"pearl-anglescan-process_8ipf.html#acca0130cccf2286863bbf5b7f91c5b3b":[9,0,2,30], +"pearl-anglescan-process_8ipf.html#acf6fddb73624fe2d21429e38c4994088":[9,0,2,2], +"pearl-anglescan-process_8ipf.html#ad0a93367d2e9b66bb7b81697e87adfaf":[9,0,2,38], +"pearl-anglescan-process_8ipf.html#ae2b036a06ffac8d2bb292a65401f8a9a":[9,0,2,4], +"pearl-anglescan-process_8ipf.html#ae57302acfc822c4817f2b7eef55efea2":[9,0,2,16], +"pearl-anglescan-process_8ipf.html#aed66bda9701d8a69b2174fac974aa665":[9,0,2,62], +"pearl-anglescan-process_8ipf.html#af00d9061e410ad033a9fd1f0ca561e0d":[9,0,2,20], +"pearl-anglescan-process_8ipf.html#af9874b5c1ce1d216741c7880a5fdcfcc":[9,0,2,47], +"pearl-anglescan-process_8ipf.html#afa14187803f5b428a96c8234e04ab217":[9,0,2,58], +"pearl-anglescan-process_8ipf.html#afed227ae79873fd32c96afbf606d1965":[9,0,2,40], +"pearl-anglescan-process_8ipf.html#afedad38a418cee5d1fb9e08aae2160a0":[9,0,2,19], "pearl-anglescan-process_8ipf_source.html":[9,0,2], "pearl-anglescan-tracker_8ipf.html":[9,0,3], "pearl-anglescan-tracker_8ipf.html#a02271bf812a3e3f87c958f4c58e9f71b":[9,0,3,10], @@ -248,6 +249,5 @@ var NAVTREEINDEX0 = "pearl-anglescan-tracker_8ipf.html#a0b8ff36cf3c20b1c0db3217d9065f7cf":[9,0,3,39], "pearl-anglescan-tracker_8ipf.html#a150243e26e8adf8b354b8afde064136d":[9,0,3,12], "pearl-anglescan-tracker_8ipf.html#a20720748c82a7eaa4b02d4084a4219b2":[9,0,3,43], -"pearl-anglescan-tracker_8ipf.html#a306b168cab2f9c4146cee87009e69f6d":[9,0,3,17], -"pearl-anglescan-tracker_8ipf.html#a33e84ae8e13f405d466b28e83f608cb9":[9,0,3,13] +"pearl-anglescan-tracker_8ipf.html#a306b168cab2f9c4146cee87009e69f6d":[9,0,3,17] }; diff --git a/doc/html/navtreeindex1.js b/doc/html/navtreeindex1.js index efa0e26..e5d7f78 100644 --- a/doc/html/navtreeindex1.js +++ b/doc/html/navtreeindex1.js @@ -1,5 +1,6 @@ var NAVTREEINDEX1 = { +"pearl-anglescan-tracker_8ipf.html#a33e84ae8e13f405d466b28e83f608cb9":[9,0,3,13], "pearl-anglescan-tracker_8ipf.html#a35a5cd8a21b48be8d726c69eb5fca134":[9,0,3,0], "pearl-anglescan-tracker_8ipf.html#a37aaf2f08c3910bed554a10dd82616ec":[9,0,3,15], "pearl-anglescan-tracker_8ipf.html#a3844e7fd93b4f54aa52f084687c2106c":[9,0,3,16], @@ -131,62 +132,74 @@ var NAVTREEINDEX1 = "pearl-compat_8ipf.html#aa1f59acc532c7eee75c83b70ee1feaa9":[9,0,8,0], "pearl-compat_8ipf_source.html":[9,0,8], "pearl-data-explorer_8ipf.html":[9,0,9], -"pearl-data-explorer_8ipf.html#a001074020ad32b290d390a450a389c69":[9,0,9,16], -"pearl-data-explorer_8ipf.html#a00bf5267a40b2b3d760c64d73e139878":[9,0,9,53], +"pearl-data-explorer_8ipf.html#a001074020ad32b290d390a450a389c69":[9,0,9,15], +"pearl-data-explorer_8ipf.html#a00307dffd6f272f13acfe4dea99a81d4":[9,0,9,57], +"pearl-data-explorer_8ipf.html#a00bf5267a40b2b3d760c64d73e139878":[9,0,9,65], +"pearl-data-explorer_8ipf.html#a01e48e67a22dc56851447bd77abecbe1":[9,0,9,7], "pearl-data-explorer_8ipf.html#a02a64144b7ed2c1bc230e265c55e81a1":[9,0,9,2], -"pearl-data-explorer_8ipf.html#a04cc0b9d5e3a649ba3514fcbf126eefe":[9,0,9,49], +"pearl-data-explorer_8ipf.html#a04cc0b9d5e3a649ba3514fcbf126eefe":[9,0,9,61], "pearl-data-explorer_8ipf.html#a0adc1b370fd3bf230b61b094b3c0accb":[9,0,9,17], -"pearl-data-explorer_8ipf.html#a0c162346b59b0f66d34ee26ce5fe1e52":[9,0,9,29], -"pearl-data-explorer_8ipf.html#a0c839d5f8f49e6937a6532bba3ef3714":[9,0,9,23], -"pearl-data-explorer_8ipf.html#a1731f8e1507d90e285885723ae32ba13":[9,0,9,37], -"pearl-data-explorer_8ipf.html#a181ccce237172811baf3de5a7a06370d":[9,0,9,50], -"pearl-data-explorer_8ipf.html#a1868754e64cb1448e564c0936e78574d":[9,0,9,11], -"pearl-data-explorer_8ipf.html#a1bbf3e1592f3344f3628526fa549dfdf":[9,0,9,22], -"pearl-data-explorer_8ipf.html#a1d7f4ad59b81ecd84bb63cfabd9f24dc":[9,0,9,43], -"pearl-data-explorer_8ipf.html#a200e7ba052fbce4614fb4254701646ab":[9,0,9,44], -"pearl-data-explorer_8ipf.html#a2178d5acf21fe4372ecc06224bec28ba":[9,0,9,28], -"pearl-data-explorer_8ipf.html#a26f2f2bf5efc39dabb2a01abcc559e3e":[9,0,9,24], -"pearl-data-explorer_8ipf.html#a3232c51a8c19eaf86b9bc67352967a9f":[9,0,9,36], -"pearl-data-explorer_8ipf.html#a340f334c6caa966ee1eb891614e57b5b":[9,0,9,39], -"pearl-data-explorer_8ipf.html#a3bbb332e319ef7ec5f0fe2d16afaf005":[9,0,9,5], -"pearl-data-explorer_8ipf.html#a415e4867be1ee37d84fd609b06f6dcb8":[9,0,9,33], -"pearl-data-explorer_8ipf.html#a457d2257ffd5880ab858fa583a5d1c99":[9,0,9,40], -"pearl-data-explorer_8ipf.html#a45be265789a5260e3daa05eca0ec309e":[9,0,9,14], -"pearl-data-explorer_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725":[9,0,9,18], -"pearl-data-explorer_8ipf.html#a4633885afab755fbc5d262178b9ddcb8":[9,0,9,38], -"pearl-data-explorer_8ipf.html#a4db79d04c74beb1af71b72916f8f0362":[9,0,9,46], +"pearl-data-explorer_8ipf.html#a0c162346b59b0f66d34ee26ce5fe1e52":[9,0,9,38], +"pearl-data-explorer_8ipf.html#a0e1e23060294bd4b18980e59229c70ed":[9,0,9,36], +"pearl-data-explorer_8ipf.html#a0f7473343cf773af9efedee1a18ac5db":[9,0,9,3], +"pearl-data-explorer_8ipf.html#a166273677188a66c25a84616c6f4baa9":[9,0,9,43], +"pearl-data-explorer_8ipf.html#a1731f8e1507d90e285885723ae32ba13":[9,0,9,46], +"pearl-data-explorer_8ipf.html#a181ccce237172811baf3de5a7a06370d":[9,0,9,63], +"pearl-data-explorer_8ipf.html#a1868754e64cb1448e564c0936e78574d":[9,0,9,9], +"pearl-data-explorer_8ipf.html#a1d7f4ad59b81ecd84bb63cfabd9f24dc":[9,0,9,51], +"pearl-data-explorer_8ipf.html#a200e7ba052fbce4614fb4254701646ab":[9,0,9,52], +"pearl-data-explorer_8ipf.html#a2178d5acf21fe4372ecc06224bec28ba":[9,0,9,37], +"pearl-data-explorer_8ipf.html#a28921b185d4e6fbe9a7a689757269f19":[9,0,9,19], +"pearl-data-explorer_8ipf.html#a3232c51a8c19eaf86b9bc67352967a9f":[9,0,9,45], +"pearl-data-explorer_8ipf.html#a36fd730f2d057513179dd59f8fddaf75":[9,0,9,27], +"pearl-data-explorer_8ipf.html#a384a37c2865baf5c21b63cff2488c3b3":[9,0,9,26], +"pearl-data-explorer_8ipf.html#a3fd06ac9aa62de7f00e10ce749ba12c9":[9,0,9,8], +"pearl-data-explorer_8ipf.html#a435adef620193e09110ff69ca8d106de":[9,0,9,32], +"pearl-data-explorer_8ipf.html#a457d2257ffd5880ab858fa583a5d1c99":[9,0,9,48], +"pearl-data-explorer_8ipf.html#a45be265789a5260e3daa05eca0ec309e":[9,0,9,12], +"pearl-data-explorer_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725":[9,0,9,29], +"pearl-data-explorer_8ipf.html#a4633885afab755fbc5d262178b9ddcb8":[9,0,9,47], +"pearl-data-explorer_8ipf.html#a4c7a521b8f1a0769c09bfa4a1fca7dab":[9,0,9,67], +"pearl-data-explorer_8ipf.html#a4db79d04c74beb1af71b72916f8f0362":[9,0,9,58], "pearl-data-explorer_8ipf.html#a4ef196f752bb5780ed4f4a588f9ebc81":[9,0,9,1], -"pearl-data-explorer_8ipf.html#a505ebda6bdecc4120e01766d7aedaf5d":[9,0,9,42], -"pearl-data-explorer_8ipf.html#a53af8689144e3aeb27ca177db5dd0c22":[9,0,9,51], -"pearl-data-explorer_8ipf.html#a5660c6f5f78d880b0805bad4eefed1d5":[9,0,9,3], -"pearl-data-explorer_8ipf.html#a5a7d3c00360944c00f236900b992694d":[9,0,9,41], -"pearl-data-explorer_8ipf.html#a5b824531904179a94e0eaa3ffa09172e":[9,0,9,32], -"pearl-data-explorer_8ipf.html#a614e89b9c06511144ccb380e61cc7bd6":[9,0,9,21], -"pearl-data-explorer_8ipf.html#a68d38e9464f7d13520ec040cffdf5c3b":[9,0,9,35], -"pearl-data-explorer_8ipf.html#a6aa44ff12b8530adbaaaf7405b1a68ba":[9,0,9,8], -"pearl-data-explorer_8ipf.html#a6b5e9729ee6dedbb217c741639a168ed":[9,0,9,19], -"pearl-data-explorer_8ipf.html#a6b642da731bde1029e0fa2ff69d5fb06":[9,0,9,4], -"pearl-data-explorer_8ipf.html#a6e8eaf8c092f5da60bd425f9bd8bf178":[9,0,9,34], -"pearl-data-explorer_8ipf.html#a71f9c277d310c3f4e7739be69dad0ab5":[9,0,9,47], -"pearl-data-explorer_8ipf.html#a742902dfaf2246f10b70f52805c6df1f":[9,0,9,9], -"pearl-data-explorer_8ipf.html#a74c69e870329c5dd3b08f92bdeb21d87":[9,0,9,27], -"pearl-data-explorer_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b":[9,0,9,55], -"pearl-data-explorer_8ipf.html#a8a923d7095071e7e6f99018379807732":[9,0,9,31], -"pearl-data-explorer_8ipf.html#a8ec37ab6c651003957d7e1ba728de89e":[9,0,9,20], -"pearl-data-explorer_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3":[9,0,9,26], -"pearl-data-explorer_8ipf.html#a98e327fa65bbcb3cd7c97545f7201afe":[9,0,9,25], -"pearl-data-explorer_8ipf.html#a9cefcdc49b2169e99c743b0a683ed3a6":[9,0,9,7], -"pearl-data-explorer_8ipf.html#ab7e3b3a0a901f7559ee9f5affb9a6fca":[9,0,9,30], -"pearl-data-explorer_8ipf.html#ac729557a307bddd2f2ad298199976c01":[9,0,9,45], -"pearl-data-explorer_8ipf.html#aca457d1f4414d20a911254b1de13ebbb":[9,0,9,54], -"pearl-data-explorer_8ipf.html#ad50f4c430d8bfe0fb5a1356cd9b84bf4":[9,0,9,48], -"pearl-data-explorer_8ipf.html#ad61aa85dcf24dbf7e093dac3d0bf6f19":[9,0,9,10], -"pearl-data-explorer_8ipf.html#ad6cfb2c00d5112add84542a25eb68b19":[9,0,9,0], -"pearl-data-explorer_8ipf.html#ad720655ff881ddecae2e1b8afed58fa0":[9,0,9,52], -"pearl-data-explorer_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5":[9,0,9,12], -"pearl-data-explorer_8ipf.html#add62ff5193206c9f207952bcd72dac88":[9,0,9,6], -"pearl-data-explorer_8ipf.html#ae79a57a41c734ce8836f427b81011b5d":[9,0,9,15], -"pearl-data-explorer_8ipf.html#af9f8769ca2989f152f23d976d1467a48":[9,0,9,13], +"pearl-data-explorer_8ipf.html#a505ebda6bdecc4120e01766d7aedaf5d":[9,0,9,50], +"pearl-data-explorer_8ipf.html#a53af8689144e3aeb27ca177db5dd0c22":[9,0,9,64], +"pearl-data-explorer_8ipf.html#a54be4e40b17906c281cdf649d6ce537e":[9,0,9,21], +"pearl-data-explorer_8ipf.html#a57e21bffee4cd64f2ea1efd9cc958bf1":[9,0,9,60], +"pearl-data-explorer_8ipf.html#a5a7d3c00360944c00f236900b992694d":[9,0,9,49], +"pearl-data-explorer_8ipf.html#a5b824531904179a94e0eaa3ffa09172e":[9,0,9,41], +"pearl-data-explorer_8ipf.html#a5d0c796365e8a24683c73e2b29571018":[9,0,9,25], +"pearl-data-explorer_8ipf.html#a614e89b9c06511144ccb380e61cc7bd6":[9,0,9,31], +"pearl-data-explorer_8ipf.html#a638a13044aede37cabe0c2c7a7c0cb06":[9,0,9,42], +"pearl-data-explorer_8ipf.html#a64bd3e5e68b30c94db00c58fa3be3f0d":[9,0,9,4], +"pearl-data-explorer_8ipf.html#a66043ccbe2e8dda258e639cb7a231537":[9,0,9,18], +"pearl-data-explorer_8ipf.html#a67cd1a025e5428d443027c1f57eaec09":[9,0,9,14], +"pearl-data-explorer_8ipf.html#a6aa44ff12b8530adbaaaf7405b1a68ba":[9,0,9,6], +"pearl-data-explorer_8ipf.html#a6b5e9729ee6dedbb217c741639a168ed":[9,0,9,30], +"pearl-data-explorer_8ipf.html#a6e8eaf8c092f5da60bd425f9bd8bf178":[9,0,9,44], +"pearl-data-explorer_8ipf.html#a70150946799d759473b409b3371e3ae2":[9,0,9,10], +"pearl-data-explorer_8ipf.html#a71f9c277d310c3f4e7739be69dad0ab5":[9,0,9,59], +"pearl-data-explorer_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b":[9,0,9,66], +"pearl-data-explorer_8ipf.html#a77047115739da6d28055f7fd44c9fd2c":[9,0,9,13], +"pearl-data-explorer_8ipf.html#a7c36ce6ccfaa77cf7a6b68b9014c1b9b":[9,0,9,24], +"pearl-data-explorer_8ipf.html#a844467a592e5b26b2324326f22b7da89":[9,0,9,0], +"pearl-data-explorer_8ipf.html#a896081071fffecdeff09ae4c9d6e84cb":[9,0,9,20], +"pearl-data-explorer_8ipf.html#a8a923d7095071e7e6f99018379807732":[9,0,9,40], +"pearl-data-explorer_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3":[9,0,9,35], +"pearl-data-explorer_8ipf.html#a93c61109535e1644f5e53aabb895b48a":[9,0,9,56], +"pearl-data-explorer_8ipf.html#a96a3ef643cc29948ba57a3bfa1339c4d":[9,0,9,33], +"pearl-data-explorer_8ipf.html#a9cefcdc49b2169e99c743b0a683ed3a6":[9,0,9,5], +"pearl-data-explorer_8ipf.html#aac8d96d9ccaeddab1cb0f463b01616cb":[9,0,9,55], +"pearl-data-explorer_8ipf.html#ab7e3b3a0a901f7559ee9f5affb9a6fca":[9,0,9,39], +"pearl-data-explorer_8ipf.html#aba2f8be504e49469194cc4b562be3a9c":[9,0,9,23], +"pearl-data-explorer_8ipf.html#ababd5be120b526ca410c53b4a2ba3f8d":[9,0,9,34], +"pearl-data-explorer_8ipf.html#ac477142f1949dc32d86663f1de4384e5":[9,0,9,54], +"pearl-data-explorer_8ipf.html#ac729557a307bddd2f2ad298199976c01":[9,0,9,53], +"pearl-data-explorer_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5":[9,0,9,11], +"pearl-data-explorer_8ipf.html#ad95697e197428ff73a1a258ea3bb79b2":[9,0,9,22], +"pearl-data-explorer_8ipf.html#ae02b954d90dc8f43c007cc3fb1a1ee16":[9,0,9,62], +"pearl-data-explorer_8ipf.html#af4474f34647ec24f27f900226c6bb3bd":[9,0,9,16], +"pearl-data-explorer_8ipf.html#af616e37167d5753b11e513bd03685ab8":[9,0,9,28], "pearl-data-explorer_8ipf_source.html":[9,0,9], "pearl-elog_8ipf.html":[9,0,10], "pearl-elog_8ipf.html#a05301d497e4796e5fb5adde3728ba971":[9,0,10,16], @@ -236,18 +249,5 @@ var NAVTREEINDEX1 = "pearl-elog_8ipf.html#ac45196cb9ce8b43b76c9daf67689c49a":[9,0,10,27], "pearl-elog_8ipf.html#ac729557a307bddd2f2ad298199976c01":[9,0,10,45], "pearl-elog_8ipf.html#ac8b61eefed231018cc36d47e95bd8c22":[9,0,10,11], -"pearl-elog_8ipf.html#aca457d1f4414d20a911254b1de13ebbb":[9,0,10,59], -"pearl-elog_8ipf.html#acbba78d869a543edf7c2b80d7a8d2344":[9,0,10,1], -"pearl-elog_8ipf.html#ace94356f691cbe343761aabd67ced23c":[9,0,10,30], -"pearl-elog_8ipf.html#acedf0c8ae34e9ebadd6fa0d9d1353aa4":[9,0,10,22], -"pearl-elog_8ipf.html#ad1a72c63f269b2e22b21a72d1ef3b279":[9,0,10,28], -"pearl-elog_8ipf.html#ad4472ea917691c41ad0b4ea6f36010a5":[9,0,10,7], -"pearl-elog_8ipf.html#ad7640d06f004ecd4a8980ea29d24dcbe":[9,0,10,10], -"pearl-elog_8ipf.html#addbdec64930e9c1e417b16b25df8c723":[9,0,10,52], -"pearl-elog_8ipf.html#adeff6678e57313cb218824f06d32b5ec":[9,0,10,9], -"pearl-elog_8ipf.html#ae824bbf81f8b7d16b36b53e3f3d85f69":[9,0,10,33], -"pearl-elog_8ipf.html#af34e46263aa50843f98f755988f9ab5c":[9,0,10,56], -"pearl-elog_8ipf.html#af652f6f257be1ee749fe788d1b03f75f":[9,0,10,13], -"pearl-elog_8ipf.html#af8b1ea711208bcc2cd1647abe04131dc":[9,0,10,21], -"pearl-elog_8ipf.html#afbace5ffc3167b42b09657ce6cc854ca":[9,0,10,23] +"pearl-elog_8ipf.html#aca457d1f4414d20a911254b1de13ebbb":[9,0,10,59] }; diff --git a/doc/html/navtreeindex2.js b/doc/html/navtreeindex2.js index 29e70c1..405a0b5 100644 --- a/doc/html/navtreeindex2.js +++ b/doc/html/navtreeindex2.js @@ -1,27 +1,42 @@ var NAVTREEINDEX2 = { +"pearl-elog_8ipf.html#acbba78d869a543edf7c2b80d7a8d2344":[9,0,10,1], +"pearl-elog_8ipf.html#ace94356f691cbe343761aabd67ced23c":[9,0,10,30], +"pearl-elog_8ipf.html#acedf0c8ae34e9ebadd6fa0d9d1353aa4":[9,0,10,22], +"pearl-elog_8ipf.html#ad1a72c63f269b2e22b21a72d1ef3b279":[9,0,10,28], +"pearl-elog_8ipf.html#ad4472ea917691c41ad0b4ea6f36010a5":[9,0,10,7], +"pearl-elog_8ipf.html#ad7640d06f004ecd4a8980ea29d24dcbe":[9,0,10,10], +"pearl-elog_8ipf.html#addbdec64930e9c1e417b16b25df8c723":[9,0,10,52], +"pearl-elog_8ipf.html#adeff6678e57313cb218824f06d32b5ec":[9,0,10,9], +"pearl-elog_8ipf.html#ae824bbf81f8b7d16b36b53e3f3d85f69":[9,0,10,33], +"pearl-elog_8ipf.html#af34e46263aa50843f98f755988f9ab5c":[9,0,10,56], +"pearl-elog_8ipf.html#af652f6f257be1ee749fe788d1b03f75f":[9,0,10,13], +"pearl-elog_8ipf.html#af8b1ea711208bcc2cd1647abe04131dc":[9,0,10,21], +"pearl-elog_8ipf.html#afbace5ffc3167b42b09657ce6cc854ca":[9,0,10,23], "pearl-elog_8ipf_source.html":[9,0,10], "pearl-fitfuncs_8ipf.html":[9,0,11], -"pearl-fitfuncs_8ipf.html#a02368cc4adfbd746cd2f1e7d73884a61":[9,0,11,21], +"pearl-fitfuncs_8ipf.html#a02368cc4adfbd746cd2f1e7d73884a61":[9,0,11,23], "pearl-fitfuncs_8ipf.html#a13a5ee22049d9a3379cd6e55654e70a3":[9,0,11,1], -"pearl-fitfuncs_8ipf.html#a1520bd078ef77fd16ba20e95dbc6829d":[9,0,11,15], -"pearl-fitfuncs_8ipf.html#a1e729418252bf0d05ea6ec5cbd65b834":[9,0,11,10], +"pearl-fitfuncs_8ipf.html#a1e729418252bf0d05ea6ec5cbd65b834":[9,0,11,11], "pearl-fitfuncs_8ipf.html#a24cd6a0c96ef8c720e371bb31ac0a479":[9,0,11,2], -"pearl-fitfuncs_8ipf.html#a2c6547164c0b46efecf4d372ea04c263":[9,0,11,17], -"pearl-fitfuncs_8ipf.html#a3a94468da285a31eed5e990cd90e5cdf":[9,0,11,18], -"pearl-fitfuncs_8ipf.html#a4d20215153c0e0cee3870dfceded8bc9":[9,0,11,13], -"pearl-fitfuncs_8ipf.html#a5a2a03026b88f3dd99214ab1b26e6f80":[9,0,11,12], +"pearl-fitfuncs_8ipf.html#a2c6547164c0b46efecf4d372ea04c263":[9,0,11,18], +"pearl-fitfuncs_8ipf.html#a4d20215153c0e0cee3870dfceded8bc9":[9,0,11,14], +"pearl-fitfuncs_8ipf.html#a5a2a03026b88f3dd99214ab1b26e6f80":[9,0,11,13], +"pearl-fitfuncs_8ipf.html#a704de4b170620d07b75f2093fe052272":[9,0,11,19], "pearl-fitfuncs_8ipf.html#a709f7c4585b1d850ea8aae1885ac18cb":[9,0,11,3], -"pearl-fitfuncs_8ipf.html#a819902ab9f541b75a0fd33a7b52465d0":[9,0,11,14], -"pearl-fitfuncs_8ipf.html#a84a0278284332631682ce032018d1716":[9,0,11,20], -"pearl-fitfuncs_8ipf.html#a9d110819fa3cd2173f3103724e394fdf":[9,0,11,7], -"pearl-fitfuncs_8ipf.html#aaa48428994f8720a12e7237ef43e86ea":[9,0,11,5], -"pearl-fitfuncs_8ipf.html#aad1418e71830c1ec71d7dd62b2ecf9ba":[9,0,11,16], -"pearl-fitfuncs_8ipf.html#ab32134566b2573672ac674565deebd36":[9,0,11,11], -"pearl-fitfuncs_8ipf.html#adb438f665e51a8dd104a37cfead04f27":[9,0,11,8], -"pearl-fitfuncs_8ipf.html#ae2d138beb7cb39e8042487893095b461":[9,0,11,6], -"pearl-fitfuncs_8ipf.html#af07f887f3ba8e3e35c9214df8bb6a49f":[9,0,11,19], -"pearl-fitfuncs_8ipf.html#af62cb65b7444ff60e956a45bd5d0ec27":[9,0,11,9], +"pearl-fitfuncs_8ipf.html#a819902ab9f541b75a0fd33a7b52465d0":[9,0,11,15], +"pearl-fitfuncs_8ipf.html#a81da09e30e2800703dd178248f0c55be":[9,0,11,20], +"pearl-fitfuncs_8ipf.html#a84a0278284332631682ce032018d1716":[9,0,11,22], +"pearl-fitfuncs_8ipf.html#a9d110819fa3cd2173f3103724e394fdf":[9,0,11,8], +"pearl-fitfuncs_8ipf.html#aaa48428994f8720a12e7237ef43e86ea":[9,0,11,6], +"pearl-fitfuncs_8ipf.html#aad1418e71830c1ec71d7dd62b2ecf9ba":[9,0,11,17], +"pearl-fitfuncs_8ipf.html#ab32134566b2573672ac674565deebd36":[9,0,11,12], +"pearl-fitfuncs_8ipf.html#aca0bf4ff35794a459e15a3b358dbfa04":[9,0,11,5], +"pearl-fitfuncs_8ipf.html#adb438f665e51a8dd104a37cfead04f27":[9,0,11,9], +"pearl-fitfuncs_8ipf.html#ae2d138beb7cb39e8042487893095b461":[9,0,11,7], +"pearl-fitfuncs_8ipf.html#af07f887f3ba8e3e35c9214df8bb6a49f":[9,0,11,21], +"pearl-fitfuncs_8ipf.html#af62cb65b7444ff60e956a45bd5d0ec27":[9,0,11,10], +"pearl-fitfuncs_8ipf.html#af669aa08d0c32d3647007155f4b7ea3c":[9,0,11,16], "pearl-fitfuncs_8ipf.html#aff8e8b103c32c8e723b57ce7ad5ef0f5":[9,0,11,4], "pearl-fitfuncs_8ipf_source.html":[9,0,11], "pearl-gui-tools_8ipf.html":[9,0,12], @@ -80,9 +95,11 @@ var NAVTREEINDEX2 = "pearl-otf-import_8ipf.html#ae2640256d7d07c11b41621430279cef6":[9,0,15,0], "pearl-otf-import_8ipf_source.html":[9,0,15], "pearl-pmsco-import_8ipf.html":[9,0,16], -"pearl-pmsco-import_8ipf.html#a0a53a4686b482d62fe1797932a1708db":[9,0,16,2], -"pearl-pmsco-import_8ipf.html#aa31bbaa2fc77b447e6c6f386b23abdd9":[9,0,16,1], -"pearl-pmsco-import_8ipf.html#ab3421c7f54aa64e5e493b267d700c0c8":[9,0,16,0], +"pearl-pmsco-import_8ipf.html#a0a53a4686b482d62fe1797932a1708db":[9,0,16,4], +"pearl-pmsco-import_8ipf.html#a98bbe8db14dba5aea9588a1b433baca7":[9,0,16,1], +"pearl-pmsco-import_8ipf.html#aa31bbaa2fc77b447e6c6f386b23abdd9":[9,0,16,3], +"pearl-pmsco-import_8ipf.html#ab3421c7f54aa64e5e493b267d700c0c8":[9,0,16,2], +"pearl-pmsco-import_8ipf.html#afae0650a37e89f18c9c54f8adc9eafb2":[9,0,16,0], "pearl-pmsco-import_8ipf_source.html":[9,0,16], "pearl-polar-coordinates_8ipf.html":[9,0,17], "pearl-polar-coordinates_8ipf.html#a58139e6ebfba242b6b2ba3533b865a9a":[9,0,17,4], @@ -92,65 +109,82 @@ var NAVTREEINDEX2 = "pearl-polar-coordinates_8ipf.html#adfc1f0b3cddf672b0ccdb6a22b97ba9e":[9,0,17,1], "pearl-polar-coordinates_8ipf_source.html":[9,0,17], "pearl-pshell-import_8ipf.html":[9,0,18], -"pearl-pshell-import_8ipf.html#a035a4df9f4508144149abdb0b46c87d1":[9,0,18,17], -"pearl-pshell-import_8ipf.html#a03f00b3299bc3df671fcc239f7dd5418":[9,0,18,41], -"pearl-pshell-import_8ipf.html#a0a02f87e19e825964aa17c46ed51df8c":[9,0,18,23], -"pearl-pshell-import_8ipf.html#a0f2c168c04d075734edb995361aefb82":[9,0,18,42], -"pearl-pshell-import_8ipf.html#a13a45e8618c1ab7406e1aa5e608e21fe":[9,0,18,16], -"pearl-pshell-import_8ipf.html#a1dc6c971120749b378014f1f63cb6668":[9,0,18,20], -"pearl-pshell-import_8ipf.html#a2152f7c39a187b740cf9890767ffac3f":[9,0,18,12], -"pearl-pshell-import_8ipf.html#a277cd450cca7832aa44f8097934e6acb":[9,0,18,36], -"pearl-pshell-import_8ipf.html#a2972587ec82cc2a261b8119a582b4215":[9,0,18,18], -"pearl-pshell-import_8ipf.html#a2c456397c36d4116bfddca452eff5954":[9,0,18,5], -"pearl-pshell-import_8ipf.html#a2fc497747287d6fe40c6de997ed4a90d":[9,0,18,9], -"pearl-pshell-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6":[9,0,18,31], -"pearl-pshell-import_8ipf.html#a3c72087695969f42ea91c000de47b26e":[9,0,18,39], -"pearl-pshell-import_8ipf.html#a3eefc2f84a09f2ce29893c71ef44ae32":[9,0,18,21], -"pearl-pshell-import_8ipf.html#a412b4753ceb753d705a113a26c018b22":[9,0,18,40], -"pearl-pshell-import_8ipf.html#a41bf534983b0662ec2609b136c395f14":[9,0,18,0], -"pearl-pshell-import_8ipf.html#a44d495fba0dd2b82dec13760a07fd226":[9,0,18,30], -"pearl-pshell-import_8ipf.html#a4508bd507c4c935bd8463d9b2b84c6fc":[9,0,18,10], -"pearl-pshell-import_8ipf.html#a5745428740b64cd66394a7fcd78b86f1":[9,0,18,37], -"pearl-pshell-import_8ipf.html#a5ad52cb10171572c454f9426d3a9be21":[9,0,18,38], -"pearl-pshell-import_8ipf.html#a79ac37bb666b42c3332e9984196ccfe7":[9,0,18,25], -"pearl-pshell-import_8ipf.html#a79b968d7439dfbfbc38c05f933071489":[9,0,18,2], -"pearl-pshell-import_8ipf.html#a83804ba9637debed6ef8b13e7b9b19e0":[9,0,18,28], -"pearl-pshell-import_8ipf.html#a83930d4384b0238fc8416ba03dbc0386":[9,0,18,35], -"pearl-pshell-import_8ipf.html#a8704627410409bcd27a1adeda4082c47":[9,0,18,8], -"pearl-pshell-import_8ipf.html#a8a5ce6c2767607de194b4c148ee98c27":[9,0,18,13], -"pearl-pshell-import_8ipf.html#a92a18d6e81c3f521ba3bb240eaf578a9":[9,0,18,33], -"pearl-pshell-import_8ipf.html#aa14b28120a07a8213e5a692930704a4b":[9,0,18,19], -"pearl-pshell-import_8ipf.html#aa56c25d64b3e59f74d6dd92a599cce4f":[9,0,18,26], -"pearl-pshell-import_8ipf.html#aa6dc3e3f7dc1ca4346132635a90fc447":[9,0,18,34], -"pearl-pshell-import_8ipf.html#aba25eb98e4c6cc9066c46ef6be1cde15":[9,0,18,7], -"pearl-pshell-import_8ipf.html#abb4afdef6ae4476c25a1ff77b17266c3":[9,0,18,32], -"pearl-pshell-import_8ipf.html#ac4dfb90b951d29b56501e904f5cc38aa":[9,0,18,14], -"pearl-pshell-import_8ipf.html#acb317b57ef137d4d5da5938013dbe442":[9,0,18,11], -"pearl-pshell-import_8ipf.html#acba7f4b98f67cc112c02dfeefe3e5acd":[9,0,18,3], -"pearl-pshell-import_8ipf.html#accc20b0fc6bda95ba0cd0aea6633086f":[9,0,18,29], -"pearl-pshell-import_8ipf.html#acfb01ee360b66f286225f6e9c7220ba2":[9,0,18,1], -"pearl-pshell-import_8ipf.html#ad26b0b56d7ccd23547535091c9430569":[9,0,18,24], -"pearl-pshell-import_8ipf.html#ad3b9354b137ba4f1bc3ed2e74f24dc88":[9,0,18,27], -"pearl-pshell-import_8ipf.html#adc11ea797562b3d99c247f4866618d39":[9,0,18,4], -"pearl-pshell-import_8ipf.html#aec191d0167bbf606d24396f4658104b5":[9,0,18,22], -"pearl-pshell-import_8ipf.html#af08a467036c64f70ca3dfe644fcc457c":[9,0,18,6], -"pearl-pshell-import_8ipf.html#afde787a00a18dc8c63b100d8ac7d992f":[9,0,18,15], +"pearl-pshell-import_8ipf.html#a03f00b3299bc3df671fcc239f7dd5418":[9,0,18,56], +"pearl-pshell-import_8ipf.html#a0f2c168c04d075734edb995361aefb82":[9,0,18,57], +"pearl-pshell-import_8ipf.html#a10224f615973777a43fefae8eb1a39f2":[9,0,18,40], +"pearl-pshell-import_8ipf.html#a113622ae05611e5051a97d223fae59d0":[9,0,18,17], +"pearl-pshell-import_8ipf.html#a237e95f14b988f58e2d4c37659f17347":[9,0,18,39], +"pearl-pshell-import_8ipf.html#a23a2e4cb2dc5364bfdbab4367ed6f234":[9,0,18,27], +"pearl-pshell-import_8ipf.html#a24afba76ed5323d8cd0abc3c7b0d9912":[9,0,18,30], +"pearl-pshell-import_8ipf.html#a277cd450cca7832aa44f8097934e6acb":[9,0,18,38], +"pearl-pshell-import_8ipf.html#a2c456397c36d4116bfddca452eff5954":[9,0,18,7], +"pearl-pshell-import_8ipf.html#a2f39f9379e66ead0d25c33adfbe05ee9":[9,0,18,3], +"pearl-pshell-import_8ipf.html#a300847a8e08161a64a199a6e7ef165c8":[9,0,18,45], +"pearl-pshell-import_8ipf.html#a3236744797a780eb144a684b0bd41d4a":[9,0,18,51], +"pearl-pshell-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6":[9,0,18,33], +"pearl-pshell-import_8ipf.html#a3c72087695969f42ea91c000de47b26e":[9,0,18,54], +"pearl-pshell-import_8ipf.html#a412b4753ceb753d705a113a26c018b22":[9,0,18,55], +"pearl-pshell-import_8ipf.html#a47513a1db5693f88d64739a5b28926b2":[9,0,18,11], +"pearl-pshell-import_8ipf.html#a476f19c72d6e54787535ab6989ee778d":[9,0,18,2], +"pearl-pshell-import_8ipf.html#a48f07030482af8315447ac2c598edd0d":[9,0,18,49], +"pearl-pshell-import_8ipf.html#a4f5d11063bd50ded36ca013a2656b539":[9,0,18,14], +"pearl-pshell-import_8ipf.html#a513091ea9a4e23f76765aa37f1d34055":[9,0,18,4], +"pearl-pshell-import_8ipf.html#a5a1961e05ea900e72d6a886ac5744f2d":[9,0,18,8], +"pearl-pshell-import_8ipf.html#a5ad52cb10171572c454f9426d3a9be21":[9,0,18,52], +"pearl-pshell-import_8ipf.html#a654f0b9fe8770a8bd09a6da4182ca3bc":[9,0,18,48], +"pearl-pshell-import_8ipf.html#a712ea7a6f18ce4178fd06b07d2d05a9f":[9,0,18,44], +"pearl-pshell-import_8ipf.html#a72465006d4e8379fad08d1a1064de2a3":[9,0,18,31], +"pearl-pshell-import_8ipf.html#a7c191ea7367f2f328333b9986c7dd538":[9,0,18,16], +"pearl-pshell-import_8ipf.html#a7c5aaa2f133862ae16ddd735df1ab73d":[9,0,18,41], +"pearl-pshell-import_8ipf.html#a7d7b67c9f983d3446c5c6f274284b82a":[9,0,18,5], +"pearl-pshell-import_8ipf.html#a8089a75744ffc3626305406e925d320a":[9,0,18,32], +"pearl-pshell-import_8ipf.html#a83930d4384b0238fc8416ba03dbc0386":[9,0,18,37], +"pearl-pshell-import_8ipf.html#a85c1fbd2aefff2028e084ea61314dc67":[9,0,18,19], +"pearl-pshell-import_8ipf.html#a8704627410409bcd27a1adeda4082c47":[9,0,18,10], +"pearl-pshell-import_8ipf.html#a92a18d6e81c3f521ba3bb240eaf578a9":[9,0,18,34], +"pearl-pshell-import_8ipf.html#a972bf23d6da0bb33e9f12e50c9d7f5e5":[9,0,18,0], +"pearl-pshell-import_8ipf.html#aa6dc3e3f7dc1ca4346132635a90fc447":[9,0,18,36], +"pearl-pshell-import_8ipf.html#aa7a48b65e465abde9aad80377605ae59":[9,0,18,12], +"pearl-pshell-import_8ipf.html#ab0bc752ab76659b492cf88c75935336b":[9,0,18,53], +"pearl-pshell-import_8ipf.html#ab41e955a4ff70f9c78571faad1b43d7b":[9,0,18,20], +"pearl-pshell-import_8ipf.html#ab684c44d5f0668631e42d9c9c9dfea9e":[9,0,18,29], +"pearl-pshell-import_8ipf.html#ab7c2cc8687f6d4550ef90c538b938dad":[9,0,18,50], +"pearl-pshell-import_8ipf.html#ab86e42bb6f9ff20f685ad5627b446b77":[9,0,18,15], +"pearl-pshell-import_8ipf.html#aba25eb98e4c6cc9066c46ef6be1cde15":[9,0,18,9], +"pearl-pshell-import_8ipf.html#abcf01e205858a512aa713da914eaf966":[9,0,18,22], +"pearl-pshell-import_8ipf.html#ac782084655d44d222742e3397051619d":[9,0,18,26], +"pearl-pshell-import_8ipf.html#ac81d8f4276cf7bb86a74796cc7199e42":[9,0,18,46], +"pearl-pshell-import_8ipf.html#acda8bf0493a2e8ba1955f12de08e28f2":[9,0,18,13], +"pearl-pshell-import_8ipf.html#ad2275b0b8a0a1ed05afc50ef50564243":[9,0,18,1], +"pearl-pshell-import_8ipf.html#ad811542ccfc7c73156c2a107faa93d87":[9,0,18,18], +"pearl-pshell-import_8ipf.html#adc11ea797562b3d99c247f4866618d39":[9,0,18,6], +"pearl-pshell-import_8ipf.html#adf778206fa825ab5006bd553c64a8760":[9,0,18,42], +"pearl-pshell-import_8ipf.html#ae2aedcb7028cccdb683c43411cc8f1e2":[9,0,18,35], +"pearl-pshell-import_8ipf.html#ae539a7501119cb2349707e2027f0f759":[9,0,18,25], +"pearl-pshell-import_8ipf.html#aeb9a7f56922ff3c862e8b29b5090c01a":[9,0,18,47], +"pearl-pshell-import_8ipf.html#aebf53e3de392d631b340ee0747b8bbbf":[9,0,18,43], +"pearl-pshell-import_8ipf.html#af3b5005859915f410ec27a31ac9519ca":[9,0,18,28], +"pearl-pshell-import_8ipf.html#af662500c4f992ef7b956f37ed463513d":[9,0,18,23], +"pearl-pshell-import_8ipf.html#af7a6eefbda58d31336c81a3dda6e9a2d":[9,0,18,21], +"pearl-pshell-import_8ipf.html#afc4fa60c5fbfdb08c2a9d3072d3e16ce":[9,0,18,24], "pearl-pshell-import_8ipf_source.html":[9,0,18], -"pearl-scienta-countrate_8ipf.html":[9,0,19], -"pearl-scienta-countrate_8ipf.html#a55886895329455b36b64d52ed6a4e228":[9,0,19,1], -"pearl-scienta-countrate_8ipf.html#af2879284b1d1397447a31733fddd6273":[9,0,19,0], -"pearl-scienta-countrate_8ipf_source.html":[9,0,19], +"pearl-scienta-live_8ipf.html":[9,0,19], +"pearl-scienta-live_8ipf.html#a55886895329455b36b64d52ed6a4e228":[9,0,19,2], +"pearl-scienta-live_8ipf.html#ad23de34bb698589e2576ce2836b89d55":[9,0,19,0], +"pearl-scienta-live_8ipf.html#af2879284b1d1397447a31733fddd6273":[9,0,19,1], +"pearl-scienta-live_8ipf_source.html":[9,0,19], "pearl-scienta-preprocess_8ipf.html":[9,0,20], -"pearl-scienta-preprocess_8ipf.html#a145c7275b8809c5e789b932ef46e4811":[9,0,20,6], -"pearl-scienta-preprocess_8ipf.html#a1514250704b40aa2614d389a2e250d61":[9,0,20,5], -"pearl-scienta-preprocess_8ipf.html#a1e91197cd7a3581b70bc59a194d3f43b":[9,0,20,3], -"pearl-scienta-preprocess_8ipf.html#a6d06ea5a11ba79160efeea7fe673af8c":[9,0,20,7], -"pearl-scienta-preprocess_8ipf.html#a6e7de6441bbcba217760448babaca827":[9,0,20,8], +"pearl-scienta-preprocess_8ipf.html#a11d42ef1352876666b710b7545360fce":[9,0,20,3], +"pearl-scienta-preprocess_8ipf.html#a145c7275b8809c5e789b932ef46e4811":[9,0,20,7], +"pearl-scienta-preprocess_8ipf.html#a1514250704b40aa2614d389a2e250d61":[9,0,20,6], +"pearl-scienta-preprocess_8ipf.html#a1e91197cd7a3581b70bc59a194d3f43b":[9,0,20,4], +"pearl-scienta-preprocess_8ipf.html#a6d06ea5a11ba79160efeea7fe673af8c":[9,0,20,8], +"pearl-scienta-preprocess_8ipf.html#a6e7de6441bbcba217760448babaca827":[9,0,20,9], "pearl-scienta-preprocess_8ipf.html#a83cdbd96c5b59011914d53118e5ef71c":[9,0,20,2], -"pearl-scienta-preprocess_8ipf.html#a8e2aef3e0d5f2b304399a11423661fdc":[9,0,20,9], +"pearl-scienta-preprocess_8ipf.html#a8e2aef3e0d5f2b304399a11423661fdc":[9,0,20,10], "pearl-scienta-preprocess_8ipf.html#a95fbd22f52f61d2bff0625b7b8e159d1":[9,0,20,1], -"pearl-scienta-preprocess_8ipf.html#ad626526589efec3f2f72ad001702fe39":[9,0,20,4], -"pearl-scienta-preprocess_8ipf.html#adb78e8b2bbfd9c0faa5eb049b1dcad1c":[9,0,20,10], +"pearl-scienta-preprocess_8ipf.html#ad626526589efec3f2f72ad001702fe39":[9,0,20,5], +"pearl-scienta-preprocess_8ipf.html#adb78e8b2bbfd9c0faa5eb049b1dcad1c":[9,0,20,11], "pearl-scienta-preprocess_8ipf.html#ae6877c51ad15c2ba8a69c65356cb34b8":[9,0,20,0], "pearl-scienta-preprocess_8ipf_source.html":[9,0,20], "pearl-tools_8ipf.html":[9,0,21], diff --git a/doc/html/pag_anglescan_processing.html b/doc/html/pag_anglescan_processing.html index 83a8a56..2ead273 100644 --- a/doc/html/pag_anglescan_processing.html +++ b/doc/html/pag_anglescan_processing.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Angle-scan processing @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -80,7 +82,7 @@ $(document).ready(function(){initNavTree('pag_anglescan_processing.html','');});
    -
    +
    Angle-scan processing
    @@ -122,30 +124,53 @@ Data reduction

    The processing steps depend on the complexity of the measured spectrum. The user may have to adopt one of the predefined or a custom procedure accordingly. Here, we describe two procedures that may cover many generic cases or that can serve as a starting point for a refined, customized procedure. However, any procedure that produces the datasets mentioned above is, of course, a valid approach. For instance, you could load the complete three-dimensional ScientaImage dataset, and generate the two-dimensional dataset using your own procedures.

    Basic steps

    -

    The central import functions are psh5_load_reduced and psh5_load_dataset_reduced. The first form is sufficient if the file contains just one scan and region. Further regions/scans need to be loaded using the second form. The first form is also exposed in the PEARL data explorer window.

    +

    The central import functions are psh5_load_reduced and psh5_load_dataset_reduced. The first form is sufficient if the file contains just one scan and region. Further regions/scans need to be loaded using the second form. The first form is also exposed in the PEARL data explorer window.

    The functions require a data reduction function and processing parameters as arguments. Some particular reduction functions are described further below. More can be found in the source code (or obtained from other users). A list of functions that look like reduction functions can be got from adh5_list_reduction_funcs.

    The basic call sequence looks as follows. Substitute the arguments in angle brackets as necessary. You may have to analyse a reference spectrum or the complete ScientaImage to figure out the processing parameters beforehand.

    First form:

    -
    setdatafolder root:
    string sparam
    sparam = "<param1=1.5;param2=test;>"
    psh5_load_reduced("<igor-datafolder>", "<igor-filepath>", "<filename>", <reduction_function>, sparam)

    Second form:

    -
    // open the file
    setdatafolder root: // or other parent folder
    variable fid
    string sparam
    fid = psh5_open_file("<igor-datafolder>", "<igor-filepath>", "<filename>")
    // load metadata for scaling
    psh5_load_scan_meta(fileID, "<scan 1>")
    newdatafolder /s /o attr
    psh5_load_scan_attrs(fileID, "<scan 1>")
    setdatafolder ::
    // load and reduce dataset
    sparam = "<param1=1.5;param2=test;>"
    psh5_load_dataset_reduced(fid, "<scan 1/region1>", "<ScientaImage>", <reduction_function>, sparam)
    // close the file
    fid = 0

    +
    setdatafolder root:
    +
    string sparam
    +
    sparam = "<param1=1.5;param2=test;>"
    +
    psh5_load_reduced("<igor-datafolder>", "<igor-filepath>", "<filename>", <reduction_function>, sparam)
    +

    Second form:

    +
    // open the file
    +
    setdatafolder root: // or other parent folder
    +
    variable fid
    +
    string sparam
    +
    fid = psh5_open_file("<igor-datafolder>", "<igor-filepath>", "<filename>")
    +
    +
    // load metadata for scaling
    +
    psh5_load_scan_meta(fileID, "<scan 1>")
    +
    newdatafolder /s /o attr
    +
    psh5_load_scan_attrs(fileID, "<scan 1>")
    +
    setdatafolder ::
    +
    +
    // load and reduce dataset
    +
    sparam = "<param1=1.5;param2=test;>"
    +
    psh5_load_dataset_reduced(fid, "<scan 1/region1>", "<ScientaImage>", <reduction_function>, sparam)
    +
    +
    // close the file
    + +
    fid = 0
    +

    Peak integration over linear background

    The int_linbg_reduction function converts a two-dimensional Scienta image I(angle, energy) into a one-dimensional angle distribution I(angle). For each angle slice, it calculates a linear background. Then, it integrates the difference between the original data and the background over a specified interval.

    The function requires the following, fixed parameters:

    - - - - - - - - - - - - - - - +
    Parameter Description Typical value
    Lcrop size of the low-energy cropping region 0.11 (fixed mode)
    Lsize size of the low-energy background region 0.2
    Hcrop size of the high-energy cropping region 0.11
    Hsize size of the high-energy background region 0.2
    Cpos position of the peak center 0.5
    Csize size of the center region 0.3
    + + + + + + + + + + + + + +
    Parameter Description Typical value
    Lcrop size of the low-energy cropping region 0.11 (fixed mode)
    Lsize size of the low-energy background region 0.2
    Hcrop size of the high-energy cropping region 0.11
    Hsize size of the high-energy background region 0.2
    Cpos position of the peak center 0.5
    Csize size of the center region 0.3

    All parameters are relative to the size of the image (length of the energy interval) and must be in the range from 0 to 1.

    The cropping region is cut away from the image for the rest of the processing. This is necessary to remove the dark corners in fixed mode but can be neglected in swept mode (cropping size = 0).

    @@ -157,33 +182,33 @@ Peak fitting

    The gauss4_reduction function converts a two-dimensional Scienta image I(angle, energy) into a one-dimensional angle distribution I(angle). For each angle slice, it performs a Gaussian curve fit with up to four components on a linear background.

    To improve the stability of the fit, the peak positions and widths are kept fixed while the amplitudes of the peaks and the background parameters are variable but constrained to reasonable values (positive amplitude). Furthermore, the function can optionally do a box averaging over three slices.

    The function requires the following, fixed parameters:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - +
    Parameter Description
    rngl lower limit of the fit interval
    rngh upper limit of the fit interval
    npeaks number of components
    pos1 center energy of peak 1
    wid1 width of peak 1
    pos2 center energy of peak 2
    wid2 width of peak 2
    pos3 center energy of peak 3
    wid3 width of peak 3
    pos4 center energy of peak 3
    wid4 width of peak 3
    ybox box size of slice averaging (1 or 3)
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Parameter Description
    rngl lower limit of the fit interval
    rngh upper limit of the fit interval
    npeaks number of components
    pos1 center energy of peak 1
    wid1 width of peak 1
    pos2 center energy of peak 2
    wid2 width of peak 2
    pos3 center energy of peak 3
    wid3 width of peak 3
    pos4 center energy of peak 3
    wid4 width of peak 3
    ybox box size of slice averaging (1 or 3)

    The peak parameters should be determined beforehand from fitting a reference spectrum, or the angle-scan integrated over all angles. Peak positions and widths have to be specified only up to the given number of peaks.

    The data reduction procedure returns the peak integrals (amplitude times width times square root of 2) in waves named ReducedDataN where N is a numeric index from 1 to npeaks. The waves starting with an index of npeaks+1 contain the corresponding error estimate of the peak integral.

    @@ -197,60 +222,83 @@ Normalization

    There is a GUI for the processing steps in pearl-anglescan-panel.ipf (asp_show_panel function or the PEARL/process menu).

    Preparations

    -

    Start by creating a new copy of the data and inspecting it:

    duplicate ReducedData1, NormData1

    To update the display after changes to NormData1:

    +

    Start by creating a new copy of the data and inspecting it:

    duplicate ReducedData1, NormData1
    + +

    To update the display after changes to NormData1:

    +

    Detector angle range

    -

    Crop the detector angle axis to a useful range (usually about -25 to +25 degrees):

    crop_strip(NormData1, -25, 25)

    +

    Crop the detector angle axis to a useful range (usually about -25 to +25 degrees):

    crop_strip(NormData1, -25, 25)
    +

    Normalize detector angle

    Remove inhomogeneity of the detector in the detector angle axis. This component may also include a contribution from the sample. If your raw data shows a flat distribution, this step is not necessary.

    -
    normalize_strip_x(NormData1, smooth_method=4, smooth_factor=0.15, check=2)

    Note that the argument check=2 causes the function to generate two check waves but not to modify the original data. To inspect the check waves:

    display check_dist, check_smoo
    ModifyGraph rgb(check_dist)=(0,0,0)

    Vary the smooth_factor (between 0.1 and 1.0) until it follows the instrumental curve but does not affect diffraction features. Then set check=1 to apply the normalization to NormData1.

    +
    normalize_strip_x(NormData1, smooth_method=4, smooth_factor=0.15, check=2)
    +

    Note that the argument check=2 causes the function to generate two check waves but not to modify the original data. To inspect the check waves:

    display check_dist, check_smoo
    +
    ModifyGraph rgb(check_dist)=(0,0,0)
    +

    Vary the smooth_factor (between 0.1 and 1.0) until it follows the instrumental curve but does not affect diffraction features. Then set check=1 to apply the normalization to NormData1.

    Azimuthal variation (wobble)

    Reduce the effect of azimuthal wobble (misaligned surface) on intensity. A misaligned surface may cause a sinusoidal variation of the intensity as a function of azimuthal angle with a 360° period. A strong azimuthal variation may affect the polar normalization in the next step. The azimuthal normalization can be based on a restricted range of polar angles (theta range). You have to find out which value works best for your sample.

    -
    normalize_strip_phi(NormData1, :attr:ManipulatorTheta, :attr:ManipulatorPhi, theta_offset=-8.8, theta_range=10, check=2)

    Note, however, that his function does not correct for angle shifts induced by the misalignment!

    +
    normalize_strip_phi(NormData1, :attr:ManipulatorTheta, :attr:ManipulatorPhi, theta_offset=-8.8, theta_range=10, check=2)
    +

    Note, however, that his function does not correct for angle shifts induced by the misalignment!

    Polar dependence

    Remove the polar angle dependence (matrix element and excitation/detection geometry).

    -
    normalize_strip_theta(NormData1, :attr:ManipulatorTheta, theta_offset=-8.8, smooth_method=4, smooth_factor=0.5, check=2)

    Use the check waves and the check argument as described above.

    +
    normalize_strip_theta(NormData1, :attr:ManipulatorTheta, theta_offset=-8.8, smooth_method=4, smooth_factor=0.5, check=2)
    +

    Use the check waves and the check argument as described above.

    Binning and plotting

    Basic steps

    You can bin and plot the data in one step:

    -
    pizza_service(NormData1, "Nickname1", -8.8, 0.5, 6)

    or two steps:

    -
    pizza_service(NormData1, "Nickname2", -8.8, 0.5, 6, nograph=1)
    display_hemi_scan("Nickname2")

    The benefit of the latter is that you have more control over the graph through optional arguments. In particular, you can select the projection or hide the ticks and grids. See display_hemi_scan for details.

    +
    pizza_service(NormData1, "Nickname1", -8.8, 0.5, 6)
    +

    or two steps:

    +
    pizza_service(NormData1, "Nickname2", -8.8, 0.5, 6, nograph=1)
    +
    display_hemi_scan("Nickname2")
    +

    The benefit of the latter is that you have more control over the graph through optional arguments. In particular, you can select the projection or hide the ticks and grids. See display_hemi_scan for details.

    The pizza_service function requires the waves with manipulator positions in a specific place, namely :attr:ManipulatorTheta (for the polar angle), and the normal emission values as function arguments. If you have moved the waves, or if you have subtracted the offsets yourself, use the alternative pizza_service_2 function.

    Additional parameters of the pizza_service function allow for rotational averaging, larger angle steps (default 1 degree), or the creation of metadata including a notebook for xpdPlot.

    Note there is currently a bug in the nick name argument of some of the following functions. If the lines shown below do not work, try to switch to the data folder that contains the generated polar plot data, and call the function with an empty nickname "".

    Refinements

    To remove high polar angles above θ = 80 from the plot (and data):

    -
    trim_hemi_scan("Nickname1", 80)

    Modify the pseudocolor scale by changing the polarY0 trace:

    -
    ModifyGraph zColor(polarY0)={mod_values, *, *, BlueGreenOrange, 0}
    ModifyGraph zColor(polarY0)={mod_values, -0.2, 0.2, BlueGreenOrange, 0}

    To set the contrast to clip specified percentiles of the data points, use the

      +
      trim_hemi_scan("Nickname1", 80)
      +

      Modify the pseudocolor scale by changing the polarY0 trace:

      +
      ModifyGraph zColor(polarY0)={mod_values, *, *, BlueGreenOrange, 0}
      +
      ModifyGraph zColor(polarY0)={mod_values, -0.2, 0.2, BlueGreenOrange, 0}
      +

      To set the contrast to clip specified percentiles of the data points, use the

      • set_contrast function:
      -
      set_contrast(2, 2, graphname="graph_Nickname1", colortable="BlueGreenOrange")

      +
      set_contrast(2, 2, graphname="graph_Nickname1", colortable="BlueGreenOrange")
      +

      Interpolation

      Polar plots can also be interpolated to a rectangular matrix, which may in some cases produce nicer images:

      -
      display_hemi_scan("Nickname1", graphtype=3, graphname="intp")
      matrix = sqrt(x^2 + y^2) <= calc_graph_radius(80) ? matrix : nan
      ModifyImage matrix ctab= {*,*,BlueGreenOrange,0}

      The matrix = line optionally removes artefacts at high polar angles. Replace the cut-off angle with your own.

      +
      +
      display_hemi_scan("Nickname1", graphtype=3, graphname="intp")
      +
      matrix = sqrt(x^2 + y^2) <= calc_graph_radius(80) ? matrix : nan
      +
      ModifyImage matrix ctab= {*,*,BlueGreenOrange,0}
      +

      The matrix = line optionally removes artefacts at high polar angles. Replace the cut-off angle with your own.

      Modulation function

      To calculate the modulation function and substitute it in the graph:

      -
      setdatafolder Nickname1
      calc_modulation(values, factor1=pol, factor2=az)
      ModifyGraph zColor(polarY0)={mod_values,-0.2,0.2,BlueGreenOrange,0}

      +
      setdatafolder Nickname1
      +
      calc_modulation(values, factor1=pol, factor2=az)
      +
      ModifyGraph zColor(polarY0)={mod_values,-0.2,0.2,BlueGreenOrange,0}
      +

      Projection

      The display_hemi_scan and interpolate_hemi_scan functions take an optional argument projection which selects one of the following projections. By default, stereographic projection is selected.

      - - - - - - - - - - - - - +
      Selector Projection Function Properties
      kProjDist = 0 azimuthal equidistant r = c * theta radius is proportional to polar angle
      kProjStereo = 1 stereographic r = c * tan theta/2 circles on sphere map to circles
      kProjArea = 2 azimuthal equal-area r = c * sin theta/2 preserves area measure
      kProjGnom = 3 gnomonic r = c * tan theta great circles map to straight lines
      kProjOrtho = 4 orthographic r = c * sin theta momentum mapping in ARPES and LEED
      + + + + + + + + + + + +
      Selector Projection Function Properties
      kProjDist = 0 azimuthal equidistant r = c * theta radius is proportional to polar angle
      kProjStereo = 1 stereographic r = c * tan theta/2 circles on sphere map to circles
      kProjArea = 2 azimuthal equal-area r = c * sin theta/2 preserves area measure
      kProjGnom = 3 gnomonic r = c * tan theta great circles map to straight lines
      kProjOrtho = 4 orthographic r = c * sin theta momentum mapping in ARPES and LEED

      For a description of the different projections, see Wikipedia, for example. The projections in this package are defined for 0 <= theta < 90.

      @@ -258,19 +306,42 @@ Data export

      Export picture

      The following line is an example of how to export a graph window. Click on the desired graph window, then issue the following command, substituting the file path and file name as appropriate.

      -
      SavePICT/P=home/E=-5/B=144/O as "some_filename.png"

      +
      SavePICT/P=home/E=-5/B=144/O as "some_filename.png"
      +

      Export processed data

      The following line saves the dataset to an Igor text file. The file contains all data necessary to recreate a polar plot without further processing.

      -
      save_hemi_scan("Nickname1", "home", "some_filename")

      For structural optimization using the PMSCO software, it is necessary to generate an ETPI file. There is currently no special function for this. Instead, you have to create and set an energy wave,

      -
      duplicate pol, en
      en = 123.4 // kinetic energy of the photoelectron

      and write the four waves en, pol, az, values to a general text file. Be careful about the ordering of the waves! You will also have to rename the file to the .etpi extension because Igor always saves with .txt extension. If you have a wave with statistical errors, add a fifth column and use the .etpis extension.

      -
      Save /G /M="\n" /O /P=home en, pol, az, values, sig as "Nickname1.etpis.txt"
    +
    save_hemi_scan("Nickname1", "home", "some_filename")
    +

    For structural optimization using the PMSCO software, it is necessary to generate an ETPI file. There is currently no special function for this. Instead, you have to create and set an energy wave,

    +
    duplicate pol, en
    +
    en = 123.4 // kinetic energy of the photoelectron
    +

    and write the four waves en, pol, az, values to a general text file. Be careful about the ordering of the waves! You will also have to rename the file to the .etpi extension because Igor always saves with .txt extension. If you have a wave with statistical errors, add a fifth column and use the .etpis extension.

    +
    Save /G /M="\n" /O /P=home en, pol, az, values, sig as "Nickname1.etpis.txt"
    +
    + +
    variable crop_strip(wave strip, variable xlo, variable xhi)
    crop a strip at the sides.
    +
    variable trim_hemi_scan(string nickname, variable theta_max)
    trim a hemispherical scan at grazing angle
    +
    variable normalize_strip_theta(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by the average polar distribution.
    +
    variable normalize_strip_x(wave strip, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by the average X distribution.
    +
    string psh5_load_dataset_reduced(dfref file_df, string datasetpath, funcref reduction_func, string reduction_params, variable create_folders=defaultValue, variable progress=defaultValue, variable nthreads=defaultValue)
    load a dataset with reduced dimensionality
    +
    string psh5_load_scan_meta(dfref file_df, string scanpath)
    load metadata of a PShell scan group.
    +
    variable ad_update_profiles(wave image)
    update a profiles graph with new data.
    +
    threadsafe variable calc_graph_radius(variable polar, variable projection=defaultValue)
    calculate the projected polar angle
    +
    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
    +
    variable interpolate_hemi_scan(string nickname, variable projection=defaultValue)
    interpolate a hemispherical scan onto a rectangular grid
    +
    variable set_contrast(variable pcmin, variable pcmax, string graphname=defaultValue, string colortable=defaultValue, variable reversecolors=defaultValue, variable symmetric=defaultValue)
    set the pseudocolor contrast by percentile.
    +
    variable save_hemi_scan(string nickname, string pathname, string filename)
    save a hemispherical scan to an Igor text file
    +
    variable psh5_close_file(dfref file_df)
    close a HDF5 file opened by psh5_open_file.
    +
    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).
    +
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    +
    dfr psh5_open_file(string path_name, string file_name, dfref dest_df=defaultValue)
    open a HDF5 file created by the PShell data acquisition program and prepare the data folder.
    +
    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.
    diff --git a/doc/html/pages.html b/doc/html/pages.html index 9fd9f62..6e60331 100644 --- a/doc/html/pages.html +++ b/doc/html/pages.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Related Pages @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -87,7 +89,7 @@ $(document).ready(function(){initNavTree('pages.html','');});
    Here is a list of all related documentation pages:
    - +
     ProjectionsFunctions of the anglescan package support the following map projections
     Projections
     Angle-scan processing
     Todo List
    @@ -97,9 +99,9 @@ $(document).ready(function(){initNavTree('pages.html','');}); diff --git a/doc/html/pearl-anglescan-panel_8ipf.html b/doc/html/pearl-anglescan-panel_8ipf.html index b912769..b8cc6fb 100644 --- a/doc/html/pearl-anglescan-panel_8ipf.html +++ b/doc/html/pearl-anglescan-panel_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-anglescan-panel.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -94,6 +96,8 @@ $(document).ready(function(){initNavTree('pearl-anglescan-panel_8ipf.html','');} More...

    #include "pearl-anglescan-process"
    #include "pearl-pmsco-import"
    +#include "pearl-scienta-preprocess"
    +#include "pearl-area-display"

    Go to the source code of this file.

    @@ -106,66 +110,66 @@ Namespaces - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -186,12 +190,12 @@ Functions - + - + @@ -249,17 +253,17 @@ Functions - + - +

    Functions

    static variable AfterCompiledHook ()
     initialize package data once when the procedure is first loaded More...
     initialize package data once when the procedure is first loaded More...
     
    static variable init_package ()
     
    static variable save_prefs ()
     save persistent package data to the preferences file. More...
     save persistent package data to the preferences file. More...
     
    static variable load_prefs ()
     load persistent package data from the preferences file. More...
     load persistent package data from the preferences file. More...
     
    variable asp_import_raw (wave raw_data)
     import raw data More...
     import raw data More...
     
    variable asp_display_previews ()
     display a graph window of the processed data. More...
     display a graph window of the processed data. More...
     
    variable asp_display_dist_check (variable xdist, variable ydist)
     display a graph window of the distribution checks. More...
     display a graph window of the distribution checks. More...
     
    static variable do_init_process (variable check)
     initialize the process data with a copy of the raw data. More...
     initialize the process data with a copy of the raw data. More...
     
    static variable do_crop (variable check, variable force=defaultValue)
     crop the process data. More...
     crop the process data. More...
     
    static variable delete_rows (string rows, wave data, wave theta, wave tilt, wave phi)
     delete individual rows from the data strip More...
     delete individual rows from the data strip More...
     
    static variable do_norm_alpha (variable check, variable force=defaultValue)
     alpha-normalize the process data. More...
     alpha-normalize the process data. More...
     
    static variable do_norm_phi (variable check, variable force=defaultValue)
     phi-normalize the process data. More...
     phi-normalize the process data. More...
     
    static variable do_norm_theta (variable check, variable force=defaultValue)
     theta-normalize the process data. More...
     theta-normalize the process data. More...
     
    static variable do_norm_thetaphi (variable check, variable force=defaultValue)
     theta,phi-normalize the process data. More...
     theta,phi-normalize the process data. More...
     
    variable asp_calculate_output ()
     calculate the output using all enabled processing filters. More...
     calculate the output using all enabled processing filters. More...
     
    string asp_display_output (dfref data_df=defaultValue, string data_name=defaultValue)
     display the output diffractogram More...
     display the output diffractogram More...
     
    variable asp_update_graph ()
     update graphs with new color table or contrast More...
     update graphs with new color table or contrast More...
     
    variable asp_close_graphs ()
     close all graphs created by the angle scan panel More...
     close all graphs created by the angle scan panel More...
     
    string asp_duplicate_output (string dest_name, variable do_graph=defaultValue)
     copy the output data to a new folder More...
     copy the output data to a new folder More...
     
    variable asp_save_output_itx ()
     save the output diffractogram to an igor text file More...
     save the output diffractogram to an igor text file More...
     
    variable asp_save_output_etpi (variable ekin)
     save the output diffractogram to a PMSCO ETPI file More...
     save the output diffractogram to a PMSCO ETPI file More...
     
    static variable check_norm_alpha ()
     
    static variable preview_norm_thetaphi ()
     
    variable asp_show_panel ()
     create the angle scan processing panel More...
     create the angle scan processing panel More...
     
    static variable arrange_controls ()
     
    static variable update_menus ()
     update the popup menus to reflect the values of the global variables More...
     update the popup menus to reflect the values of the global variables More...
     
    static variable bp_load_prefs (WMButtonAction *ba)
     

    Variables

    static const string package_name = "pearl_anglescan_panel"
     package name is used as data folder name More...
     package name is used as data folder name More...
     
    static const string package_path = "root:packages:pearl_anglescan_panel:"
     data folder path More...
     data folder path More...
     

    Detailed Description

    interactive processing of angle scanned XPD data.

    steps to process a hemispherical scan into a diffractogram:

    1. load the scan file in data reduction mode.
    2. -
    3. open the angle scan panel by calling asp_show_panel().
    4. +
    5. open the angle scan panel by calling asp_show_panel().
    6. select the dataset.
    7. set the processing parameters.
    8. start the processing and display the result.
    9. @@ -267,9 +271,9 @@ Variables
    10. export the result in the desired form.
    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -
    @@ -326,7 +330,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1052 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1055 of file pearl-anglescan-panel.ipf.

    @@ -348,7 +352,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    calculate the output using all enabled processing filters.

    the diffractogram is calculated, to display the graph, call asp_display_output.

    -

    Definition at line 620 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 623 of file pearl-anglescan-panel.ipf.

    @@ -369,7 +373,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    close all graphs created by the angle scan panel

    -

    Definition at line 728 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 731 of file pearl-anglescan-panel.ipf.

    @@ -409,7 +413,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 273 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 276 of file pearl-anglescan-panel.ipf.

    @@ -449,7 +453,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 666 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 669 of file pearl-anglescan-panel.ipf.

    @@ -471,7 +475,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    display a graph window of the processed data.

    if the window exists, it is updated and brought to the front of the window stack.

    -

    Definition at line 249 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 252 of file pearl-anglescan-panel.ipf.

    @@ -511,7 +515,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    name of the graph window
    -

    Definition at line 768 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 771 of file pearl-anglescan-panel.ipf.

    @@ -540,7 +544,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 204 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 207 of file pearl-anglescan-panel.ipf.

    @@ -568,7 +572,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 816 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 819 of file pearl-anglescan-panel.ipf.

    @@ -589,7 +593,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    save the output diffractogram to an igor text file

    -

    Definition at line 801 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 804 of file pearl-anglescan-panel.ipf.

    @@ -610,7 +614,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    create the angle scan processing panel

    -

    Definition at line 900 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 903 of file pearl-anglescan-panel.ipf.

    @@ -632,7 +636,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    update graphs with new color table or contrast

    applies to the preview graph and the diffractogram.

    -

    Definition at line 710 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 713 of file pearl-anglescan-panel.ipf.

    @@ -660,7 +664,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1370 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1373 of file pearl-anglescan-panel.ipf.

    @@ -688,7 +692,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1526 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1529 of file pearl-anglescan-panel.ipf.

    @@ -716,7 +720,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1512 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1515 of file pearl-anglescan-panel.ipf.

    @@ -744,7 +748,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1239 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1242 of file pearl-anglescan-panel.ipf.

    @@ -772,7 +776,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1314 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1317 of file pearl-anglescan-panel.ipf.

    @@ -800,7 +804,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1384 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1387 of file pearl-anglescan-panel.ipf.

    @@ -828,7 +832,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1342 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1345 of file pearl-anglescan-panel.ipf.

    @@ -856,7 +860,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1398 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1401 of file pearl-anglescan-panel.ipf.

    @@ -884,7 +888,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1328 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1331 of file pearl-anglescan-panel.ipf.

    @@ -912,7 +916,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1412 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1415 of file pearl-anglescan-panel.ipf.

    @@ -940,7 +944,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1356 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1359 of file pearl-anglescan-panel.ipf.

    @@ -968,7 +972,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1426 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1429 of file pearl-anglescan-panel.ipf.

    @@ -996,7 +1000,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1440 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1443 of file pearl-anglescan-panel.ipf.

    @@ -1024,7 +1028,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1455 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1458 of file pearl-anglescan-panel.ipf.

    @@ -1052,7 +1056,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1476 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1479 of file pearl-anglescan-panel.ipf.

    @@ -1080,7 +1084,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1498 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1501 of file pearl-anglescan-panel.ipf.

    @@ -1108,7 +1112,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1253 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1256 of file pearl-anglescan-panel.ipf.

    @@ -1136,7 +1140,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1267 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1270 of file pearl-anglescan-panel.ipf.

    @@ -1164,7 +1168,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1293 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1296 of file pearl-anglescan-panel.ipf.

    @@ -1191,7 +1195,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 836 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 839 of file pearl-anglescan-panel.ipf.

    @@ -1218,7 +1222,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 843 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 846 of file pearl-anglescan-panel.ipf.

    @@ -1245,7 +1249,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 850 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 853 of file pearl-anglescan-panel.ipf.

    @@ -1272,7 +1276,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 857 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 860 of file pearl-anglescan-panel.ipf.

    @@ -1340,7 +1344,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 406 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 409 of file pearl-anglescan-panel.ipf.

    @@ -1396,7 +1400,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 358 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 361 of file pearl-anglescan-panel.ipf.

    @@ -1438,7 +1442,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 318 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 321 of file pearl-anglescan-panel.ipf.

    @@ -1494,7 +1498,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 453 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 456 of file pearl-anglescan-panel.ipf.

    @@ -1550,7 +1554,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 494 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 497 of file pearl-anglescan-panel.ipf.

    @@ -1606,7 +1610,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 537 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 540 of file pearl-anglescan-panel.ipf.

    @@ -1662,7 +1666,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 584 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 587 of file pearl-anglescan-panel.ipf.

    @@ -1689,7 +1693,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 75 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 78 of file pearl-anglescan-panel.ipf.

    @@ -1720,7 +1724,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    the preferences file is an Igor packed experiment file in a special preferences folder.

    this function is called automatically when the procedure is first compiled, or whenever the user clicks the corresponding button.

    -

    Definition at line 168 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 171 of file pearl-anglescan-panel.ipf.

    @@ -1748,7 +1752,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1641 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1644 of file pearl-anglescan-panel.ipf.

    @@ -1776,7 +1780,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1609 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1612 of file pearl-anglescan-panel.ipf.

    @@ -1804,7 +1808,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1625 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1628 of file pearl-anglescan-panel.ipf.

    @@ -1832,7 +1836,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1545 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1548 of file pearl-anglescan-panel.ipf.

    @@ -1860,7 +1864,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1561 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1564 of file pearl-anglescan-panel.ipf.

    @@ -1888,7 +1892,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1577 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1580 of file pearl-anglescan-panel.ipf.

    @@ -1916,7 +1920,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1593 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1596 of file pearl-anglescan-panel.ipf.

    @@ -1943,7 +1947,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 864 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 867 of file pearl-anglescan-panel.ipf.

    @@ -1970,7 +1974,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 870 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 873 of file pearl-anglescan-panel.ipf.

    @@ -1997,7 +2001,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 877 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 880 of file pearl-anglescan-panel.ipf.

    @@ -2024,7 +2028,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 884 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 887 of file pearl-anglescan-panel.ipf.

    @@ -2051,7 +2055,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 891 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 894 of file pearl-anglescan-panel.ipf.

    @@ -2081,7 +2085,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    save persistent package data to the preferences file.

    this function is called when the user clicks the corresponding button.

    -

    Definition at line 142 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 145 of file pearl-anglescan-panel.ipf.

    @@ -2110,7 +2114,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    update the popup menus to reflect the values of the global variables

    -

    Definition at line 1210 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 1213 of file pearl-anglescan-panel.ipf.

    @@ -2137,7 +2141,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    package name is used as data folder name

    -

    Definition at line 45 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 48 of file pearl-anglescan-panel.ipf.

    @@ -2163,7 +2167,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    data folder path

    -

    Definition at line 47 of file pearl-anglescan-panel.ipf.

    +

    Definition at line 50 of file pearl-anglescan-panel.ipf.

    @@ -2173,9 +2177,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
    diff --git a/doc/html/pearl-anglescan-panel_8ipf_source.html b/doc/html/pearl-anglescan-panel_8ipf_source.html index dff4330..42a3d4a 100644 --- a/doc/html/pearl-anglescan-panel_8ipf_source.html +++ b/doc/html/pearl-anglescan-panel_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-anglescan-panel.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,96 +87,1569 @@ $(document).ready(function(){initNavTree('pearl-anglescan-panel_8ipf_source.html
    pearl-anglescan-panel.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 = PearlAnglescanPanel
    5 #include "pearl-anglescan-process"
    6 #include "pearl-pmsco-import"
    7 
    8 // copyright (c) 2018-20 Paul Scherrer Institut
    9 //
    10 // Licensed under the Apache License, Version 2.0 (the "License");
    11 // you may not use this file except in compliance with the License.
    12 // You may obtain a copy of the License at
    13 // http:///www.apache.org/licenses/LICENSE-2.0
    14 //
    15 // Please acknowledge the use of this code.
    16 
    38 
    43 
    45 static strconstant package_name = "pearl_anglescan_panel"
    47 static strconstant package_path = "root:packages:pearl_anglescan_panel:"
    48 
    50 static function AfterCompiledHook()
    51 
    52  dfref savedf = GetDataFolderDFR()
    53  variable do_init = 1
    54  if (DataFolderExists(package_path))
    55  setdatafolder $(package_path)
    56  nvar /z init_done
    57  if (nvar_exists(init_done))
    58  if (init_done)
    59  do_init = 0
    60  endif
    61  endif
    62  endif
    63 
    64  if (do_init)
    65  init_package()
    66  load_prefs()
    67  setdatafolder $(package_path)
    68  variable /g init_done = 1
    69  endif
    70 
    71  setdatafolder savedf
    72  return 0
    73 end
    74 
    75 static function init_package()
    76  dfref savedf = getdatafolderdfr()
    77  setdatafolder root:
    78  newdatafolder /o/s packages
    79  newdatafolder /o/s $package_name
    80 
    81  // configuration (persistent)
    82  string /g graphname = "graph_anglescan_panel"
    83  string /g prefs_objects = "prefs_objects;theta_offset;tilt_offset;phi_offset;alpha_offset;crop_enable;crop_alpha;crop_theta;"
    84  prefs_objects += "norm_alpha_enable;norm_alpha_mode;norm_alpha_smoothing;norm_phi_enable;norm_phi_mode;norm_phi_thetarange;"
    85  prefs_objects += "norm_theta_enable;norm_theta_mode;norm_theta_domain;norm_theta_smoothing;norm_thetaphi_enable;norm_thetaphi_mode;norm_thetaphi_smoothing;"
    86  prefs_objects += "output_folding;output_horizon;graph_mode;graph_projection;graph_colortable;graph_contrast;"
    87 
    88  // recently used (persistent)
    89  variable /g theta_offset = 0
    90  variable /g tilt_offset = 0
    91  variable /g phi_offset = 0
    92  variable /g alpha_offset = 0
    93  variable /g crop_enable = 0
    94  variable /g crop_alpha = 25
    95  variable /g crop_theta = 88
    96  string /g crop_rows = ""
    97  variable /g norm_alpha_enable = 0
    98  variable /g norm_alpha_mode = 4
    99  variable /g norm_alpha_smoothing = 0.25
    100  variable /g norm_theta_enable = 0
    101  variable /g norm_theta_mode = 4
    102  variable /g norm_theta_domain = 0
    103  variable /g norm_theta_smoothing = 0.25
    104  variable /g norm_thetaphi_enable = 0
    105  variable /g norm_thetaphi_mode = 4
    106  variable /g norm_thetaphi_smoothing = 0.25
    107  variable /g norm_phi_enable = 0
    108  variable /g norm_phi_mode = 4
    109  variable /g norm_phi_thetarange = 20
    110  string /g output_name = "holo1"
    111  variable /g output_folding = 1
    112  variable /g output_horizon = 88
    113  variable /g graph_mode = 1
    114  variable /g graph_projection = kProjStereo
    115  string /g graph_colortable = "grays"
    116  variable /g graph_contrast = 2
    117 
    118  // recently used (volatile)
    119  string /g source_path = ""
    120  string /g export_folderpath = "root:"
    121  variable /g export_format = 1
    122 
    123  // administrative data (volatile)
    124  string /g panel_name = ""
    125  string /g preview_graphname = ""
    126  string /g dist_x_graphname = ""
    127  string /g dist_y_graphname = ""
    128  string /g output_graphname = ""
    129 
    130  // data (volatile)
    131  make /n=(10,10) /o raw_data, process_data
    132  make /o dist_x, dist_x_smoo
    133  make /o dist_y, dist_y_smoo
    134 
    135  setdatafolder savedf
    136 end
    137 
    142 static function save_prefs()
    143  dfref saveDF = GetDataFolderDFR()
    144  dfref df = $(package_path)
    145  svar /sdfr=df prefs_objects
    146 
    147  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    148  fullPath += package_name
    149  NewPath/O/C/Q tempPackagePrefsPath, fullPath
    150  fullPath += ":preferences.pxp"
    151 
    152  SetDataFolder root:packages
    153  SetDataFolder $package_name
    154  SaveData /O /Q /J=prefs_objects fullPath
    155 
    156  KillPath/Z tempPackagePrefsPath
    157 
    158  SetDataFolder saveDF
    159 end
    160 
    168 static function load_prefs()
    169  dfref saveDF = GetDataFolderDFR()
    170 
    171  variable result = -1
    172  setdatafolder root:
    173  NewDataFolder /O/S packages
    174  NewDataFolder /O/S $package_name
    175  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    176  fullPath += package_name
    177 
    178  GetFileFolderInfo /Q /Z fullPath
    179  if (V_Flag == 0) // Disk directory exists?
    180  fullPath += ":preferences.pxp"
    181  GetFileFolderInfo /Q /Z fullPath
    182  if (V_Flag == 0) // Preference file exist?
    183  LoadData /O /R /Q fullPath
    184  result = 0
    185  endif
    186  endif
    187 
    188  SetDataFolder saveDF
    189  return result
    190 end
    191 
    204 function asp_import_raw(raw_data)
    205  wave raw_data
    206 
    207  dfref saveDF = GetDataFolderDFR()
    208  dfref datadf = GetWavesDataFolderDFR(raw_data)
    209  dfref attrdf = datadf:attr
    210  if (!DataFolderRefStatus(attrdf))
    211  setdatafolder datadf
    212  setdatafolder ::
    213  dfref parentdf = GetDataFolderDFR()
    214  dfref attrdf = parentdf:attr
    215  endif
    216  setdatafolder $(package_path)
    217 
    218  // todo : check dimensions and scales
    219 
    220  svar source_path
    221  source_path = GetWavesDataFolder(raw_data, 2)
    222 
    223  duplicate /o raw_data, raw, process_data
    224 
    225  wave /sdfr=attrdf /z ManipulatorTheta
    226  wave /sdfr=attrdf /z ManipulatorTilt
    227  wave /sdfr=attrdf /z ManipulatorPhi
    228  if (WaveExists(ManipulatorTheta) && WaveExists(ManipulatorTilt) && WaveExists(ManipulatorPhi))
    229  duplicate /o attrdf:ManipulatorTheta, raw_theta, process_theta
    230  duplicate /o attrdf:ManipulatorTilt, raw_tilt, process_tilt
    231  duplicate /o attrdf:ManipulatorPhi, raw_phi, process_phi
    232  else
    233  DoAlert 0, "Can't find manipulator angle waves.\rCheck that the attr folder exists, or provide values in the following table."
    234  make /n=(dimsize(raw_data, 1)) /o raw_theta, raw_tilt, raw_phi
    235  make /n=(dimsize(raw_data, 1)) /o process_theta, process_tilt, process_phi
    236  edit /k=1 raw_theta, raw_tilt, raw_phi
    237  endif
    238 
    239  make /o /n=(dimsize(raw_data, 0)) dist_x, dist_x_smoo
    240  make /o /n=(dimsize(raw_data, 1)) dist_y, dist_y_smoo
    241 
    242  SetDataFolder saveDF
    243 end
    244 
    250  dfref df = $(package_path)
    251  wave /sdfr=df process_data
    252  svar /sdfr=df preview_graphname
    253 
    254  if (strlen(preview_graphname) && (wintype(preview_graphname) == 1))
    255  ad_update_profiles(process_data)
    256  DoWindow /F $preview_graphname
    257  else
    258  preview_graphname = ad_display_profiles(process_data)
    259  endif
    260 
    261  nvar /sdfr=df graph_contrast
    262  svar /sdfr=df graph_colortable
    263  set_contrast(graph_contrast, graph_contrast, graphname=preview_graphname, colortable=graph_colortable)
    264 end
    265 
    273 function asp_display_dist_check(xdist, ydist)
    274  variable xdist, ydist
    275 
    276  dfref df = $(package_path)
    277  wave /sdfr=df dist_x
    278  wave /sdfr=df dist_y
    279  wave /sdfr=df dist_x_smoo
    280  wave /sdfr=df dist_y_smoo
    281  svar /sdfr=df dist_x_graphname
    282  svar /sdfr=df dist_y_graphname
    283 
    284  if (xdist)
    285  if (strlen(dist_x_graphname) && (wintype(dist_x_graphname) == 1))
    286  DoWindow /F $dist_x_graphname
    287  else
    288  display /k=1 /n=graph_asp_dist_x dist_x, dist_x_smoo
    289  dist_x_graphname = s_name
    290  ModifyGraph /w=$dist_x_graphname mode(dist_x)=2
    291  ModifyGraph /w=$dist_x_graphname lsize(dist_x)=2
    292  ModifyGraph /w=$dist_x_graphname rgb(dist_x)=(0,0,0)
    293  endif
    294  endif
    295 
    296  if (ydist)
    297  if (strlen(dist_y_graphname) && (wintype(dist_y_graphname) == 1))
    298  DoWindow /F $dist_y_graphname
    299  else
    300  display /k=1 /n=graph_asp_dist_y dist_y, dist_y_smoo
    301  dist_y_graphname = s_name
    302  ModifyGraph /w=$dist_y_graphname mode(dist_y)=2
    303  ModifyGraph /w=$dist_y_graphname lsize(dist_y)=2
    304  ModifyGraph /w=$dist_y_graphname rgb(dist_y)=(0,0,0)
    305  endif
    306  endif
    307 end
    308 
    318 static function do_init_process(check)
    319  variable check
    320 
    321  dfref df = $(package_path)
    322  wave /sdfr=df raw
    323  wave /sdfr=df raw_theta
    324  wave /sdfr=df raw_tilt
    325  wave /sdfr=df raw_phi
    326  nvar /sdfr=df theta_offset
    327  nvar /sdfr=df tilt_offset
    328  nvar /sdfr=df phi_offset
    329  nvar /sdfr=df alpha_offset
    330 
    331  duplicate /o raw, df:process_data
    332  duplicate /o raw_theta, df:process_theta
    333  duplicate /o raw_tilt, df:process_tilt
    334  duplicate /o raw_phi, df:process_phi
    335 
    336  wave /sdfr=df process_data
    337  wave /sdfr=df process_theta
    338  wave /sdfr=df process_tilt
    339  wave /sdfr=df process_phi
    340 
    341  process_theta = raw_theta - theta_offset
    342  process_tilt = raw_tilt - tilt_offset
    343  process_phi = raw_phi - phi_offset
    344  setscale /p x dimoffset(raw, 0) - alpha_offset, dimdelta(raw, 0), waveunits(raw, 0), process_data
    345 end
    346 
    358 static function do_crop(check, [force])
    359  variable check
    360  variable force
    361 
    362  if (ParamIsDefault(force))
    363  force = 0
    364  endif
    365 
    366  dfref df = $(package_path)
    367  wave /sdfr=df process_data
    368  wave /sdfr=df process_theta
    369  wave /sdfr=df process_tilt
    370  wave /sdfr=df process_phi
    371  nvar /sdfr=df crop_enable
    372  nvar /sdfr=df crop_alpha
    373  nvar /sdfr=df crop_theta
    374  svar /sdfr=df crop_rows
    375 
    376  if (force || crop_enable)
    377 
    378  if (crop_alpha > abs(dimdelta(process_data, 0)))
    379  crop_strip(process_data, -crop_alpha, +crop_alpha)
    380  endif
    381 
    382  if ((crop_theta >= 10) && (crop_theta < 90))
    383  crop_strip_theta(process_data, -0.1, crop_theta + 0.1, process_theta, process_tilt, process_phi)
    384  endif
    385 
    386  if (strlen(crop_rows) > 0)
    387  delete_rows(crop_rows, process_data, process_theta, process_tilt, process_phi)
    388  endif
    389  endif
    390 end
    391 
    406 static function delete_rows(rows, data, theta, tilt, phi)
    407  string rows
    408  wave data
    409  wave theta
    410  wave tilt
    411  wave phi
    412 
    413  make /n=(numpnts(theta)) /i /free idx
    414  idx = p
    415  variable nrows = ItemsInList(rows, ",")
    416  variable irow
    417  string srow
    418  variable q1, q2
    419  for (irow = 0; irow < nrows; irow += 1)
    420  srow = StringFromList(irow, rows, ",")
    421  q1 = str2num(StringFromList(0, srow, "-"))
    422  q2 = str2num(StringFromList(1, srow, "-"))
    423  if (numtype(q2))
    424  q2 = q1
    425  endif
    426  if (q1 <= q2)
    427  idx[q1,q2] = -1
    428  endif
    429  endfor
    430  extract /free idx, idx, idx >= 0
    431  variable nx = dimsize(data, 0)
    432  variable ny = numpnts(idx)
    433  theta = theta[idx]
    434  tilt = tilt[idx]
    435  phi = phi[idx]
    436  redimension /n=(ny) theta, tilt, phi
    437  duplicate /free data, data_copy
    438  redimension /n=(nx,ny) data
    439  data = data_copy[p][idx[q]]
    440 end
    441 
    453 static function do_norm_alpha(check, [force])
    454  variable check
    455  variable force
    456 
    457  if (ParamIsDefault(force))
    458  force = 0
    459  endif
    460 
    461  dfref saveDF = GetDataFolderDFR()
    462  dfref df = $(package_path)
    463  wave /sdfr=df process_data
    464  nvar /sdfr=df norm_alpha_enable
    465  nvar /sdfr=df norm_alpha_mode
    466  nvar /sdfr=df norm_alpha_smoothing
    467 
    468  if (force || norm_alpha_enable)
    469  dfref temp_df = newfreedatafolder()
    470  setdatafolder temp_df
    471  normalize_strip_x(process_data, smooth_method=norm_alpha_mode, smooth_factor=norm_alpha_smoothing, check=check)
    472  if (check)
    473  wave check_dist
    474  wave check_smoo
    475  duplicate /o check_dist, df:dist_x
    476  duplicate /o check_smoo, df:dist_x_smoo
    477  endif
    478  endif
    479 
    480  SetDataFolder saveDF
    481 end
    482 
    494 static function do_norm_phi(check, [force])
    495  variable check
    496  variable force
    497 
    498  if (ParamIsDefault(force))
    499  force = 0
    500  endif
    501 
    502  dfref saveDF = GetDataFolderDFR()
    503  dfref df = $(package_path)
    504  wave /sdfr=df process_data
    505  wave /sdfr=df process_theta
    506  wave /sdfr=df process_phi
    507  nvar /sdfr=df norm_phi_enable
    508  nvar /sdfr=df norm_phi_mode
    509  nvar /sdfr=df norm_phi_thetarange
    510 
    511  if (force || norm_phi_enable)
    512  dfref temp_df = newfreedatafolder()
    513  setdatafolder temp_df
    514  normalize_strip_phi(process_data, process_theta, process_phi, theta_range=norm_phi_thetarange, check=check)
    515  if (check)
    516  wave check_dist
    517  wave check_smoo
    518  duplicate /o check_dist, df:dist_y
    519  duplicate /o check_smoo, df:dist_y_smoo
    520  endif
    521  endif
    522 
    523  SetDataFolder saveDF
    524 end
    525 
    537 static function do_norm_theta(check, [force])
    538  variable check
    539  variable force
    540 
    541  if (ParamIsDefault(force))
    542  force = 0
    543  endif
    544 
    545  dfref saveDF = GetDataFolderDFR()
    546  dfref df = $(package_path)
    547  wave /sdfr=df process_data
    548  wave /sdfr=df process_theta
    549  nvar /sdfr=df norm_theta_enable
    550  nvar /sdfr=df norm_theta_mode
    551  nvar /sdfr=df norm_theta_domain
    552  nvar /sdfr=df norm_theta_smoothing
    553 
    554  if (force || norm_theta_enable)
    555  dfref temp_df = newfreedatafolder()
    556  setdatafolder temp_df
    557  if (norm_theta_domain==1)
    558  normalize_strip_theta_scans(process_data, process_theta, smooth_method=norm_theta_mode, smooth_factor=norm_theta_smoothing, check=check)
    559  else
    560  normalize_strip_theta(process_data, process_theta, smooth_method=norm_theta_mode, smooth_factor=norm_theta_smoothing, check=check)
    561  endif
    562  if (check)
    563  wave check_dist
    564  wave check_smoo
    565  duplicate /o check_dist, df:dist_y
    566  duplicate /o check_smoo, df:dist_y_smoo
    567  endif
    568  endif
    569 
    570  SetDataFolder saveDF
    571 end
    572 
    584 static function do_norm_thetaphi(check, [force])
    585  variable check
    586  variable force
    587 
    588  if (ParamIsDefault(force))
    589  force = 0
    590  endif
    591 
    592  dfref saveDF = GetDataFolderDFR()
    593  dfref df = $(package_path)
    594  wave /sdfr=df process_data
    595  wave /sdfr=df process_theta
    596  wave /sdfr=df process_phi
    597  nvar /sdfr=df norm_thetaphi_enable
    598  nvar /sdfr=df norm_thetaphi_mode
    599  nvar /sdfr=df norm_thetaphi_smoothing
    600 
    601  if (force || norm_thetaphi_enable)
    602  dfref temp_df = newfreedatafolder()
    603  setdatafolder temp_df
    604  normalize_strip_thetaphi(process_data, process_theta, process_phi, smooth_method=norm_thetaphi_mode, smooth_factor=norm_thetaphi_smoothing, check=check)
    605  if (check)
    606  wave check_dist
    607  wave check_smoo
    608  duplicate /o check_dist, df:dist_y
    609  duplicate /o check_smoo, df:dist_y_smoo
    610  endif
    611  endif
    612 
    613  SetDataFolder saveDF
    614 end
    615 
    621  dfref saveDF = GetDataFolderDFR()
    622  setdatafolder $(package_path)
    623 
    624  svar output_name
    625 
    626  wave process_data
    627  wave process_theta
    628  wave process_tilt
    629  wave process_phi
    630 
    631  nvar folding=output_folding
    632  nvar horizon=output_horizon
    633 
    634  do_init_process(0)
    635  do_crop(0)
    636  do_norm_alpha(0)
    637  do_norm_phi(0)
    638  do_norm_theta(0)
    640 
    641  pizza_service_2(process_data, output_name, process_theta, process_tilt, process_phi, folding=folding, nograph=1)
    642 
    643  setdatafolder $output_name
    644  wave values
    645  wave pol
    646  if (horizon > 0)
    647  values = pol <= horizon ? values : nan
    648  endif
    649 
    650  SetDataFolder saveDF
    651 end
    652 
    666 function /s asp_display_output([data_df, data_name])
    667  dfref data_df
    668  string data_name
    669 
    670  dfref pkg_df = $(package_path)
    671  svar /sdfr=pkg_df output_name
    672  svar /sdfr=pkg_df output_graphname
    673  nvar /sdfr=pkg_df graph_projection
    674  nvar /sdfr=pkg_df graph_mode
    675  svar /sdfr=pkg_df graph_colortable
    676  nvar /sdfr=pkg_df graph_contrast
    677 
    678  if (ParamIsDefault(data_df))
    679  dfref data_df = pkg_df
    680  endif
    681  if (ParamIsDefault(data_name))
    682  data_name = output_name
    683  endif
    684 
    685  dfref saveDF = GetDataFolderDFR()
    686  setdatafolder data_df
    687 
    688  if (graph_mode == 3)
    689  interpolate_hemi_scan(data_name, projection=graph_projection)
    690  endif
    691 
    692  string graphname = data_name
    693  graphname = display_hemi_scan(data_name, projection=graph_projection, graphtype=graph_mode, graphname=graphname)
    694  if (ParamIsDefault(data_df))
    695  output_graphname = graphname
    696  endif
    697  SetDataFolder saveDF
    698 
    699  if (strlen(graphname) && (wintype(graphname) == 1))
    700  set_contrast(graph_contrast, graph_contrast, graphname=graphname, colortable=graph_colortable)
    701  endif
    702 
    703  return graphname
    704 end
    705 
    711  dfref df = $(package_path)
    712 
    713  svar /sdfr=df preview_graphname
    714  svar /sdfr=df output_graphname
    715  svar /sdfr=df graph_colortable
    716  nvar /sdfr=df graph_contrast
    717 
    718  if (strlen(preview_graphname) && (wintype(preview_graphname) == 1))
    719  set_contrast(graph_contrast, graph_contrast, graphname=preview_graphname, colortable=graph_colortable)
    720  endif
    721  if (strlen(output_graphname) && (wintype(output_graphname) == 1))
    722  set_contrast(graph_contrast, graph_contrast, graphname=output_graphname, colortable=graph_colortable)
    723  endif
    724 end
    725 
    729  dfref df = $(package_path)
    730 
    731  svar /sdfr=df preview_graphname
    732  svar /sdfr=df output_graphname
    733  svar /sdfr=df dist_x_graphname
    734  svar /sdfr=df dist_y_graphname
    735 
    736  if (strlen(preview_graphname) && (wintype(preview_graphname) == 1))
    737  killwindow $preview_graphname
    738  endif
    739  if (strlen(output_graphname) && (wintype(output_graphname) == 1))
    740  killwindow $output_graphname
    741  endif
    742  if (strlen(dist_x_graphname) && (wintype(dist_x_graphname) == 1))
    743  killwindow $dist_x_graphname
    744  endif
    745  if (strlen(dist_y_graphname) && (wintype(dist_y_graphname) == 1))
    746  killwindow $dist_y_graphname
    747  endif
    748 
    749  preview_graphname = ""
    750  output_graphname = ""
    751  dist_x_graphname = ""
    752  dist_y_graphname = ""
    753 end
    754 
    768 function /s asp_duplicate_output(dest_name, [do_graph])
    769  string dest_name
    770  variable do_graph
    771 
    772  if (ParamIsDefault(do_graph))
    773  do_graph = 0
    774  endif
    775 
    776  dfref df = $(package_path)
    777  svar /sdfr=df source_path
    778  svar /sdfr=df output_name
    779  svar /sdfr=df output_graphname
    780  wave raw_data = $source_path
    781 
    782  dfref saveDF = GetDataFolderDFR()
    783  dfref raw_df = GetWavesDataFolderDFR(raw_data)
    784  setdatafolder raw_df
    785  newdatafolder /o /s $dest_name
    786  dfref dest_df = GetDataFolderDFR()
    787  setdatafolder df
    788  duplicate_hemi_scan(output_name, dest_df, "")
    789 
    790  string graphname = ""
    791  if (do_graph)
    792  graphname = asp_display_output(data_df=raw_df, data_name=dest_name)
    793  endif
    794 
    795  SetDataFolder saveDF
    796  return graphname
    797 end
    798 
    802  dfref df = $(package_path)
    803  svar /sdfr=df output_name
    804 
    805  dfref saveDF = GetDataFolderDFR()
    806  setdatafolder df
    807  save_hemi_scan(output_name, "", "")
    808 
    809  SetDataFolder saveDF
    810 end
    811 
    816 function asp_save_output_etpi(ekin)
    817  variable ekin
    818 
    819  dfref df = $(package_path)
    820  svar /sdfr=df output_name
    821  wave /sdfr=df process_data
    822 
    823  dfref saveDF = GetDataFolderDFR()
    824  setdatafolder df
    825  string s_prefix = ""
    826  string s_int = "values"
    827  dfref data_df = find_hemi_data(output_name, s_prefix, s_int)
    828  string s_polar = s_prefix + "pol"
    829  string s_azim = s_prefix + "az"
    830 
    831  pmsco_save_scan("", "", num2str(ekin), s_polar, s_azim, "", s_int, "", sdfr=data_df)
    832 
    833  SetDataFolder saveDF
    834 end
    835 
    836 static function check_norm_alpha()
    837  do_init_process(0)
    838  do_crop(0)
    839  do_norm_alpha(2, force=1)
    841 end
    842 
    843 static function check_norm_phi()
    844  do_init_process(0)
    845  do_crop(0)
    846  do_norm_phi(2, force=1)
    847  asp_display_dist_check(0, 1)
    848 end
    849 
    850 static function check_norm_theta()
    851  do_init_process(0)
    852  do_crop(0)
    853  do_norm_theta(2, force=1)
    854  asp_display_dist_check(0, 1)
    855 end
    856 
    857 static function check_norm_thetaphi()
    858  do_init_process(0)
    859  do_crop(0)
    860  do_norm_thetaphi(2, force=1)
    861  asp_display_dist_check(0, 1)
    862 end
    863 
    864 static function preview_crop()
    865  do_init_process(0)
    866  do_crop(0, force=1)
    868 end
    869 
    870 static function preview_norm_alpha()
    871  do_init_process(0)
    872  do_crop(0)
    873  do_norm_alpha(1, force=1)
    875 end
    876 
    877 static function preview_norm_phi()
    878  do_init_process(0)
    879  do_crop(0)
    880  do_norm_phi(1, force=1)
    882 end
    883 
    884 static function preview_norm_theta()
    885  do_init_process(0)
    886  do_crop(0)
    887  do_norm_theta(1, force=1)
    889 end
    890 
    891 static function preview_norm_thetaphi()
    892  do_init_process(0)
    893  do_crop(0)
    894  do_norm_thetaphi(1, force=1)
    896 end
    897 
    900 function asp_show_panel()
    901  dfref df = $(package_path)
    902  svar /sdfr=df panel_name
    903 
    904  if (strlen(panel_name) && (wintype(panel_name) == 7))
    905  DoWindow /F $panel_name
    906  return 0
    907  endif
    908 
    909  NewPanel /K=1 /N=anglescan_panel /W=(200,50,480,874) as "angle scan processing"
    910  panel_name = s_name
    911 
    912  GroupBox gb_source, title="data source"
    913  Button b_source_select, size={50,20},proc=PearlAnglescanPanel#bp_source_select,title="select..."
    914  Button b_source_select, help={"select the source wave, e.g. ReducedData1. it must be in the scan or region data folder. the attr folder with the manipulator waves must be in the same folder or one level up."}
    915  Button b_source_update, size={50,20},proc=PearlAnglescanPanel#bp_source_update,title="update"
    916  Button b_source_update, help={"reload the process data from the previous source (link displayed below)"}
    917  TitleBox tb_source_path, size={240,21}
    918  TitleBox tb_source_path,variable= root:packages:pearl_anglescan_panel:source_path
    919 
    920  GroupBox gb_offsets, title="offsets"
    921  SetVariable sv_theta_offset, size={88,16},bodyWidth=60,title="theta"
    922  SetVariable sv_theta_offset,value= root:packages:pearl_anglescan_panel:theta_offset
    923  SetVariable sv_theta_offset, help={"manipulator theta value that corresponds to normal emission."}
    924  SetVariable sv_tilt_offset, size={74,16},bodyWidth=60,title="tilt"
    925  SetVariable sv_tilt_offset,value= root:packages:pearl_anglescan_panel:tilt_offset
    926  SetVariable sv_tilt_offset, help={"manipulator tilt value that corresponds to normal emission."}
    927  SetVariable sv_phi_offset, size={78,16},bodyWidth=60,title="phi"
    928  SetVariable sv_phi_offset,value= root:packages:pearl_anglescan_panel:phi_offset
    929  SetVariable sv_phi_offset, help={"manipulator phi value that should map to the 3 o'clock angle."}
    930  SetVariable sv_alpha_offset, size={90,16},bodyWidth=60,title="alpha"
    931  SetVariable sv_alpha_offset,value= root:packages:pearl_anglescan_panel:alpha_offset
    932  SetVariable sv_alpha_offset, help={"alpha value that corresponds to normal emission (if the sample normal is properly aligned)."}
    933  Button b_save_prefs, size={80,20},proc=PearlAnglescanPanel#bp_save_prefs,title="save prefs"
    934  Button b_save_prefs, help={"save settings as preferences."}
    935  Button b_load_prefs, size={80,20},proc=PearlAnglescanPanel#bp_load_prefs,title="load prefs"
    936  Button b_load_prefs, help={"load settings from preferences."}
    937 
    938  GroupBox gb_crop, title="crop and delete"
    939  CheckBox cb_crop_enable, size={50,14}, title="enable"
    940  CheckBox cb_crop_enable, help={"crop at +/-alpha and +theta, delete arbitrary rows"}
    941  CheckBox cb_crop_enable, variable= root:packages:pearl_anglescan_panel:crop_enable
    942  SetVariable sv_crop_alpha, size={90,16},bodyWidth=60,title="alpha"
    943  SetVariable sv_crop_alpha, limits={0,30,1},value= root:packages:pearl_anglescan_panel:crop_alpha
    944  SetVariable sv_crop_alpha, help={"alpha (detection angle) cropping angle (positive boundary), relative to normal emission"}
    945  SetVariable sv_crop_theta, size={90,16},bodyWidth=60,title="theta"
    946  SetVariable sv_crop_theta, limits={10,90,1},value= root:packages:pearl_anglescan_panel:crop_theta
    947  SetVariable sv_crop_theta, help={"theta (polar angle) upper limit, relative to normal emission"}
    948  SetVariable sv_crop_rows, size={200,16},bodyWidth=160,title="rows"
    949  SetVariable sv_crop_rows, limits={10,90,1},value= root:packages:pearl_anglescan_panel:crop_rows
    950  SetVariable sv_crop_rows, help={"rows to delete from the raw data. comma-separated point indices, hyphen for range."}
    951  Button b_crop_preview, size={80,20},proc=PearlAnglescanPanel#bp_crop_preview,title="preview"
    952  Button b_crop_preview, help={"show a preview of the cropped dataset."}
    953 
    954  GroupBox gb_norm_alpha, title="normalize alpha"
    955  CheckBox cb_norm_alpha_enable, size={50,14}, title="enable"
    956  CheckBox cb_norm_alpha_enable,variable= root:packages:pearl_anglescan_panel:norm_alpha_enable
    957  CheckBox cb_norm_alpha_enable, help={"enable normalization of the alpha distribution"}
    958  PopupMenu pm_norm_alpha_mode, size={138,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_norm_alpha_mode,title="method"
    959  PopupMenu pm_norm_alpha_mode, mode=5, popvalue="loess", value= #"\"none;binomial;boxcar;scienta;loess;\""
    960  PopupMenu pm_norm_alpha_mode, help={"alpha normalization method. recommended: loess"}
    961  SetVariable sv_norm_alpha_smoothing, size={112,16}, bodyWidth=60, title="smoothing"
    962  SetVariable sv_norm_alpha_smoothing, limits={0,1,0.05}, value= root:packages:pearl_anglescan_panel:norm_alpha_smoothing
    963  SetVariable sv_norm_alpha_smoothing, help={"smoothing parameter (depends on the normalization method)."}
    964  Button b_norm_alpha_check, size={80,20}, proc=PearlAnglescanPanel#bp_norm_alpha_check,title="check"
    965  Button b_norm_alpha_check, help={"show a graph of the normalization function"}
    966  Button b_norm_alpha_preview, size={80,20}, proc=PearlAnglescanPanel#bp_norm_alpha_preview,title="preview"
    967  Button b_norm_alpha_preview, help={"show a preview of the normalized dataset (without other normalizations)."}
    968 
    969  GroupBox gb_norm_phi, title="normalize phi"
    970  CheckBox cb_norm_phi_enable, size={50,14}, title="enable"
    971  CheckBox cb_norm_phi_enable,variable= root:packages:pearl_anglescan_panel:norm_phi_enable
    972  CheckBox cb_norm_phi_enable, help={"enable normalization of the phi distribution to reduce the effect of wobble"}
    973  SetVariable sv_norm_phi_range, size={118,16}, bodyWidth=60, title="theta range"
    974  SetVariable sv_norm_phi_range, limits={0,90,1}, value= root:packages:pearl_anglescan_panel:norm_phi_thetarange
    975  SetVariable sv_norm_phi_range, help={"theta range (from normal) to factor into the normalization function"}
    976  Button b_norm_phi_check, size={80,20}, proc=PearlAnglescanPanel#bp_norm_phi_check, title="check"
    977  Button b_norm_phi_check, help={"show a graph of the normalization function"}
    978  Button b_norm_phi_preview, size={80,20}, proc=PearlAnglescanPanel#bp_norm_phi_preview, title="preview"
    979  Button b_norm_phi_preview, help={"show a preview of the normalized dataset (without other normalizations)."}
    980 
    981  GroupBox gb_norm_theta, title="normalize theta"
    982  CheckBox cb_norm_theta_enable, size={50,14},title="enable"
    983  CheckBox cb_norm_theta_enable, variable= root:packages:pearl_anglescan_panel:norm_theta_enable
    984  CheckBox cb_norm_theta_enable, help={"enable normalization of the theta distribution (integrated over phi)"}
    985  PopupMenu pm_norm_theta_domain, size={138,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_norm_theta_domain, title="domain"
    986  PopupMenu pm_norm_theta_domain, mode=5, popvalue="loess", value= #"\"global;scans;\""
    987  PopupMenu pm_norm_theta_domain, help={"smoothing domain: global or individual scans. use global unless there is a stronga or irregular phi variation."}
    988  PopupMenu pm_norm_theta_mode, size={138,21},bodyWidth=100,proc=PearlAnglescanPanel#pmp_norm_theta_mode,title="method"
    989  PopupMenu pm_norm_theta_mode,mode=5,popvalue="loess",value= #"\"none;binomial;boxcar;polynomial;loess;\""
    990  PopupMenu pm_norm_theta_mode, help={"theta normalization method. recommended: loess"}
    991  SetVariable sv_norm_theta_smoothing, size={112,16}, bodyWidth=60, title="smoothing"
    992  SetVariable sv_norm_theta_smoothing, limits={0,1,0.05}, value= root:packages:pearl_anglescan_panel:norm_theta_smoothing
    993  SetVariable sv_norm_theta_smoothing, help={"smoothing parameter (depends on the normalization method)."}
    994  Button b_norm_theta_check, size={80,20}, proc=PearlAnglescanPanel#bp_norm_theta_check, title="check"
    995  Button b_norm_theta_check, help={"show a graph of the normalization function"}
    996  Button b_norm_theta_preview, size={80,20}, proc=PearlAnglescanPanel#bp_norm_theta_preview, title="preview"
    997  Button b_norm_theta_preview, help={"show a preview of the normalized dataset (without other normalizations)."}
    998 
    999  GroupBox gb_norm_thetaphi, size={272,97},title="normalize (theta,phi)"
    1000  CheckBox cb_norm_thetaphi_enable, size={50,14},title="enable"
    1001  CheckBox cb_norm_thetaphi_enable, variable= root:packages:pearl_anglescan_panel:norm_thetaphi_enable
    1002  CheckBox cb_norm_thetaphi_enable, help={"enable normalization of the (theta, phi) distribution."}
    1003  PopupMenu pm_norm_thetaphi_mode, size={138,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_norm_thetaphi_mode,title="method"
    1004  PopupMenu pm_norm_thetaphi_mode, mode=5, popvalue="loess", value= #"\"none;none;none;none;loess;\""
    1005  PopupMenu pm_norm_thetaphi_mode, help={"theta normalization method. recommended: loess"}
    1006  SetVariable sv_norm_thetaphi_smoothing, size={112,16}, bodyWidth=60, title="smoothing"
    1007  SetVariable sv_norm_thetaphi_smoothing, limits={0,1,0.05}, value= root:packages:pearl_anglescan_panel:norm_thetaphi_smoothing
    1008  SetVariable sv_norm_thetaphi_smoothing, help={"smoothing parameter (depends on the normalization method)."}
    1009  Button b_norm_thetaphi_check, size={80,20}, proc=PearlAnglescanPanel#bp_norm_thetaphi_check, title="check"
    1010  Button b_norm_thetaphi_check, help={"show a graph of the normalization function"}
    1011  Button b_norm_thetaphi_preview, size={80,20}, proc=PearlAnglescanPanel#bp_norm_thetaphi_preview, title="preview"
    1012  Button b_norm_thetaphi_preview, help={"show a preview of the normalized dataset (without other normalizations)."}
    1013 
    1014  GroupBox gb_output, title="output"
    1015  SetVariable sv_output_folding, size={95,16}, bodyWidth=60, title="folding"
    1016  SetVariable sv_output_folding, limits={1,20,1}, value= root:packages:pearl_anglescan_panel:output_folding
    1017  SetVariable sv_output_folding, help={"n-fold rotational average. 1=no averaging."}
    1018  SetVariable sv_output_horizon, size={98,16}, bodyWidth=60, title="horizon"
    1019  SetVariable sv_output_horizon, limits={1,90,1}, value= root:packages:pearl_anglescan_panel:output_horizon
    1020  SetVariable sv_output_horizon, help={"highest theta to display"}
    1021  PopupMenu pm_graph_projection, size={149,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_graph_projection, title="projection"
    1022  PopupMenu pm_graph_projection, mode=2, popvalue="stereographic", value= #"\"equidistant;stereographic;equal area;gnomonic;orthographic;\""
    1023  PopupMenu pm_graph_projection, help={"projection (theta mapping) mode"}
    1024  PopupMenu pm_graph_mode, size={129,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_graph_mode,title="mode"
    1025  PopupMenu pm_graph_mode, mode=2, popvalue="dots", value= #"\"none;dots;none;image;\""
    1026  PopupMenu pm_graph_mode, help={"graph type: dots = coloured dots on circles; image = interpolated matrix"}
    1027  Button b_output_calc, size={80,20}, proc=PearlAnglescanPanel#bp_output_calc, title="calc + display"
    1028  Button b_output_calc, help={"execute data processing with the enabled filters and display the diffractogram."}
    1029  Button b_output_duplicate, size={80,20}, proc=PearlAnglescanPanel#bp_output_duplicate, title="duplicate ..."
    1030  Button b_output_duplicate, help={"copy the result to an arbitrary data folder."}
    1031  Button b_output_itx, size={80,20}, proc=PearlAnglescanPanel#bp_output_itx, title="save ITX ..."
    1032  Button b_output_itx, help={"save the result to an igor text file (itx)."}
    1033  Button b_output_etpi, size={80,20}, proc=PearlAnglescanPanel#bp_output_etpi, title="save ETPI ..."
    1034  Button b_output_etpi, help={"save the result to a pmsco angle scan file (etpi)."}
    1035 
    1036  GroupBox gb_graph, title="graph"
    1037  PopupMenu pm_graph_colortable, size={152,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_graph_colortable, title="color table"
    1038  PopupMenu pm_graph_colortable, mode=0, value= #"\"*COLORTABLEPOPNONAMES*\""
    1039  PopupMenu pm_graph_colortable, help={"color table to use in pseudocolor graphs."}
    1040  SetVariable sv_graph_contrast, size={119,16}, bodyWidth=60, title="contrast (%)"
    1041  SetVariable sv_graph_contrast, limits={0,25,1}, value= root:packages:pearl_anglescan_panel:graph_contrast
    1042  SetVariable sv_graph_contrast, help={"contrast value (percentile)."}
    1043  Button b_graph_update, size={80,20}, proc=PearlAnglescanPanel#bp_graph_update, title="update"
    1044  Button b_graph_update, help={"update the existing graph."}
    1045  Button b_graph_png, size={80,20}, proc=PearlAnglescanPanel#bp_graph_png, title="save PNG ..."
    1046  Button b_graph_png, help={"save the graph in png format."}
    1047 
    1049  update_menus()
    1050 end
    1051 
    1052 static function arrange_controls()
    1053  dfref df = $(package_path)
    1054  svar /sdfr=df panel_name
    1055 
    1056  variable gb_space = 2
    1057  variable gb_internal_top = 16
    1058  variable gb_internal_bot = 4
    1059  variable line_space = 22
    1060 
    1061  variable cb_adj = 2
    1062  variable sv_adj = 2
    1063  variable pm_adj = 0
    1064  variable b_adj = 0
    1065  variable tb_adj = 0
    1066 
    1067  variable gb_top = 4
    1068  variable gb_ht = 0
    1069 
    1070  // ht = line + 30
    1071  // gb = gb + ht + 2
    1072  // cb = gb + 18
    1073  // pm = gb + 38
    1074  // line += 26
    1075  // sv = line + 2
    1076 
    1077  GroupBox gb_source,pos={4,gb_top}
    1078  gb_ht = gb_internal_top
    1079  Button b_source_select,pos={17, gb_top + gb_ht + b_adj},size={50,20}
    1080  Button b_source_update, pos={67, gb_top + gb_ht + b_adj},size={50,20}
    1081  gb_ht += line_space
    1082  TitleBox tb_source_path,pos={18, gb_top + gb_ht + tb_adj},size={240,21}
    1083  gb_ht += line_space
    1084  gb_ht += gb_internal_bot
    1085  GroupBox gb_source, size={272,gb_ht}
    1086 
    1087  gb_top += gb_ht + gb_space
    1088  GroupBox gb_offsets,pos={4,gb_top}
    1089  gb_ht = gb_internal_top
    1090  SetVariable sv_theta_offset,pos={46, gb_top + gb_ht + sv_adj},size={88,16}
    1091  Button b_save_prefs,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1092  gb_ht += line_space
    1093  SetVariable sv_tilt_offset,pos={60, gb_top + gb_ht + sv_adj},size={74,16}
    1094  Button b_load_prefs,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1095  gb_ht += line_space
    1096  SetVariable sv_phi_offset,pos={56, gb_top + gb_ht + sv_adj},size={78,16}
    1097  gb_ht += line_space
    1098  SetVariable sv_alpha_offset,pos={44, gb_top + gb_ht + sv_adj},size={90,16}
    1099  gb_ht += line_space
    1100  gb_ht += gb_internal_bot
    1101  GroupBox gb_offsets, size={272,gb_ht}
    1102 
    1103  gb_top += gb_ht + gb_space
    1104  GroupBox gb_crop,pos={4,gb_top}
    1105  gb_ht = gb_internal_top
    1106  CheckBox cb_crop_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    1107  gb_ht += line_space
    1108  SetVariable sv_crop_alpha, pos={44, gb_top + gb_ht + sv_adj}, size={90,16}
    1109  Button b_crop_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1110  gb_ht += line_space
    1111  SetVariable sv_crop_theta, pos={44, gb_top + gb_ht + sv_adj}, size={90,16}
    1112  gb_ht += line_space
    1113  SetVariable sv_crop_rows, pos={44, gb_top + gb_ht + sv_adj}, size={190,16}
    1114  gb_ht += line_space
    1115  gb_ht += gb_internal_bot
    1116  GroupBox gb_crop, size={272,gb_ht}
    1117 
    1118  gb_top += gb_ht + gb_space
    1119  GroupBox gb_norm_alpha,pos={4,gb_top}
    1120  gb_ht = gb_internal_top
    1121  CheckBox cb_norm_alpha_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    1122  gb_ht += line_space
    1123  PopupMenu pm_norm_alpha_mode,pos={36, gb_top + gb_ht + pm_adj},size={138,21}
    1124  Button b_norm_alpha_check,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1125  gb_ht += line_space
    1126  SetVariable sv_norm_alpha_smoothing,pos={22, gb_top + gb_ht + sv_adj},size={112,16}
    1127  Button b_norm_alpha_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1128  gb_ht += line_space
    1129  gb_ht += gb_internal_bot
    1130  GroupBox gb_norm_alpha, size={272,gb_ht}
    1131 
    1132  gb_top += gb_ht + gb_space
    1133  GroupBox gb_norm_phi,pos={4,gb_top}
    1134  gb_ht = gb_internal_top
    1135  CheckBox cb_norm_phi_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    1136  Button b_norm_phi_check,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1137  gb_ht += line_space
    1138  SetVariable sv_norm_phi_range,pos={15, gb_top + gb_ht + sv_adj},size={118,16}
    1139  Button b_norm_phi_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1140  gb_ht += line_space
    1141  gb_ht += gb_internal_bot
    1142  GroupBox gb_norm_phi, size={272,gb_ht}
    1143 
    1144  gb_top += gb_ht + gb_space
    1145  GroupBox gb_norm_theta,pos={4,gb_top}
    1146  gb_ht = gb_internal_top
    1147  CheckBox cb_norm_theta_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    1148  gb_ht += line_space
    1149  PopupMenu pm_norm_theta_domain, pos={35, gb_top + gb_ht + pm_adj}, size={138,21}
    1150  Button b_norm_theta_check,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1151  gb_ht += line_space
    1152  PopupMenu pm_norm_theta_mode,pos={35, gb_top + gb_ht + pm_adj},size={138,21}
    1153  Button b_norm_theta_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1154  gb_ht += line_space
    1155  SetVariable sv_norm_theta_smoothing,pos={21, gb_top + gb_ht + sv_adj},size={112,16}
    1156  gb_ht += line_space
    1157  gb_ht += gb_internal_bot
    1158  GroupBox gb_norm_theta, size={272,gb_ht}
    1159 
    1160  gb_top += gb_ht + gb_space
    1161  GroupBox gb_norm_thetaphi,pos={4,gb_top}
    1162  gb_ht = gb_internal_top
    1163  CheckBox cb_norm_thetaphi_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    1164  gb_ht += line_space
    1165  PopupMenu pm_norm_thetaphi_mode,pos={35, gb_top + gb_ht + pm_adj},size={138,21}
    1166  Button b_norm_thetaphi_check,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1167  gb_ht += line_space
    1168  SetVariable sv_norm_thetaphi_smoothing,pos={21, gb_top + gb_ht + sv_adj},size={112,16}
    1169  Button b_norm_thetaphi_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1170  gb_ht += line_space
    1171  gb_ht += gb_internal_bot
    1172  GroupBox gb_norm_thetaphi, size={272,gb_ht}
    1173 
    1174  gb_top += gb_ht + gb_space
    1175  GroupBox gb_output,pos={4,gb_top}
    1176  gb_ht = gb_internal_top
    1177  SetVariable sv_output_folding,pos={38, gb_top + gb_ht + sv_adj},size={95,16}
    1178  Button b_output_calc,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1179  gb_ht += line_space
    1180  SetVariable sv_output_horizon,pos={35, gb_top + gb_ht + sv_adj},size={98,16}
    1181  Button b_output_duplicate,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1182  gb_ht += line_space
    1183  PopupMenu pm_graph_projection,pos={24, gb_top + gb_ht + pm_adj},size={149,21}
    1184  Button b_output_itx,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1185  gb_ht += line_space
    1186  PopupMenu pm_graph_mode,pos={44, gb_top + gb_ht + pm_adj},size={129,21}
    1187  Button b_output_etpi,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1188  gb_ht += line_space
    1189  gb_ht += gb_internal_bot
    1190  GroupBox gb_output, size={272,gb_ht}
    1191 
    1192  gb_top += gb_ht + gb_space
    1193  GroupBox gb_graph,pos={4,gb_top}
    1194  gb_ht = gb_internal_top
    1195  PopupMenu pm_graph_colortable,pos={21, gb_top + gb_ht + pm_adj},size={152,21}
    1196  Button b_graph_update,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1197  gb_ht += line_space
    1198  SetVariable sv_graph_contrast,pos={14, gb_top + gb_ht + sv_adj},size={119,16}
    1199  Button b_graph_png,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    1200  gb_ht += line_space
    1201  gb_ht += gb_internal_bot
    1202  GroupBox gb_graph, size={272,gb_ht}
    1203 
    1204  gb_top += gb_ht + gb_space
    1205  //MoveWindow 200, 100, 479, 100 + gb_top
    1206 end
    1207 
    1210 static function update_menus()
    1211  dfref df = $(package_path)
    1212  svar /sdfr=df panel_name
    1213  if (wintype(panel_name) == 7)
    1214  variable m
    1215  nvar /sdfr=df norm_alpha_mode
    1216  m = norm_alpha_mode + 1
    1217  PopupMenu pm_norm_alpha_mode win=$panel_name, mode=m
    1218  nvar /sdfr=df norm_theta_domain
    1219  m = norm_theta_domain + 1
    1220  PopupMenu pm_norm_theta_domain win=$panel_name, mode=m
    1221  nvar /sdfr=df norm_theta_mode
    1222  m = norm_theta_mode + 1
    1223  PopupMenu pm_norm_theta_mode win=$panel_name, mode=m
    1224  nvar /sdfr=df norm_thetaphi_mode
    1225  m = norm_thetaphi_mode + 1
    1226  PopupMenu pm_norm_thetaphi_mode win=$panel_name, mode=m
    1227  nvar /sdfr=df graph_mode
    1228  m = graph_mode + 1
    1229  PopupMenu pm_graph_mode win=$panel_name, mode=m
    1230  nvar /sdfr=df graph_projection
    1231  m = graph_projection + 1
    1232  PopupMenu pm_graph_projection win=$panel_name, mode=m
    1233  svar /sdfr=df graph_colortable
    1234  m = 1 + WhichListItem(graph_colortable, CTabList())
    1235  PopupMenu pm_graph_colortable win=$panel_name, mode=m
    1236  endif
    1237 end
    1238 
    1239 static function bp_load_prefs(ba) : ButtonControl
    1240  STRUCT WMButtonAction &ba
    1241 
    1242  switch( ba.eventCode )
    1243  case 2: // mouse up
    1244  load_prefs()
    1245  break
    1246  case -1: // control being killed
    1247  break
    1248  endswitch
    1249 
    1250  return 0
    1251 End
    1252 
    1253 static function bp_save_prefs(ba) : ButtonControl
    1254  STRUCT WMButtonAction &ba
    1255 
    1256  switch( ba.eventCode )
    1257  case 2: // mouse up
    1258  save_prefs()
    1259  break
    1260  case -1: // control being killed
    1261  break
    1262  endswitch
    1263 
    1264  return 0
    1265 End
    1266 
    1267 static function bp_source_select(ba) : ButtonControl
    1268  STRUCT WMButtonAction &ba
    1269 
    1270  switch( ba.eventCode )
    1271  case 2: // mouse up
    1272  dfref dfBefore = GetDataFolderDFR()
    1273  Execute /q/z "CreateBrowser prompt=\"Select 2D holo scan wave\", showWaves=1, showVars=0, showStrs=0"
    1274  dfref dfAfter = GetDataFolderDFR()
    1275  SetDataFolder dfBefore
    1276 
    1277  SVAR list = S_BrowserList
    1278  NVAR flag = V_Flag
    1279  if ((flag != 0) && (ItemsInList(list) >= 1))
    1280  string wname = StringFromList(0, list)
    1281  wave w = $wname
    1282  asp_import_raw(w)
    1283  endif
    1284 
    1285  break
    1286  case -1: // control being killed
    1287  break
    1288  endswitch
    1289 
    1290  return 0
    1291 End
    1292 
    1293 static function bp_source_update(ba) : ButtonControl
    1294  STRUCT WMButtonAction &ba
    1295 
    1296  switch( ba.eventCode )
    1297  case 2: // mouse up
    1298  dfref packdf = $package_path
    1299  svar /sdfr=packdf source_path
    1300  wave /z w = $source_path
    1301  if (waveexists(w))
    1302  asp_import_raw(w)
    1303  else
    1304  DoAlert 0, "can't find source data."
    1305  endif
    1306  break
    1307  case -1: // control being killed
    1308  break
    1309  endswitch
    1310 
    1311  return 0
    1312 End
    1313 
    1314 static function bp_norm_alpha_check(ba) : ButtonControl
    1315  STRUCT WMButtonAction &ba
    1316 
    1317  switch( ba.eventCode )
    1318  case 2: // mouse up
    1320  break
    1321  case -1: // control being killed
    1322  break
    1323  endswitch
    1324 
    1325  return 0
    1326 End
    1327 
    1328 static function bp_norm_theta_check(ba) : ButtonControl
    1329  STRUCT WMButtonAction &ba
    1330 
    1331  switch( ba.eventCode )
    1332  case 2: // mouse up
    1334  break
    1335  case -1: // control being killed
    1336  break
    1337  endswitch
    1338 
    1339  return 0
    1340 End
    1341 
    1342 static function bp_norm_phi_check(ba) : ButtonControl
    1343  STRUCT WMButtonAction &ba
    1344 
    1345  switch( ba.eventCode )
    1346  case 2: // mouse up
    1347  check_norm_phi()
    1348  break
    1349  case -1: // control being killed
    1350  break
    1351  endswitch
    1352 
    1353  return 0
    1354 End
    1355 
    1356 static function bp_norm_thetaphi_check(ba) : ButtonControl
    1357  STRUCT WMButtonAction &ba
    1358 
    1359  switch( ba.eventCode )
    1360  case 2: // mouse up
    1362  break
    1363  case -1: // control being killed
    1364  break
    1365  endswitch
    1366 
    1367  return 0
    1368 End
    1369 
    1370 static function bp_crop_preview(ba) : ButtonControl
    1371  STRUCT WMButtonAction &ba
    1372 
    1373  switch( ba.eventCode )
    1374  case 2: // mouse up
    1375  preview_crop()
    1376  break
    1377  case -1: // control being killed
    1378  break
    1379  endswitch
    1380 
    1381  return 0
    1382 End
    1383 
    1384 static function bp_norm_alpha_preview(ba) : ButtonControl
    1385  STRUCT WMButtonAction &ba
    1386 
    1387  switch( ba.eventCode )
    1388  case 2: // mouse up
    1390  break
    1391  case -1: // control being killed
    1392  break
    1393  endswitch
    1394 
    1395  return 0
    1396 End
    1397 
    1398 static function bp_norm_phi_preview(ba) : ButtonControl
    1399  STRUCT WMButtonAction &ba
    1400 
    1401  switch( ba.eventCode )
    1402  case 2: // mouse up
    1404  break
    1405  case -1: // control being killed
    1406  break
    1407  endswitch
    1408 
    1409  return 0
    1410 End
    1411 
    1412 static function bp_norm_theta_preview(ba) : ButtonControl
    1413  STRUCT WMButtonAction &ba
    1414 
    1415  switch( ba.eventCode )
    1416  case 2: // mouse up
    1418  break
    1419  case -1: // control being killed
    1420  break
    1421  endswitch
    1422 
    1423  return 0
    1424 End
    1425 
    1426 static function bp_norm_thetaphi_preview(ba) : ButtonControl
    1427  STRUCT WMButtonAction &ba
    1428 
    1429  switch( ba.eventCode )
    1430  case 2: // mouse up
    1432  break
    1433  case -1: // control being killed
    1434  break
    1435  endswitch
    1436 
    1437  return 0
    1438 End
    1439 
    1440 static function bp_output_calc(ba) : ButtonControl
    1441  STRUCT WMButtonAction &ba
    1442 
    1443  switch( ba.eventCode )
    1444  case 2: // mouse up
    1447  break
    1448  case -1: // control being killed
    1449  break
    1450  endswitch
    1451 
    1452  return 0
    1453 End
    1454 
    1455 static function bp_output_duplicate(ba) : ButtonControl
    1456  STRUCT WMButtonAction &ba
    1457 
    1458  switch( ba.eventCode )
    1459  case 2: // mouse up
    1460  string dest_folder
    1461  variable do_graph = 1
    1462  prompt dest_folder, "destination folder name (relative to data source)"
    1463  prompt do_graph, "duplicate graph (yes = 1, no = 0)"
    1464  doprompt "duplicate", dest_folder, do_graph
    1465  if (!v_flag)
    1466  asp_duplicate_output(dest_folder, do_graph=do_graph)
    1467  endif
    1468  break
    1469  case -1: // control being killed
    1470  break
    1471  endswitch
    1472 
    1473  return 0
    1474 End
    1475 
    1476 static function bp_output_etpi(ba) : ButtonControl
    1477  STRUCT WMButtonAction &ba
    1478 
    1479  switch( ba.eventCode )
    1480  case 2: // mouse up
    1481  dfref df = $(package_path)
    1482  wave /sdfr=df process_data
    1483  variable ekin
    1484  ekin = NumberByKey("KineticEnergy", note(process_data), "=", "\r")
    1485  prompt ekin, "kinetic energy"
    1486  doprompt "save etpi", ekin
    1487  if (!v_flag)
    1488  asp_save_output_etpi(ekin)
    1489  endif
    1490  break
    1491  case -1: // control being killed
    1492  break
    1493  endswitch
    1494 
    1495  return 0
    1496 End
    1497 
    1498 static function bp_output_itx(ba) : ButtonControl
    1499  STRUCT WMButtonAction &ba
    1500 
    1501  switch( ba.eventCode )
    1502  case 2: // mouse up
    1504  break
    1505  case -1: // control being killed
    1506  break
    1507  endswitch
    1508 
    1509  return 0
    1510 End
    1511 
    1512 static function bp_graph_update(ba) : ButtonControl
    1513  STRUCT WMButtonAction &ba
    1514 
    1515  switch( ba.eventCode )
    1516  case 2: // mouse up
    1518  break
    1519  case -1: // control being killed
    1520  break
    1521  endswitch
    1522 
    1523  return 0
    1524 End
    1525 
    1526 static function bp_graph_png(ba) : ButtonControl
    1527  STRUCT WMButtonAction &ba
    1528 
    1529  switch( ba.eventCode )
    1530  case 2: // mouse up
    1531  dfref df = $(package_path)
    1532  svar /sdfr=df source_path
    1533  svar /sdfr=df output_graphname
    1534  if (WinType(output_graphname) == 1)
    1535  SavePICT /WIN=$output_graphname /E=-5 /B=144 /TRAN=0
    1536  endif
    1537  break
    1538  case -1: // control being killed
    1539  break
    1540  endswitch
    1541 
    1542  return 0
    1543 End
    1544 
    1545 static function pmp_norm_alpha_mode(pa) : PopupMenuControl
    1546  STRUCT WMPopupAction &pa
    1547 
    1548  switch( pa.eventCode )
    1549  case 2: // mouse up
    1550  dfref df = $(package_path)
    1551  nvar /sdfr=df norm_alpha_mode
    1552  norm_alpha_mode = pa.popNum - 1
    1553  break
    1554  case -1: // control being killed
    1555  break
    1556  endswitch
    1557 
    1558  return 0
    1559 End
    1560 
    1561 static function pmp_norm_theta_domain(pa) : PopupMenuControl
    1562  STRUCT WMPopupAction &pa
    1563 
    1564  switch( pa.eventCode )
    1565  case 2: // mouse up
    1566  dfref df = $(package_path)
    1567  nvar /sdfr=df norm_theta_domain
    1568  norm_theta_domain = pa.popNum - 1
    1569  break
    1570  case -1: // control being killed
    1571  break
    1572  endswitch
    1573 
    1574  return 0
    1575 End
    1576 
    1577 static function pmp_norm_theta_mode(pa) : PopupMenuControl
    1578  STRUCT WMPopupAction &pa
    1579 
    1580  switch( pa.eventCode )
    1581  case 2: // mouse up
    1582  dfref df = $(package_path)
    1583  nvar /sdfr=df norm_theta_mode
    1584  norm_theta_mode = pa.popNum - 1
    1585  break
    1586  case -1: // control being killed
    1587  break
    1588  endswitch
    1589 
    1590  return 0
    1591 End
    1592 
    1593 static function pmp_norm_thetaphi_mode(pa) : PopupMenuControl
    1594  STRUCT WMPopupAction &pa
    1595 
    1596  switch( pa.eventCode )
    1597  case 2: // mouse up
    1598  dfref df = $(package_path)
    1599  nvar /sdfr=df norm_thetaphi_mode
    1600  norm_thetaphi_mode = pa.popNum - 1
    1601  break
    1602  case -1: // control being killed
    1603  break
    1604  endswitch
    1605 
    1606  return 0
    1607 End
    1608 
    1609 static function pmp_graph_mode(pa) : PopupMenuControl
    1610  STRUCT WMPopupAction &pa
    1611 
    1612  switch( pa.eventCode )
    1613  case 2: // mouse up
    1614  dfref df = $(package_path)
    1615  nvar /sdfr=df graph_mode
    1616  graph_mode = pa.popNum - 1
    1617  break
    1618  case -1: // control being killed
    1619  break
    1620  endswitch
    1621 
    1622  return 0
    1623 End
    1624 
    1625 static function pmp_graph_projection(pa) : PopupMenuControl
    1626  STRUCT WMPopupAction &pa
    1627 
    1628  switch( pa.eventCode )
    1629  case 2: // mouse up
    1630  dfref df = $(package_path)
    1631  nvar /sdfr=df graph_projection
    1632  graph_projection = pa.popNum - 1
    1633  break
    1634  case -1: // control being killed
    1635  break
    1636  endswitch
    1637 
    1638  return 0
    1639 End
    1640 
    1641 static function pmp_graph_colortable(pa) : PopupMenuControl
    1642  STRUCT WMPopupAction &pa
    1643 
    1644  switch( pa.eventCode )
    1645  case 2: // mouse up
    1646  dfref df = $(package_path)
    1647  svar /sdfr=df graph_colortable
    1648  graph_colortable = StringFromList(pa.popNum - 1, CTabList())
    1650  break
    1651  case -1: // control being killed
    1652  break
    1653  endswitch
    1654 
    1655  return 0
    1656 End
    static variable bp_norm_phi_preview(WMButtonAction *ba)
    -
    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
    -
    variable normalize_strip_theta(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by the average polar distribution.
    -
    static variable do_init_process(variable check)
    initialize the process data with a copy of the raw data.
    -
    static variable preview_norm_alpha()
    -
    variable asp_calculate_output()
    calculate the output using all enabled processing filters.
    -
    static variable check_norm_alpha()
    -
    variable asp_import_raw(wave raw_data)
    import raw data
    -
    variable crop_strip(wave strip, variable xlo, variable xhi)
    crop a strip at the sides.
    -
    variable ad_update_profiles(wave image)
    update a profiles graph with new data.
    -
    static variable bp_save_prefs(WMButtonAction *ba)
    -
    static variable preview_crop()
    -
    variable asp_save_output_itx()
    save the output diffractogram to an igor text file
    -
    string display_hemi_scan(string nickname, variable projection=defaultValue, variable graphtype=defaultValue, variable do_ticks=defaultValue, variable do_grids=defaultValue, string graphname=defaultValue)
    display a plot of a hemispherical angle scan.
    -
    static variable pmp_graph_colortable(WMPopupAction *pa)
    -
    static variable save_prefs()
    save persistent package data to the preferences file.
    -
    static variable bp_graph_update(WMButtonAction *ba)
    -
    dfr find_hemi_data(string nickname, string *prefix, string *intwave)
    finds the folder, prefix and name of holo waves given their nick name
    -
    static variable bp_norm_alpha_preview(WMButtonAction *ba)
    -
    static const string prefs_objects
    semicolon-separated list of persistent variable, string, and wave names
    -
    static variable pmp_norm_alpha_mode(WMPopupAction *pa)
    -
    static variable init_package()
    -
    static variable preview_norm_theta()
    -
    static variable delete_rows(string rows, wave data, wave theta, wave tilt, wave phi)
    delete individual rows from the data strip
    -
    static variable pmp_norm_theta_domain(WMPopupAction *pa)
    -
    static variable bp_source_update(WMButtonAction *ba)
    -
    static variable bp_norm_thetaphi_check(WMButtonAction *ba)
    -
    static variable bp_norm_theta_preview(WMButtonAction *ba)
    -
    static const string package_path
    data folder path
    -
    static variable bp_crop_preview(WMButtonAction *ba)
    -
    variable crop_strip_theta(wave strip, variable theta_lo, variable theta_hi, wave theta, wave tilt, wave phi)
    crop a strip in theta.
    -
    static variable do_norm_thetaphi(variable check, variable force=defaultValue)
    theta,phi-normalize the process data.
    -
    static variable bp_load_prefs(WMButtonAction *ba)
    -
    static variable bp_output_etpi(WMButtonAction *ba)
    -
    variable asp_display_dist_check(variable xdist, variable ydist)
    display a graph window of the distribution checks.
    -
    static variable bp_graph_png(WMButtonAction *ba)
    -
    static variable pmp_graph_mode(WMPopupAction *pa)
    -
    static variable preview_norm_phi()
    -
    string pmsco_save_scan(string pathname, string filename, string energy, string theta, string phi, string alpha, string intensity, string sigma, dfref sdfr=defaultValue)
    save waves in a PMSCO scan data file.
    -
    static variable pmp_norm_theta_mode(WMPopupAction *pa)
    -
    variable interpolate_hemi_scan(string nickname, variable projection=defaultValue)
    interpolate a hemispherical scan onto a rectangular grid
    -
    variable normalize_strip_theta_scans(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip piecewise by a smooth polar distribution.
    -
    static variable do_norm_phi(variable check, variable force=defaultValue)
    phi-normalize the process data.
    -
    static variable bp_norm_thetaphi_preview(WMButtonAction *ba)
    -
    static variable do_norm_theta(variable check, variable force=defaultValue)
    theta-normalize the process data.
    -
    static variable check_norm_phi()
    -
    variable asp_show_panel()
    create the angle scan processing panel
    -
    static variable bp_output_calc(WMButtonAction *ba)
    -
    static variable arrange_controls()
    -
    static variable bp_norm_theta_check(WMButtonAction *ba)
    -
    variable save_hemi_scan(string nickname, string pathname, string filename)
    save a hemispherical scan to an Igor text file
    -
    string asp_duplicate_output(string dest_name, variable do_graph=defaultValue)
    copy the output data to a new folder
    -
    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).
    -
    variable normalize_strip_thetaphi(wave strip, wave theta, wave phi, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by a smooth polar-azimuthal distribution.
    -
    const variable kProjStereo
    -
    static variable update_menus()
    update the popup menus to reflect the values of the global variables
    -
    static variable bp_output_itx(WMButtonAction *ba)
    -
    variable asp_close_graphs()
    close all graphs created by the angle scan panel
    -
    static variable do_norm_alpha(variable check, variable force=defaultValue)
    alpha-normalize the process data.
    -
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    -
    static variable load_prefs()
    load persistent package data from the preferences file.
    -
    static variable check_norm_theta()
    -
    variable set_contrast(variable pcmin, variable pcmax, string graphname=defaultValue, string colortable=defaultValue)
    set the pseudocolor contrast by percentile.
    -
    variable asp_display_previews()
    display a graph window of the processed data.
    -
    variable asp_save_output_etpi(variable ekin)
    save the output diffractogram to a PMSCO ETPI file
    -
    static variable bp_output_duplicate(WMButtonAction *ba)
    -
    static variable bp_norm_alpha_check(WMButtonAction *ba)
    -
    static variable check_norm_thetaphi()
    -
    static variable bp_norm_phi_check(WMButtonAction *ba)
    -
    static variable bp_source_select(WMButtonAction *ba)
    -
    static variable AfterCompiledHook()
    initialize package data once when the procedure is first loaded
    -
    variable duplicate_hemi_scan(string source_nickname, dfref dest_folder, string dest_nickname, variable xpdplot=defaultValue)
    duplicate a hemispherical scan dataset.
    -
    static variable do_crop(variable check, variable force=defaultValue)
    crop the process data.
    -
    static variable pmp_norm_thetaphi_mode(WMPopupAction *pa)
    -
    static variable preview_norm_thetaphi()
    -
    string asp_display_output(dfref data_df=defaultValue, string data_name=defaultValue)
    display the output diffractogram
    -
    static const string package_name
    package name is used as data folder name
    -
    variable asp_update_graph()
    update graphs with new color table or contrast
    -
    interactive processing of angle scanned XPD data.
    -
    static variable pmp_graph_projection(WMPopupAction *pa)
    -
    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.
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma version = 1.8
    +
    4 #pragma IgorVersion = 6.2
    +
    5 #pragma ModuleName = PearlAnglescanPanel
    +
    6 #include "pearl-anglescan-process"
    +
    7 #include "pearl-pmsco-import"
    +
    8 #include "pearl-scienta-preprocess"
    +
    9 #include "pearl-area-display"
    +
    10 
    +
    11 // copyright (c) 2018-20 Paul Scherrer Institut
    +
    12 //
    +
    13 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    14 // you may not use this file except in compliance with the License.
    +
    15 // You may obtain a copy of the License at
    +
    16 // http:///www.apache.org/licenses/LICENSE-2.0
    +
    17 //
    +
    18 // Please acknowledge the use of this code.
    +
    19 
    +
    41 
    +
    46 
    +
    48 static strconstant package_name = "pearl_anglescan_panel"
    +
    50 static strconstant package_path = "root:packages:pearl_anglescan_panel:"
    +
    51 
    +
    53 static function AfterCompiledHook()
    +
    54 
    +
    55  dfref savedf = GetDataFolderDFR()
    +
    56  variable do_init = 1
    +
    57  if (DataFolderExists(package_path))
    +
    58  setdatafolder $(package_path)
    +
    59  nvar /z init_done
    +
    60  if (nvar_exists(init_done))
    +
    61  if (init_done)
    +
    62  do_init = 0
    +
    63  endif
    +
    64  endif
    +
    65  endif
    +
    66 
    +
    67  if (do_init)
    +
    68  init_package()
    +
    69  load_prefs()
    +
    70  setdatafolder $(package_path)
    +
    71  variable /g init_done = 1
    +
    72  endif
    +
    73 
    +
    74  setdatafolder savedf
    +
    75  return 0
    +
    76 end
    +
    77 
    +
    78 static function init_package()
    +
    79  dfref savedf = getdatafolderdfr()
    +
    80  setdatafolder root:
    +
    81  newdatafolder /o/s packages
    +
    82  newdatafolder /o/s $package_name
    +
    83 
    +
    84  // configuration (persistent)
    +
    85  string /g graphname = "graph_anglescan_panel"
    +
    86  string /g prefs_objects = "prefs_objects;theta_offset;tilt_offset;phi_offset;alpha_offset;crop_enable;crop_alpha;crop_theta;"
    +
    87  prefs_objects += "norm_alpha_enable;norm_alpha_mode;norm_alpha_smoothing;norm_phi_enable;norm_phi_mode;norm_phi_thetarange;"
    +
    88  prefs_objects += "norm_theta_enable;norm_theta_mode;norm_theta_domain;norm_theta_smoothing;norm_thetaphi_enable;norm_thetaphi_mode;norm_thetaphi_smoothing;"
    +
    89  prefs_objects += "output_folding;output_horizon;graph_mode;graph_projection;graph_colortable;graph_contrast;"
    +
    90 
    +
    91  // recently used (persistent)
    +
    92  variable /g theta_offset = 0
    +
    93  variable /g tilt_offset = 0
    +
    94  variable /g phi_offset = 0
    +
    95  variable /g alpha_offset = 0
    +
    96  variable /g crop_enable = 0
    +
    97  variable /g crop_alpha = 25
    +
    98  variable /g crop_theta = 88
    +
    99  string /g crop_rows = ""
    +
    100  variable /g norm_alpha_enable = 0
    +
    101  variable /g norm_alpha_mode = 4
    +
    102  variable /g norm_alpha_smoothing = 0.25
    +
    103  variable /g norm_theta_enable = 0
    +
    104  variable /g norm_theta_mode = 4
    +
    105  variable /g norm_theta_domain = 0
    +
    106  variable /g norm_theta_smoothing = 0.25
    +
    107  variable /g norm_thetaphi_enable = 0
    +
    108  variable /g norm_thetaphi_mode = 4
    +
    109  variable /g norm_thetaphi_smoothing = 0.25
    +
    110  variable /g norm_phi_enable = 0
    +
    111  variable /g norm_phi_mode = 4
    +
    112  variable /g norm_phi_thetarange = 20
    +
    113  string /g output_name = "holo1"
    +
    114  variable /g output_folding = 1
    +
    115  variable /g output_horizon = 88
    +
    116  variable /g graph_mode = 1
    +
    117  variable /g graph_projection = kProjStereo
    +
    118  string /g graph_colortable = "grays"
    +
    119  variable /g graph_contrast = 2
    +
    120 
    +
    121  // recently used (volatile)
    +
    122  string /g source_path = ""
    +
    123  string /g export_folderpath = "root:"
    +
    124  variable /g export_format = 1
    +
    125 
    +
    126  // administrative data (volatile)
    +
    127  string /g panel_name = ""
    +
    128  string /g preview_graphname = ""
    +
    129  string /g dist_x_graphname = ""
    +
    130  string /g dist_y_graphname = ""
    +
    131  string /g output_graphname = ""
    +
    132 
    +
    133  // data (volatile)
    +
    134  make /n=(10,10) /o raw_data, process_data
    +
    135  make /o dist_x, dist_x_smoo
    +
    136  make /o dist_y, dist_y_smoo
    +
    137 
    +
    138  setdatafolder savedf
    +
    139 end
    +
    140 
    +
    145 static function save_prefs()
    +
    146  dfref saveDF = GetDataFolderDFR()
    +
    147  dfref df = $(package_path)
    +
    148  svar /sdfr=df prefs_objects
    +
    149 
    +
    150  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    +
    151  fullPath += package_name
    +
    152  NewPath/O/C/Q tempPackagePrefsPath, fullPath
    +
    153  fullPath += ":preferences.pxp"
    +
    154 
    +
    155  SetDataFolder root:packages
    +
    156  SetDataFolder $package_name
    +
    157  SaveData /O /Q /J=prefs_objects fullPath
    +
    158 
    +
    159  KillPath/Z tempPackagePrefsPath
    +
    160 
    +
    161  SetDataFolder saveDF
    +
    162 end
    +
    163 
    +
    171 static function load_prefs()
    +
    172  dfref saveDF = GetDataFolderDFR()
    +
    173 
    +
    174  variable result = -1
    +
    175  setdatafolder root:
    +
    176  NewDataFolder /O/S packages
    +
    177  NewDataFolder /O/S $package_name
    +
    178  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    +
    179  fullPath += package_name
    +
    180 
    +
    181  GetFileFolderInfo /Q /Z fullPath
    +
    182  if (V_Flag == 0) // Disk directory exists?
    +
    183  fullPath += ":preferences.pxp"
    +
    184  GetFileFolderInfo /Q /Z fullPath
    +
    185  if (V_Flag == 0) // Preference file exist?
    +
    186  LoadData /O /R /Q fullPath
    +
    187  result = 0
    +
    188  endif
    +
    189  endif
    +
    190 
    +
    191  SetDataFolder saveDF
    +
    192  return result
    +
    193 end
    +
    194 
    +
    207 function asp_import_raw(raw_data)
    +
    208  wave raw_data
    +
    209 
    +
    210  dfref saveDF = GetDataFolderDFR()
    +
    211  dfref datadf = GetWavesDataFolderDFR(raw_data)
    +
    212  dfref attrdf = datadf:attr
    +
    213  if (!DataFolderRefStatus(attrdf))
    +
    214  setdatafolder datadf
    +
    215  setdatafolder ::
    +
    216  dfref parentdf = GetDataFolderDFR()
    +
    217  dfref attrdf = parentdf:attr
    +
    218  endif
    +
    219  setdatafolder $(package_path)
    +
    220 
    +
    221  // todo : check dimensions and scales
    +
    222 
    +
    223  svar source_path
    +
    224  source_path = GetWavesDataFolder(raw_data, 2)
    +
    225 
    +
    226  duplicate /o raw_data, raw, process_data
    +
    227 
    +
    228  wave /sdfr=attrdf /z ManipulatorTheta
    +
    229  wave /sdfr=attrdf /z ManipulatorTilt
    +
    230  wave /sdfr=attrdf /z ManipulatorPhi
    +
    231  if (WaveExists(ManipulatorTheta) && WaveExists(ManipulatorTilt) && WaveExists(ManipulatorPhi))
    +
    232  duplicate /o attrdf:ManipulatorTheta, raw_theta, process_theta
    +
    233  duplicate /o attrdf:ManipulatorTilt, raw_tilt, process_tilt
    +
    234  duplicate /o attrdf:ManipulatorPhi, raw_phi, process_phi
    +
    235  else
    +
    236  DoAlert 0, "Can't find manipulator angle waves.\rCheck that the attr folder exists, or provide values in the following table."
    +
    237  make /n=(dimsize(raw_data, 1)) /o raw_theta, raw_tilt, raw_phi
    +
    238  make /n=(dimsize(raw_data, 1)) /o process_theta, process_tilt, process_phi
    +
    239  edit /k=1 raw_theta, raw_tilt, raw_phi
    +
    240  endif
    +
    241 
    +
    242  make /o /n=(dimsize(raw_data, 0)) dist_x, dist_x_smoo
    +
    243  make /o /n=(dimsize(raw_data, 1)) dist_y, dist_y_smoo
    +
    244 
    +
    245  SetDataFolder saveDF
    +
    246 end
    +
    247 
    + +
    253  dfref df = $(package_path)
    +
    254  wave /sdfr=df process_data
    +
    255  svar /sdfr=df preview_graphname
    +
    256 
    +
    257  if (strlen(preview_graphname) && (wintype(preview_graphname) == 1))
    +
    258  ad_update_profiles(process_data)
    +
    259  DoWindow /F $preview_graphname
    +
    260  else
    +
    261  preview_graphname = ad_display_profiles(process_data)
    +
    262  endif
    +
    263 
    +
    264  nvar /sdfr=df graph_contrast
    +
    265  svar /sdfr=df graph_colortable
    +
    266  set_contrast(graph_contrast, graph_contrast, graphname=preview_graphname, colortable=graph_colortable)
    +
    267 end
    +
    268 
    +
    276 function asp_display_dist_check(xdist, ydist)
    +
    277  variable xdist, ydist
    +
    278 
    +
    279  dfref df = $(package_path)
    +
    280  wave /sdfr=df dist_x
    +
    281  wave /sdfr=df dist_y
    +
    282  wave /sdfr=df dist_x_smoo
    +
    283  wave /sdfr=df dist_y_smoo
    +
    284  svar /sdfr=df dist_x_graphname
    +
    285  svar /sdfr=df dist_y_graphname
    +
    286 
    +
    287  if (xdist)
    +
    288  if (strlen(dist_x_graphname) && (wintype(dist_x_graphname) == 1))
    +
    289  DoWindow /F $dist_x_graphname
    +
    290  else
    +
    291  display /k=1 /n=graph_asp_dist_x dist_x, dist_x_smoo
    +
    292  dist_x_graphname = s_name
    +
    293  ModifyGraph /w=$dist_x_graphname mode(dist_x)=2
    +
    294  ModifyGraph /w=$dist_x_graphname lsize(dist_x)=2
    +
    295  ModifyGraph /w=$dist_x_graphname rgb(dist_x)=(0,0,0)
    +
    296  endif
    +
    297  endif
    +
    298 
    +
    299  if (ydist)
    +
    300  if (strlen(dist_y_graphname) && (wintype(dist_y_graphname) == 1))
    +
    301  DoWindow /F $dist_y_graphname
    +
    302  else
    +
    303  display /k=1 /n=graph_asp_dist_y dist_y, dist_y_smoo
    +
    304  dist_y_graphname = s_name
    +
    305  ModifyGraph /w=$dist_y_graphname mode(dist_y)=2
    +
    306  ModifyGraph /w=$dist_y_graphname lsize(dist_y)=2
    +
    307  ModifyGraph /w=$dist_y_graphname rgb(dist_y)=(0,0,0)
    +
    308  endif
    +
    309  endif
    +
    310 end
    +
    311 
    +
    321 static function do_init_process(check)
    +
    322  variable check
    +
    323 
    +
    324  dfref df = $(package_path)
    +
    325  wave /sdfr=df raw
    +
    326  wave /sdfr=df raw_theta
    +
    327  wave /sdfr=df raw_tilt
    +
    328  wave /sdfr=df raw_phi
    +
    329  nvar /sdfr=df theta_offset
    +
    330  nvar /sdfr=df tilt_offset
    +
    331  nvar /sdfr=df phi_offset
    +
    332  nvar /sdfr=df alpha_offset
    +
    333 
    +
    334  duplicate /o raw, df:process_data
    +
    335  duplicate /o raw_theta, df:process_theta
    +
    336  duplicate /o raw_tilt, df:process_tilt
    +
    337  duplicate /o raw_phi, df:process_phi
    +
    338 
    +
    339  wave /sdfr=df process_data
    +
    340  wave /sdfr=df process_theta
    +
    341  wave /sdfr=df process_tilt
    +
    342  wave /sdfr=df process_phi
    +
    343 
    +
    344  process_theta = raw_theta - theta_offset
    +
    345  process_tilt = raw_tilt - tilt_offset
    +
    346  process_phi = raw_phi - phi_offset
    +
    347  setscale /p x dimoffset(raw, 0) - alpha_offset, dimdelta(raw, 0), waveunits(raw, 0), process_data
    +
    348 end
    +
    349 
    +
    361 static function do_crop(check, [force])
    +
    362  variable check
    +
    363  variable force
    +
    364 
    +
    365  if (ParamIsDefault(force))
    +
    366  force = 0
    +
    367  endif
    +
    368 
    +
    369  dfref df = $(package_path)
    +
    370  wave /sdfr=df process_data
    +
    371  wave /sdfr=df process_theta
    +
    372  wave /sdfr=df process_tilt
    +
    373  wave /sdfr=df process_phi
    +
    374  nvar /sdfr=df crop_enable
    +
    375  nvar /sdfr=df crop_alpha
    +
    376  nvar /sdfr=df crop_theta
    +
    377  svar /sdfr=df crop_rows
    +
    378 
    +
    379  if (force || crop_enable)
    +
    380 
    +
    381  if (crop_alpha > abs(dimdelta(process_data, 0)))
    +
    382  crop_strip(process_data, -crop_alpha, +crop_alpha)
    +
    383  endif
    +
    384 
    +
    385  if ((crop_theta >= 10) && (crop_theta < 90))
    +
    386  crop_strip_theta(process_data, -0.1, crop_theta + 0.1, process_theta, process_tilt, process_phi)
    +
    387  endif
    +
    388 
    +
    389  if (strlen(crop_rows) > 0)
    +
    390  delete_rows(crop_rows, process_data, process_theta, process_tilt, process_phi)
    +
    391  endif
    +
    392  endif
    +
    393 end
    +
    394 
    +
    409 static function delete_rows(rows, data, theta, tilt, phi)
    +
    410  string rows
    +
    411  wave data
    +
    412  wave theta
    +
    413  wave tilt
    +
    414  wave phi
    +
    415 
    +
    416  make /n=(numpnts(theta)) /i /free idx
    +
    417  idx = p
    +
    418  variable nrows = ItemsInList(rows, ",")
    +
    419  variable irow
    +
    420  string srow
    +
    421  variable q1, q2
    +
    422  for (irow = 0; irow < nrows; irow += 1)
    +
    423  srow = StringFromList(irow, rows, ",")
    +
    424  q1 = str2num(StringFromList(0, srow, "-"))
    +
    425  q2 = str2num(StringFromList(1, srow, "-"))
    +
    426  if (numtype(q2))
    +
    427  q2 = q1
    +
    428  endif
    +
    429  if (q1 <= q2)
    +
    430  idx[q1,q2] = -1
    +
    431  endif
    +
    432  endfor
    +
    433  extract /free idx, idx, idx >= 0
    +
    434  variable nx = dimsize(data, 0)
    +
    435  variable ny = numpnts(idx)
    +
    436  theta[0,ny-1] = theta[idx]
    +
    437  tilt[0,ny-1] = tilt[idx]
    +
    438  phi[0,ny-1] = phi[idx]
    +
    439  redimension /n=(ny) theta, tilt, phi
    +
    440  duplicate /free data, data_copy
    +
    441  redimension /n=(nx,ny) data
    +
    442  data = data_copy[p][idx[q]]
    +
    443 end
    +
    444 
    +
    456 static function do_norm_alpha(check, [force])
    +
    457  variable check
    +
    458  variable force
    +
    459 
    +
    460  if (ParamIsDefault(force))
    +
    461  force = 0
    +
    462  endif
    +
    463 
    +
    464  dfref saveDF = GetDataFolderDFR()
    +
    465  dfref df = $(package_path)
    +
    466  wave /sdfr=df process_data
    +
    467  nvar /sdfr=df norm_alpha_enable
    +
    468  nvar /sdfr=df norm_alpha_mode
    +
    469  nvar /sdfr=df norm_alpha_smoothing
    +
    470 
    +
    471  if (force || norm_alpha_enable)
    +
    472  dfref temp_df = newfreedatafolder()
    +
    473  setdatafolder temp_df
    +
    474  normalize_strip_x(process_data, smooth_method=norm_alpha_mode, smooth_factor=norm_alpha_smoothing, check=check)
    +
    475  if (check)
    +
    476  wave check_dist
    +
    477  wave check_smoo
    +
    478  duplicate /o check_dist, df:dist_x
    +
    479  duplicate /o check_smoo, df:dist_x_smoo
    +
    480  endif
    +
    481  endif
    +
    482 
    +
    483  SetDataFolder saveDF
    +
    484 end
    +
    485 
    +
    497 static function do_norm_phi(check, [force])
    +
    498  variable check
    +
    499  variable force
    +
    500 
    +
    501  if (ParamIsDefault(force))
    +
    502  force = 0
    +
    503  endif
    +
    504 
    +
    505  dfref saveDF = GetDataFolderDFR()
    +
    506  dfref df = $(package_path)
    +
    507  wave /sdfr=df process_data
    +
    508  wave /sdfr=df process_theta
    +
    509  wave /sdfr=df process_phi
    +
    510  nvar /sdfr=df norm_phi_enable
    +
    511  nvar /sdfr=df norm_phi_mode
    +
    512  nvar /sdfr=df norm_phi_thetarange
    +
    513 
    +
    514  if (force || norm_phi_enable)
    +
    515  dfref temp_df = newfreedatafolder()
    +
    516  setdatafolder temp_df
    +
    517  normalize_strip_phi(process_data, process_theta, process_phi, theta_range=norm_phi_thetarange, check=check)
    +
    518  if (check)
    +
    519  wave check_dist
    +
    520  wave check_smoo
    +
    521  duplicate /o check_dist, df:dist_y
    +
    522  duplicate /o check_smoo, df:dist_y_smoo
    +
    523  endif
    +
    524  endif
    +
    525 
    +
    526  SetDataFolder saveDF
    +
    527 end
    +
    528 
    +
    540 static function do_norm_theta(check, [force])
    +
    541  variable check
    +
    542  variable force
    +
    543 
    +
    544  if (ParamIsDefault(force))
    +
    545  force = 0
    +
    546  endif
    +
    547 
    +
    548  dfref saveDF = GetDataFolderDFR()
    +
    549  dfref df = $(package_path)
    +
    550  wave /sdfr=df process_data
    +
    551  wave /sdfr=df process_theta
    +
    552  nvar /sdfr=df norm_theta_enable
    +
    553  nvar /sdfr=df norm_theta_mode
    +
    554  nvar /sdfr=df norm_theta_domain
    +
    555  nvar /sdfr=df norm_theta_smoothing
    +
    556 
    +
    557  if (force || norm_theta_enable)
    +
    558  dfref temp_df = newfreedatafolder()
    +
    559  setdatafolder temp_df
    +
    560  if (norm_theta_domain==1)
    +
    561  normalize_strip_theta_scans(process_data, process_theta, smooth_method=norm_theta_mode, smooth_factor=norm_theta_smoothing, check=check)
    +
    562  else
    +
    563  normalize_strip_theta(process_data, process_theta, smooth_method=norm_theta_mode, smooth_factor=norm_theta_smoothing, check=check)
    +
    564  endif
    +
    565  if (check)
    +
    566  wave check_dist
    +
    567  wave check_smoo
    +
    568  duplicate /o check_dist, df:dist_y
    +
    569  duplicate /o check_smoo, df:dist_y_smoo
    +
    570  endif
    +
    571  endif
    +
    572 
    +
    573  SetDataFolder saveDF
    +
    574 end
    +
    575 
    +
    587 static function do_norm_thetaphi(check, [force])
    +
    588  variable check
    +
    589  variable force
    +
    590 
    +
    591  if (ParamIsDefault(force))
    +
    592  force = 0
    +
    593  endif
    +
    594 
    +
    595  dfref saveDF = GetDataFolderDFR()
    +
    596  dfref df = $(package_path)
    +
    597  wave /sdfr=df process_data
    +
    598  wave /sdfr=df process_theta
    +
    599  wave /sdfr=df process_phi
    +
    600  nvar /sdfr=df norm_thetaphi_enable
    +
    601  nvar /sdfr=df norm_thetaphi_mode
    +
    602  nvar /sdfr=df norm_thetaphi_smoothing
    +
    603 
    +
    604  if (force || norm_thetaphi_enable)
    +
    605  dfref temp_df = newfreedatafolder()
    +
    606  setdatafolder temp_df
    +
    607  normalize_strip_thetaphi(process_data, process_theta, process_phi, smooth_method=norm_thetaphi_mode, smooth_factor=norm_thetaphi_smoothing, check=check)
    +
    608  if (check)
    +
    609  wave check_dist
    +
    610  wave check_smoo
    +
    611  duplicate /o check_dist, df:dist_y
    +
    612  duplicate /o check_smoo, df:dist_y_smoo
    +
    613  endif
    +
    614  endif
    +
    615 
    +
    616  SetDataFolder saveDF
    +
    617 end
    +
    618 
    + +
    624  dfref saveDF = GetDataFolderDFR()
    +
    625  setdatafolder $(package_path)
    +
    626 
    +
    627  svar output_name
    +
    628 
    +
    629  wave process_data
    +
    630  wave process_theta
    +
    631  wave process_tilt
    +
    632  wave process_phi
    +
    633 
    +
    634  nvar folding=output_folding
    +
    635  nvar horizon=output_horizon
    +
    636 
    +
    637  do_init_process(0)
    +
    638  do_crop(0)
    +
    639  do_norm_alpha(0)
    +
    640  do_norm_phi(0)
    +
    641  do_norm_theta(0)
    + +
    643 
    +
    644  pizza_service_2(process_data, output_name, process_theta, process_tilt, process_phi, folding=folding, nograph=1)
    +
    645 
    +
    646  setdatafolder $output_name
    +
    647  wave values
    +
    648  wave pol
    +
    649  if (horizon > 0)
    +
    650  values = pol <= horizon ? values : nan
    +
    651  endif
    +
    652 
    +
    653  SetDataFolder saveDF
    +
    654 end
    +
    655 
    +
    669 function /s asp_display_output([data_df, data_name])
    +
    670  dfref data_df
    +
    671  string data_name
    +
    672 
    +
    673  dfref pkg_df = $(package_path)
    +
    674  svar /sdfr=pkg_df output_name
    +
    675  svar /sdfr=pkg_df output_graphname
    +
    676  nvar /sdfr=pkg_df graph_projection
    +
    677  nvar /sdfr=pkg_df graph_mode
    +
    678  svar /sdfr=pkg_df graph_colortable
    +
    679  nvar /sdfr=pkg_df graph_contrast
    +
    680 
    +
    681  if (ParamIsDefault(data_df))
    +
    682  dfref data_df = pkg_df
    +
    683  endif
    +
    684  if (ParamIsDefault(data_name))
    +
    685  data_name = output_name
    +
    686  endif
    +
    687 
    +
    688  dfref saveDF = GetDataFolderDFR()
    +
    689  setdatafolder data_df
    +
    690 
    +
    691  if (graph_mode == 3)
    +
    692  interpolate_hemi_scan(data_name, projection=graph_projection)
    +
    693  endif
    +
    694 
    +
    695  string graphname = data_name
    +
    696  graphname = display_hemi_scan(data_name, projection=graph_projection, graphtype=graph_mode, graphname=graphname)
    +
    697  if (ParamIsDefault(data_df))
    +
    698  output_graphname = graphname
    +
    699  endif
    +
    700  SetDataFolder saveDF
    +
    701 
    +
    702  if (strlen(graphname) && (wintype(graphname) == 1))
    +
    703  set_contrast(graph_contrast, graph_contrast, graphname=graphname, colortable=graph_colortable)
    +
    704  endif
    +
    705 
    +
    706  return graphname
    +
    707 end
    +
    708 
    + +
    714  dfref df = $(package_path)
    +
    715 
    +
    716  svar /sdfr=df preview_graphname
    +
    717  svar /sdfr=df output_graphname
    +
    718  svar /sdfr=df graph_colortable
    +
    719  nvar /sdfr=df graph_contrast
    +
    720 
    +
    721  if (strlen(preview_graphname) && (wintype(preview_graphname) == 1))
    +
    722  set_contrast(graph_contrast, graph_contrast, graphname=preview_graphname, colortable=graph_colortable)
    +
    723  endif
    +
    724  if (strlen(output_graphname) && (wintype(output_graphname) == 1))
    +
    725  set_contrast(graph_contrast, graph_contrast, graphname=output_graphname, colortable=graph_colortable)
    +
    726  endif
    +
    727 end
    +
    728 
    + +
    732  dfref df = $(package_path)
    +
    733 
    +
    734  svar /sdfr=df preview_graphname
    +
    735  svar /sdfr=df output_graphname
    +
    736  svar /sdfr=df dist_x_graphname
    +
    737  svar /sdfr=df dist_y_graphname
    +
    738 
    +
    739  if (strlen(preview_graphname) && (wintype(preview_graphname) == 1))
    +
    740  killwindow $preview_graphname
    +
    741  endif
    +
    742  if (strlen(output_graphname) && (wintype(output_graphname) == 1))
    +
    743  killwindow $output_graphname
    +
    744  endif
    +
    745  if (strlen(dist_x_graphname) && (wintype(dist_x_graphname) == 1))
    +
    746  killwindow $dist_x_graphname
    +
    747  endif
    +
    748  if (strlen(dist_y_graphname) && (wintype(dist_y_graphname) == 1))
    +
    749  killwindow $dist_y_graphname
    +
    750  endif
    +
    751 
    +
    752  preview_graphname = ""
    +
    753  output_graphname = ""
    +
    754  dist_x_graphname = ""
    +
    755  dist_y_graphname = ""
    +
    756 end
    +
    757 
    +
    771 function /s asp_duplicate_output(dest_name, [do_graph])
    +
    772  string dest_name
    +
    773  variable do_graph
    +
    774 
    +
    775  if (ParamIsDefault(do_graph))
    +
    776  do_graph = 0
    +
    777  endif
    +
    778 
    +
    779  dfref df = $(package_path)
    +
    780  svar /sdfr=df source_path
    +
    781  svar /sdfr=df output_name
    +
    782  svar /sdfr=df output_graphname
    +
    783  wave raw_data = $source_path
    +
    784 
    +
    785  dfref saveDF = GetDataFolderDFR()
    +
    786  dfref raw_df = GetWavesDataFolderDFR(raw_data)
    +
    787  setdatafolder raw_df
    +
    788  newdatafolder /o /s $dest_name
    +
    789  dfref dest_df = GetDataFolderDFR()
    +
    790  setdatafolder df
    +
    791  duplicate_hemi_scan(output_name, dest_df, "")
    +
    792 
    +
    793  string graphname = ""
    +
    794  if (do_graph)
    +
    795  graphname = asp_display_output(data_df=raw_df, data_name=dest_name)
    +
    796  endif
    +
    797 
    +
    798  SetDataFolder saveDF
    +
    799  return graphname
    +
    800 end
    +
    801 
    + +
    805  dfref df = $(package_path)
    +
    806  svar /sdfr=df output_name
    +
    807 
    +
    808  dfref saveDF = GetDataFolderDFR()
    +
    809  setdatafolder df
    +
    810  save_hemi_scan(output_name, "", "")
    +
    811 
    +
    812  SetDataFolder saveDF
    +
    813 end
    +
    814 
    +
    819 function asp_save_output_etpi(ekin)
    +
    820  variable ekin
    +
    821 
    +
    822  dfref df = $(package_path)
    +
    823  svar /sdfr=df output_name
    +
    824  wave /sdfr=df process_data
    +
    825 
    +
    826  dfref saveDF = GetDataFolderDFR()
    +
    827  setdatafolder df
    +
    828  string s_prefix = ""
    +
    829  string s_int = "values"
    +
    830  dfref data_df = find_hemi_data(output_name, s_prefix, s_int)
    +
    831  string s_polar = s_prefix + "pol"
    +
    832  string s_azim = s_prefix + "az"
    +
    833 
    +
    834  pmsco_save_scan("", "", num2str(ekin), s_polar, s_azim, "", s_int, "", sdfr=data_df)
    +
    835 
    +
    836  SetDataFolder saveDF
    +
    837 end
    +
    838 
    +
    839 static function check_norm_alpha()
    +
    840  do_init_process(0)
    +
    841  do_crop(0)
    +
    842  do_norm_alpha(2, force=1)
    + +
    844 end
    +
    845 
    +
    846 static function check_norm_phi()
    +
    847  do_init_process(0)
    +
    848  do_crop(0)
    +
    849  do_norm_phi(2, force=1)
    + +
    851 end
    +
    852 
    +
    853 static function check_norm_theta()
    +
    854  do_init_process(0)
    +
    855  do_crop(0)
    +
    856  do_norm_theta(2, force=1)
    + +
    858 end
    +
    859 
    +
    860 static function check_norm_thetaphi()
    +
    861  do_init_process(0)
    +
    862  do_crop(0)
    +
    863  do_norm_thetaphi(2, force=1)
    + +
    865 end
    +
    866 
    +
    867 static function preview_crop()
    +
    868  do_init_process(0)
    +
    869  do_crop(0, force=1)
    + +
    871 end
    +
    872 
    +
    873 static function preview_norm_alpha()
    +
    874  do_init_process(0)
    +
    875  do_crop(0)
    +
    876  do_norm_alpha(1, force=1)
    + +
    878 end
    +
    879 
    +
    880 static function preview_norm_phi()
    +
    881  do_init_process(0)
    +
    882  do_crop(0)
    +
    883  do_norm_phi(1, force=1)
    + +
    885 end
    +
    886 
    +
    887 static function preview_norm_theta()
    +
    888  do_init_process(0)
    +
    889  do_crop(0)
    +
    890  do_norm_theta(1, force=1)
    + +
    892 end
    +
    893 
    +
    894 static function preview_norm_thetaphi()
    +
    895  do_init_process(0)
    +
    896  do_crop(0)
    +
    897  do_norm_thetaphi(1, force=1)
    + +
    899 end
    +
    900 
    +
    903 function asp_show_panel()
    +
    904  dfref df = $(package_path)
    +
    905  svar /sdfr=df panel_name
    +
    906 
    +
    907  if (strlen(panel_name) && (wintype(panel_name) == 7))
    +
    908  DoWindow /F $panel_name
    +
    909  return 0
    +
    910  endif
    +
    911 
    +
    912  NewPanel /K=1 /N=anglescan_panel /W=(200,50,480,874) as "angle scan processing"
    +
    913  panel_name = s_name
    +
    914 
    +
    915  GroupBox gb_source, title="data source"
    +
    916  Button b_source_select, size={50,20},proc=PearlAnglescanPanel#bp_source_select,title="select..."
    +
    917  Button b_source_select, help={"select the source wave, e.g. ReducedData1. it must be in the scan or region data folder. the attr folder with the manipulator waves must be in the same folder or one level up."}
    +
    918  Button b_source_update, size={50,20},proc=PearlAnglescanPanel#bp_source_update,title="update"
    +
    919  Button b_source_update, help={"reload the process data from the previous source (link displayed below)"}
    +
    920  TitleBox tb_source_path, size={240,21}
    +
    921  TitleBox tb_source_path,variable= root:packages:pearl_anglescan_panel:source_path
    +
    922 
    +
    923  GroupBox gb_offsets, title="offsets"
    +
    924  SetVariable sv_theta_offset, size={88,16},bodyWidth=60,title="theta"
    +
    925  SetVariable sv_theta_offset,value= root:packages:pearl_anglescan_panel:theta_offset
    +
    926  SetVariable sv_theta_offset, help={"manipulator theta value that corresponds to normal emission."}
    +
    927  SetVariable sv_tilt_offset, size={74,16},bodyWidth=60,title="tilt"
    +
    928  SetVariable sv_tilt_offset,value= root:packages:pearl_anglescan_panel:tilt_offset
    +
    929  SetVariable sv_tilt_offset, help={"manipulator tilt value that corresponds to normal emission."}
    +
    930  SetVariable sv_phi_offset, size={78,16},bodyWidth=60,title="phi"
    +
    931  SetVariable sv_phi_offset,value= root:packages:pearl_anglescan_panel:phi_offset
    +
    932  SetVariable sv_phi_offset, help={"manipulator phi value that should map to the 3 o'clock angle."}
    +
    933  SetVariable sv_alpha_offset, size={90,16},bodyWidth=60,title="alpha"
    +
    934  SetVariable sv_alpha_offset,value= root:packages:pearl_anglescan_panel:alpha_offset
    +
    935  SetVariable sv_alpha_offset, help={"alpha value that corresponds to normal emission (if the sample normal is properly aligned)."}
    +
    936  Button b_save_prefs, size={80,20},proc=PearlAnglescanPanel#bp_save_prefs,title="save prefs"
    +
    937  Button b_save_prefs, help={"save settings as preferences."}
    +
    938  Button b_load_prefs, size={80,20},proc=PearlAnglescanPanel#bp_load_prefs,title="load prefs"
    +
    939  Button b_load_prefs, help={"load settings from preferences."}
    +
    940 
    +
    941  GroupBox gb_crop, title="crop and delete"
    +
    942  CheckBox cb_crop_enable, size={50,14}, title="enable"
    +
    943  CheckBox cb_crop_enable, help={"crop at +/-alpha and +theta, delete arbitrary rows"}
    +
    944  CheckBox cb_crop_enable, variable= root:packages:pearl_anglescan_panel:crop_enable
    +
    945  SetVariable sv_crop_alpha, size={90,16},bodyWidth=60,title="alpha"
    +
    946  SetVariable sv_crop_alpha, limits={0,30,1},value= root:packages:pearl_anglescan_panel:crop_alpha
    +
    947  SetVariable sv_crop_alpha, help={"alpha (detection angle) cropping angle (positive boundary), relative to normal emission"}
    +
    948  SetVariable sv_crop_theta, size={90,16},bodyWidth=60,title="theta"
    +
    949  SetVariable sv_crop_theta, limits={10,90,1},value= root:packages:pearl_anglescan_panel:crop_theta
    +
    950  SetVariable sv_crop_theta, help={"theta (polar angle) upper limit, relative to normal emission"}
    +
    951  SetVariable sv_crop_rows, size={200,16},bodyWidth=160,title="rows"
    +
    952  SetVariable sv_crop_rows, limits={10,90,1},value= root:packages:pearl_anglescan_panel:crop_rows
    +
    953  SetVariable sv_crop_rows, help={"rows to delete from the raw data. comma-separated point indices, hyphen for range."}
    +
    954  Button b_crop_preview, size={80,20},proc=PearlAnglescanPanel#bp_crop_preview,title="preview"
    +
    955  Button b_crop_preview, help={"show a preview of the cropped dataset."}
    +
    956 
    +
    957  GroupBox gb_norm_alpha, title="normalize alpha"
    +
    958  CheckBox cb_norm_alpha_enable, size={50,14}, title="enable"
    +
    959  CheckBox cb_norm_alpha_enable,variable= root:packages:pearl_anglescan_panel:norm_alpha_enable
    +
    960  CheckBox cb_norm_alpha_enable, help={"enable normalization of the alpha distribution"}
    +
    961  PopupMenu pm_norm_alpha_mode, size={138,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_norm_alpha_mode,title="method"
    +
    962  PopupMenu pm_norm_alpha_mode, mode=5, popvalue="loess", value= #"\"none;binomial;boxcar;scienta;loess;\""
    +
    963  PopupMenu pm_norm_alpha_mode, help={"alpha normalization method. recommended: loess"}
    +
    964  SetVariable sv_norm_alpha_smoothing, size={112,16}, bodyWidth=60, title="smoothing"
    +
    965  SetVariable sv_norm_alpha_smoothing, limits={0,1,0.05}, value= root:packages:pearl_anglescan_panel:norm_alpha_smoothing
    +
    966  SetVariable sv_norm_alpha_smoothing, help={"smoothing parameter (depends on the normalization method)."}
    +
    967  Button b_norm_alpha_check, size={80,20}, proc=PearlAnglescanPanel#bp_norm_alpha_check,title="check"
    +
    968  Button b_norm_alpha_check, help={"show a graph of the normalization function"}
    +
    969  Button b_norm_alpha_preview, size={80,20}, proc=PearlAnglescanPanel#bp_norm_alpha_preview,title="preview"
    +
    970  Button b_norm_alpha_preview, help={"show a preview of the normalized dataset (without other normalizations)."}
    +
    971 
    +
    972  GroupBox gb_norm_phi, title="normalize phi"
    +
    973  CheckBox cb_norm_phi_enable, size={50,14}, title="enable"
    +
    974  CheckBox cb_norm_phi_enable,variable= root:packages:pearl_anglescan_panel:norm_phi_enable
    +
    975  CheckBox cb_norm_phi_enable, help={"enable normalization of the phi distribution to reduce the effect of wobble"}
    +
    976  SetVariable sv_norm_phi_range, size={118,16}, bodyWidth=60, title="theta range"
    +
    977  SetVariable sv_norm_phi_range, limits={0,90,1}, value= root:packages:pearl_anglescan_panel:norm_phi_thetarange
    +
    978  SetVariable sv_norm_phi_range, help={"theta range (from normal) to factor into the normalization function"}
    +
    979  Button b_norm_phi_check, size={80,20}, proc=PearlAnglescanPanel#bp_norm_phi_check, title="check"
    +
    980  Button b_norm_phi_check, help={"show a graph of the normalization function"}
    +
    981  Button b_norm_phi_preview, size={80,20}, proc=PearlAnglescanPanel#bp_norm_phi_preview, title="preview"
    +
    982  Button b_norm_phi_preview, help={"show a preview of the normalized dataset (without other normalizations)."}
    +
    983 
    +
    984  GroupBox gb_norm_theta, title="normalize theta"
    +
    985  CheckBox cb_norm_theta_enable, size={50,14},title="enable"
    +
    986  CheckBox cb_norm_theta_enable, variable= root:packages:pearl_anglescan_panel:norm_theta_enable
    +
    987  CheckBox cb_norm_theta_enable, help={"enable normalization of the theta distribution (integrated over phi)"}
    +
    988  PopupMenu pm_norm_theta_domain, size={138,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_norm_theta_domain, title="domain"
    +
    989  PopupMenu pm_norm_theta_domain, mode=5, popvalue="loess", value= #"\"global;scans;\""
    +
    990  PopupMenu pm_norm_theta_domain, help={"smoothing domain: global or individual scans. use global unless there is a stronga or irregular phi variation."}
    +
    991  PopupMenu pm_norm_theta_mode, size={138,21},bodyWidth=100,proc=PearlAnglescanPanel#pmp_norm_theta_mode,title="method"
    +
    992  PopupMenu pm_norm_theta_mode,mode=5,popvalue="loess",value= #"\"none;binomial;boxcar;polynomial;loess;\""
    +
    993  PopupMenu pm_norm_theta_mode, help={"theta normalization method. recommended: loess"}
    +
    994  SetVariable sv_norm_theta_smoothing, size={112,16}, bodyWidth=60, title="smoothing"
    +
    995  SetVariable sv_norm_theta_smoothing, limits={0,1,0.05}, value= root:packages:pearl_anglescan_panel:norm_theta_smoothing
    +
    996  SetVariable sv_norm_theta_smoothing, help={"smoothing parameter (depends on the normalization method)."}
    +
    997  Button b_norm_theta_check, size={80,20}, proc=PearlAnglescanPanel#bp_norm_theta_check, title="check"
    +
    998  Button b_norm_theta_check, help={"show a graph of the normalization function"}
    +
    999  Button b_norm_theta_preview, size={80,20}, proc=PearlAnglescanPanel#bp_norm_theta_preview, title="preview"
    +
    1000  Button b_norm_theta_preview, help={"show a preview of the normalized dataset (without other normalizations)."}
    +
    1001 
    +
    1002  GroupBox gb_norm_thetaphi, size={272,97},title="normalize (theta,phi)"
    +
    1003  CheckBox cb_norm_thetaphi_enable, size={50,14},title="enable"
    +
    1004  CheckBox cb_norm_thetaphi_enable, variable= root:packages:pearl_anglescan_panel:norm_thetaphi_enable
    +
    1005  CheckBox cb_norm_thetaphi_enable, help={"enable normalization of the (theta, phi) distribution."}
    +
    1006  PopupMenu pm_norm_thetaphi_mode, size={138,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_norm_thetaphi_mode,title="method"
    +
    1007  PopupMenu pm_norm_thetaphi_mode, mode=5, popvalue="loess", value= #"\"none;none;none;none;loess;\""
    +
    1008  PopupMenu pm_norm_thetaphi_mode, help={"theta normalization method. recommended: loess"}
    +
    1009  SetVariable sv_norm_thetaphi_smoothing, size={112,16}, bodyWidth=60, title="smoothing"
    +
    1010  SetVariable sv_norm_thetaphi_smoothing, limits={0,1,0.05}, value= root:packages:pearl_anglescan_panel:norm_thetaphi_smoothing
    +
    1011  SetVariable sv_norm_thetaphi_smoothing, help={"smoothing parameter (depends on the normalization method)."}
    +
    1012  Button b_norm_thetaphi_check, size={80,20}, proc=PearlAnglescanPanel#bp_norm_thetaphi_check, title="check"
    +
    1013  Button b_norm_thetaphi_check, help={"show a graph of the normalization function"}
    +
    1014  Button b_norm_thetaphi_preview, size={80,20}, proc=PearlAnglescanPanel#bp_norm_thetaphi_preview, title="preview"
    +
    1015  Button b_norm_thetaphi_preview, help={"show a preview of the normalized dataset (without other normalizations)."}
    +
    1016 
    +
    1017  GroupBox gb_output, title="output"
    +
    1018  SetVariable sv_output_folding, size={95,16}, bodyWidth=60, title="folding"
    +
    1019  SetVariable sv_output_folding, limits={1,20,1}, value= root:packages:pearl_anglescan_panel:output_folding
    +
    1020  SetVariable sv_output_folding, help={"n-fold rotational average. 1=no averaging."}
    +
    1021  SetVariable sv_output_horizon, size={98,16}, bodyWidth=60, title="horizon"
    +
    1022  SetVariable sv_output_horizon, limits={1,90,1}, value= root:packages:pearl_anglescan_panel:output_horizon
    +
    1023  SetVariable sv_output_horizon, help={"highest theta to display"}
    +
    1024  PopupMenu pm_graph_projection, size={149,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_graph_projection, title="projection"
    +
    1025  PopupMenu pm_graph_projection, mode=2, popvalue="stereographic", value= #"\"equidistant;stereographic;equal area;gnomonic;orthographic;\""
    +
    1026  PopupMenu pm_graph_projection, help={"projection (theta mapping) mode"}
    +
    1027  PopupMenu pm_graph_mode, size={129,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_graph_mode,title="mode"
    +
    1028  PopupMenu pm_graph_mode, mode=2, popvalue="dots", value= #"\"none;dots;none;image;\""
    +
    1029  PopupMenu pm_graph_mode, help={"graph type: dots = coloured dots on circles; image = interpolated matrix"}
    +
    1030  Button b_output_calc, size={80,20}, proc=PearlAnglescanPanel#bp_output_calc, title="calc + display"
    +
    1031  Button b_output_calc, help={"execute data processing with the enabled filters and display the diffractogram."}
    +
    1032  Button b_output_duplicate, size={80,20}, proc=PearlAnglescanPanel#bp_output_duplicate, title="duplicate ..."
    +
    1033  Button b_output_duplicate, help={"copy the result to an arbitrary data folder."}
    +
    1034  Button b_output_itx, size={80,20}, proc=PearlAnglescanPanel#bp_output_itx, title="save ITX ..."
    +
    1035  Button b_output_itx, help={"save the result to an igor text file (itx)."}
    +
    1036  Button b_output_etpi, size={80,20}, proc=PearlAnglescanPanel#bp_output_etpi, title="save ETPI ..."
    +
    1037  Button b_output_etpi, help={"save the result to a pmsco angle scan file (etpi)."}
    +
    1038 
    +
    1039  GroupBox gb_graph, title="graph"
    +
    1040  PopupMenu pm_graph_colortable, size={152,21}, bodyWidth=100, proc=PearlAnglescanPanel#pmp_graph_colortable, title="color table"
    +
    1041  PopupMenu pm_graph_colortable, mode=0, value= #"\"*COLORTABLEPOPNONAMES*\""
    +
    1042  PopupMenu pm_graph_colortable, help={"color table to use in pseudocolor graphs."}
    +
    1043  SetVariable sv_graph_contrast, size={119,16}, bodyWidth=60, title="contrast (%)"
    +
    1044  SetVariable sv_graph_contrast, limits={0,25,1}, value= root:packages:pearl_anglescan_panel:graph_contrast
    +
    1045  SetVariable sv_graph_contrast, help={"contrast value (percentile)."}
    +
    1046  Button b_graph_update, size={80,20}, proc=PearlAnglescanPanel#bp_graph_update, title="update"
    +
    1047  Button b_graph_update, help={"update the existing graph."}
    +
    1048  Button b_graph_png, size={80,20}, proc=PearlAnglescanPanel#bp_graph_png, title="save PNG ..."
    +
    1049  Button b_graph_png, help={"save the graph in png format."}
    +
    1050 
    + +
    1052  update_menus()
    +
    1053 end
    +
    1054 
    +
    1055 static function arrange_controls()
    +
    1056  dfref df = $(package_path)
    +
    1057  svar /sdfr=df panel_name
    +
    1058 
    +
    1059  variable gb_space = 2
    +
    1060  variable gb_internal_top = 16
    +
    1061  variable gb_internal_bot = 4
    +
    1062  variable line_space = 22
    +
    1063 
    +
    1064  variable cb_adj = 2
    +
    1065  variable sv_adj = 2
    +
    1066  variable pm_adj = 0
    +
    1067  variable b_adj = 0
    +
    1068  variable tb_adj = 0
    +
    1069 
    +
    1070  variable gb_top = 4
    +
    1071  variable gb_ht = 0
    +
    1072 
    +
    1073  // ht = line + 30
    +
    1074  // gb = gb + ht + 2
    +
    1075  // cb = gb + 18
    +
    1076  // pm = gb + 38
    +
    1077  // line += 26
    +
    1078  // sv = line + 2
    +
    1079 
    +
    1080  GroupBox gb_source,pos={4,gb_top}
    +
    1081  gb_ht = gb_internal_top
    +
    1082  Button b_source_select,pos={17, gb_top + gb_ht + b_adj},size={50,20}
    +
    1083  Button b_source_update, pos={67, gb_top + gb_ht + b_adj},size={50,20}
    +
    1084  gb_ht += line_space
    +
    1085  TitleBox tb_source_path,pos={18, gb_top + gb_ht + tb_adj},size={240,21}
    +
    1086  gb_ht += line_space
    +
    1087  gb_ht += gb_internal_bot
    +
    1088  GroupBox gb_source, size={272,gb_ht}
    +
    1089 
    +
    1090  gb_top += gb_ht + gb_space
    +
    1091  GroupBox gb_offsets,pos={4,gb_top}
    +
    1092  gb_ht = gb_internal_top
    +
    1093  SetVariable sv_theta_offset,pos={46, gb_top + gb_ht + sv_adj},size={88,16}
    +
    1094  Button b_save_prefs,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1095  gb_ht += line_space
    +
    1096  SetVariable sv_tilt_offset,pos={60, gb_top + gb_ht + sv_adj},size={74,16}
    +
    1097  Button b_load_prefs,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1098  gb_ht += line_space
    +
    1099  SetVariable sv_phi_offset,pos={56, gb_top + gb_ht + sv_adj},size={78,16}
    +
    1100  gb_ht += line_space
    +
    1101  SetVariable sv_alpha_offset,pos={44, gb_top + gb_ht + sv_adj},size={90,16}
    +
    1102  gb_ht += line_space
    +
    1103  gb_ht += gb_internal_bot
    +
    1104  GroupBox gb_offsets, size={272,gb_ht}
    +
    1105 
    +
    1106  gb_top += gb_ht + gb_space
    +
    1107  GroupBox gb_crop,pos={4,gb_top}
    +
    1108  gb_ht = gb_internal_top
    +
    1109  CheckBox cb_crop_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    +
    1110  gb_ht += line_space
    +
    1111  SetVariable sv_crop_alpha, pos={44, gb_top + gb_ht + sv_adj}, size={90,16}
    +
    1112  Button b_crop_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1113  gb_ht += line_space
    +
    1114  SetVariable sv_crop_theta, pos={44, gb_top + gb_ht + sv_adj}, size={90,16}
    +
    1115  gb_ht += line_space
    +
    1116  SetVariable sv_crop_rows, pos={44, gb_top + gb_ht + sv_adj}, size={190,16}
    +
    1117  gb_ht += line_space
    +
    1118  gb_ht += gb_internal_bot
    +
    1119  GroupBox gb_crop, size={272,gb_ht}
    +
    1120 
    +
    1121  gb_top += gb_ht + gb_space
    +
    1122  GroupBox gb_norm_alpha,pos={4,gb_top}
    +
    1123  gb_ht = gb_internal_top
    +
    1124  CheckBox cb_norm_alpha_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    +
    1125  gb_ht += line_space
    +
    1126  PopupMenu pm_norm_alpha_mode,pos={36, gb_top + gb_ht + pm_adj},size={138,21}
    +
    1127  Button b_norm_alpha_check,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1128  gb_ht += line_space
    +
    1129  SetVariable sv_norm_alpha_smoothing,pos={22, gb_top + gb_ht + sv_adj},size={112,16}
    +
    1130  Button b_norm_alpha_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1131  gb_ht += line_space
    +
    1132  gb_ht += gb_internal_bot
    +
    1133  GroupBox gb_norm_alpha, size={272,gb_ht}
    +
    1134 
    +
    1135  gb_top += gb_ht + gb_space
    +
    1136  GroupBox gb_norm_phi,pos={4,gb_top}
    +
    1137  gb_ht = gb_internal_top
    +
    1138  CheckBox cb_norm_phi_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    +
    1139  Button b_norm_phi_check,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1140  gb_ht += line_space
    +
    1141  SetVariable sv_norm_phi_range,pos={15, gb_top + gb_ht + sv_adj},size={118,16}
    +
    1142  Button b_norm_phi_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1143  gb_ht += line_space
    +
    1144  gb_ht += gb_internal_bot
    +
    1145  GroupBox gb_norm_phi, size={272,gb_ht}
    +
    1146 
    +
    1147  gb_top += gb_ht + gb_space
    +
    1148  GroupBox gb_norm_theta,pos={4,gb_top}
    +
    1149  gb_ht = gb_internal_top
    +
    1150  CheckBox cb_norm_theta_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    +
    1151  gb_ht += line_space
    +
    1152  PopupMenu pm_norm_theta_domain, pos={35, gb_top + gb_ht + pm_adj}, size={138,21}
    +
    1153  Button b_norm_theta_check,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1154  gb_ht += line_space
    +
    1155  PopupMenu pm_norm_theta_mode,pos={35, gb_top + gb_ht + pm_adj},size={138,21}
    +
    1156  Button b_norm_theta_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1157  gb_ht += line_space
    +
    1158  SetVariable sv_norm_theta_smoothing,pos={21, gb_top + gb_ht + sv_adj},size={112,16}
    +
    1159  gb_ht += line_space
    +
    1160  gb_ht += gb_internal_bot
    +
    1161  GroupBox gb_norm_theta, size={272,gb_ht}
    +
    1162 
    +
    1163  gb_top += gb_ht + gb_space
    +
    1164  GroupBox gb_norm_thetaphi,pos={4,gb_top}
    +
    1165  gb_ht = gb_internal_top
    +
    1166  CheckBox cb_norm_thetaphi_enable,pos={73, gb_top + gb_ht + cb_adj},size={50,14}
    +
    1167  gb_ht += line_space
    +
    1168  PopupMenu pm_norm_thetaphi_mode,pos={35, gb_top + gb_ht + pm_adj},size={138,21}
    +
    1169  Button b_norm_thetaphi_check,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1170  gb_ht += line_space
    +
    1171  SetVariable sv_norm_thetaphi_smoothing,pos={21, gb_top + gb_ht + sv_adj},size={112,16}
    +
    1172  Button b_norm_thetaphi_preview,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1173  gb_ht += line_space
    +
    1174  gb_ht += gb_internal_bot
    +
    1175  GroupBox gb_norm_thetaphi, size={272,gb_ht}
    +
    1176 
    +
    1177  gb_top += gb_ht + gb_space
    +
    1178  GroupBox gb_output,pos={4,gb_top}
    +
    1179  gb_ht = gb_internal_top
    +
    1180  SetVariable sv_output_folding,pos={38, gb_top + gb_ht + sv_adj},size={95,16}
    +
    1181  Button b_output_calc,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1182  gb_ht += line_space
    +
    1183  SetVariable sv_output_horizon,pos={35, gb_top + gb_ht + sv_adj},size={98,16}
    +
    1184  Button b_output_duplicate,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1185  gb_ht += line_space
    +
    1186  PopupMenu pm_graph_projection,pos={24, gb_top + gb_ht + pm_adj},size={149,21}
    +
    1187  Button b_output_itx,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1188  gb_ht += line_space
    +
    1189  PopupMenu pm_graph_mode,pos={44, gb_top + gb_ht + pm_adj},size={129,21}
    +
    1190  Button b_output_etpi,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1191  gb_ht += line_space
    +
    1192  gb_ht += gb_internal_bot
    +
    1193  GroupBox gb_output, size={272,gb_ht}
    +
    1194 
    +
    1195  gb_top += gb_ht + gb_space
    +
    1196  GroupBox gb_graph,pos={4,gb_top}
    +
    1197  gb_ht = gb_internal_top
    +
    1198  PopupMenu pm_graph_colortable,pos={21, gb_top + gb_ht + pm_adj},size={152,21}
    +
    1199  Button b_graph_update,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1200  gb_ht += line_space
    +
    1201  SetVariable sv_graph_contrast,pos={14, gb_top + gb_ht + sv_adj},size={119,16}
    +
    1202  Button b_graph_png,pos={186, gb_top + gb_ht + b_adj},size={80,20}
    +
    1203  gb_ht += line_space
    +
    1204  gb_ht += gb_internal_bot
    +
    1205  GroupBox gb_graph, size={272,gb_ht}
    +
    1206 
    +
    1207  gb_top += gb_ht + gb_space
    +
    1208  //MoveWindow 200, 100, 479, 100 + gb_top
    +
    1209 end
    +
    1210 
    +
    1213 static function update_menus()
    +
    1214  dfref df = $(package_path)
    +
    1215  svar /sdfr=df panel_name
    +
    1216  if (wintype(panel_name) == 7)
    +
    1217  variable m
    +
    1218  nvar /sdfr=df norm_alpha_mode
    +
    1219  m = norm_alpha_mode + 1
    +
    1220  PopupMenu pm_norm_alpha_mode win=$panel_name, mode=m
    +
    1221  nvar /sdfr=df norm_theta_domain
    +
    1222  m = norm_theta_domain + 1
    +
    1223  PopupMenu pm_norm_theta_domain win=$panel_name, mode=m
    +
    1224  nvar /sdfr=df norm_theta_mode
    +
    1225  m = norm_theta_mode + 1
    +
    1226  PopupMenu pm_norm_theta_mode win=$panel_name, mode=m
    +
    1227  nvar /sdfr=df norm_thetaphi_mode
    +
    1228  m = norm_thetaphi_mode + 1
    +
    1229  PopupMenu pm_norm_thetaphi_mode win=$panel_name, mode=m
    +
    1230  nvar /sdfr=df graph_mode
    +
    1231  m = graph_mode + 1
    +
    1232  PopupMenu pm_graph_mode win=$panel_name, mode=m
    +
    1233  nvar /sdfr=df graph_projection
    +
    1234  m = graph_projection + 1
    +
    1235  PopupMenu pm_graph_projection win=$panel_name, mode=m
    +
    1236  svar /sdfr=df graph_colortable
    +
    1237  m = 1 + WhichListItem(graph_colortable, CTabList())
    +
    1238  PopupMenu pm_graph_colortable win=$panel_name, mode=m
    +
    1239  endif
    +
    1240 end
    +
    1241 
    +
    1242 static function bp_load_prefs(ba) : ButtonControl
    +
    1243  STRUCT WMButtonAction &ba
    +
    1244 
    +
    1245  switch( ba.eventCode )
    +
    1246  case 2: // mouse up
    +
    1247  load_prefs()
    +
    1248  break
    +
    1249  case -1: // control being killed
    +
    1250  break
    +
    1251  endswitch
    +
    1252 
    +
    1253  return 0
    +
    1254 End
    +
    1255 
    +
    1256 static function bp_save_prefs(ba) : ButtonControl
    +
    1257  STRUCT WMButtonAction &ba
    +
    1258 
    +
    1259  switch( ba.eventCode )
    +
    1260  case 2: // mouse up
    +
    1261  save_prefs()
    +
    1262  break
    +
    1263  case -1: // control being killed
    +
    1264  break
    +
    1265  endswitch
    +
    1266 
    +
    1267  return 0
    +
    1268 End
    +
    1269 
    +
    1270 static function bp_source_select(ba) : ButtonControl
    +
    1271  STRUCT WMButtonAction &ba
    +
    1272 
    +
    1273  switch( ba.eventCode )
    +
    1274  case 2: // mouse up
    +
    1275  dfref dfBefore = GetDataFolderDFR()
    +
    1276  Execute /q/z "CreateBrowser prompt=\"Select 2D holo scan wave\", showWaves=1, showVars=0, showStrs=0"
    +
    1277  dfref dfAfter = GetDataFolderDFR()
    +
    1278  SetDataFolder dfBefore
    +
    1279 
    +
    1280  SVAR list = S_BrowserList
    +
    1281  NVAR flag = V_Flag
    +
    1282  if ((flag != 0) && (ItemsInList(list) >= 1))
    +
    1283  string wname = StringFromList(0, list)
    +
    1284  wave w = $wname
    +
    1285  asp_import_raw(w)
    +
    1286  endif
    +
    1287 
    +
    1288  break
    +
    1289  case -1: // control being killed
    +
    1290  break
    +
    1291  endswitch
    +
    1292 
    +
    1293  return 0
    +
    1294 End
    +
    1295 
    +
    1296 static function bp_source_update(ba) : ButtonControl
    +
    1297  STRUCT WMButtonAction &ba
    +
    1298 
    +
    1299  switch( ba.eventCode )
    +
    1300  case 2: // mouse up
    +
    1301  dfref packdf = $package_path
    +
    1302  svar /sdfr=packdf source_path
    +
    1303  wave /z w = $source_path
    +
    1304  if (waveexists(w))
    +
    1305  asp_import_raw(w)
    +
    1306  else
    +
    1307  DoAlert 0, "can't find source data."
    +
    1308  endif
    +
    1309  break
    +
    1310  case -1: // control being killed
    +
    1311  break
    +
    1312  endswitch
    +
    1313 
    +
    1314  return 0
    +
    1315 End
    +
    1316 
    +
    1317 static function bp_norm_alpha_check(ba) : ButtonControl
    +
    1318  STRUCT WMButtonAction &ba
    +
    1319 
    +
    1320  switch( ba.eventCode )
    +
    1321  case 2: // mouse up
    + +
    1323  break
    +
    1324  case -1: // control being killed
    +
    1325  break
    +
    1326  endswitch
    +
    1327 
    +
    1328  return 0
    +
    1329 End
    +
    1330 
    +
    1331 static function bp_norm_theta_check(ba) : ButtonControl
    +
    1332  STRUCT WMButtonAction &ba
    +
    1333 
    +
    1334  switch( ba.eventCode )
    +
    1335  case 2: // mouse up
    + +
    1337  break
    +
    1338  case -1: // control being killed
    +
    1339  break
    +
    1340  endswitch
    +
    1341 
    +
    1342  return 0
    +
    1343 End
    +
    1344 
    +
    1345 static function bp_norm_phi_check(ba) : ButtonControl
    +
    1346  STRUCT WMButtonAction &ba
    +
    1347 
    +
    1348  switch( ba.eventCode )
    +
    1349  case 2: // mouse up
    +
    1350  check_norm_phi()
    +
    1351  break
    +
    1352  case -1: // control being killed
    +
    1353  break
    +
    1354  endswitch
    +
    1355 
    +
    1356  return 0
    +
    1357 End
    +
    1358 
    +
    1359 static function bp_norm_thetaphi_check(ba) : ButtonControl
    +
    1360  STRUCT WMButtonAction &ba
    +
    1361 
    +
    1362  switch( ba.eventCode )
    +
    1363  case 2: // mouse up
    + +
    1365  break
    +
    1366  case -1: // control being killed
    +
    1367  break
    +
    1368  endswitch
    +
    1369 
    +
    1370  return 0
    +
    1371 End
    +
    1372 
    +
    1373 static function bp_crop_preview(ba) : ButtonControl
    +
    1374  STRUCT WMButtonAction &ba
    +
    1375 
    +
    1376  switch( ba.eventCode )
    +
    1377  case 2: // mouse up
    +
    1378  preview_crop()
    +
    1379  break
    +
    1380  case -1: // control being killed
    +
    1381  break
    +
    1382  endswitch
    +
    1383 
    +
    1384  return 0
    +
    1385 End
    +
    1386 
    +
    1387 static function bp_norm_alpha_preview(ba) : ButtonControl
    +
    1388  STRUCT WMButtonAction &ba
    +
    1389 
    +
    1390  switch( ba.eventCode )
    +
    1391  case 2: // mouse up
    + +
    1393  break
    +
    1394  case -1: // control being killed
    +
    1395  break
    +
    1396  endswitch
    +
    1397 
    +
    1398  return 0
    +
    1399 End
    +
    1400 
    +
    1401 static function bp_norm_phi_preview(ba) : ButtonControl
    +
    1402  STRUCT WMButtonAction &ba
    +
    1403 
    +
    1404  switch( ba.eventCode )
    +
    1405  case 2: // mouse up
    + +
    1407  break
    +
    1408  case -1: // control being killed
    +
    1409  break
    +
    1410  endswitch
    +
    1411 
    +
    1412  return 0
    +
    1413 End
    +
    1414 
    +
    1415 static function bp_norm_theta_preview(ba) : ButtonControl
    +
    1416  STRUCT WMButtonAction &ba
    +
    1417 
    +
    1418  switch( ba.eventCode )
    +
    1419  case 2: // mouse up
    + +
    1421  break
    +
    1422  case -1: // control being killed
    +
    1423  break
    +
    1424  endswitch
    +
    1425 
    +
    1426  return 0
    +
    1427 End
    +
    1428 
    +
    1429 static function bp_norm_thetaphi_preview(ba) : ButtonControl
    +
    1430  STRUCT WMButtonAction &ba
    +
    1431 
    +
    1432  switch( ba.eventCode )
    +
    1433  case 2: // mouse up
    + +
    1435  break
    +
    1436  case -1: // control being killed
    +
    1437  break
    +
    1438  endswitch
    +
    1439 
    +
    1440  return 0
    +
    1441 End
    +
    1442 
    +
    1443 static function bp_output_calc(ba) : ButtonControl
    +
    1444  STRUCT WMButtonAction &ba
    +
    1445 
    +
    1446  switch( ba.eventCode )
    +
    1447  case 2: // mouse up
    + + +
    1450  break
    +
    1451  case -1: // control being killed
    +
    1452  break
    +
    1453  endswitch
    +
    1454 
    +
    1455  return 0
    +
    1456 End
    +
    1457 
    +
    1458 static function bp_output_duplicate(ba) : ButtonControl
    +
    1459  STRUCT WMButtonAction &ba
    +
    1460 
    +
    1461  switch( ba.eventCode )
    +
    1462  case 2: // mouse up
    +
    1463  string dest_folder
    +
    1464  variable do_graph = 1
    +
    1465  prompt dest_folder, "destination folder name (relative to data source)"
    +
    1466  prompt do_graph, "duplicate graph (yes = 1, no = 0)"
    +
    1467  doprompt "duplicate", dest_folder, do_graph
    +
    1468  if (!v_flag)
    +
    1469  asp_duplicate_output(dest_folder, do_graph=do_graph)
    +
    1470  endif
    +
    1471  break
    +
    1472  case -1: // control being killed
    +
    1473  break
    +
    1474  endswitch
    +
    1475 
    +
    1476  return 0
    +
    1477 End
    +
    1478 
    +
    1479 static function bp_output_etpi(ba) : ButtonControl
    +
    1480  STRUCT WMButtonAction &ba
    +
    1481 
    +
    1482  switch( ba.eventCode )
    +
    1483  case 2: // mouse up
    +
    1484  dfref df = $(package_path)
    +
    1485  wave /sdfr=df process_data
    +
    1486  variable ekin
    +
    1487  ekin = NumberByKey("KineticEnergy", note(process_data), "=", "\r")
    +
    1488  prompt ekin, "kinetic energy"
    +
    1489  doprompt "save etpi", ekin
    +
    1490  if (!v_flag)
    +
    1491  asp_save_output_etpi(ekin)
    +
    1492  endif
    +
    1493  break
    +
    1494  case -1: // control being killed
    +
    1495  break
    +
    1496  endswitch
    +
    1497 
    +
    1498  return 0
    +
    1499 End
    +
    1500 
    +
    1501 static function bp_output_itx(ba) : ButtonControl
    +
    1502  STRUCT WMButtonAction &ba
    +
    1503 
    +
    1504  switch( ba.eventCode )
    +
    1505  case 2: // mouse up
    + +
    1507  break
    +
    1508  case -1: // control being killed
    +
    1509  break
    +
    1510  endswitch
    +
    1511 
    +
    1512  return 0
    +
    1513 End
    +
    1514 
    +
    1515 static function bp_graph_update(ba) : ButtonControl
    +
    1516  STRUCT WMButtonAction &ba
    +
    1517 
    +
    1518  switch( ba.eventCode )
    +
    1519  case 2: // mouse up
    + +
    1521  break
    +
    1522  case -1: // control being killed
    +
    1523  break
    +
    1524  endswitch
    +
    1525 
    +
    1526  return 0
    +
    1527 End
    +
    1528 
    +
    1529 static function bp_graph_png(ba) : ButtonControl
    +
    1530  STRUCT WMButtonAction &ba
    +
    1531 
    +
    1532  switch( ba.eventCode )
    +
    1533  case 2: // mouse up
    +
    1534  dfref df = $(package_path)
    +
    1535  svar /sdfr=df source_path
    +
    1536  svar /sdfr=df output_graphname
    +
    1537  if (WinType(output_graphname) == 1)
    +
    1538  SavePICT /WIN=$output_graphname /E=-5 /B=144 /TRAN=0
    +
    1539  endif
    +
    1540  break
    +
    1541  case -1: // control being killed
    +
    1542  break
    +
    1543  endswitch
    +
    1544 
    +
    1545  return 0
    +
    1546 End
    +
    1547 
    +
    1548 static function pmp_norm_alpha_mode(pa) : PopupMenuControl
    +
    1549  STRUCT WMPopupAction &pa
    +
    1550 
    +
    1551  switch( pa.eventCode )
    +
    1552  case 2: // mouse up
    +
    1553  dfref df = $(package_path)
    +
    1554  nvar /sdfr=df norm_alpha_mode
    +
    1555  norm_alpha_mode = pa.popNum - 1
    +
    1556  break
    +
    1557  case -1: // control being killed
    +
    1558  break
    +
    1559  endswitch
    +
    1560 
    +
    1561  return 0
    +
    1562 End
    +
    1563 
    +
    1564 static function pmp_norm_theta_domain(pa) : PopupMenuControl
    +
    1565  STRUCT WMPopupAction &pa
    +
    1566 
    +
    1567  switch( pa.eventCode )
    +
    1568  case 2: // mouse up
    +
    1569  dfref df = $(package_path)
    +
    1570  nvar /sdfr=df norm_theta_domain
    +
    1571  norm_theta_domain = pa.popNum - 1
    +
    1572  break
    +
    1573  case -1: // control being killed
    +
    1574  break
    +
    1575  endswitch
    +
    1576 
    +
    1577  return 0
    +
    1578 End
    +
    1579 
    +
    1580 static function pmp_norm_theta_mode(pa) : PopupMenuControl
    +
    1581  STRUCT WMPopupAction &pa
    +
    1582 
    +
    1583  switch( pa.eventCode )
    +
    1584  case 2: // mouse up
    +
    1585  dfref df = $(package_path)
    +
    1586  nvar /sdfr=df norm_theta_mode
    +
    1587  norm_theta_mode = pa.popNum - 1
    +
    1588  break
    +
    1589  case -1: // control being killed
    +
    1590  break
    +
    1591  endswitch
    +
    1592 
    +
    1593  return 0
    +
    1594 End
    +
    1595 
    +
    1596 static function pmp_norm_thetaphi_mode(pa) : PopupMenuControl
    +
    1597  STRUCT WMPopupAction &pa
    +
    1598 
    +
    1599  switch( pa.eventCode )
    +
    1600  case 2: // mouse up
    +
    1601  dfref df = $(package_path)
    +
    1602  nvar /sdfr=df norm_thetaphi_mode
    +
    1603  norm_thetaphi_mode = pa.popNum - 1
    +
    1604  break
    +
    1605  case -1: // control being killed
    +
    1606  break
    +
    1607  endswitch
    +
    1608 
    +
    1609  return 0
    +
    1610 End
    +
    1611 
    +
    1612 static function pmp_graph_mode(pa) : PopupMenuControl
    +
    1613  STRUCT WMPopupAction &pa
    +
    1614 
    +
    1615  switch( pa.eventCode )
    +
    1616  case 2: // mouse up
    +
    1617  dfref df = $(package_path)
    +
    1618  nvar /sdfr=df graph_mode
    +
    1619  graph_mode = pa.popNum - 1
    +
    1620  break
    +
    1621  case -1: // control being killed
    +
    1622  break
    +
    1623  endswitch
    +
    1624 
    +
    1625  return 0
    +
    1626 End
    +
    1627 
    +
    1628 static function pmp_graph_projection(pa) : PopupMenuControl
    +
    1629  STRUCT WMPopupAction &pa
    +
    1630 
    +
    1631  switch( pa.eventCode )
    +
    1632  case 2: // mouse up
    +
    1633  dfref df = $(package_path)
    +
    1634  nvar /sdfr=df graph_projection
    +
    1635  graph_projection = pa.popNum - 1
    +
    1636  break
    +
    1637  case -1: // control being killed
    +
    1638  break
    +
    1639  endswitch
    +
    1640 
    +
    1641  return 0
    +
    1642 End
    +
    1643 
    +
    1644 static function pmp_graph_colortable(pa) : PopupMenuControl
    +
    1645  STRUCT WMPopupAction &pa
    +
    1646 
    +
    1647  switch( pa.eventCode )
    +
    1648  case 2: // mouse up
    +
    1649  dfref df = $(package_path)
    +
    1650  svar /sdfr=df graph_colortable
    +
    1651  graph_colortable = StringFromList(pa.popNum - 1, CTabList())
    + +
    1653  break
    +
    1654  case -1: // control being killed
    +
    1655  break
    +
    1656  endswitch
    +
    1657 
    +
    1658  return 0
    +
    1659 End
    +
    static variable pmp_graph_colortable(WMPopupAction *pa)
    +
    static variable preview_norm_thetaphi()
    +
    variable asp_save_output_etpi(variable ekin)
    save the output diffractogram to a PMSCO ETPI file
    +
    variable crop_strip(wave strip, variable xlo, variable xhi)
    crop a strip at the sides.
    +
    static variable bp_norm_phi_preview(WMButtonAction *ba)
    +
    static variable bp_norm_thetaphi_preview(WMButtonAction *ba)
    +
    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
    +
    variable normalize_strip_theta(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by the average polar distribution.
    +
    variable normalize_strip_x(wave strip, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by the average X distribution.
    +
    variable asp_update_graph()
    update graphs with new color table or contrast
    +
    static variable bp_load_prefs(WMButtonAction *ba)
    +
    static variable AfterCompiledHook()
    initialize package data once when the procedure is first loaded
    +
    static variable check_norm_theta()
    +
    variable asp_import_raw(wave raw_data)
    import raw data
    +
    static variable do_norm_alpha(variable check, variable force=defaultValue)
    alpha-normalize the process data.
    +
    static variable do_crop(variable check, variable force=defaultValue)
    crop the process data.
    +
    static variable bp_output_etpi(WMButtonAction *ba)
    +
    static variable bp_norm_alpha_preview(WMButtonAction *ba)
    +
    static const string package_path
    data folder path
    +
    variable asp_show_panel()
    create the angle scan processing panel
    +
    static variable do_init_process(variable check)
    initialize the process data with a copy of the raw data.
    +
    static variable bp_norm_theta_preview(WMButtonAction *ba)
    +
    variable normalize_strip_theta_scans(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip piecewise by a smooth polar distribution.
    +
    variable crop_strip_theta(wave strip, variable theta_lo, variable theta_hi, wave theta, wave tilt, wave phi)
    crop a strip in theta.
    +
    static variable pmp_norm_alpha_mode(WMPopupAction *pa)
    +
    variable asp_display_previews()
    display a graph window of the processed data.
    +
    variable asp_display_dist_check(variable xdist, variable ydist)
    display a graph window of the distribution checks.
    +
    variable ad_update_profiles(wave image)
    update a profiles graph with new data.
    +
    static variable bp_norm_theta_check(WMButtonAction *ba)
    +
    dfr find_hemi_data(string nickname, string *prefix, string *intwave)
    finds the folder, prefix and name of holo waves given their nick name
    +
    static variable check_norm_alpha()
    +
    string asp_duplicate_output(string dest_name, variable do_graph=defaultValue)
    copy the output data to a new folder
    +
    static variable bp_output_itx(WMButtonAction *ba)
    +
    static variable pmp_graph_mode(WMPopupAction *pa)
    +
    static variable bp_norm_alpha_check(WMButtonAction *ba)
    +
    variable interpolate_hemi_scan(string nickname, variable projection=defaultValue)
    interpolate a hemispherical scan onto a rectangular grid
    +
    static variable preview_norm_phi()
    +
    static variable pmp_norm_thetaphi_mode(WMPopupAction *pa)
    +
    static variable bp_save_prefs(WMButtonAction *ba)
    +
    static variable load_prefs()
    load persistent package data from the preferences file.
    +
    static variable update_menus()
    update the popup menus to reflect the values of the global variables
    +
    static variable bp_source_update(WMButtonAction *ba)
    +
    static variable do_norm_phi(variable check, variable force=defaultValue)
    phi-normalize the process data.
    +
    static variable do_norm_theta(variable check, variable force=defaultValue)
    theta-normalize the process data.
    +
    string pmsco_save_scan(string pathname, string filename, string energy, string theta, string phi, string alpha, string intensity, string sigma, dfref sdfr=defaultValue)
    save waves in a PMSCO scan data file.
    +
    static variable pmp_norm_theta_mode(WMPopupAction *pa)
    +
    static const string prefs_objects
    semicolon-separated list of persistent variable, string, and wave names
    +
    variable asp_close_graphs()
    close all graphs created by the angle scan panel
    +
    static variable init_package()
    +
    static variable check_norm_thetaphi()
    +
    static variable delete_rows(string rows, wave data, wave theta, wave tilt, wave phi)
    delete individual rows from the data strip
    +
    variable set_contrast(variable pcmin, variable pcmax, string graphname=defaultValue, string colortable=defaultValue, variable reversecolors=defaultValue, variable symmetric=defaultValue)
    set the pseudocolor contrast by percentile.
    +
    static variable pmp_graph_projection(WMPopupAction *pa)
    +
    variable save_hemi_scan(string nickname, string pathname, string filename)
    save a hemispherical scan to an Igor text file
    +
    static variable check_norm_phi()
    +
    const variable kProjStereo
    +
    variable normalize_strip_thetaphi(wave strip, wave theta, wave phi, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by a smooth polar-azimuthal distribution.
    +
    static variable preview_norm_alpha()
    +
    static variable arrange_controls()
    +
    static variable do_norm_thetaphi(variable check, variable force=defaultValue)
    theta,phi-normalize the process data.
    +
    static variable pmp_norm_theta_domain(WMPopupAction *pa)
    +
    static variable bp_graph_update(WMButtonAction *ba)
    +
    static variable save_prefs()
    save persistent package data to the preferences file.
    +
    static variable bp_output_calc(WMButtonAction *ba)
    +
    variable duplicate_hemi_scan(string source_nickname, dfref dest_folder, string dest_nickname, variable xpdplot=defaultValue)
    duplicate a hemispherical scan dataset.
    +
    variable asp_calculate_output()
    calculate the output using all enabled processing filters.
    +
    static variable bp_output_duplicate(WMButtonAction *ba)
    +
    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).
    +
    static variable bp_norm_thetaphi_check(WMButtonAction *ba)
    +
    static variable bp_graph_png(WMButtonAction *ba)
    +
    variable asp_save_output_itx()
    save the output diffractogram to an igor text file
    +
    static variable bp_norm_phi_check(WMButtonAction *ba)
    +
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    +
    static variable preview_norm_theta()
    +
    static variable preview_crop()
    +
    string asp_display_output(dfref data_df=defaultValue, string data_name=defaultValue)
    display the output diffractogram
    +
    static const string package_name
    package name is used as data folder name
    +
    static variable bp_crop_preview(WMButtonAction *ba)
    +
    static variable bp_source_select(WMButtonAction *ba)
    +
    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.
    +
    interactive processing of angle scanned XPD data.
    diff --git a/doc/html/pearl-anglescan-process_8ipf.html b/doc/html/pearl-anglescan-process_8ipf.html index cdece11..36468a1 100644 --- a/doc/html/pearl-anglescan-process_8ipf.html +++ b/doc/html/pearl-anglescan-process_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-anglescan-process.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -106,155 +108,164 @@ Namespaces + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + - + - + - + - + - + - + - + - + - + - - - - - + + + + + - +

    Functions

    string strip_append (wave strip1, wave strip2)
     append an angle scan strip to another one More...
     
    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. More...
     delete a contiguous range of frames from a strip. More...
     
    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. More...
     divide the strip by the average X distribution. More...
     
    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). More...
     divide the strip by a sine function in phi (wobble correction). More...
     
    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. More...
     divide the strip by the average polar distribution. More...
     
    variable normalize_strip_thetaphi (wave strip, wave theta, wave phi, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
     divide the strip by a smooth polar-azimuthal distribution. More...
     divide the strip by a smooth polar-azimuthal distribution. More...
     
    variable normalize_strip_theta_scans (wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
     divide the strip piecewise by a smooth polar distribution. More...
     divide the strip piecewise by a smooth polar distribution. More...
     
    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. More...
     divide the strip by a two-dimensional normalization function. More...
     
    variable crop_strip (wave strip, variable xlo, variable xhi)
     crop a strip at the sides. More...
     crop a strip at the sides. More...
     
    variable crop_strip_theta (wave strip, variable theta_lo, variable theta_hi, wave theta, wave tilt, wave phi)
     crop a strip in theta. More...
     crop a strip in theta. More...
     
    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 More...
     create a pizza plot from a measured (energy-integrated) data strip More...
     
    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 More...
     create a pizza plot from a measured (energy-integrated) data strip More...
     
    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 More...
     calculate and display the line seen by the analyser for a specific emission angle More...
     
    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. More...
     convert angles from TTPA (theta-tilt-phi-analyser) scheme to polar coordinates. More...
     
    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. More...
     convert angles from TTPA (theta-tilt-phi-analyser) scheme to polar coordinates. More...
     
    static variable line_average (wave source, wave dest)
     
    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 More...
     calculate the number of phis for a given theta More...
     
    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 More...
     calculate delta-phi for a given theta More...
     
    static variable Calc_The_step (variable th, variable Theta_st, string Holomode)
     calculate delta-theta for a given theta More...
     calculate delta-theta for a given theta More...
     
    static variable CalcN_Theta (string HoloMode, variable Theta_in, variable Theta_ran, variable Theta_st)
     calculate the number of thetas for a pattern More...
     calculate the number of thetas for a pattern More...
     
    variable make_hemi_grid (variable npol, string nickname, variable xpdplot=defaultValue)
     create a hemispherical, constant solid angle grid More...
     create a hemispherical, constant solid angle grid More...
     
    string get_hemi_nickname (wave w)
     finds the nick name given any hemi wave More...
     finds the nick name given any hemi wave More...
     
    string get_hemi_prefix (wave w)
     finds the prefix given any hemi wave More...
     finds the prefix given any hemi wave More...
     
    dfr find_hemi_data (string nickname, string *prefix, string *intwave)
     finds the folder, prefix and name of holo waves given their nick name More...
     finds the folder, prefix and name of holo waves given their nick name More...
     
    variable clear_hemi_grid (string nickname)
     clear a hemispherical scan grid More...
     clear a hemispherical scan grid More...
     
    variable duplicate_hemi_scan (string source_nickname, dfref dest_folder, string dest_nickname, variable xpdplot=defaultValue)
     duplicate a hemispherical scan dataset. More...
     duplicate a hemispherical scan dataset. More...
     
    variable rotate_hemi_scan (string nickname, variable angle)
     azimuthally rotate a hemispherical scan dataset. More...
     azimuthally rotate a hemispherical scan dataset. More...
     
    string prepare_hemi_scan_display (string nickname, variable projection=defaultValue)
     create waves for plotting a hemispherical angle scan. More...
     create waves for plotting a hemispherical angle scan. More...
     
    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. More...
     display a plot of a hemispherical angle scan. More...
     
    static string display_polar_graph (string graphname, variable angle_offset=defaultValue, variable do_ticks=defaultValue)
     displays an empty polar graph More...
     displays an empty polar graph More...
     
    static string draw_hemi_axes (string graphname, variable do_grids=defaultValue)
     draw polar and azimuthal grids in an existing polar graph. More...
     draw polar and azimuthal grids in an existing polar graph. More...
     
    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. More...
     draw the circle of a diffraction cone in a stereographic polar graph. More...
     
    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. More...
     display a polar graph with lines indicating the angles covered by an angle scan. More...
     
    threadsafe variable calc_graph_radius (variable polar, variable projection=defaultValue)
     calculate the projected polar angle More...
     calculate the projected polar angle More...
     
    threadsafe variable calc_graph_polar (variable x, variable y, variable projection=defaultValue)
     calculate polar angle from Cartesian coordinate More...
     calculate polar angle from Cartesian coordinate More...
     
    threadsafe variable calc_graph_azi (variable x, variable y, variable projection=defaultValue, variable zeroAngle=defaultValue)
     calculate azimuthal angle from Cartesian coordinate More...
     calculate azimuthal angle from Cartesian coordinate More...
     
    static variable update_polar_info (string graphname)
     update the angles info based on cursors A and B of a given polar graph window More...
     update the angles info based on cursors A and B of a given polar graph window More...
     
    static variable polar_graph_hook (WMWinHookStruct *s)
     polar graph window hook More...
     polar graph window hook More...
     
    variable set_polar_graph_cursor (string nickname, string cursorname, variable polar_angle, variable azim_angle, string graphname=defaultValue)
     
    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. More...
     add arbitrary angle scan data to a hemispherical scan grid. More...
     
    static threadsafe dfr add_anglescan_worker (variable ith, wave values, wave weights, wave polar, wave azi, wave w_polar, wave w_azim, wave w_theta, wave w_index, wave w_dphi, wave w_nphis)
     thread worker for hemi_add_anglescan More...
     
    static threadsafe variable add_aziscan_core (wave values, wave weights, variable polar, wave azi, wave w_theta, wave w_azim, wave w_index, wave w_dphi, wave w_totals, wave w_weights)
     thread worker for hemi_add_anglescan and hemi_add_aziscan More...
     
    variable hemi_add_aziscan (string nickname, wave values, variable polar, wave azi, wave weights=defaultValue)
     add an azimuthal scan to a hemispherical scan grid. More...
     add azimuthal data to a hemispherical scan grid. More...
     
    variable interpolate_hemi_scan (string nickname, variable projection=defaultValue)
     interpolate a hemispherical scan onto a rectangular grid More...
     interpolate a hemispherical scan onto a rectangular grid More...
     
    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 More...
     map angle scan data onto a rectangular grid in stereographic projection More...
     
    variable save_hemi_scan (string nickname, string pathname, string filename)
     save a hemispherical scan to an Igor text file More...
     save a hemispherical scan to an Igor text file More...
     
    variable load_hemi_scan (string nickname, string pathname, string filename)
     load a hemispherical scan from an Igor text file More...
     load a hemispherical scan from an Igor text file More...
     
    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 More...
     import a hemispherical scan from theta-phi-intensity waves and display it More...
     
    variable trim_hemi_scan (string nickname, variable theta_max)
     trim a hemispherical scan at grazing angle More...
     trim a hemispherical scan at grazing angle More...
     
    wave hemi_polar_cut (string nickname, variable azim)
     extract a polar cut from a hemispherical scan. More...
     extract a polar cut from a hemispherical scan. More...
     
    wave hemi_azi_cut (string nickname, variable pol)
     extract an azimuthal cut from a hemispherical scan More...
     extract an azimuthal cut from a hemispherical scan More...
     
    static variable check_contrast (wave values, variable pcmin, variable pcmax, variable *vmin, variable *vmax)
     
    variable set_contrast (variable pcmin, variable pcmax, string graphname=defaultValue, string colortable=defaultValue)
     set the pseudocolor contrast by percentile. More...
     
    static variable check_contrast (wave values, variable pcmin, variable pcmax, variable *vmin, variable *vmax, variable sym)
     
    variable set_contrast (variable pcmin, variable pcmax, string graphname=defaultValue, string colortable=defaultValue, variable reversecolors=defaultValue, variable symmetric=defaultValue)
     set the pseudocolor contrast by percentile. More...
     
    variable AngleToK (wave inwave)
     k-space mapping of 2D angle-energy distribution (scienta image) More...
     k-space mapping of 2D angle-energy distribution (scienta image) More...
     
    - +

    @@ -293,14 +304,201 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to * phi_sample = 270 if tilt_manipulator - tilt_offset > 0 * phi_sample = 90 if tilt_manipulator - tilt_offset < 0 *
    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -
    Returns
    the output wave has the name of the input wave with the suffix "_k".
    -

    Definition at line 3332 of file pearl-anglescan-process.ipf.

    +

    Definition at line 3562 of file pearl-anglescan-process.ipf.

    @@ -392,7 +590,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Returns
    polar angle in degrees
    -

    Definition at line 2393 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2467 of file pearl-anglescan-process.ipf.

    @@ -429,7 +627,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    calculate polar angle from Cartesian coordinate

    -

    this is the reverse mapping to calc_graph_radius()

    +

    this is the reverse mapping to calc_graph_radius()

    Parameters
    @@ -446,7 +644,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Returns
    polar angle in degrees
    -

    Definition at line 2340 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2414 of file pearl-anglescan-process.ipf.

    @@ -493,7 +691,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Returns
    projected radius. the radius is scaled such that grazing emission maps to 2.
    -

    Definition at line 2295 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2369 of file pearl-anglescan-process.ipf.

    @@ -558,7 +756,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    calculate the number of phis for a given theta

    adapted from XPDplot 8.03

    -

    Definition at line 1149 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1223 of file pearl-anglescan-process.ipf.

    @@ -623,7 +821,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    calculate delta-phi for a given theta

    adapted from XPDplot 8.03

    -

    Definition at line 1178 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1252 of file pearl-anglescan-process.ipf.

    @@ -670,7 +868,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    calculate delta-theta for a given theta

    adapted from XPDplot 8.03

    -

    Definition at line 1222 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1296 of file pearl-anglescan-process.ipf.

    @@ -723,12 +921,12 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    calculate the number of thetas for a pattern

    adapted from XPDplot 8.03

    -

    Definition at line 1253 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1327 of file pearl-anglescan-process.ipf.

    - -

    ◆ check_contrast()

    + +

    ◆ check_contrast()

    @@ -764,7 +962,13 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    - + + + + + + + @@ -779,7 +983,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    x,yprojected Cartesian coordinate
    variable * vmax vmax,
    variable sym 
    -

    Definition at line 3212 of file pearl-anglescan-process.ipf.

    +

    Definition at line 3407 of file pearl-anglescan-process.ipf.

    @@ -808,7 +1012,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to -

    Definition at line 1532 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1606 of file pearl-anglescan-process.ipf.

    @@ -877,7 +1081,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    for the output parameters polar and azi, you need to pass in existing numeric waves. dimension size does not matter, the waves are redimensioned by the function so that they have the same dimensions as the intensity data set. X dimension = analyser scale, Y dimension = manipulator scan.

    -

    Definition at line 1088 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1162 of file pearl-anglescan-process.ipf.

    @@ -932,9 +1136,9 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    convert angles from TTPA (theta-tilt-phi-analyser) scheme to polar coordinates.

    -

    similar to convert_angles_ttpa2polar() but reads the analyser angles from the X scale of data

    +

    similar to convert_angles_ttpa2polar() but reads the analyser angles from the X scale of data

    -

    Definition at line 1049 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1123 of file pearl-anglescan-process.ipf.

    @@ -982,7 +1186,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Remarks
    cropping should be done after smoothing and normalization operations to reduce artefacts.
    -

    Definition at line 673 of file pearl-anglescan-process.ipf.

    +

    Definition at line 747 of file pearl-anglescan-process.ipf.

    @@ -1050,7 +1254,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to -

    Definition at line 705 of file pearl-anglescan-process.ipf.

    +

    Definition at line 779 of file pearl-anglescan-process.ipf.

    @@ -1120,7 +1324,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    graphtypetype of graph
    • 1 (pol, az) trace in Igor "New Polar" (default).
    • 2 XPDplot (reserved, not implemented).
    • -
    • 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.
    • +
    • 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.
    do_ticksselect which ticks to draw. value must be the arithmetic OR of all selected items. default: 3
      @@ -1141,7 +1345,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
      Returns
      the name of the graph window
      -

      Definition at line 1784 of file pearl-anglescan-process.ipf.

      +

      Definition at line 1858 of file pearl-anglescan-process.ipf.

      @@ -1211,7 +1415,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
      Returns
      the name of the graph window.
      Version
      1.7 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.
      -

      Definition at line 1929 of file pearl-anglescan-process.ipf.

      +

      Definition at line 2003 of file pearl-anglescan-process.ipf.

      @@ -1287,13 +1491,13 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    m_tiltmanipulator tilt angles, 0 = normal emission. size = dimsize(data, 1)
    m_phimanipulator phi angles, 0 = azimuthal origin. size = dimsize(data, 1)
    foldingrotational averaging, default = 1
    projectionmapping function from polar to cartesian coordinates. see calc_graph_radius().
    projectionmapping function from polar to cartesian coordinates. see calc_graph_radius().
    Remarks
    this function is extremely slow.
    -

    Definition at line 2180 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2254 of file pearl-anglescan-process.ipf.

    @@ -1355,7 +1559,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Warning
    EXPERIMENTAL! this function is under development. the interface and behaviour of this function may change significantly in future versions.
    -

    Definition at line 2116 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2190 of file pearl-anglescan-process.ipf.

    @@ -1399,7 +1603,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
  • 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. in interactive drawing mode, you can select the active drawing layer by clicking the tree icon while holding the Alt key.

    -

    the graph must have been created by display_polar_graph(). the function reads the projection mode from the window user data "projection".

    +

    the graph must have been created by display_polar_graph(). the function reads the projection mode from the window user data "projection".

    Parameters
    @@ -1414,7 +1618,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Warning
    EXPERIMENTAL! this function is under development. the interface and behaviour of this function may change significantly in future versions.
    -

    Definition at line 2044 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2118 of file pearl-anglescan-process.ipf.

    @@ -1457,7 +1661,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    duplicate a hemispherical scan dataset.

    -

    this function works only for hemi scans created by make_hemi_grid() (or compatible functions). the angle grid is recreated rather than copied point-by-point. the new dataset is independent from the original one.

    +

    this function works only for hemi scans created by make_hemi_grid() (or compatible functions). the angle grid is recreated rather than copied point-by-point. the new dataset is independent from the original one.

    if the version of the source dataset is pre 1.6, it is converted to version 1.6.

    Parameters
    graphnamename of graph window.
    @@ -1473,7 +1677,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to -

    Definition at line 1579 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1653 of file pearl-anglescan-process.ipf.

    @@ -1526,7 +1730,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Returns
    reference of the data folder which contains the waves
    -

    Definition at line 1498 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1572 of file pearl-anglescan-process.ipf.

    @@ -1550,7 +1754,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    the nick name is either the name of a child folder in the current data folder (PEARL specification), or a prefix of the hemi wave names (XPDplot specification).

    Returns
    the nick name
    -

    Definition at line 1442 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1516 of file pearl-anglescan-process.ipf.

    @@ -1574,7 +1778,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    the prefix is the part of the wave name before the first underscore. the prefix is used by XPDplot where it is identical to the nick name. the prefix is empty in the PEARL specification.

    Returns
    the prefix
    -

    Definition at line 1467 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1541 of file pearl-anglescan-process.ipf.

    @@ -1622,10 +1826,23 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    -

    add an arbitrary angle scan to a hemispherical scan grid.

    -

    the hemi grid must have been created in the current data folder by the make_hemi_grid function. the function determines the bin size at the given polar angle, and adds all data points which fall into a bin. a point which lies exactly on the upper boundary falls into the next bin. this function does not clear previous values before adding new data. values are added to the _tot wave, weights to the _wt wave. the intensity (_i) wave is calculated as _tot / _wt.

    +

    add arbitrary angle scan data to a hemispherical scan grid.

    +

    the function fills the input data into bins defined by the hemi scan grid. it sums up the values and weights of the data points which fall into each bin, and adds the results to the totals and weights waves of the existing hemi grid. finally, it updates the values wave (values divided by weights).

    +

    the hemi grid must have been created in the current data folder by the make_hemi_grid() function. the function does not clear previous values before adding new data. values are added to the _tot wave, weights to the _wt wave. the intensity (_i/values) wave is calculated as _tot divided by _wt.

    +
    Parameters
    + + + + + + +
    nicknamename prefix of holo waves. empty if waves are in current data folder.
    valuescounts/intensity values at the positions given in the polara nd azi waves. one- or two-dimensional. NaN values are ignored.
    polarpolar angles (in degrees) of each data point. allowed range 0 <= theta <= 90. no specific ordering required.
    aziazimuthal angles (in degrees) of each data point. allowed range -360 <= phi < +360. no specific order required.
    weightsweight or accumulation time of each point of values. weights must be positive. values with weight 0 are ignored. defaults to 1 if not specified.
    +
    +
    +

    the values, weights, polar and azi waves must have the same dimensions (one- or two-dimensional). no specific order is required, the function sorts (copies of) the arrays internally.

    +

    the actual binning is delegated to the thread-safe add_anglescan_worker() function under Igor's automatic multi-threading facility.

    -

    Definition at line 2538 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2637 of file pearl-anglescan-process.ipf.

    @@ -1673,10 +1890,21 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    -

    add an azimuthal scan to a hemispherical scan grid.

    -

    the hemi grid must have been created in the current data folder by the make_hemi_grid function. the function determines the bin size at the given polar angle, and calculates the mean values of the data points which fall into a bin. a point which lies exactly on the upper boundary falls into the next bin.

    +

    add azimuthal data to a hemispherical scan grid.

    +

    the hemi grid must have been created in the current data folder by the make_hemi_grid() function. the function determines the bin size at the given polar angle, sums up the values and weights of the data points which fall into each bin, and adds the results to the totals and weights waves of the existing hemi grid. finally, it updates the values wave (values divided by weights).

    +
    Parameters
    + + + + + + +
    nicknamename prefix of holo waves. empty if waves are in current data folder.
    valuescounts/intensity values of the azimuthal scan at the positions given in the azi parameter.
    polarpolar angle (in degrees) where to add the azi scan.
    aziangle positions of the azimuthal scan. acceptable range: >= -360 and < +360. no specific order required, the function sorts the array internally.
    weightsweight or accumulation time of each point of values. defaults to 1 if not specified.
    +
    +
    +

    the actual binning is delegated to the thread-safe add_aziscan_core() function shared with hemi_add_anglescan().

    -

    Definition at line 2608 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2844 of file pearl-anglescan-process.ipf.

    @@ -1718,7 +1946,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Returns
    reference of the created wave. the wave has the same name as the intensity wave of the dataset with the suffix "_azi" and the azimuthal angle rounded to integer. it is created in the same datafolder as the original data.
    -

    Definition at line 3159 of file pearl-anglescan-process.ipf.

    +

    Definition at line 3354 of file pearl-anglescan-process.ipf.

    @@ -1760,7 +1988,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    Returns
    reference of the created wave. the wave has the same name as the intensity wave of the dataset with the suffix "_azi" and the azimuthal angle rounded to integer. it is created in the same datafolder as the original data.
    -

    Definition at line 3073 of file pearl-anglescan-process.ipf.

    +

    Definition at line 3268 of file pearl-anglescan-process.ipf.

    @@ -1854,7 +2082,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to -

    Definition at line 2985 of file pearl-anglescan-process.ipf.

    +

    Definition at line 3179 of file pearl-anglescan-process.ipf.

    @@ -1888,7 +2116,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    the scan data must exist in the current data folder or in the sub-folder given by the nickname parameter.

    the interpolated data is written to a new two-dimensional wave "matrix". the wave has a fixed size of 181 x 181 points optimized for 1-degree polar steps.

    missing values (nan) are interpolated. this works well only if the missing values are reasonable sparse. the function also applies a gaussian filter to smooth the image. empty rings at high polar angles map are preserved.

    -

    to display the result call display_hemi_scan() with graphtype=3.

    +

    to display the result call display_hemi_scan() with graphtype=3.

    Parameters
    @@ -1904,7 +2132,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to -

    Definition at line 2726 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2920 of file pearl-anglescan-process.ipf.

    @@ -1942,7 +2170,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    nicknamename prefix of holo waves. may be empty.
    -

    Definition at line 1131 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1205 of file pearl-anglescan-process.ipf.

    @@ -1981,7 +2209,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to

    load a hemispherical scan from an Igor text file

    Todo:
    function not implemented
    -

    Definition at line 2936 of file pearl-anglescan-process.ipf.

    +

    Definition at line 3130 of file pearl-anglescan-process.ipf.

    @@ -2033,7 +2261,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to
    -

    Definition at line 1291 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1365 of file pearl-anglescan-process.ipf.

    @@ -2106,7 +2334,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to -

    Definition at line 613 of file pearl-anglescan-process.ipf.

    +

    Definition at line 686 of file pearl-anglescan-process.ipf.

    @@ -2186,7 +2414,7 @@ data imported with version 1.5 and earlier, must be offset by 180 deg in phi to -

    Definition at line 283 of file pearl-anglescan-process.ipf.

    +

    Definition at line 348 of file pearl-anglescan-process.ipf.

    @@ -2275,7 +2503,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

    Definition at line 366 of file pearl-anglescan-process.ipf.

    +

    Definition at line 433 of file pearl-anglescan-process.ipf.

    @@ -2332,7 +2560,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp

    divide the strip piecewise by a smooth polar distribution.

    Warning
    experimental. this function is under development.
    -

    Definition at line 523 of file pearl-anglescan-process.ipf.

    +

    Definition at line 594 of file pearl-anglescan-process.ipf.

    @@ -2426,7 +2654,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

    Definition at line 464 of file pearl-anglescan-process.ipf.

    +

    Definition at line 533 of file pearl-anglescan-process.ipf.

    @@ -2498,7 +2726,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

    Definition at line 187 of file pearl-anglescan-process.ipf.

    +

    Definition at line 252 of file pearl-anglescan-process.ipf.

    @@ -2571,7 +2799,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp

    create a pizza plot from a measured (energy-integrated) data strip

    -

    accepts angle-scan data as returned by adh5_load_reduced(), maps them onto a hemispherical scan grid, and displays a polar graph.

    +

    accepts angle-scan data as returned by adh5_load_reduced(), maps them onto a hemispherical scan grid, and displays a polar graph.

    Parameters
    data2D intensity wave, see requirements above
      @@ -2602,9 +2830,9 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -
    Attention
    if you modify the structure of the data wave, e.g. delete some angles, this function cannot be used because the manipulator settings do not correspond to the original manipulator waves! instead, create your own manipulator waves and use pizza_service_2().
    +
    Attention
    if you modify the structure of the data wave, e.g. delete some angles, this function cannot be used because the manipulator settings do not correspond to the original manipulator waves! instead, create your own manipulator waves and use pizza_service_2().
    -

    Definition at line 769 of file pearl-anglescan-process.ipf.

    +

    Definition at line 843 of file pearl-anglescan-process.ipf.

    @@ -2677,8 +2905,8 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp

    create a pizza plot from a measured (energy-integrated) data strip

    -

    accepts angle-scan data as returned by adh5_load_reduced(), maps them onto a hemispherical scan grid, and displays a polar graph.

    -

    the behaviour of this function is the same as pizza_service() except that the manipulator waves are specified explicitly.

    +

    accepts angle-scan data as returned by adh5_load_reduced(), maps them onto a hemispherical scan grid, and displays a polar graph.

    +

    the behaviour of this function is the same as pizza_service() except that the manipulator waves are specified explicitly.

    Parameters
    data2D intensity wave, see requirements above
      @@ -2710,7 +2938,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

      Definition at line 862 of file pearl-anglescan-process.ipf.

      +

      Definition at line 936 of file pearl-anglescan-process.ipf.

      @@ -2741,7 +2969,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp

      polar graph window hook

      this hook converts the cursor positions to polar coordinates and displays them in a text box on the graph. the text box is visible while the cursor info box is visible.

      -

      Definition at line 2473 of file pearl-anglescan-process.ipf.

      +

      Definition at line 2547 of file pearl-anglescan-process.ipf.

      @@ -2788,7 +3016,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

      Definition at line 1702 of file pearl-anglescan-process.ipf.

      +

      Definition at line 1776 of file pearl-anglescan-process.ipf.

      @@ -2865,7 +3093,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
      Precondition
      manipulator angles as attributes in attr folder next to the data wave
      Warning
      EXPERIMENTAL
      -

      Definition at line 2792 of file pearl-anglescan-process.ipf.

      +

      Definition at line 2986 of file pearl-anglescan-process.ipf.

      @@ -2896,7 +3124,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp

      azimuthally rotate a hemispherical scan dataset.

      -

      this function works only for hemi scans created by make_hemi_grid() (or compatible functions).

      +

      this function works only for hemi scans created by make_hemi_grid() (or compatible functions).

      Parameters
      @@ -2905,7 +3133,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

      Definition at line 1654 of file pearl-anglescan-process.ipf.

      +

      Definition at line 1728 of file pearl-anglescan-process.ipf.

      @@ -2943,12 +3171,12 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp

      save a hemispherical scan to an Igor text file

      -

      Definition at line 2903 of file pearl-anglescan-process.ipf.

      +

      Definition at line 3097 of file pearl-anglescan-process.ipf.

      - -

      ◆ set_contrast()

      + +

      ◆ set_contrast()

      @@ -2975,7 +3203,19 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
      - + + + + + + + + + + + + + @@ -2995,11 +3235,21 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp + +
      nicknamename prefix for waves. source data must be in current data folder.
      string colortable = defaultValue colortable = defaultValue,
      variable reversecolors = defaultValue,
      variable symmetric = defaultValue 
      pcmaxpercentile above the maximum color (0-100).
      graphnamename of graph. default: top graph.
      colortablename of new colortable. default: keep current table.
      reversecolorsreverse colors of new colorable. takes effect only if colortable argument is defined.
        +
      • 0 (default) normal colors,
      • +
      • 1 reverse color table
      • +
      +
      symmetricmake scale symmetric about zero (for modulation functions, e.g.).
        +
      • 0 (default) do not enforce symmetry.
      • +
      • 1 try symmetric scale if "reasonable".
      • +
      +
      -

      Definition at line 3247 of file pearl-anglescan-process.ipf.

      +

      Definition at line 3463 of file pearl-anglescan-process.ipf.

      @@ -3047,7 +3297,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2493 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2567 of file pearl-anglescan-process.ipf.

    @@ -3145,7 +3395,50 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    Remarks
    the function creates angle scan data under the nickname analyser.
    -

    Definition at line 979 of file pearl-anglescan-process.ipf.

    +

    Definition at line 1053 of file pearl-anglescan-process.ipf.

    + + + + +

    ◆ strip_append()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    string strip_append (wave strip1,
    wave strip2 
    )
    +
    + +

    append an angle scan strip to another one

    +

    concatenate two angle scan strips including matching attribute waves and replace the first strip with the resulting waves. this is useful if a scan was interrupted and continues in a second data file.

    +

    all accompanying 1D waves which have a matching length and exist in both source and destination folders are concatenated and stored in the destination. 'accompanying waves' are those in the same folder as the 2D strip wave and those in the :attr sub-folder.

    +
    Attention
    this function modifies all matching waves in the data and attr folders of strip1! consider a backup before calling the function, or work on a copy of the original data (cf. Igor's DuplicateDataFolder operation)!
    +
    Parameters
    + + + +
    [in,out]strip12D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan. this is the first source wave and destination wave.
    [in]strip22D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan. this is the second source wave.
    +
    +
    +
    Returns
    (string) semicolon-separated list of modified wave names (without folder path).
    + +

    Definition at line 106 of file pearl-anglescan-process.ipf.

    @@ -3213,7 +3506,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

    Definition at line 105 of file pearl-anglescan-process.ipf.

    +

    Definition at line 170 of file pearl-anglescan-process.ipf.

    @@ -3253,7 +3546,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

    Definition at line 3034 of file pearl-anglescan-process.ipf.

    +

    Definition at line 3229 of file pearl-anglescan-process.ipf.

    @@ -3291,7 +3584,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp -

    Definition at line 2438 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2512 of file pearl-anglescan-process.ipf.

    @@ -3308,7 +3601,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2270 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2344 of file pearl-anglescan-process.ipf.

    @@ -3324,7 +3617,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2268 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2342 of file pearl-anglescan-process.ipf.

    @@ -3340,7 +3633,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2271 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2345 of file pearl-anglescan-process.ipf.

    @@ -3356,7 +3649,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2272 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2346 of file pearl-anglescan-process.ipf.

    @@ -3380,7 +3673,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2276 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2350 of file pearl-anglescan-process.ipf.

    @@ -3404,7 +3697,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2274 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2348 of file pearl-anglescan-process.ipf.

    @@ -3428,7 +3721,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2278 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2352 of file pearl-anglescan-process.ipf.

    @@ -3452,7 +3745,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2279 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2353 of file pearl-anglescan-process.ipf.

    @@ -3476,7 +3769,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2275 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2349 of file pearl-anglescan-process.ipf.

    @@ -3492,7 +3785,7 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp
    -

    Definition at line 2269 of file pearl-anglescan-process.ipf.

    +

    Definition at line 2343 of file pearl-anglescan-process.ipf.

    @@ -3502,9 +3795,9 @@ caution: binomial and boxcar smoothing are not aware of theta. this may give unp diff --git a/doc/html/pearl-anglescan-process_8ipf.js b/doc/html/pearl-anglescan-process_8ipf.js index 8a4dea7..71dd876 100644 --- a/doc/html/pearl-anglescan-process_8ipf.js +++ b/doc/html/pearl-anglescan-process_8ipf.js @@ -1,5 +1,7 @@ var pearl_anglescan_process_8ipf = [ + [ "add_anglescan_worker", "pearl-anglescan-process_8ipf.html#a8c83a187e371783dea62c9f2bc97c52c", null ], + [ "add_aziscan_core", "pearl-anglescan-process_8ipf.html#a8eabc7feca73f9e0db2109a78ee382cb", null ], [ "AngleToK", "pearl-anglescan-process_8ipf.html#acf6fddb73624fe2d21429e38c4994088", null ], [ "calc_graph_azi", "pearl-anglescan-process_8ipf.html#a4fc744e24e3e9c5efb17f14ab622bcae", null ], [ "calc_graph_polar", "pearl-anglescan-process_8ipf.html#ae2b036a06ffac8d2bb292a65401f8a9a", null ], @@ -8,7 +10,7 @@ var pearl_anglescan_process_8ipf = [ "calc_phi_step", "pearl-anglescan-process_8ipf.html#a999a9cd7d00d3e1ec8e768228a664ad1", null ], [ "Calc_The_step", "pearl-anglescan-process_8ipf.html#a1fb6aa7870dfbf0ed92660b7aae579e0", null ], [ "CalcN_Theta", "pearl-anglescan-process_8ipf.html#ac0def1ded61f9cd758df0c99f4ff9470", null ], - [ "check_contrast", "pearl-anglescan-process_8ipf.html#a2e1ed05781f9eb4be5e77695ef049962", null ], + [ "check_contrast", "pearl-anglescan-process_8ipf.html#a67d53a1c362d7e5bbeccf1c9c12ae0c2", null ], [ "clear_hemi_grid", "pearl-anglescan-process_8ipf.html#a3ec6935a5903d0974c93a2072d743013", null ], [ "convert_angles_ttpa2polar", "pearl-anglescan-process_8ipf.html#a3cc7eddf5c6b0658260cfb32dd2c026d", null ], [ "convert_angles_ttpd2polar", "pearl-anglescan-process_8ipf.html#a2b38c6c9b6e60593ba69d3773b6bc779", null ], @@ -45,9 +47,10 @@ var pearl_anglescan_process_8ipf = [ "quick_pizza_image", "pearl-anglescan-process_8ipf.html#a0b9e2b025e1d55d2a064edccf6c1c3e3", null ], [ "rotate_hemi_scan", "pearl-anglescan-process_8ipf.html#a5162488b366e217195d8f8bd7cdde0ce", null ], [ "save_hemi_scan", "pearl-anglescan-process_8ipf.html#a48cbd596656bc6d849c53afb4c58b90d", null ], - [ "set_contrast", "pearl-anglescan-process_8ipf.html#a666dab03bb2e97ffef81cea450184d42", null ], + [ "set_contrast", "pearl-anglescan-process_8ipf.html#af9874b5c1ce1d216741c7880a5fdcfcc", null ], [ "set_polar_graph_cursor", "pearl-anglescan-process_8ipf.html#a70b0e243bcbd549e2b1da74aab605629", null ], [ "show_analyser_line", "pearl-anglescan-process_8ipf.html#a01bac9e7d4ba743c3c34177a05070466", null ], + [ "strip_append", "pearl-anglescan-process_8ipf.html#ab97a936bc0fa6137b6d0b43cb61d39a1", null ], [ "strip_delete_frames", "pearl-anglescan-process_8ipf.html#a13e0d37ae23f68cdc5da3d84cb4beed8", null ], [ "trim_hemi_scan", "pearl-anglescan-process_8ipf.html#a5dc0cc7db9d3d7a6b3fa3f1b04d84a5e", null ], [ "update_polar_info", "pearl-anglescan-process_8ipf.html#a1baaa3ffd9495ed427b43cbfe6e1edf8", null ], diff --git a/doc/html/pearl-anglescan-process_8ipf_source.html b/doc/html/pearl-anglescan-process_8ipf_source.html index 01e7a39..9276d42 100644 --- a/doc/html/pearl-anglescan-process_8ipf_source.html +++ b/doc/html/pearl-anglescan-process_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-anglescan-process.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,85 +87,2690 @@ $(document).ready(function(){initNavTree('pearl-anglescan-process_8ipf_source.ht
    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 function strip_delete_frames(strip, qlo, qhi, theta, tilt, 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 end
    157 
    187 function normalize_strip_x(strip, [smooth_method, smooth_factor, check])
    188  wave strip
    189  variable smooth_method
    190  variable smooth_factor
    191  variable check
    192 
    193  if (ParamIsDefault(smooth_method))
    194  smooth_method = 4
    195  endif
    196  if (ParamIsDefault(smooth_factor))
    197  switch(smooth_method)
    198  case 4:
    199  smooth_factor = 0.5
    200  break
    201  default:
    202  smooth_factor = 2
    203  endswitch
    204  endif
    205  if (ParamIsDefault(check))
    206  check = 0
    207  endif
    208 
    209  // average over all scan positions
    210  wave raw_dist = ad_profile_x(strip, -inf, inf, "")
    211 
    212  // remove nans
    213  extract /free /indx raw_dist, clean_index, numtype(raw_dist) == 0
    214  duplicate /free raw_dist, dist, dist_x
    215  redimension /n=(numpnts(clean_index)) dist, dist_x
    216  dist = raw_dist[clean_index[p]]
    217  dist_x = pnt2x(raw_dist, clean_index[p])
    218  variable div = mean(dist)
    219  dist /= div
    220 
    221  if (check)
    222  duplicate /o raw_dist, check_dist
    223  check_dist = numtype(raw_dist) == 0 ? interp(x, dist_x, dist) : nan
    224  endif
    225 
    226  // smooth distribution function
    227  switch(smooth_method)
    228  case 1:
    229  Smooth /B /E=3 smooth_factor, dist
    230  break
    231  case 2:
    232  Smooth /E=3 smooth_factor, dist
    233  break
    234  case 3:
    235  make /n=1 /d /free fit_params
    236  fit_scienta_ang_transm(raw_dist, fit_params)
    237  duplicate /free raw_dist, dist, dist_x
    238  dist_x = x
    239  dist = scienta_ang_transm(fit_params, x)
    240  break
    241  case 4:
    242  loess /smth=(smooth_factor) srcWave=dist, factors={dist_x}
    243  break
    244  endswitch
    245 
    246  if (check)
    247  duplicate /o raw_dist, check_smoo
    248  check_smoo = interp(x, dist_x, dist)
    249  endif
    250 
    251  // divide
    252  if (check != 2)
    253  strip /= interp(x, dist_x, dist)
    254  endif
    255 end
    256 
    283 function normalize_strip_phi(strip, theta, phi, [theta_offset, theta_range, check])
    284  wave strip
    285  wave theta
    286  wave phi
    287  variable theta_offset
    288  variable theta_range
    289  variable check
    290 
    291  if (ParamIsDefault(check))
    292  check = 0
    293  endif
    294  if (ParamIsDefault(theta_offset))
    295  theta_offset = 0
    296  endif
    297  if (ParamIsDefault(theta_range))
    298  theta_offset = 10
    299  endif
    300 
    301  // average over analyser angles
    302  wave dist = ad_profile_y(strip, -inf, inf, "")
    303 
    304  // smooth distribution function
    305  duplicate /free dist, dist_smoo
    306  duplicate /free theta, theta_int
    307  theta_int = theta - theta_offset
    308  duplicate /free phi, phi_int
    309  setscale /p x phi_int[0], phi_int[1] - phi_int[0], waveunits(phi, -1), dist, dist_smoo
    310 
    311  extract /free /indx dist, red_idx, theta_int < theta_range
    312  duplicate /free red_idx, red_dist, red_phi
    313  red_dist = dist[red_idx]
    314  red_phi = phi_int[red_idx]
    315 
    316  variable wavg = mean(red_dist)
    317  make /n=4 /d /free coef
    318  coef[0] = {wavg, wavg/100, pi/180, 0}
    319  CurveFit /q /h="0010" /g /w=2 sin, kwcWave=coef, red_dist /x=red_phi
    320  dist_smoo = coef[0] + coef[1] * sin(coef[2] * phi_int[p] + coef[3])
    321 
    322  // divide
    323  if (check != 2)
    324  strip = strip / dist_smoo[q] * coef[0]
    325  endif
    326 
    327  // check
    328  if (check)
    329  duplicate /o dist, check_dist
    330  duplicate /o dist_smoo, check_smoo
    331  setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
    332  endif
    333 end
    334 
    366 function normalize_strip_theta(strip, theta, [theta_offset, smooth_method, smooth_factor, check])
    367  wave strip
    368  wave theta
    369  variable theta_offset
    370  variable smooth_method
    371  variable smooth_factor
    372  variable check
    373 
    374  if (ParamIsDefault(check))
    375  check = 0
    376  endif
    377  if (ParamIsDefault(theta_offset))
    378  theta_offset = 0
    379  endif
    380  if (ParamIsDefault(smooth_method))
    381  smooth_method = 4
    382  endif
    383  if (ParamIsDefault(smooth_factor))
    384  smooth_factor = 0.5
    385  endif
    386 
    387  // average over analyser angles
    388  wave dist = ad_profile_y(strip, -inf, inf, "")
    389 
    390  // smooth distribution function
    391  duplicate /free dist, dist_smoo
    392  duplicate /free theta, theta_int
    393  theta_int = theta - theta_offset
    394  setscale /p x theta_int[0], theta_int[1] - theta_int[0], waveunits(theta,-1), dist, dist_smoo
    395  variable nx = dimsize(strip, 0)
    396  variable ix
    397 
    398  switch(smooth_method)
    399  case 1:
    400  Smooth /B /E=3 smooth_factor, dist_smoo
    401  break
    402  case 2:
    403  Smooth /E=3 smooth_factor, dist_smoo
    404  break
    405  case 4:
    406  loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={theta_int}
    407  break
    408  case 3:
    409  for (ix = 0; ix < nx; ix += 1)
    410  dist = strip[ix][p]
    411  if (smooth_factor > 1)
    412  CurveFit /nthr=0 /q /w=2 poly smooth_factor+1, dist /x=theta_int /d=dist_smoo
    413  else
    414  CurveFit /nthr=0 /q /w=2 line, dist /x=theta_int /d=dist_smoo
    415  endif
    416  strip[ix,ix][] /= dist_smoo[q]
    417  endfor
    418  dist_smoo = 1
    419  break
    420  endswitch
    421 
    422  // divide
    423  if (check != 2)
    424  strip /= dist_smoo[q]
    425  endif
    426 
    427  // check
    428  if (check)
    429  duplicate /o dist, check_dist
    430  duplicate /o dist_smoo, check_smoo
    431  setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
    432  endif
    433 end
    434 
    464 function normalize_strip_thetaphi(strip, theta, phi, [theta_offset, smooth_method, smooth_factor, check])
    465  wave strip
    466  wave theta
    467  wave phi
    468  variable theta_offset
    469  variable smooth_method
    470  variable smooth_factor
    471  variable check
    472 
    473  if (ParamIsDefault(check))
    474  check = 0
    475  endif
    476  if (ParamIsDefault(theta_offset))
    477  theta_offset = 0
    478  endif
    479  if (ParamIsDefault(smooth_method))
    480  smooth_method = 4
    481  endif
    482  if (ParamIsDefault(smooth_factor))
    483  smooth_factor = 0.5
    484  endif
    485 
    486  // average over analyser angles
    487  wave dist = ad_profile_y(strip, -inf, inf, "")
    488 
    489  // smooth distribution function
    490  duplicate /free dist, dist_smoo
    491  duplicate /free theta, theta_int
    492  theta_int = theta - theta_offset
    493  setscale /p x theta_int[0], theta_int[1] - theta_int[0], waveunits(theta,-1), dist, dist_smoo
    494  variable nx = dimsize(strip, 0)
    495  variable ix
    496 
    497  switch(smooth_method)
    498  case 4:
    499  loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={theta_int, phi}
    500  break
    501  default:
    502  abort "smooth method not supported"
    503  endswitch
    504 
    505  // divide
    506  if (check != 2)
    507  strip /= dist_smoo[q]
    508  endif
    509 
    510  // check
    511  if (check)
    512  duplicate /o dist, check_dist
    513  duplicate /o dist_smoo, check_smoo
    514  setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
    515  endif
    516 end
    517 
    523 function normalize_strip_theta_scans(strip, theta, [theta_offset, smooth_method, smooth_factor, check])
    524  wave strip
    525  wave theta
    526  variable theta_offset
    527  variable smooth_method
    528  variable smooth_factor
    529  variable check
    530 
    531  if (ParamIsDefault(check))
    532  check = 0
    533  endif
    534  if (ParamIsDefault(theta_offset))
    535  theta_offset = 0
    536  endif
    537  if (ParamIsDefault(smooth_method))
    538  smooth_method = 4
    539  endif
    540  if (ParamIsDefault(smooth_factor))
    541  smooth_factor = 0.5
    542  endif
    543 
    544  // average over analyser angles
    545  wave dist = ad_profile_y(strip, -inf, inf, "")
    546 
    547  // smooth distribution function
    548  duplicate /free dist, dist_smoo
    549  duplicate /free theta, theta_int
    550  theta_int = theta - theta_offset
    551  setscale /p x theta_int[0], theta_int[1] - theta_int[0], waveunits(theta,-1), dist, dist_smoo
    552 
    553  // analyse scanning scheme
    554  duplicate /free theta_int, d1_theta, d2_theta
    555  Differentiate /METH=2 theta_int /D=d1_theta
    556  Differentiate /METH=2 d1_theta /D=d2_theta
    557  d2_theta = abs(d2_theta)
    558  make /free w_levels
    559  FindLevels /edge=1 /p /q /d=w_levels d2_theta, 0.1
    560  if (v_flag != 1)
    561  abort "unrecognized scanning scheme"
    562  endif
    563  w_levels = ceil(w_levels)
    564  InsertPoints 0, 1, w_levels
    565  w_levels[0] = 0
    566  InsertPoints numpnts(w_levels), 1, w_levels
    567  w_levels[numpnts(w_levels)-1] = numpnts(theta_int)
    568 
    569  variable n_scans = numpnts(w_levels) - 1
    570  variable i_scan
    571  variable p1, p2
    572  for (i_scan = 0; i_scan < n_scans; i_scan += 1)
    573  p1 = w_levels[i_scan]
    574  p2 = w_levels[i_scan+1] - 1
    575  duplicate /free /r=[p1, p2] dist, dist_piece, smooth_piece
    576  duplicate /free /r=[p1, p2] theta_int, theta_piece
    577  switch(smooth_method)
    578  case 4:
    579  loess /dest=smooth_piece /smth=(smooth_factor) srcWave=dist_piece, factors={theta_piece}
    580  break
    581  default:
    582  abort "smooth method not supported"
    583  endswitch
    584  dist_smoo[p1, p2] = smooth_piece[p - p1]
    585  endfor
    586 
    587  // divide
    588  if (check != 2)
    589  strip /= dist_smoo[q]
    590  endif
    591 
    592  // check
    593  if (check)
    594  duplicate /o dist, check_dist
    595  duplicate /o dist_smoo, check_smoo
    596  setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
    597  endif
    598 end
    599 
    613 function normalize_strip_2d(strip, theta, [theta_offset, smooth_method, smooth_factor, check])
    614  wave strip
    615  wave theta
    616  variable theta_offset
    617  variable smooth_method
    618  variable smooth_factor
    619  variable check
    620 
    621  if (ParamIsDefault(check))
    622  check = 0
    623  endif
    624  if (ParamIsDefault(theta_offset))
    625  theta_offset = 0
    626  endif
    627  if (ParamIsDefault(smooth_method))
    628  smooth_method = 4
    629  endif
    630  if (ParamIsDefault(smooth_factor))
    631  smooth_factor = 0.5
    632  endif
    633 
    634  variable nx = dimsize(strip, 0)
    635  variable ny = dimsize(strip, 1)
    636 
    637  duplicate /free strip, dist, alpha_int, theta_int
    638  theta_int = theta[q] - theta_offset
    639  alpha_int = dimoffset(strip, 0) + p * dimdelta(strip, 0)
    640  redimension /n=(nx * ny) dist, alpha_int, theta_int
    641 
    642  switch(smooth_method)
    643  case 4:
    644  loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={alpha_int, theta_int}
    645  redimension /n=(nx, ny) dist_smoo
    646  break
    647  default:
    648  Abort "undefined smooth method"
    649  break
    650  endswitch
    651 
    652  // divide
    653  if (check != 2)
    654  strip /= dist_smoo
    655  endif
    656 
    657  // check
    658  if (check)
    659  //duplicate /o dist, check_dist
    660  duplicate /o dist_smoo, check_smoo
    661  endif
    662 end
    663 
    673 function crop_strip(strip, xlo, xhi)
    674  wave strip
    675  variable xlo
    676  variable xhi
    677 
    678  variable plo = round((xlo - dimoffset(strip, 0)) / dimdelta(strip, 0))
    679  variable phi = round((xhi - dimoffset(strip, 0)) / dimdelta(strip, 0))
    680  xlo = plo * dimdelta(strip, 0) + dimoffset(strip, 0)
    681  xhi = phi * dimdelta(strip, 0) + dimoffset(strip, 0)
    682  variable nx = phi - plo + 1
    683  variable ny = dimsize(strip, 1)
    684 
    685  duplicate /free strip, strip_copy
    686  redimension /n=(nx,ny) strip
    687  strip = strip_copy[p + plo][q]
    688  setscale /i x xlo, xhi, waveunits(strip, 0), strip
    689 end
    690 
    705 function crop_strip_theta(strip, theta_lo, theta_hi, theta, tilt, phi)
    706  wave strip
    707  variable theta_lo
    708  variable theta_hi
    709  wave theta
    710  wave tilt
    711  wave phi
    712 
    713  extract /indx /free theta, idx, (theta >= theta_lo) && (theta <= theta_hi)
    714  variable nx = dimsize(strip, 0)
    715  variable ny = numpnts(idx)
    716 
    717  theta[0, ny-1] = theta[idx]
    718  tilt[0, ny-1] = tilt[idx]
    719  phi[0, ny-1] = phi[idx]
    720  redimension /n=(ny) theta, tilt, phi
    721 
    722  duplicate /free strip, strip_copy
    723  redimension /n=(nx,ny) strip
    724  strip = strip_copy[p][idx[q]]
    725 end
    726 
    769 function pizza_service(data, nickname, theta_offset, tilt_offset, phi_offset, [npolar, nograph, folding, xpdplot])
    770  wave data
    771  string nickname
    772  variable theta_offset
    773  variable tilt_offset
    774  variable phi_offset
    775  variable npolar
    776  variable nograph
    777  variable folding
    778  variable xpdplot
    779 
    780  if (ParamIsDefault(npolar))
    781  npolar = 91
    782  endif
    783  if (ParamIsDefault(nograph))
    784  nograph = 0
    785  endif
    786  if (ParamIsDefault(folding))
    787  folding = 1
    788  endif
    789  if (ParamIsDefault(xpdplot))
    790  xpdplot = 0
    791  endif
    792 
    793  // sort out data folder structure
    794  dfref saveDF = GetDataFolderDFR()
    795  dfref dataDF = GetWavesDataFolderDFR(data)
    796  setdatafolder dataDF
    797  if (DataFolderExists(":attr"))
    798  setdatafolder :attr
    799  endif
    800  dfref attrDF = GetDataFolderDFR()
    801 
    802  wave /sdfr=attrDF ManipulatorTheta
    803  wave /sdfr=attrDF ManipulatorTilt
    804  wave /sdfr=attrDF ManipulatorPhi
    805 
    806  if ((dimsize(ManipulatorTheta, 0) != dimsize(data, 1)) || (dimsize(ManipulatorTilt, 0) != dimsize(data, 1)) || (dimsize(ManipulatorPhi, 0) != dimsize(data, 1)))
    807  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."
    808  endif
    809 
    810  duplicate /free ManipulatorTheta, m_theta
    811  duplicate /free ManipulatorTilt, m_tilt
    812  duplicate /free ManipulatorPhi, m_phi
    813 
    814  m_theta -= theta_offset
    815  m_tilt -= tilt_offset
    816  m_phi -= phi_offset
    817 
    818  pizza_service_2(data, nickname, m_theta, m_tilt, m_phi, npolar=npolar, nograph=nograph, folding=folding, xpdplot=xpdplot)
    819 
    820  setdatafolder saveDF
    821 end
    822 
    862 function pizza_service_2(data, nickname, m_theta, m_tilt, m_phi, [npolar, nograph, folding, xpdplot])
    863  wave data
    864  string nickname
    865  wave m_theta
    866  wave m_tilt
    867  wave m_phi
    868  variable npolar
    869  variable nograph
    870  variable folding
    871  variable xpdplot
    872 
    873  if (ParamIsDefault(npolar))
    874  npolar = 91
    875  endif
    876  if (ParamIsDefault(nograph))
    877  nograph = 0
    878  endif
    879  if (ParamIsDefault(folding))
    880  folding = 1
    881  endif
    882  if (ParamIsDefault(xpdplot))
    883  xpdplot = 0
    884  endif
    885 
    886  if ((dimsize(m_theta, 0) != dimsize(data, 1)) || (dimsize(m_tilt, 0) != dimsize(data, 1)) || (dimsize(m_phi, 0) != dimsize(data, 1)))
    887  Abort "Warning: The dimension size of the manipulator waves does not match the Y dimension of the data wave!"
    888  endif
    889 
    890  string graphname = "graph_" + nickname
    891  string outprefix = nickname
    892 
    893  // sort out data folder structure
    894  dfref saveDF = GetDataFolderDFR()
    895  dfref dataDF = GetWavesDataFolderDFR(data)
    896  setdatafolder dataDF
    897 
    898  if (xpdplot)
    899  setdatafolder root:
    900  outprefix = nickname
    901  else
    902  setdatafolder dataDF
    903  newdatafolder /s/o $nickname
    904  outprefix = ""
    905  endif
    906  dfref destDF = GetDataFolderDFR()
    907 
    908  // performance monitoring
    909  variable timerRefNum
    910  variable /g pol_perf_secs
    911  timerRefNum = startMSTimer
    912 
    913  duplicate /free m_tilt, corr_tilt
    914  duplicate /free m_phi, corr_phi
    915  corr_tilt = -m_tilt // checked 140702
    916  corr_phi = m_phi // checked 140702
    917 
    918  make /n=1/d/free d_polar, d_azi
    919 
    920  convert_angles_ttpd2polar(m_theta, corr_tilt, corr_phi, data, d_polar, d_azi)
    921  d_azi += 180 // changed 151030 (v1.6)
    922  make_hemi_grid(npolar, outprefix, xpdplot=xpdplot)
    923  variable ifold
    924  for (ifold = 0; ifold < folding; ifold += 1)
    925  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
    926  hemi_add_anglescan(outprefix, data, d_polar, d_azi)
    927  d_azi += 360 / folding
    928  endfor
    929 
    930  // normalize folding
    931  if (strlen(outprefix))
    932  string s_prefix = outprefix + "_"
    933  string s_int = s_prefix + "i"
    934  else
    935  s_prefix = ""
    936  s_int = "values"
    937  endif
    938  if (folding > 1)
    939  wave values = $s_int
    940  values /= folding
    941  endif
    942 
    943  if (!nograph)
    944  display_hemi_scan(outprefix, graphname = graphname)
    945  endif
    946 
    947  if (timerRefNum >= 0)
    948  pol_perf_secs = stopMSTimer(timerRefNum) / 1e6
    949  endif
    950 
    951  setdatafolder saveDF
    952 end
    953 
    979 function show_analyser_line(theta, tilt, phi, theta_offset, tilt_offset, phi_offset, [npolar, nograph, xpdplot])
    980  variable theta
    981  variable tilt
    982  variable phi
    983  variable theta_offset
    984  variable tilt_offset
    985  variable phi_offset
    986  variable npolar
    987  variable nograph
    988  variable xpdplot
    989 
    990  string nickname = "analyser"
    991 
    992  if (ParamIsDefault(npolar))
    993  npolar = 91
    994  endif
    995  if (ParamIsDefault(nograph))
    996  nograph = 0
    997  endif
    998  if (ParamIsDefault(xpdplot))
    999  xpdplot = 0
    1000  endif
    1001  string graphname = "graph_" + nickname
    1002  string outprefix = nickname
    1003 
    1004  // sort out data folder structure
    1005  dfref saveDF = GetDataFolderDFR()
    1006  dfref dataDF = saveDF
    1007  if (xpdplot)
    1008  setdatafolder root:
    1009  outprefix = nickname
    1010  else
    1011  setdatafolder dataDF
    1012  newdatafolder /s/o $nickname
    1013  outprefix = ""
    1014  endif
    1015  dfref destDF = GetDataFolderDFR()
    1016 
    1017  make /n=1 /free m_theta
    1018  make /n=1 /free m_tilt
    1019  make /n=1 /free m_phi
    1020  m_theta = theta - theta_offset
    1021  m_tilt = tilt - tilt_offset
    1022  m_tilt *= -1 // checked 140702
    1023  m_phi = phi - phi_offset
    1024  //m_phi *= -1 // checked 140702
    1025 
    1026  make /n=60 /free data
    1027  setscale /i x -30, 30, data
    1028  data = x
    1029  make /n=1/d/free d_polar, d_azi
    1030 
    1031  convert_angles_ttpa2polar(m_theta, m_tilt, m_phi, data, d_polar, d_azi)
    1032  d_azi += 180 // changed 151030 (v1.6)
    1033  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
    1034  make_hemi_grid(npolar, outprefix, xpdplot=xpdplot)
    1035  hemi_add_anglescan(outprefix, data, d_polar, d_azi)
    1036 
    1037  if (!nograph)
    1038  display_hemi_scan(outprefix, graphname = graphname)
    1039  endif
    1040 
    1041  setdatafolder saveDF
    1042 end
    1043 
    1048 
    1049 function convert_angles_ttpd2polar(theta, tilt, phi, data, polar, azi)
    1050  wave theta, tilt, phi // see convert_angles_ttpa2polar
    1051  wave data // in, 1D or 2D
    1052  // X-scale must be set to analyser angle scale
    1053  wave polar, azi // see convert_angles_ttpa2polar
    1054 
    1055  make /n=(dimsize(data, 0)) /d /free ana
    1056  setscale /p x dimoffset(data, 0), dimdelta(data, 0), waveunits(data, 0), ana
    1057  ana = x
    1058  convert_angles_ttpa2polar(theta, tilt, phi, ana, polar, azi)
    1059 end
    1060 
    1088 function convert_angles_ttpa2polar(theta, tilt, phi, analyser, polar, azi)
    1089  wave theta
    1090  wave tilt
    1091  wave phi
    1092  wave analyser
    1093  wave polar, azi
    1094 
    1095  variable nn = numpnts(theta)
    1096  variable na = numpnts(analyser)
    1097  redimension /n=(na, nn) polar, azi
    1098 
    1099  variable radius = 1 // don't need to specify - everything is scalable
    1100 
    1101  // step 1: calculate cartesian detection vectors at normal emission
    1102  // this is simply a polar-cartesian mapping, independent of the manipulator
    1103  // phi=0 is in the polar rotation plane
    1104  make /n=(3,na) /d /free w_orig_polar, w_orig_cart, w_rot_cart, w_rot_polar
    1105  w_orig_polar[0][] = radius
    1106  w_orig_polar[1][] = analyser[q]
    1107  w_orig_polar[2][] = 0
    1108  polar2cart_wave(w_orig_polar, w_orig_cart)
    1109  // if the angle-dispersive axis was horizontal, we'd need to rotate the detector
    1110  //rotate_z_wave(w_orig_cart, 90)
    1111 
    1112  variable ii
    1113  for (ii = 0; ii < nn; ii += 1)
    1114  // step 2: rotate the detection vectors according to the manipulator angles
    1115  // the order of rotations is important because we rotate about fixed axes
    1116  // y-axis = tilt rotation axis
    1117  // x-axis = polar rotation axis
    1118  // z-axis = normal emission = azimuthal rotation axis
    1119  w_rot_cart = w_orig_cart
    1120  rotate_y_wave(w_rot_cart, -tilt[ii])
    1121  rotate_x_wave(w_rot_cart, -theta[ii])
    1122  rotate_z_wave(w_rot_cart, -phi[ii] - 90)
    1123  // map the vectors back to the sample coordinate system
    1124  cart2polar_wave(w_rot_cart, w_rot_polar)
    1125  // copy to output
    1126  polar[][ii] = w_rot_polar[1][p]
    1127  azi[][ii] = w_rot_polar[2][p]
    1128  endfor
    1129 end
    1130 
    1131 static function line_average(source, dest)
    1132  // is this function used?
    1133  wave source
    1134  wave dest
    1135 
    1136  variable ii
    1137  variable nn = dimsize(source, 1)
    1138  make /n=(dimsize(source, 0))/d/free line
    1139  for (ii = 0; ii < nn; ii += 1)
    1140  line = source[p][ii]
    1141  wavestats /q line
    1142  dest[][ii] = line[p] / v_max
    1143  endfor
    1144 end
    1145 
    1149 static function calc_nth(Theta_st, Theta_in, th, Phi_ran, Phi_ref, Holomode)
    1150  Variable Theta_st, Theta_in, th, Phi_ran, Phi_ref
    1151  String Holomode
    1152  Variable The_step
    1153  Variable deg2rad=0.01745329
    1154 
    1155  if ( cmpstr(Holomode, "Stereographic") == 0)
    1156  The_step =trunc( Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st )
    1157  if(th==90)
    1158  The_step =trunc( Phi_ran*sin(th*pi/180)*Phi_ref/Theta_st )
    1159  endif
    1160  else
    1161  if (cmpstr(Holomode, "Parallel") == 0)
    1162  The_step=trunc( Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st )
    1163  else
    1164  if ( cmpstr(Holomode, "h") == 0)
    1165  The_step=trunc( th/Theta_in*Phi_ran/Theta_st )
    1166  else
    1167  //altro
    1168  endif
    1169  endif
    1170  endif
    1171 
    1172  return(The_step)
    1173 end
    1174 
    1178 static function calc_phi_step(Theta_in, th, Theta_st, Phi_ran, Phi_ref, Holomode)
    1179  Variable Theta_in, th, Theta_st, Phi_ran, Phi_ref
    1180  String Holomode
    1181 
    1182  Variable Phi_st
    1183  Variable deg2rad=0.01745329
    1184 
    1185  if ( cmpstr(Holomode, "Stereographic") == 0 )
    1186  if ((th < 0.5) || (trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st) == 0))
    1187  Phi_st=0.0
    1188  else
    1189  Phi_st=Phi_ran/(trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st))
    1190  endif
    1191  if(th==90)
    1192  Phi_st=2.0
    1193  endif
    1194  endif
    1195 
    1196  if ( cmpstr(Holomode, "Parallel") == 0 )
    1197  if((th < 0.5) || (trunc(Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st) == 0))
    1198  Phi_st=0.0
    1199  else
    1200  Phi_st=Phi_ran/(trunc(Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st))
    1201  endif
    1202  endif
    1203 
    1204  if ( cmpstr(Holomode, "h") == 0 )
    1205  if((th < 0.5) || (trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st) == 0))
    1206  Phi_st=0.0
    1207  else
    1208  Phi_st=Phi_ran/trunc(th/Theta_in*Phi_ran/Theta_st)
    1209  endif
    1210  endif
    1211 
    1212  if (Phi_st==0)
    1213  Phi_st=360
    1214  endif
    1215 
    1216  return(Phi_st)
    1217 end
    1218 
    1222 static function Calc_The_step(th, Theta_st, Holomode)
    1223  String Holomode
    1224  Variable th, Theta_st
    1225 
    1226  Variable deg2rad=0.01745329, dt_loc,The_step
    1227 
    1228  if ( (cmpstr(Holomode, "Stereographic")) ==0 )
    1229  The_step=Theta_st
    1230  endif
    1231 
    1232  if ( (cmpstr(Holomode, "h")) ==0 )
    1233  The_step=Theta_st
    1234  endif
    1235 
    1236  if ( cmpstr(Holomode, "Parallel") == 0 )
    1237  if(th < 89.5)
    1238  dt_loc = Theta_st/cos(th*deg2rad)
    1239  if(dt_loc > 10)
    1240  dt_loc=10
    1241  endif
    1242  The_step=dt_loc
    1243  else
    1244  The_step=10
    1245  endif
    1246  endif
    1247  return(The_step)
    1248 end
    1249 
    1253 static function CalcN_Theta(HoloMode,Theta_in,Theta_ran,Theta_st)
    1254  String HoloMode
    1255  Variable Theta_in,Theta_ran,Theta_st
    1256  Variable n_theta, aux, aux1,ii
    1257 
    1258  aux = Theta_in
    1259  aux1= Theta_in - Theta_ran
    1260  ii = 0
    1261  do
    1262  aux = aux - Calc_The_step(aux, Theta_st, HoloMode)
    1263  if(aux<=Theta_in-Theta_ran)
    1264  aux=Theta_in-Theta_ran
    1265  endif
    1266  ii = ii+1
    1267  while((aux>aux1)%&(Theta_in-aux<=Theta_ran)) //
    1268  n_theta=ii+1
    1269  Return(n_theta)
    1270 end
    1271 
    1291 function make_hemi_grid(npol, nickname, [xpdplot])
    1292  variable npol
    1293  string nickname
    1294  variable xpdplot
    1295 
    1296  if (ParamIsDefault(xpdplot))
    1297  xpdplot = 0
    1298  endif
    1299 
    1300  string HoloMode = "h"
    1301  variable Theta_in = 90
    1302  variable Theta_ran = 90
    1303  variable Theta_st = 90 / (npol - 1)
    1304  variable Phi_ran = 360
    1305  variable Phi_ref = 1
    1306  variable Phi_in = 0
    1307 
    1308  variable n_theta = CalcN_Theta(HoloMode, Theta_in, Theta_ran, Theta_st)
    1309 
    1310  // wave names
    1311  if (strlen(nickname))
    1312  string s_prefix = nickname + "_"
    1313  string s_int = s_prefix + "i" // Intensity wave (counts/sec)
    1314  else
    1315  s_prefix = ""
    1316  s_int = "values" // "i" is not a valid wave name
    1317  endif
    1318  string s_polar = s_prefix + "pol" // thetas for each int-point of the holo
    1319  string s_azim = s_prefix + "az" // phis for each int-point of the holo
    1320 
    1321  string s_index = s_prefix + "index" // starting index for each theta
    1322  string s_theta = s_prefix + "th" // theta values
    1323  string s_dphi = s_prefix + "dphi" // delta phis at each theta
    1324  string s_nphis = s_prefix + "nphis" // number of phis at each theta
    1325 
    1326  string s_HoloData = s_prefix + "data" // All holo exp.- parameter information
    1327  string s_HoloInfo = s_prefix + "info"
    1328 
    1329  // the following two waves are used by the pearl-anglescan procedures but not by XPDplot
    1330  string s_tot = s_prefix + "tot" // accumulated counts at each point
    1331  string s_weight = s_prefix + "wt" // total accumulation time at each point (arb. units)
    1332 
    1333  make /O/D/n=(n_theta) $s_index /wave=index
    1334  make /O/D/n=(n_theta) $s_theta /wave=theta
    1335  make /O/D/n=(n_theta) $s_dphi /wave=dphi
    1336  make /O/D/n=(n_theta) $s_nphis /wave=nphis
    1337 
    1338  //---------- calculate phi-step-size for this theta:
    1339  variable aux = Calc_The_step(Theta_in, Theta_st, HoloMode)
    1340  dphi[0] = calc_phi_step(Theta_in, Theta_in, aux, Phi_ran, Phi_ref, HoloMode)
    1341  Theta[0] = Theta_in
    1342  nphis[0] = calc_nth(aux, Theta_in, Theta_in, Phi_ran, Phi_ref, HoloMode)
    1343  Index[0] = nphis[0]
    1344 
    1345  //---------- calculate number of phis, phi-step, and starting-index for each theta:
    1346  variable ii = 1
    1347  do
    1348  Theta[ii] = Theta[ii-1] - aux
    1349  if(Theta[ii] <= Theta_in-Theta_ran)
    1350  Theta[ii] = Theta_in-Theta_ran
    1351  endif
    1352  aux = Calc_The_step(Theta[ii], Theta_st, HoloMode)
    1353  dphi[ii] = calc_phi_step(Theta_in, Theta[ii], aux, Phi_ran, Phi_ref, HoloMode)
    1354  nphis[ii] = calc_nth(aux, Theta_in, Theta[ii], Phi_ran, Phi_ref, HoloMode)
    1355  Index[ii] = Index[ii-1] + nphis[ii]
    1356  ii=ii+1
    1357  while(ii < n_theta)
    1358 
    1359  if (Index[n_theta-1]==Index[n_theta-2])
    1360  Index[n_theta-1]=Index[n_theta-2]+1
    1361  nphis[n_theta-1]=1
    1362  endif
    1363 
    1364  variable NumPoints = sum(nphis, 0, numpnts(nphis))
    1365 
    1366  //---------- calculate theta and phi for each data point:
    1367  make /O/D/N=(NumPoints) $s_polar /wave=polar, $s_azim /wave=azim
    1368  note azim, "version=1.6"
    1369 
    1370  ii = 0
    1371  variable StartIndex = 0
    1372  variable EndIndex
    1373  do
    1374  EndIndex=Index[ii]
    1375  Polar[StartIndex, EndIndex-1]=Theta[ii]
    1376  Azim[StartIndex, EndIndex-1]= mod(Phi_ran+(x-StartIndex)*dphi[ii]+Phi_in,Phi_ran)
    1377  ii = ii + 1
    1378  StartIndex = EndIndex
    1379  while(ii < n_theta)
    1380 
    1381  duplicate /o azim, $s_int /wave=values
    1382  duplicate /o azim, $s_tot /wave=totals
    1383  duplicate /o azim, $s_weight /wave=weights
    1384  values = nan
    1385  totals = 0
    1386  weights = 0
    1387 
    1388  // XPDplot metadata
    1389  if (xpdplot)
    1390  string s_FileName = ""
    1391  string s_Comment = "created by pearl-anglescan-process.ipf"
    1392  string s_HoloMode = "Stereographic"
    1393  variable /g gb_SpectraFile = 0
    1394 
    1395  Make/O/D/n=22 $s_HoloData /wave=HoloData
    1396  HoloData[0] = NaN // v_StartKE
    1397  HoloData[1] = NaN // v_StoppKE
    1398  HoloData[6] = NumPoints
    1399  HoloData[7] = Theta_in
    1400  HoloData[8] = Theta_ran
    1401  HoloData[9] = Theta_st
    1402  HoloData[11] = Phi_in
    1403  HoloData[12] = Phi_ran
    1404  HoloData[13] = Theta_st
    1405  HoloData[15] = Phi_ref
    1406  HoloData[16] = Phi_ran
    1407  HoloData[17] = 0 // v_HoloBit (stereographic)
    1408 
    1409  Make/O/T/n=22 $s_HoloInfo /wave=HoloInfo
    1410  HoloInfo[0] = s_FileName
    1411  HoloInfo[1] = s_Comment
    1412  HoloInfo[10] = s_HoloMode
    1413  HoloInfo[11] = "" // s_MeasuringMode
    1414 
    1415  // notebook for XPDplot
    1416  if (WinType(NickName) == 5)
    1417  Notebook $NickName selection={startOfFile, endOfFile}
    1418  Notebook $NickName text=""
    1419  else
    1420  NewNotebook /F=0 /K=1 /N=$NickName /W=(5,40,341,260)
    1421  Notebook $NickName defaultTab=140
    1422  Notebook $NickName statusWidth=300
    1423  Notebook $NickName backRGB=(56797,56797,56797)
    1424  Notebook $NickName pageMargins={80,80,80,80}
    1425  Notebook $NickName fSize=10
    1426  Notebook $NickName fStyle=0,textRGB=(65535,0,26214)
    1427  Notebook $NickName textRGB=(65535,0,26214)
    1428  endif
    1429  Notebook $NickName text = "File:\t" + s_FileName + "\r"
    1430  Notebook $NickName text = "*** " + s_Comment + " ***\r\r"
    1431  Notebook $NickName text = "Angle-Mode:\t" + s_HoloMode + "\r"
    1432  Notebook $NickName text = "XPDplot Nickname:\t" + NickName + "\r"
    1433  endif
    1434 end
    1435 
    1442 function /s get_hemi_nickname(w)
    1443  wave w
    1444 
    1445  string prefix = get_hemi_prefix(w)
    1446  string wname = nameofwave(w)
    1447  string nickname
    1448 
    1449  if (strlen(prefix))
    1450  nickname = prefix
    1451  else
    1452  string s_wave_df = GetWavesDataFolder(w, 1)
    1453  dfref parent_df = $(s_wave_df + "::")
    1454  nickname = GetDataFolder(0, parent_df)
    1455  endif
    1456 
    1457  return nickname
    1458 end
    1459 
    1467 function /s get_hemi_prefix(w)
    1468  wave w
    1469 
    1470  string wname = nameofwave(w)
    1471  string prefix
    1472  if (ItemsInList(wname, "_") >= 2)
    1473  prefix = StringFromList(0, wname, "_")
    1474  else
    1475  prefix = ""
    1476  endif
    1477 
    1478  return prefix
    1479 end
    1480 
    1498 function /df find_hemi_data(nickname, prefix, intwave)
    1499  string nickname
    1500  string &prefix
    1501  string &intwave
    1502 
    1503  dfref datadf
    1504  prefix = ""
    1505  intwave = "values"
    1506  if (strlen(nickname))
    1507  if (DataFolderExists(nickname))
    1508  datadf = $nickname
    1509  else
    1510  datadf = getdatafolderdfr()
    1511  prefix = nickname + "_"
    1512  intwave = prefix + "i"
    1513  if (exists(intwave) != 1)
    1514  datadf = root:
    1515  endif
    1516  endif
    1517  else
    1518  datadf = getdatafolderdfr()
    1519  prefix = ""
    1520  intwave = "values"
    1521  endif
    1522  return datadf
    1523 end
    1524 
    1532 function clear_hemi_grid(nickname)
    1533  string nickname
    1534 
    1535  dfref datadf
    1536  string s_prefix
    1537  string s_int
    1538  datadf = find_hemi_data(nickname, s_prefix, s_int)
    1539 
    1540  string s_totals = s_prefix + "tot"
    1541  string s_weights = s_prefix + "wt"
    1542 
    1543  wave /sdfr=datadf /z w_values = $s_int
    1544  wave /sdfr=datadf /z w_totals = $s_totals
    1545  wave /sdfr=datadf /z w_weights = $s_weights
    1546 
    1547  if (waveexists(w_totals))
    1548  w_totals = 0
    1549  endif
    1550  if (waveexists(w_weights))
    1551  w_weights = 0
    1552  endif
    1553  if (waveexists(w_values))
    1554  w_values = nan
    1555  endif
    1556 end
    1557 
    1579 function duplicate_hemi_scan(source_nickname, dest_folder, dest_nickname, [xpdplot])
    1580  string source_nickname
    1581  dfref dest_folder
    1582  string dest_nickname
    1583  variable xpdplot
    1584 
    1585  if (ParamIsDefault(xpdplot))
    1586  xpdplot = 0
    1587  endif
    1588 
    1589  dfref savedf = getdatafolderdfr()
    1590 
    1591  // source data
    1592  string s_prefix = ""
    1593  string s_int = "values"
    1594  dfref source_df = find_hemi_data(source_nickname, s_prefix, s_int)
    1595  string s_polar = s_prefix + "pol"
    1596  string s_azim = s_prefix + "az"
    1597  string s_theta = s_prefix + "th"
    1598  string s_tot = s_prefix + "tot"
    1599  string s_weight = s_prefix + "wt"
    1600  string s_matrix = s_prefix + "matrix"
    1601 
    1602  wave /sdfr=source_df theta1 = $s_theta
    1603  wave /sdfr=source_df polar1 = $s_polar
    1604  wave /sdfr=source_df azim1 = $s_azim
    1605  wave /sdfr=source_df tot1 = $s_tot
    1606  wave /sdfr=source_df weight1 = $s_weight
    1607  wave /sdfr=source_df values1 = $s_int
    1608  wave /sdfr=source_df /z matrix1 = $s_matrix
    1609 
    1610  variable npol = numpnts(theta1)
    1611 
    1612  setdatafolder dest_folder
    1613  make_hemi_grid(npol, dest_nickname, xpdplot=xpdplot)
    1614 
    1615  // dest data
    1616  dfref dest_df = find_hemi_data(dest_nickname, s_prefix, s_int)
    1617  s_polar = s_prefix + "pol"
    1618  s_azim = s_prefix + "az"
    1619  s_theta = s_prefix + "th"
    1620  s_tot = s_prefix + "tot"
    1621  s_weight = s_prefix + "wt"
    1622  s_matrix = s_prefix + "matrix"
    1623 
    1624  wave /sdfr=dest_df theta2 = $s_theta
    1625  wave /sdfr=dest_df polar2 = $s_polar
    1626  wave /sdfr=dest_df azim2 = $s_azim
    1627  wave /sdfr=dest_df tot2 = $s_tot
    1628  wave /sdfr=dest_df weight2 = $s_weight
    1629  wave /sdfr=dest_df values2 = $s_int
    1630 
    1631  tot2 = tot1
    1632  weight2 = weight1
    1633  values2 = values1
    1634  if (waveexists(matrix1))
    1635  setdatafolder dest_df
    1636  duplicate /o matrix1, $s_matrix
    1637  endif
    1638 
    1639  if (!(NumberByKey("version", note(azim1), "=", "\r") >= 1.6))
    1640  azim2 += 180 // changed 151030 (v1.6)
    1641  azim2 = azim2 >= 360 ? azim2 - 360 : azim2
    1642  endif
    1643 
    1644  setdatafolder saveDF
    1645 end
    1646 
    1654 function rotate_hemi_scan(nickname, angle)
    1655  string nickname
    1656  variable angle
    1657 
    1658  dfref savedf = getdatafolderdfr()
    1659 
    1660  string s_prefix = ""
    1661  string s_int = "values"
    1662  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    1663 
    1664  string s_polar = s_prefix + "pol"
    1665  string s_azim = s_prefix + "az"
    1666  string s_tot = s_prefix + "tot"
    1667  string s_weight = s_prefix + "wt"
    1668 
    1669  wave /sdfr=df polar = $s_polar
    1670  wave /sdfr=df azim = $s_azim
    1671  wave /sdfr=df tot = $s_tot
    1672  wave /sdfr=df weight = $s_weight
    1673  wave /sdfr=df values = $s_int
    1674 
    1675  azim += angle
    1676  azim = azim < 0 ? azim + 360 : azim
    1677  azim = azim >= 360 ? azim - 360 : azim
    1678 
    1679  duplicate /free polar, neg_polar
    1680  neg_polar = -polar
    1681  sort {neg_polar, azim}, polar, azim, tot, weight, values
    1682 
    1683  setdatafolder saveDF
    1684 end
    1685 
    1702 function /s prepare_hemi_scan_display(nickname, [projection])
    1703  string nickname
    1704  variable projection
    1705 
    1706  dfref savedf = getdatafolderdfr()
    1707 
    1708  if (ParamIsDefault(projection))
    1709  projection = 1
    1710  endif
    1711 
    1712  // hemi grid waves
    1713  string s_prefix = ""
    1714  string s_int = "values"
    1715  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    1716 
    1717  string s_polar = s_prefix + "pol"
    1718  string s_azim = s_prefix + "az"
    1719 
    1720  wave /sdfr=df /z values = $s_int
    1721  wave /sdfr=df /z azim = $s_azim
    1722  wave /sdfr=df /z polar = $s_polar
    1723 
    1724  setdatafolder df
    1725  string s_ster_rad = s_prefix + "ster_rad"
    1726  duplicate /o polar, $s_ster_rad /wave=ster_rad
    1727  ster_rad = calc_graph_radius(polar, projection=projection)
    1728 
    1729  string s_ster_x = s_prefix + "ster_x"
    1730  string s_ster_y = s_prefix + "ster_y"
    1731  duplicate /o azim, $s_ster_x /wave=ster_x, $s_ster_y /wave=ster_y
    1732  ster_x = ster_rad * cos(azim * pi / 180)
    1733  ster_y = ster_rad * sin(azim * pi / 180)
    1734 
    1735  setdatafolder savedf
    1736 end
    1737 
    1784 function /s display_hemi_scan(nickname, [projection, graphtype, do_ticks, do_grids, graphname])
    1785  string nickname
    1786  variable projection
    1787  variable graphtype
    1788  variable do_ticks
    1789  variable do_grids
    1790  string graphname
    1791 
    1792  dfref savedf = getdatafolderdfr()
    1793 
    1794  if (ParamIsDefault(projection))
    1795  projection = 1
    1796  endif
    1797  if (ParamIsDefault(graphtype))
    1798  graphtype = 1
    1799  endif
    1800  if (ParamIsDefault(do_ticks))
    1801  do_ticks = 3
    1802  endif
    1803  if (ParamIsDefault(do_grids))
    1804  do_grids = 3
    1805  endif
    1806  if (ParamIsDefault(graphname))
    1807  if (strlen(nickname) > 0)
    1808  graphname = nickname
    1809  else
    1810  graphname = GetDataFolder(0)
    1811  endif
    1812  endif
    1813 
    1814  prepare_hemi_scan_display(nickname, projection=projection)
    1815 
    1816  // hemi grid waves
    1817  string s_prefix = ""
    1818  string s_int = "values"
    1819  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    1820 
    1821  string s_polar = s_prefix + "pol"
    1822  string s_azim = s_prefix + "az"
    1823  string s_matrix = s_prefix + "matrix"
    1824  string s_ster_rad = s_prefix + "ster_rad"
    1825 
    1826  wave /sdfr=df /z values = $s_int
    1827  wave /sdfr=df /z azim = $s_azim
    1828  wave /sdfr=df /z polar = $s_polar
    1829  wave /sdfr=df /z ster_rad = $s_ster_rad
    1830  wave /sdfr=df /z matrix = $s_matrix
    1831 
    1832  setdatafolder df
    1833  variable azim_offset = 0
    1834  if (!(NumberByKey("version", note(azim), "=", "\r") >= 1.6))
    1835  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!"
    1836  azim_offset = 180 // changed 151030 (v1.6)
    1837  endif
    1838 
    1839  string s_trace
    1840  DoWindow $graphname
    1841  if (v_flag)
    1842  if (str2num(GetUserData(graphname, "", "graphtype")) == graphtype)
    1843  // graph exists and will update automatically - do not recreate
    1844  graphtype = 0
    1845  else
    1846  // graph exists - but needs recreating
    1847  killwindow $graphname
    1848  endif
    1849  endif
    1850 
    1851  switch(graphtype)
    1852  case 1:
    1853  graphname = display_polar_graph(graphname, angle_offset=azim_offset, do_ticks=do_ticks)
    1854 
    1855  s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360)
    1856  ModifyGraph /W=$graphname mode($s_trace)=2, lsize($s_trace)=2
    1857  ModifyGraph /W=$graphname zColor($s_trace)={values,*,*,BlueGreenOrange,0}
    1858 
    1859  ColorScale /W=$graphname /C /N=text0 /E=2 /F=0 /B=1 /A=RB /X=0.00 /Y=0.00 trace=polarY0
    1860  ColorScale /W=$graphname /C /N=text0 side=2, width=5, heightPct=40, frame=0.50, lblMargin=0
    1861  ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50
    1862 
    1863  SetWindow $graphname, userdata(projection)=num2str(projection)
    1864  SetWindow $graphname, userdata(graphtype)=num2str(graphtype)
    1865  draw_hemi_axes(graphname, do_grids=do_grids)
    1866  break
    1867  case 3:
    1868  graphname = display_polar_graph(graphname, angle_offset=azim_offset, do_ticks=do_ticks)
    1869 
    1870  s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360)
    1871  ModifyGraph /W=$graphname mode($s_trace)=0, lsize($s_trace)=0
    1872  AppendImage /L=VertCrossing /B=HorizCrossing matrix
    1873 
    1874  ColorScale /W=$graphname /C /N=text0 /E=2 /F=0 /B=1 /A=RB /X=0.00 /Y=0.00 image=$s_matrix
    1875  ColorScale /W=$graphname /C /N=text0 side=2, width=5, heightPct=40, frame=0.50, lblMargin=0
    1876  ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50
    1877 
    1878  SetWindow $graphname, userdata(projection)=num2str(projection)
    1879  SetWindow $graphname, userdata(graphtype)=num2str(graphtype)
    1880  draw_hemi_axes(graphname, do_grids=do_grids)
    1881  break
    1882  endswitch
    1883 
    1884  setdatafolder savedf
    1885  return graphname
    1886 end
    1887 
    1929 static function /s display_polar_graph(graphname, [angle_offset, do_ticks])
    1930 
    1931  string graphname
    1932  variable angle_offset
    1933  variable do_ticks
    1934 
    1935  dfref savedf = GetDataFolderDFR()
    1936 
    1937  if (ParamIsDefault(angle_offset))
    1938  angle_offset = 0
    1939  endif
    1940  if (ParamIsDefault(do_ticks))
    1941  do_ticks = 3
    1942  endif
    1943 
    1944  if ((strlen(graphname) == 0) || (wintype(graphname) == 0))
    1945  Display /k=1 /W=(10,45,360,345)
    1946  DoWindow /C $graphname
    1947  graphname = WMNewPolarGraph("", graphname)
    1948  WMPolarGraphSetVar(graphname, "zeroAngleWhere", angle_offset)
    1949 
    1950  WMPolarGraphSetVar(graphname, "angleAxisThick", 0.5)
    1951  WMPolarGraphSetStr(graphname, "doMajorAngleTicks", "manual")
    1952  WMPolarGraphSetVar(graphname, "majorAngleInc", 30) // major ticks in 30 deg steps
    1953  WMPolarGraphSetVar(graphname, "minorAngleTicks", 2) // minor ticks in 10 deg steps
    1954  WMPolarGraphSetStr(graphname, "angleTicksLocation", "Outside")
    1955  WMPolarGraphSetVar(graphname, "doAngleTickLabelSubRange", 1)
    1956  WMPolarGraphSetVar(graphname, "angleTickLabelRangeStart", 0)
    1957  WMPolarGraphSetVar(graphname, "angleTickLabelRangeExtent", 90)
    1958  WMPolarGraphSetStr(graphname, "angleTickLabelNotation", "%g°")
    1959 
    1960  WMPolarGraphSetVar(graphname, "doPolarGrids", 0)
    1961  WMPolarGraphSetVar(graphname, "doRadiusTickLabels", 0)
    1962  WMPolarGraphSetStr(graphname, "radiusAxesWhere", " Off") // note the leading spaces, cf. WMPolarAnglesForRadiusAxes
    1963  WMPolarGraphSetStr(graphname, "radiusTicksLocation", "Off")
    1964 
    1965  WMPolarGraphSetVar(graphname, "majorTickLength", 2)
    1966  WMPolarGraphSetVar(graphname, "majorTickThick", 0.5)
    1967  WMPolarGraphSetVar(graphname, "minorTickLength", 1)
    1968  WMPolarGraphSetVar(graphname, "minorTickThick", 0.5)
    1969  WMPolarGraphSetVar(graphname, "tickLabelOpaque", 0)
    1970  WMPolarGraphSetVar(graphname, "tickLabelFontSize", 7)
    1971 
    1972  // changes
    1973  if (do_ticks & 1)
    1974  WMPolarGraphSetStr(graphname, "angleTicksLocation", "Outside")
    1975  else
    1976  WMPolarGraphSetStr(graphname, "angleTicksLocation", "Off")
    1977  endif
    1978  if (do_ticks & 2)
    1979  WMPolarGraphSetVar(graphname, "doMinorAngleTicks", 1)
    1980  else
    1981  WMPolarGraphSetVar(graphname, "doMinorAngleTicks", 0)
    1982  endif
    1983 
    1984  DoWindow /T $graphname, graphname
    1985 
    1986  // cursor info in angles
    1987  string graphdf = "root:packages:WMPolarGraphs:" + graphname
    1988  setdatafolder graphdf
    1989  // current theta, phi coordinates are stored in global variables in the package folder of the graph
    1990  variable /g csrA_theta
    1991  variable /g csrA_phi
    1992  variable /g csrB_theta
    1993  variable /g csrB_phi
    1994  // the text box is hidden initially. it shows up and hides with the cursor info box.
    1995  string tb
    1996  tb = "\\{"
    1997  tb = tb + "\"A = (%.1f, %.1f)\","
    1998  tb = tb + graphdf + ":csrA_theta,"
    1999  tb = tb + graphdf + ":csrA_phi"
    2000  tb = tb + "}"
    2001  TextBox /W=$graphname /A=LT /B=1 /E=2 /F=0 /N=tb_angles /X=1 /Y=1 /V=0 tb
    2002  tb = "\\{"
    2003  tb = tb + "\"B = (%.1f, %.1f)\","
    2004  tb = tb + graphdf + ":csrB_theta,"
    2005  tb = tb + graphdf + ":csrB_phi"
    2006  tb = tb + "}"
    2007  AppendText /W=$graphname /N=tb_angles tb
    2008  // updates are triggered by a window hook
    2009  SetWindow $graphname, hook(polar_graph_hook)=PearlAnglescanProcess#polar_graph_hook
    2010  else
    2011  // graph window exists
    2012  DoWindow /F $graphname
    2013  endif
    2014 
    2015  setdatafolder savedf
    2016  return graphname
    2017 end
    2018 
    2044 static function /s draw_hemi_axes(graphname, [do_grids])
    2045  string graphname
    2046  variable do_grids
    2047 
    2048  if (ParamIsDefault(do_grids))
    2049  do_grids = 3
    2050  endif
    2051 
    2052  dfref savedf = GetDataFolderDFR()
    2053 
    2054  string sproj = GetUserData(graphname, "", "projection")
    2055  variable projection = str2num("0" + sproj)
    2056 
    2057  SetDrawLayer /W=$graphname ProgFront
    2058 
    2059  // polar axis
    2060  SetDrawEnv /W=$graphname xcoord=HorizCrossing, ycoord=VertCrossing
    2061  SetDrawEnv /W=$graphname linethick= 0.5
    2062  SetDrawEnv /W=$graphname dash=2
    2063  SetDrawEnv /W=$graphname fillpat=0
    2064  SetDrawEnv /W=$graphname fname="default", fsize=7
    2065  SetDrawEnv /W=$graphname textxjust=1, textyjust=1
    2066  //SetDrawEnv /W=$graphname linefgc=(65535,65535,65535)
    2067  SetDrawEnv /W=$graphname save
    2068 
    2069  if (do_grids & 1)
    2070  DrawLine /W=$graphname 0, -2, 0, 2
    2071  DrawLine /W=$graphname -2, 0, 2, 0
    2072  endif
    2073 
    2074  variable radi
    2075  if (do_grids & 2)
    2076  radi = calc_graph_radius(0.5, projection=projection)
    2077  DrawOval /W=$graphname -radi, radi, radi, -radi
    2078  radi = calc_graph_radius(30, projection=projection)
    2079  DrawOval /W=$graphname -radi, radi, radi, -radi
    2080  radi = calc_graph_radius(60, projection=projection)
    2081  DrawOval /W=$graphname -radi, radi, radi, -radi
    2082 
    2083  SetDrawEnv /W=$graphname textxjust= 1,textyjust= 2
    2084  SetDrawEnv /W=$graphname save
    2085  radi = calc_graph_radius(30, projection=projection)
    2086  DrawText /W=$graphname radi, -0.1, "30°"
    2087  radi = calc_graph_radius(60, projection=projection)
    2088  DrawText /W=$graphname radi, -0.1, "60°"
    2089  endif
    2090 
    2091  setdatafolder savedf
    2092 end
    2093 
    2116 function draw_diffraction_cone(graphname, groupname, theta_axis, theta_inner, phi)
    2117  string graphname
    2118  string groupname
    2119 
    2120  variable theta_axis
    2121  variable theta_inner
    2122  variable phi
    2123 
    2124  variable r_axis = calc_graph_radius(theta_axis)
    2125  variable r_inner = calc_graph_radius(theta_inner)
    2126  variable r_outer = calc_graph_radius(2 * theta_axis - theta_inner)
    2127 
    2128  SetDrawEnv push
    2129  SetDrawLayer UserFront
    2130  DrawAction getgroup=$groupname, delete
    2131  SetDrawEnv gstart, gname=$groupname
    2132  variable xc, yc, xr, yr
    2133 
    2134  // cone periphery
    2135  variable r_center = (r_outer + r_inner) / 2
    2136  variable r_radius = (r_outer - r_inner) / 2
    2137  xc = r_center * cos(phi * pi / 180)
    2138  yc = r_center * sin(phi * pi / 180)
    2139  xr = r_radius
    2140  yr = r_radius
    2141  SetDrawEnv xcoord=HorizCrossing, ycoord=VertCrossing
    2142  SetDrawEnv dash=11, fillpat=0
    2143  DrawOval xc - xr, yc - yr, xc + xr, yc + yr
    2144 
    2145  // cone axis
    2146  xc = r_axis * cos(phi * pi / 180)
    2147  yc = r_axis * sin(phi * pi / 180)
    2148  r_radius = calc_graph_radius(2)
    2149  xr = r_radius
    2150  yr = r_radius
    2151  SetDrawEnv xcoord=HorizCrossing, ycoord=VertCrossing
    2152  SetDrawEnv fillfgc=(0,0,0)
    2153  DrawOval xc - xr, yc - yr, xc + xr, yc + yr
    2154 
    2155  SetDrawEnv gstop
    2156  SetDrawEnv pop
    2157 end
    2158 
    2180 function /s display_scanlines(nickname, alpha_lo, alpha_hi, m_theta, m_tilt, m_phi, [folding, projection])
    2181  string nickname
    2182  variable alpha_lo
    2183  variable alpha_hi
    2184  wave m_theta
    2185  wave m_tilt
    2186  wave m_phi
    2187  variable folding
    2188  variable projection
    2189 
    2190  if (ParamIsDefault(folding))
    2191  folding = 1
    2192  endif
    2193  if (ParamIsDefault(projection))
    2194  projection = 1
    2195  endif
    2196 
    2197  // sort out data folder structure
    2198  dfref saveDF = GetDataFolderDFR()
    2199  newdatafolder /s/o $nickname
    2200  string graphname = "graph_" + nickname
    2201 
    2202  duplicate /free m_tilt, loc_m_tilt
    2203  loc_m_tilt = -m_tilt
    2204 
    2205  make /n=1 /d /free d_polar, d_azi
    2206  variable n_alpha = round(alpha_hi - alpha_lo) + 1
    2207  make /n=(n_alpha) /d /free analyser
    2208  setscale /i x alpha_lo, alpha_hi, "°", analyser
    2209  analyser = x
    2210 
    2211  convert_angles_ttpa2polar(m_theta, loc_m_tilt, m_phi, analyser, d_polar, d_azi)
    2212  duplicate /free d_polar, d_radius
    2213  d_radius = calc_graph_radius(d_polar, projection=projection)
    2214  d_azi += 180 // changed 151030 (v1.6)
    2215 
    2216  graphname = display_polar_graph(graphname)
    2217  SetWindow $graphname, userdata(projection)=num2str(projection)
    2218 
    2219  variable ifold
    2220  variable iang
    2221  variable nang = numpnts(m_theta)
    2222  string s_rad
    2223  string s_azi
    2224  string s_trace
    2225  for (ifold = 0; ifold < folding; ifold += 1)
    2226  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
    2227  for (iang = 0; iang < nang; iang += 1)
    2228  sprintf s_rad, "rad_%d_%d", ifold, iang
    2229  duplicate /o analyser, $s_rad
    2230  wave w_rad = $s_rad
    2231  w_rad = d_radius[p][iang]
    2232 
    2233  sprintf s_azi, "azi_%d_%d", ifold, iang
    2234  duplicate /o analyser, $s_azi
    2235  wave w_azi = $s_azi
    2236  w_azi = d_azi[p][iang]
    2237 
    2238  if (numtype(sum(w_rad)) == 0)
    2239  s_trace = WMPolarAppendTrace(graphname, w_rad, w_azi, 360)
    2240  ModifyGraph /w=$graphname mode($s_trace)=0, lsize($s_trace)=0.5
    2241  endif
    2242  endfor
    2243  d_azi += 360 / folding
    2244  endfor
    2245 
    2246  draw_hemi_axes(graphname)
    2247 
    2248  setdatafolder saveDF
    2249  return graphname
    2250 end
    2251 
    2268 constant kProjDist = 0
    2269 constant kProjStereo = 1
    2270 constant kProjArea = 2
    2271 constant kProjGnom = 3
    2272 constant kProjOrtho = 4
    2273 
    2274 static constant kProjScaleDist = 2
    2275 static constant kProjScaleStereo = 2
    2276 static constant kProjScaleArea = 2
    2277 // scaled so that radius(gnom) = radius(stereo) for polar = 88
    2278 static constant kProjScaleGnom = 0.06744519021
    2279 static constant kProjScaleOrtho = 2
    2280 
    2295 threadsafe function calc_graph_radius(polar, [projection])
    2296  variable polar
    2297  variable projection
    2298 
    2299  if (ParamIsDefault(projection))
    2300  projection = 1
    2301  endif
    2302 
    2303  variable radius
    2304  switch(projection)
    2305  case kProjStereo: // stereographic
    2306  radius = kProjScaleStereo * tan(polar / 2 * pi / 180)
    2307  break
    2308  case kProjArea: // equal area
    2309  radius = kProjScaleArea * sin(polar / 2 * pi / 180)
    2310  break
    2311  case kProjGnom: // gnomonic
    2312  radius = polar < 90 ? kProjScaleGnom * tan(polar * pi / 180) : inf
    2313  break
    2314  case kProjOrtho: // orthographic
    2315  radius = kProjScaleOrtho * sin(polar * pi / 180)
    2316  break
    2317  default: // equidistant
    2318  radius = kProjScaleDist * polar / 90
    2319  endswitch
    2320 
    2321  return radius
    2322 end
    2323 
    2340 threadsafe function calc_graph_polar(x, y, [projection])
    2341  variable x
    2342  variable y
    2343  variable projection
    2344 
    2345  if (ParamIsDefault(projection))
    2346  projection = 1
    2347  endif
    2348 
    2349  variable radius
    2350  variable polar
    2351 
    2352  radius = sqrt(x^2 + y^2)
    2353  switch(projection)
    2354  case kProjStereo: // stereographic
    2355  polar = 2 * atan(radius / kProjScaleStereo) * 180 / pi
    2356  break
    2357  case kProjArea: // equal area
    2358  polar = 2 * asin(radius / kProjScaleArea) * 180 / pi
    2359  break
    2360  case kProjGnom: // gnomonic
    2361  polar = atan(radius / kProjScaleGnom) * 180 / pi
    2362  break
    2363  case kProjOrtho: // orthographic
    2364  polar = asin(radius / kProjScaleOrtho) * 180 / pi
    2365  break
    2366  default: // equidistant
    2367  polar = 90 * radius / kProjScaleDist
    2368  endswitch
    2369 
    2370  return polar
    2371 end
    2372 
    2393 threadsafe function calc_graph_azi(x, y, [projection,zeroAngle])
    2394  variable x
    2395  variable y
    2396  variable projection
    2397  variable zeroAngle
    2398 
    2399  if (ParamIsDefault(projection))
    2400  projection = 1
    2401  endif
    2402  if (ParamIsDefault(zeroAngle))
    2403  zeroAngle = 0
    2404  endif
    2405 
    2406  variable azi
    2407  if (x > 0)
    2408  azi = atan(y / x) * 180 / pi
    2409  else
    2410  azi = atan(y / x) * 180 / pi + 180
    2411  endif
    2412 
    2413  azi += zeroAngle
    2414  if (azi < 0)
    2415  azi += 360
    2416  endif
    2417  if (azi >= 360)
    2418  azi -= 360
    2419  endif
    2420  if (numtype(azi) != 0)
    2421  azi = 0
    2422  endif
    2423 
    2424  return azi
    2425 end
    2426 
    2438 static function update_polar_info(graphname)
    2439  string graphname
    2440 
    2441  dfref savedf = GetDataFolderDFR()
    2442 
    2443  string graphdf = "root:packages:WMPolarGraphs:" + graphname
    2444  setdatafolder graphdf
    2445 
    2446  nvar csrA_theta
    2447  nvar csrA_phi
    2448  nvar csrB_theta
    2449  nvar csrB_phi
    2450 
    2451  string sproj = GetUserData(graphname, "", "projection")
    2452  variable projection = str2num("0" + sproj)
    2453  nvar zeroAngleWhere
    2454 
    2455  variable x = hcsr(A, graphname)
    2456  variable y = vcsr(A, graphname)
    2457  csrA_theta = calc_graph_polar(x, y, projection=projection)
    2458  csrA_phi = calc_graph_azi(x, y, projection=projection, zeroAngle=zeroAngleWhere)
    2459 
    2460  x = hcsr(B, graphname)
    2461  y = vcsr(B, graphname)
    2462  csrB_theta = calc_graph_polar(x, y, projection=projection)
    2463  csrB_phi = calc_graph_azi(x, y, projection=projection, zeroAngle=zeroAngleWhere)
    2464 
    2465  setdatafolder savedf
    2466 end
    2467 
    2473 static function polar_graph_hook(s)
    2474  STRUCT WMWinHookStruct &s
    2475 
    2476  Variable hookResult = 0
    2477 
    2478  switch(s.eventCode)
    2479  case 7: // cursor moved
    2480  update_polar_info(s.winname)
    2481  break
    2482  case 20: // show info
    2483  TextBox /W=$s.winname /N=tb_angles /C /V=1
    2484  break
    2485  case 21: // hide info
    2486  TextBox /W=$s.winname /N=tb_angles /C /V=0
    2487  break
    2488  endswitch
    2489 
    2490  return hookResult // 0 if nothing done, else 1
    2491 end
    2492 
    2493 function set_polar_graph_cursor(nickname, cursorname, polar_angle, azim_angle, [graphname])
    2494  string nickname
    2495  string cursorname
    2496  variable polar_angle
    2497  variable azim_angle
    2498  string graphname
    2499 
    2500  if (ParamIsDefault(graphname))
    2501  if (strlen(nickname) > 0)
    2502  graphname = nickname
    2503  else
    2504  graphname = GetDataFolder(0)
    2505  endif
    2506  endif
    2507 
    2508  string s_prefix = ""
    2509  string s_int = "values"
    2510  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    2511 
    2512  string s_polar = s_prefix + "pol"
    2513  string s_azim = s_prefix + "az"
    2514  wave /sdfr=df /z azim = $s_azim
    2515  wave /sdfr=df /z polar = $s_polar
    2516 
    2517  FindLevel /P /Q polar, polar_angle
    2518  if (v_flag == 0)
    2519  variable polar_level = floor(v_levelx)
    2520  FindLevel /P /Q /R=[polar_level] azim, azim_angle
    2521  if (v_flag == 0)
    2522  variable azim_level = round(v_levelx)
    2523  string tracename = "polarY0"
    2524  Cursor /W=$graphname /P $cursorname $traceName azim_level
    2525  endif
    2526  endif
    2527 end
    2528 
    2538 function hemi_add_anglescan(nickname, values, polar, azi, [weights])
    2539  string nickname // name prefix of holo waves.
    2540  // may be empty.
    2541  wave values // intensity values
    2542  // the wave can be one- or two-dimensional.
    2543  // no specific order required, the function sorts the arrays internally
    2544  wave polar // polar coordinates. allowed range 0 <= theta <= 90
    2545  // dimensions corresponding to value.
    2546  wave azi // azimuthal coordinates. allowed range -360 <= phi < +360
    2547  // dimensions corresponding to value.
    2548  wave weights // total accumulation time of each point of values. default = 1
    2549 
    2550  if (ParamIsDefault(weights))
    2551  duplicate /free values, weights
    2552  weights = 1
    2553  endif
    2554 
    2555  // quick check whether hemi grid is existing
    2556  string s_prefix = ""
    2557  string s_int = "values"
    2558  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    2559 
    2560  string s_polar = s_prefix + "pol"
    2561  string s_azim = s_prefix + "az"
    2562  string s_theta = s_prefix + "th"
    2563 
    2564  wave /sdfr=df /z w_values = $s_int
    2565  wave /sdfr=df /z w_azim = $s_azim
    2566  wave /sdfr=df /z w_polar = $s_polar
    2567  wave /sdfr=df /z w_theta = $s_theta
    2568  if (!waveexists(w_values) || !waveexists(w_azim) || !waveexists(w_polar))
    2569  abort "Missing hemispherical scan grid. Please call make_hemi_grid() first."
    2570  endif
    2571 
    2572  // make internal copies, one-dimensional, ordered in theta
    2573  duplicate /free values, values_copy
    2574  duplicate /free polar, polar_copy
    2575  duplicate /free azi, azi_copy
    2576  duplicate /free weights, weights_copy
    2577  variable nn = dimsize(values, 0) * max(dimsize(values, 1), 1)
    2578  redimension /n=(nn) values_copy, polar_copy, azi_copy, weights_copy
    2579  sort /r polar_copy, polar_copy, azi_copy, values_copy, weights_copy
    2580 
    2581  variable pol
    2582  variable pol_st = abs(w_theta[1] - w_theta[0])
    2583  variable pol1, pol2
    2584 
    2585  duplicate /free azi_copy, azi_slice
    2586  duplicate /free values_copy, values_slice
    2587  duplicate /free weights_copy, weights_slice
    2588  for (pol = 90; pol >= 0; pol -= pol_st)
    2589  pol1 = pol - pol_st / 2
    2590  pol2 = pol + pol_st / 2
    2591  extract /free /indx polar_copy, sel, (pol1 < polar_copy) && (polar_copy <= pol2)
    2592  if (numpnts(sel) > 0)
    2593  redimension /n=(numpnts(sel)) azi_slice, values_slice, weights_slice
    2594  azi_slice = azi_copy[sel]
    2595  values_slice = values_copy[sel]
    2596  weights_slice = weights_copy[sel]
    2597  hemi_add_aziscan(nickname, values_slice, pol, azi_slice, weights=weights_slice)
    2598  endif
    2599  endfor
    2600 end
    2601 
    2608 function hemi_add_aziscan(nickname, values, polar, azi, [weights])
    2609  string nickname // name prefix of holo waves.
    2610  // may be empty.
    2611  wave values // intensity values of the azimuthal scan at the positions given in the azi parameter
    2612  variable polar // polar angle where to add the azi scan
    2613  wave azi // angle positions of the azimuthal scan
    2614  // acceptable range: >= -360 and < +360
    2615  // no specific order required, the function sorts the array internally
    2616  wave weights // total accumulation time of each point of values. default = 1
    2617 
    2618  if (ParamIsDefault(weights))
    2619  duplicate /free values, weights
    2620  weights = 1
    2621  endif
    2622 
    2623  // hemi grid waves
    2624  string s_prefix = ""
    2625  string s_int = "values"
    2626  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    2627 
    2628  string s_totals = s_prefix + "tot"
    2629  string s_weights = s_prefix + "wt"
    2630  string s_polar = s_prefix + "pol"
    2631  string s_azim = s_prefix + "az"
    2632  string s_index = s_prefix + "index"
    2633  string s_theta = s_prefix + "th"
    2634  string s_dphi = s_prefix + "dphi"
    2635  string s_nphis = s_prefix + "nphis"
    2636 
    2637  wave /sdfr=df w_polar = $s_polar
    2638  wave /sdfr=df w_azim = $s_azim
    2639  wave /sdfr=df w_values = $s_int
    2640  wave /sdfr=df w_totals = $s_totals
    2641  wave /sdfr=df w_weights = $s_weights
    2642  wave /sdfr=df w_index = $s_index
    2643  wave /sdfr=df w_theta = $s_theta
    2644  wave /sdfr=df w_dphi = $s_dphi
    2645  wave /sdfr=df w_nphis = $s_nphis
    2646 
    2647  // destination slice coordinates
    2648  //polar = round(polar)
    2649  //variable ipol = 90 - polar
    2650  variable ipol = BinarySearch(w_theta, polar)
    2651  if (ipol < 0)
    2652  abort "assertion failed in hemi_add_aziscan(): polar angle not found in grid."
    2653  endif
    2654 
    2655  variable d1, d2
    2656  if (ipol >= 1)
    2657  d1 = w_index[ipol - 1]
    2658  else
    2659  d1 = 0
    2660  endif
    2661  d2 = w_index[ipol] - 1
    2662  variable nd = d2 - d1 + 1
    2663  variable dphi = w_dphi[ipol]
    2664  variable az1, az2
    2665 
    2666  // source slice coordinates
    2667  // order the slice from -dphi/2 to 360-dphi/2
    2668  azi = azi < 0 ? azi + 360 : azi
    2669  azi = azi >= 360 - dphi/2 ? azi - 360 : azi
    2670  duplicate /free values, sel_values
    2671  duplicate /free weights, sel_weights
    2672 
    2673  // loop over destination
    2674  variable id
    2675  variable v1, v2, w1, w2
    2676  for (id = 0; id < nd; id += 1)
    2677  az1 = (id - 0.5) * dphi
    2678  az2 = (id + 0.5) * dphi
    2679  extract /free /indx azi, sel, (az1 <= azi) && (azi < az2)
    2680  if (numpnts(sel) > 0)
    2681  redimension /n=(numpnts(sel)) sel_values, sel_weights
    2682  sel_values = values[sel]
    2683  sel_weights = weights[sel]
    2684  v1 = w_totals[d1 + id]
    2685  w1 = w_weights[d1 + id]
    2686  if ((numtype(v1) == 2) || (w1 <= 0))
    2687  v1 = 0
    2688  w1 = 0
    2689  endif
    2690  v2 = sum(sel_values)
    2691  w2 = sum(sel_weights)
    2692  w_totals[d1 + id] = v1 + v2
    2693  w_weights[d1 + id] = w1 + w2
    2694  endif
    2695  endfor
    2696  w_values[d1, d1 + nd - 1] = w_totals[p] / w_weights[p]
    2697 end
    2698 
    2726 function interpolate_hemi_scan(nickname, [projection])
    2727  string nickname
    2728  variable projection
    2729 
    2730  dfref savedf = GetDataFolderDFR()
    2731 
    2732  if (ParamIsDefault(projection))
    2733  projection = 1
    2734  endif
    2735 
    2736  string s_prefix = ""
    2737  string s_int = "values"
    2738  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    2739  prepare_hemi_scan_display(nickname, projection=projection)
    2740 
    2741  string s_polar = s_prefix + "pol"
    2742  string s_azim = s_prefix + "az"
    2743  string s_matrix = s_prefix + "matrix"
    2744  string s_ster_rad = s_prefix + "ster_rad"
    2745  string s_ster_x = s_prefix + "ster_x"
    2746  string s_ster_y = s_prefix + "ster_y"
    2747 
    2748  wave /sdfr=df /z values = $s_int
    2749  wave /sdfr=df /z azim = $s_azim
    2750  wave /sdfr=df /z polar = $s_polar
    2751  wave /sdfr=df /z ster_rad = $s_ster_rad
    2752  wave /sdfr=df /z ster_x = $s_ster_x
    2753  wave /sdfr=df /z ster_y = $s_ster_y
    2754 
    2755  variable min_ster_x = wavemin(ster_x)
    2756  variable max_ster_x = wavemax(ster_x)
    2757  variable x0 = min_ster_x
    2758  variable xn = 181
    2759  variable dx = (max_ster_x - min_ster_x) / (xn - 1)
    2760  make /n=(numpnts(ster_x), 3) /free triplet
    2761  triplet[][0] = ster_x[p]
    2762  triplet[][1] = ster_y[p]
    2763  triplet[][2] = values[p]
    2764 
    2765  variable size = 181
    2766  setdatafolder df
    2767  make /n=(size, size) /d /o $(s_prefix + "matrix") /wave=matrix
    2768  make /n=(size, size) /free mnorm
    2769  ImageFromXYZ /as {ster_x, ster_y, values}, matrix, mnorm
    2770  matrix /= mnorm
    2771  matrixfilter NanZapMedian, matrix
    2772  matrixfilter gauss, matrix
    2773 
    2774  duplicate /free values, ster_finite
    2775  ster_finite = (numtype(values) == 0) * (ster_x^2 + ster_y^2)
    2776  variable ster_max = wavemax(ster_finite)
    2777  matrix = (x^2 + y^2) <= ster_max ? matrix : nan
    2778 
    2779  setdatafolder savedf
    2780 end
    2781 
    2792 function quick_pizza_image(data, nickname, theta_offset, tilt_offset, phi_offset, [npolar, nograph, folding])
    2793  wave data // 2D intensity wave, see requirements above
    2794  string nickname // nick name for output data
    2795  // in default mode, this will be the name of a child folder containing the output
    2796  // in XPDplot mode, this will be a prefix of the generated data in the root folder
    2797  variable theta_offset // manipulator theta angle corresponding to normal emission
    2798  variable tilt_offset // manipulator tilt angle corresponding to normal emission
    2799  variable phi_offset // manipulator phi angle corresponding to phi_result = 0
    2800  variable npolar // number of polar angles, determines polar and azimuthal step size
    2801  // default = 91 (1 degree steps)
    2802  variable nograph // 0 (default) = display a new polar graph
    2803  // 1 = don't display a new graph (if a graph is existing from a previous call, it will update)
    2804  variable folding // rotational averaging, default = 1
    2805 
    2806  if (ParamIsDefault(npolar))
    2807  npolar = 91
    2808  endif
    2809  if (ParamIsDefault(nograph))
    2810  nograph = 0
    2811  endif
    2812  if (ParamIsDefault(folding))
    2813  folding = 1
    2814  endif
    2815  string graphname = "graph_" + nickname
    2816  string s_prefix = ""
    2817 
    2818  // sort out data folder structure
    2819  dfref saveDF = GetDataFolderDFR()
    2820  dfref dataDF = GetWavesDataFolderDFR(data)
    2821  setdatafolder dataDF
    2822  if (DataFolderExists(":attr"))
    2823  setdatafolder :attr
    2824  endif
    2825  dfref attrDF = GetDataFolderDFR()
    2826  setdatafolder dataDF
    2827  newdatafolder /s/o $nickname
    2828  dfref destDF = GetDataFolderDFR()
    2829 
    2830  // performance monitoring
    2831  variable timerRefNum
    2832  variable /g xyz_perf_secs
    2833  timerRefNum = startMSTimer
    2834 
    2835  wave /sdfr=attrDF ManipulatorTheta
    2836  wave /sdfr=attrDF ManipulatorTilt
    2837  wave /sdfr=attrDF ManipulatorPhi
    2838  duplicate /free ManipulatorTheta, m_theta
    2839  duplicate /free ManipulatorTilt, m_tilt
    2840  duplicate /free ManipulatorPhi, m_phi
    2841  m_theta -= theta_offset
    2842  m_tilt -= tilt_offset
    2843  m_tilt *= -1 // checked 140702
    2844  m_phi -= phi_offset
    2845  //m_phi *= -1 // checked 140702
    2846 
    2847  make /n=1/d/free d_polar, d_azi
    2848  convert_angles_ttpd2polar(m_theta, m_tilt, m_phi, data, d_polar, d_azi)
    2849  d_azi += 180 // changed 151030 (v1.6)
    2850  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
    2851 
    2852  duplicate /free data, values
    2853  variable nn = dimsize(values, 0) * max(dimsize(values, 1), 1)
    2854  redimension /n=(nn) values, d_polar, d_azi
    2855  duplicate /o d_polar, ster_rad, ster_x, ster_y
    2856 
    2857  variable projection = 1
    2858  switch(projection)
    2859  case 1: // stereographic
    2860  ster_rad = 2 * tan(d_polar / 2 * pi / 180)
    2861  break
    2862  case 2: // azimuthal
    2863  ster_rad = 2 * cos((180 - d_polar) / 2 * pi / 180)
    2864  break
    2865  endswitch
    2866  string s_ster_x = s_prefix + "ster_x"
    2867  string s_ster_y = s_prefix + "ster_y"
    2868 
    2869  nn = 401
    2870  make /n=(nn, nn) /d /o matrix
    2871  make /n=(nn, nn) /free mnorm
    2872  setscale /i x -2, +2, matrix, mnorm
    2873  setscale /i y -2, +2, matrix, mnorm
    2874  matrix = 0
    2875  mnorm = 0
    2876 
    2877  variable ifold
    2878  for (ifold = 0; ifold < folding; ifold += 1)
    2879  ster_x = ster_rad * cos(d_azi * pi / 180)
    2880  ster_y = ster_rad * sin(d_azi * pi / 180)
    2881  ImageFromXYZ {ster_x, ster_y, values}, matrix, mnorm
    2882  d_azi = d_azi >= 180 ? d_azi + 360 / folding - 180 : d_azi + 360 / folding
    2883  endfor
    2884 
    2885  matrix /= mnorm
    2886  matrixfilter /n=5 NanZapMedian matrix
    2887  matrixfilter /n=3 gauss matrix
    2888 
    2889  if (!nograph)
    2890  display /k=1
    2891  appendimage matrix
    2892  modifygraph width={Plan,1,bottom,left}
    2893  endif
    2894 
    2895  if (timerRefNum >= 0)
    2896  xyz_perf_secs = stopMSTimer(timerRefNum) / 1e6
    2897  endif
    2898 
    2899  setdatafolder saveDF
    2900 end
    2901 
    2903 function save_hemi_scan(nickname, pathname, filename)
    2904  string nickname
    2905  string pathname
    2906  string filename
    2907 
    2908  dfref savedf = getdatafolderdfr()
    2909 
    2910  // source data
    2911  string s_prefix = ""
    2912  string s_int = "values"
    2913  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    2914 
    2915  string s_polar = s_prefix + "pol"
    2916  string s_azim = s_prefix + "az"
    2917  string s_theta = s_prefix + "th"
    2918  string s_tot = s_prefix + "tot"
    2919  string s_weight = s_prefix + "wt"
    2920 
    2921  wave /sdfr=df theta1 = $s_theta
    2922  wave /sdfr=df polar1 = $s_polar
    2923  wave /sdfr=df azim1 = $s_azim
    2924  wave /sdfr=df tot1 = $s_tot
    2925  wave /sdfr=df weight1 = $s_weight
    2926  wave /sdfr=df values1 = $s_int
    2927 
    2928  save /m="\r\n" /o /p=$pathname /t theta1, polar1, azim1, tot1, weight1, values1 as filename
    2929 
    2930  setdatafolder saveDF
    2931 end
    2932 
    2936 function load_hemi_scan(nickname, pathname, filename)
    2937  string nickname
    2938  string pathname
    2939  string filename
    2940 
    2941  dfref savedf = getdatafolderdfr()
    2942 
    2943  //loadwave /p=$pathname /t theta1, polar1, azim1, tot1, weight1, values1 as filename
    2944  //LoadWave /t/p=pearl_explorer_filepath/q filename
    2945  //svar waves = s_wavenames
    2946  //if (v_flag > 0)
    2947  // string /g pearl_explorer_import = "load_itx_file"
    2948  //endif
    2949 
    2950  setdatafolder saveDF
    2951 end
    2952 
    2985 function import_tpi_scan(nickname, theta, phi, intensity, [folding, npolar, nograph, xpdplot])
    2986  string nickname
    2987  wave theta
    2988  wave phi
    2989  wave intensity
    2990 
    2991  variable folding
    2992  variable npolar
    2993  variable nograph
    2994  variable xpdplot
    2995 
    2996  if (ParamIsDefault(npolar))
    2997  npolar = 91
    2998  endif
    2999  if (ParamIsDefault(nograph))
    3000  nograph = 0
    3001  endif
    3002  if (ParamIsDefault(folding))
    3003  folding = 1
    3004  endif
    3005  if (ParamIsDefault(xpdplot))
    3006  xpdplot = 0
    3007  endif
    3008 
    3009  make_hemi_grid(npolar, nickname, xpdplot=xpdplot)
    3010 
    3011  variable ifold
    3012  duplicate /free phi, fold_phi
    3013  for (ifold = 0; ifold < folding; ifold += 1)
    3014  hemi_add_anglescan(nickname, intensity, theta, fold_phi)
    3015  fold_phi = fold_phi >= 180 ? fold_phi + 360 / folding - fold_phi : fold_phi + 360 / folding
    3016  endfor
    3017 
    3018  if (nograph==0)
    3019  display_hemi_scan(nickname)
    3020  endif
    3021 end
    3022 
    3034 function trim_hemi_scan(nickname, theta_max)
    3035  string nickname
    3036  variable theta_max
    3037 
    3038  string s_prefix = ""
    3039  string s_int = "values"
    3040  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    3041 
    3042  string s_totals = s_prefix + "tot"
    3043  string s_weights = s_prefix + "wt"
    3044  string s_polar = s_prefix + "pol"
    3045 
    3046  wave /sdfr=df w_polar = $s_polar
    3047  wave /sdfr=df w_values = $s_int
    3048  wave /sdfr=df w_totals = $s_totals
    3049  wave /sdfr=df w_weights = $s_weights
    3050 
    3051  w_values = w_polar <= theta_max ? w_totals / w_weights : nan
    3052 end
    3053 
    3073 function /wave hemi_polar_cut(nickname, azim)
    3074  string nickname
    3075  variable azim
    3076 
    3077  dfref savedf = getdatafolderdfr()
    3078  string s_prefix = ""
    3079  string s_int = "values"
    3080  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    3081 
    3082  string s_totals = s_prefix + "tot"
    3083  string s_weights = s_prefix + "wt"
    3084  string s_polar = s_prefix + "pol"
    3085  string s_azim = s_prefix + "az"
    3086  string s_index = s_prefix + "index"
    3087  string s_theta = s_prefix + "th"
    3088  string s_dphi = s_prefix + "dphi"
    3089  string s_nphis = s_prefix + "nphis"
    3090  string s_cut
    3091  sprintf s_cut, "%s_azi%03u", s_int, round(azim)
    3092 
    3093  wave /sdfr=df w_polar = $s_polar
    3094  wave /sdfr=df w_azim = $s_azim
    3095  wave /sdfr=df w_values = $s_int
    3096  wave /sdfr=df w_totals = $s_totals
    3097  wave /sdfr=df w_weights = $s_weights
    3098  wave /sdfr=df w_index = $s_index
    3099  wave /sdfr=df w_theta = $s_theta
    3100  wave /sdfr=df w_dphi = $s_dphi
    3101  wave /sdfr=df w_nphis = $s_nphis
    3102 
    3103  variable npol = numpnts(w_theta)
    3104  variable ipol
    3105  variable pol_st = abs(w_theta[1] - w_theta[0])
    3106  variable pol
    3107  variable pol1, pol2
    3108  variable nsel
    3109 
    3110  setdatafolder df
    3111  make /n=(npol) /o $s_cut
    3112  wave w_cut = $s_cut
    3113  setscale /i x w_theta[0], w_theta[numpnts(w_theta)-1], "deg", w_cut
    3114  make /n=1 /free azi_slice
    3115  make /n=1 /free values_slice
    3116 
    3117  for (ipol = 0; ipol < npol; ipol += 1)
    3118  pol = w_theta[ipol]
    3119  pol1 = pol - pol_st / 2
    3120  pol2 = pol + pol_st / 2
    3121  extract /free /indx w_polar, sel, (pol1 < w_polar) && (w_polar <= pol2)
    3122  nsel = numpnts(sel)
    3123  if (nsel > 0)
    3124  redimension /n=(nsel+2) azi_slice, values_slice
    3125  azi_slice[1, nsel] = w_azim[sel[p-1]]
    3126  azi_slice[0] = azi_slice[nsel] - 360
    3127  azi_slice[nsel+1] = azi_slice[1] + 360
    3128  values_slice[1, nsel] = w_values[sel[p-1]]
    3129  values_slice[0] = values_slice[nsel]
    3130  values_slice[nsel+1] = values_slice[1]
    3131  w_cut[ipol] = interp(azim, azi_slice, values_slice)
    3132  else
    3133  w_cut[ipol] = nan
    3134  endif
    3135  endfor
    3136 
    3137  setdatafolder savedf
    3138  return w_cut
    3139 end
    3140 
    3159 function /wave hemi_azi_cut(nickname, pol)
    3160  string nickname
    3161  variable pol
    3162 
    3163  dfref savedf = getdatafolderdfr()
    3164  string s_prefix = ""
    3165  string s_int = "values"
    3166  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    3167 
    3168  string s_totals = s_prefix + "tot"
    3169  string s_weights = s_prefix + "wt"
    3170  string s_polar = s_prefix + "pol"
    3171  string s_azim = s_prefix + "az"
    3172  string s_index = s_prefix + "index"
    3173  string s_theta = s_prefix + "th"
    3174  string s_dphi = s_prefix + "dphi"
    3175  string s_nphis = s_prefix + "nphis"
    3176  string s_cut
    3177  sprintf s_cut, "%s_pol%03u", s_int, round(pol)
    3178 
    3179  wave /sdfr=df w_polar = $s_polar
    3180  wave /sdfr=df w_azim = $s_azim
    3181  wave /sdfr=df w_values = $s_int
    3182  wave /sdfr=df w_totals = $s_totals
    3183  wave /sdfr=df w_weights = $s_weights
    3184  wave /sdfr=df w_index = $s_index
    3185  wave /sdfr=df w_theta = $s_theta
    3186  wave /sdfr=df w_dphi = $s_dphi
    3187  wave /sdfr=df w_nphis = $s_nphis
    3188 
    3189  variable pol_st = abs(w_theta[1] - w_theta[0])
    3190  variable pol1, pol2
    3191  variable nsel
    3192 
    3193  pol1 = pol - pol_st / 2
    3194  pol2 = pol + pol_st / 2
    3195  extract /free /indx w_polar, sel, (pol1 < w_polar) && (w_polar <= pol2)
    3196  nsel = numpnts(sel)
    3197  if (nsel > 0)
    3198  setdatafolder df
    3199  make /n=(nsel) /o $s_cut
    3200  wave w_cut = $s_cut
    3201  w_cut = w_values[sel]
    3202  setscale /i x w_azim[sel[0]], w_azim[sel[nsel-1]], "°", w_cut
    3203  setdatafolder savedf
    3204  return w_cut
    3205  else
    3206  setdatafolder savedf
    3207  return $""
    3208  endif
    3209  setdatafolder savedf
    3210 end
    3211 
    3212 static function check_contrast(values, pcmin, pcmax, vmin, vmax)
    3213  wave values
    3214  variable pcmin
    3215  variable pcmax
    3216  variable &vmin
    3217  variable &vmax
    3218 
    3219  dfref save_df = GetDataFolderDFR()
    3220  dfref dfr = NewFreeDataFolder()
    3221  setdatafolder dfr
    3222  StatsQuantiles /inan /iw /q /z values
    3223  wave index = w_quantilesindex
    3224  variable imin = round(numpnts(index) * pcmin / 100)
    3225  variable imax = round(numpnts(index) * (100 - pcmax) / 100)
    3226  vmin = values[index[imin]]
    3227  vmax = values[index[imax]]
    3228  setdatafolder save_df
    3229 end
    3230 
    3247 function set_contrast(pcmin, pcmax, [graphname, colortable])
    3248  variable pcmin
    3249  variable pcmax
    3250  string graphname
    3251  string colortable
    3252 
    3253  if (ParamIsDefault(graphname))
    3254  graphname = ""
    3255  endif
    3256  if (ParamIsDefault(colortable))
    3257  colortable = ""
    3258  endif
    3259 
    3260  dfref save_df = GetDataFolderDFR()
    3261 
    3262  string objname
    3263  string info
    3264  string wname
    3265  string ctab
    3266  variable rev
    3267  variable n
    3268  variable i
    3269  variable vmin
    3270  variable vmax
    3271 
    3272  string traces = TraceNameList(graphname, ";", 1+4)
    3273  n = ItemsInList(traces, ";")
    3274  for (i = 0; i < n; i += 1)
    3275  objname = StringFromList(i, traces, ";")
    3276  info = TraceInfo(graphname, objname, 0)
    3277  if (strlen(info) > 0)
    3278  info = StringByKey("RECREATION", info, ":", ";")
    3279  info = StringByKey("zColor(x)", info, "=", ";")
    3280  if (strlen(info) > 2)
    3281  info = info[1,strlen(info)-2]
    3282  wname = StringFromList(0, info, ",")
    3283  wave w = $wname
    3284  ctab = StringFromList(3, info, ",")
    3285  rev = str2num("0" + StringFromList(4, info, ","))
    3286  if (strlen(colortable) > 0)
    3287  ctab = colortable
    3288  endif
    3289  check_contrast(w, pcmin, pcmax, vmin, vmax)
    3290  ModifyGraph /w=$graphname zColor($objname)={w, vmin, vmax, $ctab, rev}
    3291  endif
    3292  endif
    3293  endfor
    3294 
    3295  string images = ImageNameList(graphname, ";")
    3296  n = ItemsInList(images, ";")
    3297  for (i = 0; i < n; i += 1)
    3298  objname = StringFromList(i, images, ";")
    3299  wave w = ImageNameToWaveRef(graphname, objname)
    3300  info = ImageInfo(graphname, objname, 0)
    3301  if (strlen(info) > 0)
    3302  info = StringByKey("RECREATION", info, ":", ";")
    3303  info = StringByKey("ctab", info, "=", ";")
    3304  if (strlen(info) > 2)
    3305  info = info[1,strlen(info)-2]
    3306  ctab = StringFromList(2, info, ",")
    3307  rev = str2num("0" + StringFromList(3, info, ","))
    3308  if (strlen(colortable) > 0)
    3309  ctab = colortable
    3310  endif
    3311  check_contrast(w, pcmin, pcmax, vmin, vmax)
    3312  ModifyImage /w=$graphname $objname ctab={vmin, vmax, $ctab, rev}
    3313  endif
    3314  endif
    3315  endfor
    3316 
    3317  setdatafolder save_df
    3318 end
    3319 
    3332 Function AngleToK(inwave)
    3333  Wave inwave
    3334  String newname = NameofWave(inwave)+"_k"
    3335  Duplicate/O inwave, $newname
    3336  Wave outwave = $newname
    3337  Variable rows,columns,xdelta,xoffset,ydelta,yoffset,kmin,kmax,Emax
    3338  // inwave parameters
    3339  rows = DimSize(inwave,0)
    3340  columns = DimSize(inwave,1)
    3341  xdelta = DimDelta(inwave,0)
    3342  xoffset = DimOffset(inwave,0)
    3343  ydelta = DimDelta(inwave,1)
    3344  yoffset = DimOffset(inwave,1)
    3345  Emax= xoffset + xdelta*(rows-1)
    3346  kmin = 0.5123*sqrt(Emax)*sin(pi/180*(yoffset)) // calculate the k boundaries
    3347  kmax = 0.5123*sqrt(Emax)*sin(pi/180*(yoffset+(columns-1)*ydelta))
    3348  SetScale/I y kmin,kmax,"Ang^-1", outwave
    3349  // scale the y axis
    3350  outwave = interp2D(inwave, x, 180/pi*asin(y/ (0.5123*sqrt(x)))) // recalculate to k
    3351  outwave = (NumType(outwave)==2) ? 0 : outwave // replace NaNs (optional)
    3352 End
    wave hemi_polar_cut(string nickname, variable azim)
    extract a polar cut from a hemispherical scan.
    -
    variable trim_hemi_scan(string nickname, variable theta_max)
    trim a hemispherical scan at grazing angle
    -
    string prepare_hemi_scan_display(string nickname, variable projection=defaultValue)
    create waves for plotting a hemispherical angle scan.
    -
    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
    -
    variable AngleToK(wave inwave)
    k-space mapping of 2D angle-energy distribution (scienta image)
    -
    static const variable kProjScaleOrtho
    -
    variable polar2cart_wave(wave in, wave out)
    -
    variable normalize_strip_theta(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by the average polar distribution.
    -
    variable 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.
    -
    variable crop_strip(wave strip, variable xlo, variable xhi)
    crop a strip at the sides.
    -
    const variable kProjGnom
    -
    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.
    -
    variable make_hemi_grid(variable npol, string nickname, variable xpdplot=defaultValue)
    create a hemispherical, constant solid angle grid
    -
    variable hemi_add_anglescan(string nickname, wave values, wave polar, wave azi, wave weights=defaultValue)
    add an arbitrary angle scan to a hemispherical scan grid.
    -
    string get_hemi_nickname(wave w)
    finds the nick name given any hemi wave
    -
    string get_hemi_prefix(wave w)
    finds the prefix given any hemi wave
    -
    string display_hemi_scan(string nickname, variable projection=defaultValue, variable graphtype=defaultValue, variable do_ticks=defaultValue, variable do_grids=defaultValue, string graphname=defaultValue)
    display a plot of a hemispherical angle scan.
    -
    static variable CalcN_Theta(string HoloMode, variable Theta_in, variable Theta_ran, variable Theta_st)
    calculate the number of thetas for a pattern
    -
    dfr find_hemi_data(string nickname, string *prefix, string *intwave)
    finds the folder, prefix and name of holo waves given their nick name
    -
    variable convert_angles_ttpd2polar(wave theta, wave tilt, wave phi, wave data, wave polar, wave azi)
    convert angles from TTPA (theta-tilt-phi-analyser) scheme to polar coordinates.
    -
    variable clear_hemi_grid(string nickname)
    clear a hemispherical scan grid
    -
    static const variable kProjScaleDist
    -
    threadsafe variable calc_graph_polar(variable x, variable y, variable projection=defaultValue)
    calculate polar angle from Cartesian coordinate
    -
    static variable check_contrast(wave values, variable pcmin, variable pcmax, variable *vmin, variable *vmax)
    -
    static variable Calc_The_step(variable th, variable Theta_st, string Holomode)
    calculate delta-theta for a given theta
    -
    const variable kProjArea
    -
    static variable line_average(wave source, wave dest)
    -
    threadsafe variable calc_graph_radius(variable polar, variable projection=defaultValue)
    calculate the projected polar angle
    -
    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
    -
    variable rotate_x_wave(wave inout, variable angle)
    rotate a wave of 3-vectors about the x axis.
    -
    variable cart2polar_wave(wave in, wave out)
    -
    variable crop_strip_theta(wave strip, variable theta_lo, variable theta_hi, wave theta, wave tilt, wave phi)
    crop a strip in theta.
    - -
    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.
    -
    wave hemi_azi_cut(string nickname, variable pol)
    extract an azimuthal cut from a hemispherical scan
    -
    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.
    -
    variable interpolate_hemi_scan(string nickname, variable projection=defaultValue)
    interpolate a hemispherical scan onto a rectangular grid
    -
    variable normalize_strip_theta_scans(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip piecewise by a smooth polar distribution.
    -
    variable hemi_add_aziscan(string nickname, wave values, variable polar, wave azi, wave weights=defaultValue)
    add an azimuthal scan to a hemispherical scan grid.
    -
    static const variable kProjScaleGnom
    -
    variable rotate_y_wave(wave inout, variable angle)
    rotates a wave of 3-vectors about the y axis
    -
    variable rotate_hemi_scan(string nickname, variable angle)
    azimuthally rotate a hemispherical scan dataset.
    -
    static const variable kProjScaleStereo
    -
    processing and holographic mapping of angle scanned XPD data.
    -
    static string display_polar_graph(string graphname, variable angle_offset=defaultValue, variable do_ticks=defaultValue)
    displays an empty polar graph
    -
    const variable kProjOrtho
    -
    variable save_hemi_scan(string nickname, string pathname, string filename)
    save a hemispherical scan to an Igor text file
    -
    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).
    -
    variable normalize_strip_thetaphi(wave strip, wave theta, wave phi, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by a smooth polar-azimuthal distribution.
    -
    const variable kProjStereo
    -
    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
    -
    static variable polar_graph_hook(WMWinHookStruct *s)
    polar graph window hook
    -
    const variable kProjDist
    -
    threadsafe variable calc_graph_azi(variable x, variable y, variable projection=defaultValue, variable zeroAngle=defaultValue)
    calculate azimuthal angle from Cartesian coordinate
    -
    variable set_contrast(variable pcmin, variable pcmax, string graphname=defaultValue, string colortable=defaultValue)
    set the pseudocolor contrast by percentile.
    -
    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.
    -
    variable rotate_z_wave(wave inout, variable angle)
    rotates a wave of 3-vectors about the z axis
    -
    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
    -
    static const variable kProjScaleArea
    -
    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 ...
    -
    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.
    -
    static string draw_hemi_axes(string graphname, variable do_grids=defaultValue)
    draw polar and azimuthal grids in an existing polar graph.
    -
    variable duplicate_hemi_scan(string source_nickname, dfref dest_folder, string dest_nickname, variable xpdplot=defaultValue)
    duplicate a hemispherical scan dataset.
    -
    variable set_polar_graph_cursor(string nickname, string cursorname, variable polar_angle, variable azim_angle, string graphname=defaultValue)
    -
    static variable update_polar_info(string graphname)
    update the angles info based on cursors A and B of a given polar graph window
    -
    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
    -
    variable load_hemi_scan(string nickname, string pathname, string filename)
    load a hemispherical scan from an Igor text file
    -
    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.
    -
    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
    -
    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.
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma version = 1.9
    +
    4 #pragma IgorVersion = 6.2
    +
    5 #pragma ModuleName = PearlAnglescanProcess
    +
    6 #include "pearl-vector-operations"
    +
    7 #include "pearl-polar-coordinates"
    +
    8 #include <New Polar Graphs>
    +
    9 
    +
    10 // copyright (c) 2013-21 Paul Scherrer Institut
    +
    11 //
    +
    12 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    13 // you may not use this file except in compliance with the License.
    +
    14 // You may obtain a copy of the License at
    +
    15 // http:///www.apache.org/licenses/LICENSE-2.0
    +
    16 //
    +
    17 // Please acknowledge the use of this code.
    +
    18 
    +
    77 
    +
    82 
    +
    83 
    +
    106 function /s strip_append(strip1, strip2)
    +
    107  wave strip1
    +
    108  wave strip2
    +
    109 
    +
    110  dfref df1 = GetWavesDataFolderDFR(strip1)
    +
    111  dfref df2 = GetWavesDataFolderDFR(strip2)
    +
    112  variable ny1 = dimsize(strip1, 1)
    +
    113  variable ny2 = dimsize(strip2, 1)
    +
    114 
    +
    115  concatenate /np=1 {strip2}, strip1
    +
    116  string modified = AddListItem(NameOfWave(strip1), "")
    +
    117 
    +
    118  variable idf = 0
    +
    119  do
    +
    120  variable iw = 0
    +
    121  do
    +
    122  wave /z w1 = WaveRefIndexedDFR(df1, iw)
    +
    123  if (!WaveExists(w1))
    +
    124  break
    +
    125  endif
    +
    126 
    +
    127  wave /z w2 = df2:$(NameOfWave(w1))
    +
    128  if (WaveExists(w1) && WaveExists(w2))
    +
    129  if ((DimSize(w1, 0) == ny1) && (DimSize(w1, 1) == 0) && (DimSize(w2, 0) == ny2) && (DimSize(w2, 1) == 0))
    +
    130  concatenate /np=0 {w2}, w1
    +
    131  modified = AddListItem(NameOfWave(w1), modified, "", Inf)
    +
    132  endif
    +
    133  endif
    +
    134  iw += 1
    +
    135  while(1)
    +
    136 
    +
    137  df1 = df1:attr
    +
    138  df2 = df2:attr
    +
    139  if ((DataFolderRefStatus(df1) != 1) || (DataFolderRefStatus(df2) != 1))
    +
    140  break
    +
    141  endif
    +
    142  idf += 1
    +
    143  while(idf < 2)
    +
    144 
    +
    145  return modified
    +
    146 end
    +
    147 
    +
    170 function strip_delete_frames(strip, qlo, qhi, theta, tilt, phi)
    +
    171  wave strip // 2D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan
    +
    172  variable qlo
    +
    173  variable qhi
    +
    174  wave theta
    +
    175  wave tilt
    +
    176  wave phi
    +
    177 
    +
    178  if (qlo > qhi)
    +
    179  return -1
    +
    180  endif
    +
    181 
    +
    182  // source indices
    +
    183  variable snx = dimsize(strip, 0)
    +
    184  variable sny = dimsize(strip, 1)
    +
    185  variable sq1lo = 0
    +
    186  variable sq1hi = max(qlo-1, 0)
    +
    187  variable sq2lo = min(qhi+1, sny - 1)
    +
    188  variable sq2hi = dimsize(strip, 1) - 1
    +
    189 
    +
    190  // dest indices
    +
    191  variable dnx = snx
    +
    192  variable dny = sny - (sq2lo - sq1hi + 1)
    +
    193  variable dq1lo = 0
    +
    194  variable dq1hi = sq1hi
    +
    195  variable dq2lo = dq1hi + 1
    +
    196  variable dq2hi = dny - 1
    +
    197  variable q1ofs = sq1lo - dq1lo
    +
    198  variable q2ofs = sq2lo - dq2lo
    +
    199 
    +
    200  duplicate /free strip, strip_copy
    +
    201  redimension /n=(dnx,dny) strip
    +
    202  strip[][dq1lo,dq1hi] = strip_copy[p][q + q1ofs]
    +
    203  strip[][dq2lo,dq2hi] = strip_copy[p][q + q2ofs]
    +
    204 
    +
    205  duplicate /free theta, theta_copy
    +
    206  redimension /n=(dny) theta
    +
    207  theta[dq1lo,dq1hi] = theta_copy[p + q1ofs]
    +
    208  theta[dq2lo,dq2hi] = theta_copy[p + q2ofs]
    +
    209 
    +
    210  duplicate /free tilt, tilt_copy
    +
    211  redimension /n=(dny) tilt
    +
    212  tilt[dq1lo,dq1hi] = tilt_copy[p + q1ofs]
    +
    213  tilt[dq2lo,dq2hi] = tilt_copy[p + q2ofs]
    +
    214 
    +
    215  duplicate /free phi, phi_copy
    +
    216  redimension /n=(dny) phi
    +
    217  phi[dq1lo,dq1hi] = phi_copy[p + q1ofs]
    +
    218  phi[dq2lo,dq2hi] = phi_copy[p + q2ofs]
    +
    219 
    +
    220  return 0
    +
    221 end
    +
    222 
    +
    252 function normalize_strip_x(strip, [smooth_method, smooth_factor, check])
    +
    253  wave strip
    +
    254  variable smooth_method
    +
    255  variable smooth_factor
    +
    256  variable check
    +
    257 
    +
    258  if (ParamIsDefault(smooth_method))
    +
    259  smooth_method = 4
    +
    260  endif
    +
    261  if (ParamIsDefault(smooth_factor))
    +
    262  switch(smooth_method)
    +
    263  case 4:
    +
    264  smooth_factor = 0.5
    +
    265  break
    +
    266  default:
    +
    267  smooth_factor = 2
    +
    268  endswitch
    +
    269  endif
    +
    270  if (ParamIsDefault(check))
    +
    271  check = 0
    +
    272  endif
    +
    273 
    +
    274  // average over all scan positions
    +
    275  wave raw_dist = ad_profile_x(strip, -inf, inf, "")
    +
    276 
    +
    277  // remove nans
    +
    278  extract /free /indx raw_dist, clean_index, numtype(raw_dist) == 0
    +
    279  duplicate /free raw_dist, dist, dist_x
    +
    280  redimension /n=(numpnts(clean_index)) dist, dist_x
    +
    281  dist = raw_dist[clean_index[p]]
    +
    282  dist_x = pnt2x(raw_dist, clean_index[p])
    +
    283  variable div = mean(dist)
    +
    284  dist /= div
    +
    285 
    +
    286  if (check)
    +
    287  duplicate /o raw_dist, check_dist
    +
    288  check_dist = numtype(raw_dist) == 0 ? interp(x, dist_x, dist) : nan
    +
    289  endif
    +
    290 
    +
    291  // smooth distribution function
    +
    292  switch(smooth_method)
    +
    293  case 1:
    +
    294  Smooth /B /E=3 smooth_factor, dist
    +
    295  break
    +
    296  case 2:
    +
    297  Smooth /E=3 smooth_factor, dist
    +
    298  break
    +
    299  case 3:
    +
    300  make /n=1 /d /free fit_params
    +
    301  fit_scienta_ang_transm(raw_dist, fit_params)
    +
    302  duplicate /free raw_dist, dist, dist_x
    +
    303  dist_x = x
    +
    304  dist = scienta_ang_transm(fit_params, x)
    +
    305  break
    +
    306  case 4:
    +
    307  loess /smth=(smooth_factor) srcWave=dist, factors={dist_x}
    +
    308  break
    +
    309  endswitch
    +
    310 
    +
    311  if (check)
    +
    312  duplicate /o raw_dist, check_smoo
    +
    313  check_smoo = interp(x, dist_x, dist)
    +
    314  endif
    +
    315 
    +
    316  // divide
    +
    317  if (check != 2)
    +
    318  strip /= interp(x, dist_x, dist)
    +
    319  endif
    +
    320 end
    +
    321 
    +
    348 function normalize_strip_phi(strip, theta, phi, [theta_offset, theta_range, check])
    +
    349  wave strip
    +
    350  wave theta
    +
    351  wave phi
    +
    352  variable theta_offset
    +
    353  variable theta_range
    +
    354  variable check
    +
    355 
    +
    356  if (ParamIsDefault(check))
    +
    357  check = 0
    +
    358  endif
    +
    359  if (ParamIsDefault(theta_offset))
    +
    360  theta_offset = 0
    +
    361  endif
    +
    362  if (ParamIsDefault(theta_range))
    +
    363  theta_offset = 10
    +
    364  endif
    +
    365 
    +
    366  // average over analyser angles
    +
    367  duplicate /free strip, strip_copy
    +
    368  MatrixFilter NanZapMedian strip_copy
    +
    369  wave dist = ad_profile_y(strip_copy, -inf, inf, "")
    +
    370 
    +
    371  // smooth distribution function
    +
    372  duplicate /free dist, dist_smoo
    +
    373  duplicate /free theta, theta_int
    +
    374  theta_int = theta - theta_offset
    +
    375  duplicate /free phi, phi_int
    +
    376  setscale /p x phi_int[0], phi_int[1] - phi_int[0], waveunits(phi, -1), dist, dist_smoo
    +
    377 
    +
    378  extract /free /indx dist, red_idx, theta_int < theta_range
    +
    379  duplicate /free red_idx, red_dist, red_phi
    +
    380  red_dist = dist[red_idx]
    +
    381  red_phi = phi_int[red_idx]
    +
    382 
    +
    383  variable wavg = mean(red_dist)
    +
    384  make /n=4 /d /free coef
    +
    385  coef[0] = {wavg, wavg/100, pi/180, 0}
    +
    386  CurveFit /q /h="0010" /g /w=2 sin, kwcWave=coef, red_dist /x=red_phi
    +
    387  dist_smoo = coef[0] + coef[1] * sin(coef[2] * phi_int[p] + coef[3])
    +
    388 
    +
    389  // divide
    +
    390  if (check != 2)
    +
    391  strip = strip / dist_smoo[q] * coef[0]
    +
    392  endif
    +
    393 
    +
    394  // check
    +
    395  if (check)
    +
    396  duplicate /o dist, check_dist
    +
    397  duplicate /o dist_smoo, check_smoo
    +
    398  setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
    +
    399  endif
    +
    400 end
    +
    401 
    +
    433 function normalize_strip_theta(strip, theta, [theta_offset, smooth_method, smooth_factor, check])
    +
    434  wave strip
    +
    435  wave theta
    +
    436  variable theta_offset
    +
    437  variable smooth_method
    +
    438  variable smooth_factor
    +
    439  variable check
    +
    440 
    +
    441  if (ParamIsDefault(check))
    +
    442  check = 0
    +
    443  endif
    +
    444  if (ParamIsDefault(theta_offset))
    +
    445  theta_offset = 0
    +
    446  endif
    +
    447  if (ParamIsDefault(smooth_method))
    +
    448  smooth_method = 4
    +
    449  endif
    +
    450  if (ParamIsDefault(smooth_factor))
    +
    451  smooth_factor = 0.5
    +
    452  endif
    +
    453 
    +
    454  // average over analyser angles
    +
    455  duplicate /free strip, strip_copy
    +
    456  MatrixFilter NanZapMedian strip_copy
    +
    457  wave dist = ad_profile_y(strip_copy, -inf, inf, "")
    +
    458 
    +
    459  // smooth distribution function
    +
    460  duplicate /free dist, dist_smoo
    +
    461  duplicate /free theta, theta_int
    +
    462  theta_int = theta - theta_offset
    +
    463  setscale /p x theta_int[0], theta_int[1] - theta_int[0], waveunits(theta,-1), dist, dist_smoo
    +
    464  variable nx = dimsize(strip, 0)
    +
    465  variable ix
    +
    466 
    +
    467  switch(smooth_method)
    +
    468  case 1:
    +
    469  Smooth /B /E=3 smooth_factor, dist_smoo
    +
    470  break
    +
    471  case 2:
    +
    472  Smooth /E=3 smooth_factor, dist_smoo
    +
    473  break
    +
    474  case 4:
    +
    475  loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={theta_int}
    +
    476  break
    +
    477  case 3:
    +
    478  for (ix = 0; ix < nx; ix += 1)
    +
    479  dist = strip[ix][p]
    +
    480  if (smooth_factor > 1)
    +
    481  CurveFit /nthr=0 /q /w=2 poly smooth_factor+1, dist /x=theta_int /d=dist_smoo
    +
    482  else
    +
    483  CurveFit /nthr=0 /q /w=2 line, dist /x=theta_int /d=dist_smoo
    +
    484  endif
    +
    485  strip[ix,ix][] /= dist_smoo[q]
    +
    486  endfor
    +
    487  dist_smoo = 1
    +
    488  break
    +
    489  endswitch
    +
    490 
    +
    491  // divide
    +
    492  if (check != 2)
    +
    493  strip /= dist_smoo[q]
    +
    494  endif
    +
    495 
    +
    496  // check
    +
    497  if (check)
    +
    498  duplicate /o dist, check_dist
    +
    499  duplicate /o dist_smoo, check_smoo
    +
    500  setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
    +
    501  endif
    +
    502 end
    +
    503 
    +
    533 function normalize_strip_thetaphi(strip, theta, phi, [theta_offset, smooth_method, smooth_factor, check])
    +
    534  wave strip
    +
    535  wave theta
    +
    536  wave phi
    +
    537  variable theta_offset
    +
    538  variable smooth_method
    +
    539  variable smooth_factor
    +
    540  variable check
    +
    541 
    +
    542  if (ParamIsDefault(check))
    +
    543  check = 0
    +
    544  endif
    +
    545  if (ParamIsDefault(theta_offset))
    +
    546  theta_offset = 0
    +
    547  endif
    +
    548  if (ParamIsDefault(smooth_method))
    +
    549  smooth_method = 4
    +
    550  endif
    +
    551  if (ParamIsDefault(smooth_factor))
    +
    552  smooth_factor = 0.5
    +
    553  endif
    +
    554 
    +
    555  // average over analyser angles
    +
    556  duplicate /free strip, strip_copy
    +
    557  MatrixFilter NanZapMedian strip_copy
    +
    558  wave dist = ad_profile_y(strip_copy, -inf, inf, "")
    +
    559 
    +
    560  // smooth distribution function
    +
    561  duplicate /free dist, dist_smoo
    +
    562  duplicate /free theta, theta_int
    +
    563  theta_int = theta - theta_offset
    +
    564  setscale /p x theta_int[0], theta_int[1] - theta_int[0], waveunits(theta,-1), dist, dist_smoo
    +
    565  variable nx = dimsize(strip, 0)
    +
    566  variable ix
    +
    567 
    +
    568  switch(smooth_method)
    +
    569  case 4:
    +
    570  loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={theta_int, phi}
    +
    571  break
    +
    572  default:
    +
    573  abort "smooth method not supported"
    +
    574  endswitch
    +
    575 
    +
    576  // divide
    +
    577  if (check != 2)
    +
    578  strip /= dist_smoo[q]
    +
    579  endif
    +
    580 
    +
    581  // check
    +
    582  if (check)
    +
    583  duplicate /o dist, check_dist
    +
    584  duplicate /o dist_smoo, check_smoo
    +
    585  setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
    +
    586  endif
    +
    587 end
    +
    588 
    +
    594 function normalize_strip_theta_scans(strip, theta, [theta_offset, smooth_method, smooth_factor, check])
    +
    595  wave strip
    +
    596  wave theta
    +
    597  variable theta_offset
    +
    598  variable smooth_method
    +
    599  variable smooth_factor
    +
    600  variable check
    +
    601 
    +
    602  if (ParamIsDefault(check))
    +
    603  check = 0
    +
    604  endif
    +
    605  if (ParamIsDefault(theta_offset))
    +
    606  theta_offset = 0
    +
    607  endif
    +
    608  if (ParamIsDefault(smooth_method))
    +
    609  smooth_method = 4
    +
    610  endif
    +
    611  if (ParamIsDefault(smooth_factor))
    +
    612  smooth_factor = 0.5
    +
    613  endif
    +
    614 
    +
    615  // average over analyser angles
    +
    616  duplicate /free strip, strip_copy
    +
    617  MatrixFilter NanZapMedian strip_copy
    +
    618  wave dist = ad_profile_y(strip_copy, -inf, inf, "")
    +
    619 
    +
    620  // smooth distribution function
    +
    621  duplicate /free dist, dist_smoo
    +
    622  duplicate /free theta, theta_int
    +
    623  theta_int = theta - theta_offset
    +
    624  setscale /p x theta_int[0], theta_int[1] - theta_int[0], waveunits(theta,-1), dist, dist_smoo
    +
    625 
    +
    626  // analyse scanning scheme
    +
    627  duplicate /free theta_int, d1_theta, d2_theta
    +
    628  Differentiate /METH=2 theta_int /D=d1_theta
    +
    629  Differentiate /METH=2 d1_theta /D=d2_theta
    +
    630  d2_theta = abs(d2_theta)
    +
    631  make /free w_levels
    +
    632  FindLevels /edge=1 /p /q /d=w_levels d2_theta, 0.1
    +
    633  if (v_flag != 1)
    +
    634  abort "unrecognized scanning scheme"
    +
    635  endif
    +
    636  w_levels = ceil(w_levels)
    +
    637  InsertPoints 0, 1, w_levels
    +
    638  w_levels[0] = 0
    +
    639  InsertPoints numpnts(w_levels), 1, w_levels
    +
    640  w_levels[numpnts(w_levels)-1] = numpnts(theta_int)
    +
    641 
    +
    642  variable n_scans = numpnts(w_levels) - 1
    +
    643  variable i_scan
    +
    644  variable p1, p2
    +
    645  for (i_scan = 0; i_scan < n_scans; i_scan += 1)
    +
    646  p1 = w_levels[i_scan]
    +
    647  p2 = w_levels[i_scan+1] - 1
    +
    648  duplicate /free /r=[p1, p2] dist, dist_piece, smooth_piece
    +
    649  duplicate /free /r=[p1, p2] theta_int, theta_piece
    +
    650  switch(smooth_method)
    +
    651  case 4:
    +
    652  loess /dest=smooth_piece /smth=(smooth_factor) srcWave=dist_piece, factors={theta_piece}
    +
    653  break
    +
    654  default:
    +
    655  abort "smooth method not supported"
    +
    656  endswitch
    +
    657  dist_smoo[p1, p2] = smooth_piece[p - p1]
    +
    658  endfor
    +
    659 
    +
    660  // divide
    +
    661  if (check != 2)
    +
    662  strip /= dist_smoo[q]
    +
    663  endif
    +
    664 
    +
    665  // check
    +
    666  if (check)
    +
    667  duplicate /o dist, check_dist
    +
    668  duplicate /o dist_smoo, check_smoo
    +
    669  setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
    +
    670  endif
    +
    671 end
    +
    672 
    +
    686 function normalize_strip_2d(strip, theta, [theta_offset, smooth_method, smooth_factor, check])
    +
    687  wave strip
    +
    688  wave theta
    +
    689  variable theta_offset
    +
    690  variable smooth_method
    +
    691  variable smooth_factor
    +
    692  variable check
    +
    693 
    +
    694  if (ParamIsDefault(check))
    +
    695  check = 0
    +
    696  endif
    +
    697  if (ParamIsDefault(theta_offset))
    +
    698  theta_offset = 0
    +
    699  endif
    +
    700  if (ParamIsDefault(smooth_method))
    +
    701  smooth_method = 4
    +
    702  endif
    +
    703  if (ParamIsDefault(smooth_factor))
    +
    704  smooth_factor = 0.5
    +
    705  endif
    +
    706 
    +
    707  variable nx = dimsize(strip, 0)
    +
    708  variable ny = dimsize(strip, 1)
    +
    709 
    +
    710  duplicate /free strip, dist, alpha_int, theta_int
    +
    711  MatrixFilter NanZapMedian dist
    +
    712  theta_int = theta[q] - theta_offset
    +
    713  alpha_int = dimoffset(strip, 0) + p * dimdelta(strip, 0)
    +
    714  redimension /n=(nx * ny) dist, alpha_int, theta_int
    +
    715 
    +
    716  switch(smooth_method)
    +
    717  case 4:
    +
    718  loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={alpha_int, theta_int}
    +
    719  redimension /n=(nx, ny) dist_smoo
    +
    720  break
    +
    721  default:
    +
    722  Abort "undefined smooth method"
    +
    723  break
    +
    724  endswitch
    +
    725 
    +
    726  // divide
    +
    727  if (check != 2)
    +
    728  strip /= dist_smoo
    +
    729  endif
    +
    730 
    +
    731  // check
    +
    732  if (check)
    +
    733  //duplicate /o dist, check_dist
    +
    734  duplicate /o dist_smoo, check_smoo
    +
    735  endif
    +
    736 end
    +
    737 
    +
    747 function crop_strip(strip, xlo, xhi)
    +
    748  wave strip
    +
    749  variable xlo
    +
    750  variable xhi
    +
    751 
    +
    752  variable plo = round((xlo - dimoffset(strip, 0)) / dimdelta(strip, 0))
    +
    753  variable phi = round((xhi - dimoffset(strip, 0)) / dimdelta(strip, 0))
    +
    754  xlo = plo * dimdelta(strip, 0) + dimoffset(strip, 0)
    +
    755  xhi = phi * dimdelta(strip, 0) + dimoffset(strip, 0)
    +
    756  variable nx = phi - plo + 1
    +
    757  variable ny = dimsize(strip, 1)
    +
    758 
    +
    759  duplicate /free strip, strip_copy
    +
    760  redimension /n=(nx,ny) strip
    +
    761  strip = strip_copy[p + plo][q]
    +
    762  setscale /i x xlo, xhi, waveunits(strip, 0), strip
    +
    763 end
    +
    764 
    +
    779 function crop_strip_theta(strip, theta_lo, theta_hi, theta, tilt, phi)
    +
    780  wave strip
    +
    781  variable theta_lo
    +
    782  variable theta_hi
    +
    783  wave theta
    +
    784  wave tilt
    +
    785  wave phi
    +
    786 
    +
    787  extract /indx /free theta, idx, (theta >= theta_lo) && (theta <= theta_hi)
    +
    788  variable nx = dimsize(strip, 0)
    +
    789  variable ny = numpnts(idx)
    +
    790 
    +
    791  theta[0, ny-1] = theta[idx]
    +
    792  tilt[0, ny-1] = tilt[idx]
    +
    793  phi[0, ny-1] = phi[idx]
    +
    794  redimension /n=(ny) theta, tilt, phi
    +
    795 
    +
    796  duplicate /free strip, strip_copy
    +
    797  redimension /n=(nx,ny) strip
    +
    798  strip = strip_copy[p][idx[q]]
    +
    799 end
    +
    800 
    +
    843 function pizza_service(data, nickname, theta_offset, tilt_offset, phi_offset, [npolar, nograph, folding, xpdplot])
    +
    844  wave data
    +
    845  string nickname
    +
    846  variable theta_offset
    +
    847  variable tilt_offset
    +
    848  variable phi_offset
    +
    849  variable npolar
    +
    850  variable nograph
    +
    851  variable folding
    +
    852  variable xpdplot
    +
    853 
    +
    854  if (ParamIsDefault(npolar))
    +
    855  npolar = 91
    +
    856  endif
    +
    857  if (ParamIsDefault(nograph))
    +
    858  nograph = 0
    +
    859  endif
    +
    860  if (ParamIsDefault(folding))
    +
    861  folding = 1
    +
    862  endif
    +
    863  if (ParamIsDefault(xpdplot))
    +
    864  xpdplot = 0
    +
    865  endif
    +
    866 
    +
    867  // sort out data folder structure
    +
    868  dfref saveDF = GetDataFolderDFR()
    +
    869  dfref dataDF = GetWavesDataFolderDFR(data)
    +
    870  setdatafolder dataDF
    +
    871  if (DataFolderExists(":attr"))
    +
    872  setdatafolder :attr
    +
    873  endif
    +
    874  dfref attrDF = GetDataFolderDFR()
    +
    875 
    +
    876  wave /sdfr=attrDF ManipulatorTheta
    +
    877  wave /sdfr=attrDF ManipulatorTilt
    +
    878  wave /sdfr=attrDF ManipulatorPhi
    +
    879 
    +
    880  if ((dimsize(ManipulatorTheta, 0) != dimsize(data, 1)) || (dimsize(ManipulatorTilt, 0) != dimsize(data, 1)) || (dimsize(ManipulatorPhi, 0) != dimsize(data, 1)))
    +
    881  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."
    +
    882  endif
    +
    883 
    +
    884  duplicate /free ManipulatorTheta, m_theta
    +
    885  duplicate /free ManipulatorTilt, m_tilt
    +
    886  duplicate /free ManipulatorPhi, m_phi
    +
    887 
    +
    888  m_theta -= theta_offset
    +
    889  m_tilt -= tilt_offset
    +
    890  m_phi -= phi_offset
    +
    891 
    +
    892  pizza_service_2(data, nickname, m_theta, m_tilt, m_phi, npolar=npolar, nograph=nograph, folding=folding, xpdplot=xpdplot)
    +
    893 
    +
    894  setdatafolder saveDF
    +
    895 end
    +
    896 
    +
    936 function pizza_service_2(data, nickname, m_theta, m_tilt, m_phi, [npolar, nograph, folding, xpdplot])
    +
    937  wave data
    +
    938  string nickname
    +
    939  wave m_theta
    +
    940  wave m_tilt
    +
    941  wave m_phi
    +
    942  variable npolar
    +
    943  variable nograph
    +
    944  variable folding
    +
    945  variable xpdplot
    +
    946 
    +
    947  if (ParamIsDefault(npolar))
    +
    948  npolar = 91
    +
    949  endif
    +
    950  if (ParamIsDefault(nograph))
    +
    951  nograph = 0
    +
    952  endif
    +
    953  if (ParamIsDefault(folding))
    +
    954  folding = 1
    +
    955  endif
    +
    956  if (ParamIsDefault(xpdplot))
    +
    957  xpdplot = 0
    +
    958  endif
    +
    959 
    +
    960  if ((dimsize(m_theta, 0) != dimsize(data, 1)) || (dimsize(m_tilt, 0) != dimsize(data, 1)) || (dimsize(m_phi, 0) != dimsize(data, 1)))
    +
    961  Abort "Warning: The dimension size of the manipulator waves does not match the Y dimension of the data wave!"
    +
    962  endif
    +
    963 
    +
    964  string graphname = "graph_" + nickname
    +
    965  string outprefix = nickname
    +
    966 
    +
    967  // sort out data folder structure
    +
    968  dfref saveDF = GetDataFolderDFR()
    +
    969  dfref dataDF = GetWavesDataFolderDFR(data)
    +
    970  setdatafolder dataDF
    +
    971 
    +
    972  if (xpdplot)
    +
    973  setdatafolder root:
    +
    974  outprefix = nickname
    +
    975  else
    +
    976  setdatafolder dataDF
    +
    977  newdatafolder /s/o $nickname
    +
    978  outprefix = ""
    +
    979  endif
    +
    980  dfref destDF = GetDataFolderDFR()
    +
    981 
    +
    982  // performance monitoring
    +
    983  variable timerRefNum
    +
    984  variable /g pol_perf_secs
    +
    985  timerRefNum = startMSTimer
    +
    986 
    +
    987  duplicate /free m_tilt, corr_tilt
    +
    988  duplicate /free m_phi, corr_phi
    +
    989  corr_tilt = -m_tilt // checked 140702
    +
    990  corr_phi = m_phi // checked 140702
    +
    991 
    +
    992  make /n=1/d/free d_polar, d_azi
    +
    993 
    +
    994  convert_angles_ttpd2polar(m_theta, corr_tilt, corr_phi, data, d_polar, d_azi)
    +
    995  d_azi += 180 // changed 151030 (v1.6)
    +
    996  make_hemi_grid(npolar, outprefix, xpdplot=xpdplot)
    +
    997  variable ifold
    +
    998  for (ifold = 0; ifold < folding; ifold += 1)
    +
    999  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
    +
    1000  hemi_add_anglescan(outprefix, data, d_polar, d_azi)
    +
    1001  d_azi += 360 / folding
    +
    1002  endfor
    +
    1003 
    +
    1004  // normalize folding
    +
    1005  if (strlen(outprefix))
    +
    1006  string s_prefix = outprefix + "_"
    +
    1007  string s_int = s_prefix + "i"
    +
    1008  else
    +
    1009  s_prefix = ""
    +
    1010  s_int = "values"
    +
    1011  endif
    +
    1012  if (folding > 1)
    +
    1013  wave values = $s_int
    +
    1014  values /= folding
    +
    1015  endif
    +
    1016 
    +
    1017  if (!nograph)
    +
    1018  display_hemi_scan(outprefix, graphname = graphname)
    +
    1019  endif
    +
    1020 
    +
    1021  if (timerRefNum >= 0)
    +
    1022  pol_perf_secs = stopMSTimer(timerRefNum) / 1e6
    +
    1023  endif
    +
    1024 
    +
    1025  setdatafolder saveDF
    +
    1026 end
    +
    1027 
    +
    1053 function show_analyser_line(theta, tilt, phi, theta_offset, tilt_offset, phi_offset, [npolar, nograph, xpdplot])
    +
    1054  variable theta
    +
    1055  variable tilt
    +
    1056  variable phi
    +
    1057  variable theta_offset
    +
    1058  variable tilt_offset
    +
    1059  variable phi_offset
    +
    1060  variable npolar
    +
    1061  variable nograph
    +
    1062  variable xpdplot
    +
    1063 
    +
    1064  string nickname = "analyser"
    +
    1065 
    +
    1066  if (ParamIsDefault(npolar))
    +
    1067  npolar = 91
    +
    1068  endif
    +
    1069  if (ParamIsDefault(nograph))
    +
    1070  nograph = 0
    +
    1071  endif
    +
    1072  if (ParamIsDefault(xpdplot))
    +
    1073  xpdplot = 0
    +
    1074  endif
    +
    1075  string graphname = "graph_" + nickname
    +
    1076  string outprefix = nickname
    +
    1077 
    +
    1078  // sort out data folder structure
    +
    1079  dfref saveDF = GetDataFolderDFR()
    +
    1080  dfref dataDF = saveDF
    +
    1081  if (xpdplot)
    +
    1082  setdatafolder root:
    +
    1083  outprefix = nickname
    +
    1084  else
    +
    1085  setdatafolder dataDF
    +
    1086  newdatafolder /s/o $nickname
    +
    1087  outprefix = ""
    +
    1088  endif
    +
    1089  dfref destDF = GetDataFolderDFR()
    +
    1090 
    +
    1091  make /n=1 /free m_theta
    +
    1092  make /n=1 /free m_tilt
    +
    1093  make /n=1 /free m_phi
    +
    1094  m_theta = theta - theta_offset
    +
    1095  m_tilt = tilt - tilt_offset
    +
    1096  m_tilt *= -1 // checked 140702
    +
    1097  m_phi = phi - phi_offset
    +
    1098  //m_phi *= -1 // checked 140702
    +
    1099 
    +
    1100  make /n=60 /free data
    +
    1101  setscale /i x -30, 30, data
    +
    1102  data = x
    +
    1103  make /n=1/d/free d_polar, d_azi
    +
    1104 
    +
    1105  convert_angles_ttpa2polar(m_theta, m_tilt, m_phi, data, d_polar, d_azi)
    +
    1106  d_azi += 180 // changed 151030 (v1.6)
    +
    1107  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
    +
    1108  make_hemi_grid(npolar, outprefix, xpdplot=xpdplot)
    +
    1109  hemi_add_anglescan(outprefix, data, d_polar, d_azi)
    +
    1110 
    +
    1111  if (!nograph)
    +
    1112  display_hemi_scan(outprefix, graphname = graphname)
    +
    1113  endif
    +
    1114 
    +
    1115  setdatafolder saveDF
    +
    1116 end
    +
    1117 
    +
    1122 
    +
    1123 function convert_angles_ttpd2polar(theta, tilt, phi, data, polar, azi)
    +
    1124  wave theta, tilt, phi // see convert_angles_ttpa2polar
    +
    1125  wave data // in, 1D or 2D
    +
    1126  // X-scale must be set to analyser angle scale
    +
    1127  wave polar, azi // see convert_angles_ttpa2polar
    +
    1128 
    +
    1129  make /n=(dimsize(data, 0)) /d /free ana
    +
    1130  setscale /p x dimoffset(data, 0), dimdelta(data, 0), waveunits(data, 0), ana
    +
    1131  ana = x
    +
    1132  convert_angles_ttpa2polar(theta, tilt, phi, ana, polar, azi)
    +
    1133 end
    +
    1134 
    +
    1162 function convert_angles_ttpa2polar(theta, tilt, phi, analyser, polar, azi)
    +
    1163  wave theta
    +
    1164  wave tilt
    +
    1165  wave phi
    +
    1166  wave analyser
    +
    1167  wave polar, azi
    +
    1168 
    +
    1169  variable nn = numpnts(theta)
    +
    1170  variable na = numpnts(analyser)
    +
    1171  redimension /n=(na, nn) polar, azi
    +
    1172 
    +
    1173  variable radius = 1 // don't need to specify - everything is scalable
    +
    1174 
    +
    1175  // step 1: calculate cartesian detection vectors at normal emission
    +
    1176  // this is simply a polar-cartesian mapping, independent of the manipulator
    +
    1177  // phi=0 is in the polar rotation plane
    +
    1178  make /n=(3,na) /d /free w_orig_polar, w_orig_cart, w_rot_cart, w_rot_polar
    +
    1179  w_orig_polar[0][] = radius
    +
    1180  w_orig_polar[1][] = analyser[q]
    +
    1181  w_orig_polar[2][] = 0
    +
    1182  polar2cart_wave(w_orig_polar, w_orig_cart)
    +
    1183  // if the angle-dispersive axis was horizontal, we'd need to rotate the detector
    +
    1184  //rotate_z_wave(w_orig_cart, 90)
    +
    1185 
    +
    1186  variable ii
    +
    1187  for (ii = 0; ii < nn; ii += 1)
    +
    1188  // step 2: rotate the detection vectors according to the manipulator angles
    +
    1189  // the order of rotations is important because we rotate about fixed axes
    +
    1190  // y-axis = tilt rotation axis
    +
    1191  // x-axis = polar rotation axis
    +
    1192  // z-axis = normal emission = azimuthal rotation axis
    +
    1193  w_rot_cart = w_orig_cart
    +
    1194  rotate_y_wave(w_rot_cart, -tilt[ii])
    +
    1195  rotate_x_wave(w_rot_cart, -theta[ii])
    +
    1196  rotate_z_wave(w_rot_cart, -phi[ii] - 90)
    +
    1197  // map the vectors back to the sample coordinate system
    +
    1198  cart2polar_wave(w_rot_cart, w_rot_polar)
    +
    1199  // copy to output
    +
    1200  polar[][ii] = w_rot_polar[1][p]
    +
    1201  azi[][ii] = w_rot_polar[2][p]
    +
    1202  endfor
    +
    1203 end
    +
    1204 
    +
    1205 static function line_average(source, dest)
    +
    1206  // is this function used?
    +
    1207  wave source
    +
    1208  wave dest
    +
    1209 
    +
    1210  variable ii
    +
    1211  variable nn = dimsize(source, 1)
    +
    1212  make /n=(dimsize(source, 0))/d/free line
    +
    1213  for (ii = 0; ii < nn; ii += 1)
    +
    1214  line = source[p][ii]
    +
    1215  wavestats /q line
    +
    1216  dest[][ii] = line[p] / v_max
    +
    1217  endfor
    +
    1218 end
    +
    1219 
    +
    1223 static function calc_nth(Theta_st, Theta_in, th, Phi_ran, Phi_ref, Holomode)
    +
    1224  Variable Theta_st, Theta_in, th, Phi_ran, Phi_ref
    +
    1225  String Holomode
    +
    1226  Variable The_step
    +
    1227  Variable deg2rad=0.01745329
    +
    1228 
    +
    1229  if ( cmpstr(Holomode, "Stereographic") == 0)
    +
    1230  The_step =trunc( Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st )
    +
    1231  if(th==90)
    +
    1232  The_step =trunc( Phi_ran*sin(th*pi/180)*Phi_ref/Theta_st )
    +
    1233  endif
    +
    1234  else
    +
    1235  if (cmpstr(Holomode, "Parallel") == 0)
    +
    1236  The_step=trunc( Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st )
    +
    1237  else
    +
    1238  if ( cmpstr(Holomode, "h") == 0)
    +
    1239  The_step=trunc( th/Theta_in*Phi_ran/Theta_st )
    +
    1240  else
    +
    1241  //altro
    +
    1242  endif
    +
    1243  endif
    +
    1244  endif
    +
    1245 
    +
    1246  return(The_step)
    +
    1247 end
    +
    1248 
    +
    1252 static function calc_phi_step(Theta_in, th, Theta_st, Phi_ran, Phi_ref, Holomode)
    +
    1253  Variable Theta_in, th, Theta_st, Phi_ran, Phi_ref
    +
    1254  String Holomode
    +
    1255 
    +
    1256  Variable Phi_st
    +
    1257  Variable deg2rad=0.01745329
    +
    1258 
    +
    1259  if ( cmpstr(Holomode, "Stereographic") == 0 )
    +
    1260  if ((th < 0.5) || (trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st) == 0))
    +
    1261  Phi_st=0.0
    +
    1262  else
    +
    1263  Phi_st=Phi_ran/(trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st))
    +
    1264  endif
    +
    1265  if(th==90)
    +
    1266  Phi_st=2.0
    +
    1267  endif
    +
    1268  endif
    +
    1269 
    +
    1270  if ( cmpstr(Holomode, "Parallel") == 0 )
    +
    1271  if((th < 0.5) || (trunc(Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st) == 0))
    +
    1272  Phi_st=0.0
    +
    1273  else
    +
    1274  Phi_st=Phi_ran/(trunc(Phi_ran*tan(th*deg2rad)*Phi_ref/Theta_st))
    +
    1275  endif
    +
    1276  endif
    +
    1277 
    +
    1278  if ( cmpstr(Holomode, "h") == 0 )
    +
    1279  if((th < 0.5) || (trunc(Phi_ran*sin(th*deg2rad)*Phi_ref/Theta_st) == 0))
    +
    1280  Phi_st=0.0
    +
    1281  else
    +
    1282  Phi_st=Phi_ran/trunc(th/Theta_in*Phi_ran/Theta_st)
    +
    1283  endif
    +
    1284  endif
    +
    1285 
    +
    1286  if (Phi_st==0)
    +
    1287  Phi_st=360
    +
    1288  endif
    +
    1289 
    +
    1290  return(Phi_st)
    +
    1291 end
    +
    1292 
    +
    1296 static function Calc_The_step(th, Theta_st, Holomode)
    +
    1297  String Holomode
    +
    1298  Variable th, Theta_st
    +
    1299 
    +
    1300  Variable deg2rad=0.01745329, dt_loc,The_step
    +
    1301 
    +
    1302  if ( (cmpstr(Holomode, "Stereographic")) ==0 )
    +
    1303  The_step=Theta_st
    +
    1304  endif
    +
    1305 
    +
    1306  if ( (cmpstr(Holomode, "h")) ==0 )
    +
    1307  The_step=Theta_st
    +
    1308  endif
    +
    1309 
    +
    1310  if ( cmpstr(Holomode, "Parallel") == 0 )
    +
    1311  if(th < 89.5)
    +
    1312  dt_loc = Theta_st/cos(th*deg2rad)
    +
    1313  if(dt_loc > 10)
    +
    1314  dt_loc=10
    +
    1315  endif
    +
    1316  The_step=dt_loc
    +
    1317  else
    +
    1318  The_step=10
    +
    1319  endif
    +
    1320  endif
    +
    1321  return(The_step)
    +
    1322 end
    +
    1323 
    +
    1327 static function CalcN_Theta(HoloMode,Theta_in,Theta_ran,Theta_st)
    +
    1328  String HoloMode
    +
    1329  Variable Theta_in,Theta_ran,Theta_st
    +
    1330  Variable n_theta, aux, aux1,ii
    +
    1331 
    +
    1332  aux = Theta_in
    +
    1333  aux1= Theta_in - Theta_ran
    +
    1334  ii = 0
    +
    1335  do
    +
    1336  aux = aux - Calc_The_step(aux, Theta_st, HoloMode)
    +
    1337  if(aux<=Theta_in-Theta_ran)
    +
    1338  aux=Theta_in-Theta_ran
    +
    1339  endif
    +
    1340  ii = ii+1
    +
    1341  while((aux>aux1)%&(Theta_in-aux<=Theta_ran)) //
    +
    1342  n_theta=ii+1
    +
    1343  Return(n_theta)
    +
    1344 end
    +
    1345 
    +
    1365 function make_hemi_grid(npol, nickname, [xpdplot])
    +
    1366  variable npol
    +
    1367  string nickname
    +
    1368  variable xpdplot
    +
    1369 
    +
    1370  if (ParamIsDefault(xpdplot))
    +
    1371  xpdplot = 0
    +
    1372  endif
    +
    1373 
    +
    1374  string HoloMode = "h"
    +
    1375  variable Theta_in = 90
    +
    1376  variable Theta_ran = 90
    +
    1377  variable Theta_st = 90 / (npol - 1)
    +
    1378  variable Phi_ran = 360
    +
    1379  variable Phi_ref = 1
    +
    1380  variable Phi_in = 0
    +
    1381 
    +
    1382  variable n_theta = CalcN_Theta(HoloMode, Theta_in, Theta_ran, Theta_st)
    +
    1383 
    +
    1384  // wave names
    +
    1385  if (strlen(nickname))
    +
    1386  string s_prefix = nickname + "_"
    +
    1387  string s_int = s_prefix + "i" // Intensity wave (counts/sec)
    +
    1388  else
    +
    1389  s_prefix = ""
    +
    1390  s_int = "values" // "i" is not a valid wave name
    +
    1391  endif
    +
    1392  string s_polar = s_prefix + "pol" // thetas for each int-point of the holo
    +
    1393  string s_azim = s_prefix + "az" // phis for each int-point of the holo
    +
    1394 
    +
    1395  string s_index = s_prefix + "index" // starting index for each theta
    +
    1396  string s_theta = s_prefix + "th" // theta values
    +
    1397  string s_dphi = s_prefix + "dphi" // delta phis at each theta
    +
    1398  string s_nphis = s_prefix + "nphis" // number of phis at each theta
    +
    1399 
    +
    1400  string s_HoloData = s_prefix + "data" // All holo exp.- parameter information
    +
    1401  string s_HoloInfo = s_prefix + "info"
    +
    1402 
    +
    1403  // the following two waves are used by the pearl-anglescan procedures but not by XPDplot
    +
    1404  string s_tot = s_prefix + "tot" // accumulated counts at each point
    +
    1405  string s_weight = s_prefix + "wt" // total accumulation time at each point (arb. units)
    +
    1406 
    +
    1407  make /O/D/n=(n_theta) $s_index /wave=index
    +
    1408  make /O/D/n=(n_theta) $s_theta /wave=theta
    +
    1409  make /O/D/n=(n_theta) $s_dphi /wave=dphi
    +
    1410  make /O/D/n=(n_theta) $s_nphis /wave=nphis
    +
    1411 
    +
    1412  //---------- calculate phi-step-size for this theta:
    +
    1413  variable aux = Calc_The_step(Theta_in, Theta_st, HoloMode)
    +
    1414  dphi[0] = calc_phi_step(Theta_in, Theta_in, aux, Phi_ran, Phi_ref, HoloMode)
    +
    1415  Theta[0] = Theta_in
    +
    1416  nphis[0] = calc_nth(aux, Theta_in, Theta_in, Phi_ran, Phi_ref, HoloMode)
    +
    1417  Index[0] = nphis[0]
    +
    1418 
    +
    1419  //---------- calculate number of phis, phi-step, and starting-index for each theta:
    +
    1420  variable ii = 1
    +
    1421  do
    +
    1422  Theta[ii] = Theta[ii-1] - aux
    +
    1423  if(Theta[ii] <= Theta_in-Theta_ran)
    +
    1424  Theta[ii] = Theta_in-Theta_ran
    +
    1425  endif
    +
    1426  aux = Calc_The_step(Theta[ii], Theta_st, HoloMode)
    +
    1427  dphi[ii] = calc_phi_step(Theta_in, Theta[ii], aux, Phi_ran, Phi_ref, HoloMode)
    +
    1428  nphis[ii] = calc_nth(aux, Theta_in, Theta[ii], Phi_ran, Phi_ref, HoloMode)
    +
    1429  Index[ii] = Index[ii-1] + nphis[ii]
    +
    1430  ii=ii+1
    +
    1431  while(ii < n_theta)
    +
    1432 
    +
    1433  if (Index[n_theta-1]==Index[n_theta-2])
    +
    1434  Index[n_theta-1]=Index[n_theta-2]+1
    +
    1435  nphis[n_theta-1]=1
    +
    1436  endif
    +
    1437 
    +
    1438  variable NumPoints = sum(nphis, 0, numpnts(nphis))
    +
    1439 
    +
    1440  //---------- calculate theta and phi for each data point:
    +
    1441  make /O/D/N=(NumPoints) $s_polar /wave=polar, $s_azim /wave=azim
    +
    1442  note azim, "version=1.6"
    +
    1443 
    +
    1444  ii = 0
    +
    1445  variable StartIndex = 0
    +
    1446  variable EndIndex
    +
    1447  do
    +
    1448  EndIndex=Index[ii]
    +
    1449  Polar[StartIndex, EndIndex-1]=Theta[ii]
    +
    1450  Azim[StartIndex, EndIndex-1]= mod(Phi_ran+(x-StartIndex)*dphi[ii]+Phi_in,Phi_ran)
    +
    1451  ii = ii + 1
    +
    1452  StartIndex = EndIndex
    +
    1453  while(ii < n_theta)
    +
    1454 
    +
    1455  duplicate /o azim, $s_int /wave=values
    +
    1456  duplicate /o azim, $s_tot /wave=totals
    +
    1457  duplicate /o azim, $s_weight /wave=weights
    +
    1458  values = nan
    +
    1459  totals = 0
    +
    1460  weights = 0
    +
    1461 
    +
    1462  // XPDplot metadata
    +
    1463  if (xpdplot)
    +
    1464  string s_FileName = ""
    +
    1465  string s_Comment = "created by pearl-anglescan-process.ipf"
    +
    1466  string s_HoloMode = "Stereographic"
    +
    1467  variable /g gb_SpectraFile = 0
    +
    1468 
    +
    1469  Make/O/D/n=22 $s_HoloData /wave=HoloData
    +
    1470  HoloData[0] = NaN // v_StartKE
    +
    1471  HoloData[1] = NaN // v_StoppKE
    +
    1472  HoloData[6] = NumPoints
    +
    1473  HoloData[7] = Theta_in
    +
    1474  HoloData[8] = Theta_ran
    +
    1475  HoloData[9] = Theta_st
    +
    1476  HoloData[11] = Phi_in
    +
    1477  HoloData[12] = Phi_ran
    +
    1478  HoloData[13] = Theta_st
    +
    1479  HoloData[15] = Phi_ref
    +
    1480  HoloData[16] = Phi_ran
    +
    1481  HoloData[17] = 0 // v_HoloBit (stereographic)
    +
    1482 
    +
    1483  Make/O/T/n=22 $s_HoloInfo /wave=HoloInfo
    +
    1484  HoloInfo[0] = s_FileName
    +
    1485  HoloInfo[1] = s_Comment
    +
    1486  HoloInfo[10] = s_HoloMode
    +
    1487  HoloInfo[11] = "" // s_MeasuringMode
    +
    1488 
    +
    1489  // notebook for XPDplot
    +
    1490  if (WinType(NickName) == 5)
    +
    1491  Notebook $NickName selection={startOfFile, endOfFile}
    +
    1492  Notebook $NickName text=""
    +
    1493  else
    +
    1494  NewNotebook /F=0 /K=1 /N=$NickName /W=(5,40,341,260)
    +
    1495  Notebook $NickName defaultTab=140
    +
    1496  Notebook $NickName statusWidth=300
    +
    1497  Notebook $NickName backRGB=(56797,56797,56797)
    +
    1498  Notebook $NickName pageMargins={80,80,80,80}
    +
    1499  Notebook $NickName fSize=10
    +
    1500  Notebook $NickName fStyle=0,textRGB=(65535,0,26214)
    +
    1501  Notebook $NickName textRGB=(65535,0,26214)
    +
    1502  endif
    +
    1503  Notebook $NickName text = "File:\t" + s_FileName + "\r"
    +
    1504  Notebook $NickName text = "*** " + s_Comment + " ***\r\r"
    +
    1505  Notebook $NickName text = "Angle-Mode:\t" + s_HoloMode + "\r"
    +
    1506  Notebook $NickName text = "XPDplot Nickname:\t" + NickName + "\r"
    +
    1507  endif
    +
    1508 end
    +
    1509 
    +
    1516 function /s get_hemi_nickname(w)
    +
    1517  wave w
    +
    1518 
    +
    1519  string prefix = get_hemi_prefix(w)
    +
    1520  string wname = nameofwave(w)
    +
    1521  string nickname
    +
    1522 
    +
    1523  if (strlen(prefix))
    +
    1524  nickname = prefix
    +
    1525  else
    +
    1526  string s_wave_df = GetWavesDataFolder(w, 1)
    +
    1527  dfref parent_df = $(s_wave_df + "::")
    +
    1528  nickname = GetDataFolder(0, parent_df)
    +
    1529  endif
    +
    1530 
    +
    1531  return nickname
    +
    1532 end
    +
    1533 
    +
    1541 function /s get_hemi_prefix(w)
    +
    1542  wave w
    +
    1543 
    +
    1544  string wname = nameofwave(w)
    +
    1545  string prefix
    +
    1546  if (ItemsInList(wname, "_") >= 2)
    +
    1547  prefix = StringFromList(0, wname, "_")
    +
    1548  else
    +
    1549  prefix = ""
    +
    1550  endif
    +
    1551 
    +
    1552  return prefix
    +
    1553 end
    +
    1554 
    +
    1572 function /df find_hemi_data(nickname, prefix, intwave)
    +
    1573  string nickname
    +
    1574  string &prefix
    +
    1575  string &intwave
    +
    1576 
    +
    1577  dfref datadf
    +
    1578  prefix = ""
    +
    1579  intwave = "values"
    +
    1580  if (strlen(nickname))
    +
    1581  if (DataFolderExists(nickname))
    +
    1582  datadf = $nickname
    +
    1583  else
    +
    1584  datadf = getdatafolderdfr()
    +
    1585  prefix = nickname + "_"
    +
    1586  intwave = prefix + "i"
    +
    1587  if (exists(intwave) != 1)
    +
    1588  datadf = root:
    +
    1589  endif
    +
    1590  endif
    +
    1591  else
    +
    1592  datadf = getdatafolderdfr()
    +
    1593  prefix = ""
    +
    1594  intwave = "values"
    +
    1595  endif
    +
    1596  return datadf
    +
    1597 end
    +
    1598 
    +
    1606 function clear_hemi_grid(nickname)
    +
    1607  string nickname
    +
    1608 
    +
    1609  dfref datadf
    +
    1610  string s_prefix
    +
    1611  string s_int
    +
    1612  datadf = find_hemi_data(nickname, s_prefix, s_int)
    +
    1613 
    +
    1614  string s_totals = s_prefix + "tot"
    +
    1615  string s_weights = s_prefix + "wt"
    +
    1616 
    +
    1617  wave /sdfr=datadf /z w_values = $s_int
    +
    1618  wave /sdfr=datadf /z w_totals = $s_totals
    +
    1619  wave /sdfr=datadf /z w_weights = $s_weights
    +
    1620 
    +
    1621  if (waveexists(w_totals))
    +
    1622  w_totals = 0
    +
    1623  endif
    +
    1624  if (waveexists(w_weights))
    +
    1625  w_weights = 0
    +
    1626  endif
    +
    1627  if (waveexists(w_values))
    +
    1628  w_values = nan
    +
    1629  endif
    +
    1630 end
    +
    1631 
    +
    1653 function duplicate_hemi_scan(source_nickname, dest_folder, dest_nickname, [xpdplot])
    +
    1654  string source_nickname
    +
    1655  dfref dest_folder
    +
    1656  string dest_nickname
    +
    1657  variable xpdplot
    +
    1658 
    +
    1659  if (ParamIsDefault(xpdplot))
    +
    1660  xpdplot = 0
    +
    1661  endif
    +
    1662 
    +
    1663  dfref savedf = getdatafolderdfr()
    +
    1664 
    +
    1665  // source data
    +
    1666  string s_prefix = ""
    +
    1667  string s_int = "values"
    +
    1668  dfref source_df = find_hemi_data(source_nickname, s_prefix, s_int)
    +
    1669  string s_polar = s_prefix + "pol"
    +
    1670  string s_azim = s_prefix + "az"
    +
    1671  string s_theta = s_prefix + "th"
    +
    1672  string s_tot = s_prefix + "tot"
    +
    1673  string s_weight = s_prefix + "wt"
    +
    1674  string s_matrix = s_prefix + "matrix"
    +
    1675 
    +
    1676  wave /sdfr=source_df theta1 = $s_theta
    +
    1677  wave /sdfr=source_df polar1 = $s_polar
    +
    1678  wave /sdfr=source_df azim1 = $s_azim
    +
    1679  wave /sdfr=source_df tot1 = $s_tot
    +
    1680  wave /sdfr=source_df weight1 = $s_weight
    +
    1681  wave /sdfr=source_df values1 = $s_int
    +
    1682  wave /sdfr=source_df /z matrix1 = $s_matrix
    +
    1683 
    +
    1684  variable npol = numpnts(theta1)
    +
    1685 
    +
    1686  setdatafolder dest_folder
    +
    1687  make_hemi_grid(npol, dest_nickname, xpdplot=xpdplot)
    +
    1688 
    +
    1689  // dest data
    +
    1690  dfref dest_df = find_hemi_data(dest_nickname, s_prefix, s_int)
    +
    1691  s_polar = s_prefix + "pol"
    +
    1692  s_azim = s_prefix + "az"
    +
    1693  s_theta = s_prefix + "th"
    +
    1694  s_tot = s_prefix + "tot"
    +
    1695  s_weight = s_prefix + "wt"
    +
    1696  s_matrix = s_prefix + "matrix"
    +
    1697 
    +
    1698  wave /sdfr=dest_df theta2 = $s_theta
    +
    1699  wave /sdfr=dest_df polar2 = $s_polar
    +
    1700  wave /sdfr=dest_df azim2 = $s_azim
    +
    1701  wave /sdfr=dest_df tot2 = $s_tot
    +
    1702  wave /sdfr=dest_df weight2 = $s_weight
    +
    1703  wave /sdfr=dest_df values2 = $s_int
    +
    1704 
    +
    1705  tot2 = tot1
    +
    1706  weight2 = weight1
    +
    1707  values2 = values1
    +
    1708  if (waveexists(matrix1))
    +
    1709  setdatafolder dest_df
    +
    1710  duplicate /o matrix1, $s_matrix
    +
    1711  endif
    +
    1712 
    +
    1713  if (!(NumberByKey("version", note(azim1), "=", "\r") >= 1.6))
    +
    1714  azim2 += 180 // changed 151030 (v1.6)
    +
    1715  azim2 = azim2 >= 360 ? azim2 - 360 : azim2
    +
    1716  endif
    +
    1717 
    +
    1718  setdatafolder saveDF
    +
    1719 end
    +
    1720 
    +
    1728 function rotate_hemi_scan(nickname, angle)
    +
    1729  string nickname
    +
    1730  variable angle
    +
    1731 
    +
    1732  dfref savedf = getdatafolderdfr()
    +
    1733 
    +
    1734  string s_prefix = ""
    +
    1735  string s_int = "values"
    +
    1736  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    1737 
    +
    1738  string s_polar = s_prefix + "pol"
    +
    1739  string s_azim = s_prefix + "az"
    +
    1740  string s_tot = s_prefix + "tot"
    +
    1741  string s_weight = s_prefix + "wt"
    +
    1742 
    +
    1743  wave /sdfr=df polar = $s_polar
    +
    1744  wave /sdfr=df azim = $s_azim
    +
    1745  wave /sdfr=df tot = $s_tot
    +
    1746  wave /sdfr=df weight = $s_weight
    +
    1747  wave /sdfr=df values = $s_int
    +
    1748 
    +
    1749  azim += angle
    +
    1750  azim = azim < 0 ? azim + 360 : azim
    +
    1751  azim = azim >= 360 ? azim - 360 : azim
    +
    1752 
    +
    1753  duplicate /free polar, neg_polar
    +
    1754  neg_polar = -polar
    +
    1755  sort {neg_polar, azim}, polar, azim, tot, weight, values
    +
    1756 
    +
    1757  setdatafolder saveDF
    +
    1758 end
    +
    1759 
    +
    1776 function /s prepare_hemi_scan_display(nickname, [projection])
    +
    1777  string nickname
    +
    1778  variable projection
    +
    1779 
    +
    1780  dfref savedf = getdatafolderdfr()
    +
    1781 
    +
    1782  if (ParamIsDefault(projection))
    +
    1783  projection = 1
    +
    1784  endif
    +
    1785 
    +
    1786  // hemi grid waves
    +
    1787  string s_prefix = ""
    +
    1788  string s_int = "values"
    +
    1789  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    1790 
    +
    1791  string s_polar = s_prefix + "pol"
    +
    1792  string s_azim = s_prefix + "az"
    +
    1793 
    +
    1794  wave /sdfr=df /z values = $s_int
    +
    1795  wave /sdfr=df /z azim = $s_azim
    +
    1796  wave /sdfr=df /z polar = $s_polar
    +
    1797 
    +
    1798  setdatafolder df
    +
    1799  string s_ster_rad = s_prefix + "ster_rad"
    +
    1800  duplicate /o polar, $s_ster_rad /wave=ster_rad
    +
    1801  ster_rad = calc_graph_radius(polar, projection=projection)
    +
    1802 
    +
    1803  string s_ster_x = s_prefix + "ster_x"
    +
    1804  string s_ster_y = s_prefix + "ster_y"
    +
    1805  duplicate /o azim, $s_ster_x /wave=ster_x, $s_ster_y /wave=ster_y
    +
    1806  ster_x = ster_rad * cos(azim * pi / 180)
    +
    1807  ster_y = ster_rad * sin(azim * pi / 180)
    +
    1808 
    +
    1809  setdatafolder savedf
    +
    1810 end
    +
    1811 
    +
    1858 function /s display_hemi_scan(nickname, [projection, graphtype, do_ticks, do_grids, graphname])
    +
    1859  string nickname
    +
    1860  variable projection
    +
    1861  variable graphtype
    +
    1862  variable do_ticks
    +
    1863  variable do_grids
    +
    1864  string graphname
    +
    1865 
    +
    1866  dfref savedf = getdatafolderdfr()
    +
    1867 
    +
    1868  if (ParamIsDefault(projection))
    +
    1869  projection = 1
    +
    1870  endif
    +
    1871  if (ParamIsDefault(graphtype))
    +
    1872  graphtype = 1
    +
    1873  endif
    +
    1874  if (ParamIsDefault(do_ticks))
    +
    1875  do_ticks = 3
    +
    1876  endif
    +
    1877  if (ParamIsDefault(do_grids))
    +
    1878  do_grids = 3
    +
    1879  endif
    +
    1880  if (ParamIsDefault(graphname))
    +
    1881  if (strlen(nickname) > 0)
    +
    1882  graphname = nickname
    +
    1883  else
    +
    1884  graphname = GetDataFolder(0)
    +
    1885  endif
    +
    1886  endif
    +
    1887 
    +
    1888  prepare_hemi_scan_display(nickname, projection=projection)
    +
    1889 
    +
    1890  // hemi grid waves
    +
    1891  string s_prefix = ""
    +
    1892  string s_int = "values"
    +
    1893  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    1894 
    +
    1895  string s_polar = s_prefix + "pol"
    +
    1896  string s_azim = s_prefix + "az"
    +
    1897  string s_matrix = s_prefix + "matrix"
    +
    1898  string s_ster_rad = s_prefix + "ster_rad"
    +
    1899 
    +
    1900  wave /sdfr=df /z values = $s_int
    +
    1901  wave /sdfr=df /z azim = $s_azim
    +
    1902  wave /sdfr=df /z polar = $s_polar
    +
    1903  wave /sdfr=df /z ster_rad = $s_ster_rad
    +
    1904  wave /sdfr=df /z matrix = $s_matrix
    +
    1905 
    +
    1906  setdatafolder df
    +
    1907  variable azim_offset = 0
    +
    1908  if (!(NumberByKey("version", note(azim), "=", "\r") >= 1.6))
    +
    1909  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!"
    +
    1910  azim_offset = 180 // changed 151030 (v1.6)
    +
    1911  endif
    +
    1912 
    +
    1913  string s_trace
    +
    1914  DoWindow $graphname
    +
    1915  if (v_flag)
    +
    1916  if (str2num(GetUserData(graphname, "", "graphtype")) == graphtype)
    +
    1917  // graph exists and will update automatically - do not recreate
    +
    1918  graphtype = 0
    +
    1919  else
    +
    1920  // graph exists - but needs recreating
    +
    1921  killwindow $graphname
    +
    1922  endif
    +
    1923  endif
    +
    1924 
    +
    1925  switch(graphtype)
    +
    1926  case 1:
    +
    1927  graphname = display_polar_graph(graphname, angle_offset=azim_offset, do_ticks=do_ticks)
    +
    1928 
    +
    1929  s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360)
    +
    1930  ModifyGraph /W=$graphname mode($s_trace)=2, lsize($s_trace)=2
    +
    1931  ModifyGraph /W=$graphname zColor($s_trace)={values,*,*,BlueGreenOrange,0}
    +
    1932 
    +
    1933  ColorScale /W=$graphname /C /N=text0 /E=2 /F=0 /B=1 /A=RB /X=0.00 /Y=0.00 trace=polarY0
    +
    1934  ColorScale /W=$graphname /C /N=text0 side=2, width=5, heightPct=40, frame=0.50, lblMargin=0
    +
    1935  ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50
    +
    1936 
    +
    1937  SetWindow $graphname, userdata(projection)=num2str(projection)
    +
    1938  SetWindow $graphname, userdata(graphtype)=num2str(graphtype)
    +
    1939  draw_hemi_axes(graphname, do_grids=do_grids)
    +
    1940  break
    +
    1941  case 3:
    +
    1942  graphname = display_polar_graph(graphname, angle_offset=azim_offset, do_ticks=do_ticks)
    +
    1943 
    +
    1944  s_trace = WMPolarAppendTrace(graphname, ster_rad, azim, 360)
    +
    1945  ModifyGraph /W=$graphname mode($s_trace)=0, lsize($s_trace)=0
    +
    1946  AppendImage /L=VertCrossing /B=HorizCrossing matrix
    +
    1947 
    +
    1948  ColorScale /W=$graphname /C /N=text0 /E=2 /F=0 /B=1 /A=RB /X=0.00 /Y=0.00 image=$s_matrix
    +
    1949  ColorScale /W=$graphname /C /N=text0 side=2, width=5, heightPct=40, frame=0.50, lblMargin=0
    +
    1950  ColorScale /W=$graphname /C /N=text0 nticks=2, minor=1, tickLen=4.00, tickThick=0.50
    +
    1951 
    +
    1952  SetWindow $graphname, userdata(projection)=num2str(projection)
    +
    1953  SetWindow $graphname, userdata(graphtype)=num2str(graphtype)
    +
    1954  draw_hemi_axes(graphname, do_grids=do_grids)
    +
    1955  break
    +
    1956  endswitch
    +
    1957 
    +
    1958  setdatafolder savedf
    +
    1959  return graphname
    +
    1960 end
    +
    1961 
    +
    2003 static function /s display_polar_graph(graphname, [angle_offset, do_ticks])
    +
    2004 
    +
    2005  string graphname
    +
    2006  variable angle_offset
    +
    2007  variable do_ticks
    +
    2008 
    +
    2009  dfref savedf = GetDataFolderDFR()
    +
    2010 
    +
    2011  if (ParamIsDefault(angle_offset))
    +
    2012  angle_offset = 0
    +
    2013  endif
    +
    2014  if (ParamIsDefault(do_ticks))
    +
    2015  do_ticks = 3
    +
    2016  endif
    +
    2017 
    +
    2018  if ((strlen(graphname) == 0) || (wintype(graphname) == 0))
    +
    2019  Display /k=1 /W=(10,45,360,345)
    +
    2020  DoWindow /C $graphname
    +
    2021  graphname = WMNewPolarGraph("", graphname)
    +
    2022  WMPolarGraphSetVar(graphname, "zeroAngleWhere", angle_offset)
    +
    2023 
    +
    2024  WMPolarGraphSetVar(graphname, "angleAxisThick", 0.5)
    +
    2025  WMPolarGraphSetStr(graphname, "doMajorAngleTicks", "manual")
    +
    2026  WMPolarGraphSetVar(graphname, "majorAngleInc", 30) // major ticks in 30 deg steps
    +
    2027  WMPolarGraphSetVar(graphname, "minorAngleTicks", 2) // minor ticks in 10 deg steps
    +
    2028  WMPolarGraphSetStr(graphname, "angleTicksLocation", "Outside")
    +
    2029  WMPolarGraphSetVar(graphname, "doAngleTickLabelSubRange", 1)
    +
    2030  WMPolarGraphSetVar(graphname, "angleTickLabelRangeStart", 0)
    +
    2031  WMPolarGraphSetVar(graphname, "angleTickLabelRangeExtent", 90)
    +
    2032  WMPolarGraphSetStr(graphname, "angleTickLabelNotation", "%g°")
    +
    2033 
    +
    2034  WMPolarGraphSetVar(graphname, "doPolarGrids", 0)
    +
    2035  WMPolarGraphSetVar(graphname, "doRadiusTickLabels", 0)
    +
    2036  WMPolarGraphSetStr(graphname, "radiusAxesWhere", " Off") // note the leading spaces, cf. WMPolarAnglesForRadiusAxes
    +
    2037  WMPolarGraphSetStr(graphname, "radiusTicksLocation", "Off")
    +
    2038 
    +
    2039  WMPolarGraphSetVar(graphname, "majorTickLength", 2)
    +
    2040  WMPolarGraphSetVar(graphname, "majorTickThick", 0.5)
    +
    2041  WMPolarGraphSetVar(graphname, "minorTickLength", 1)
    +
    2042  WMPolarGraphSetVar(graphname, "minorTickThick", 0.5)
    +
    2043  WMPolarGraphSetVar(graphname, "tickLabelOpaque", 0)
    +
    2044  WMPolarGraphSetVar(graphname, "tickLabelFontSize", 7)
    +
    2045 
    +
    2046  // changes
    +
    2047  if (do_ticks & 1)
    +
    2048  WMPolarGraphSetStr(graphname, "angleTicksLocation", "Outside")
    +
    2049  else
    +
    2050  WMPolarGraphSetStr(graphname, "angleTicksLocation", "Off")
    +
    2051  endif
    +
    2052  if (do_ticks & 2)
    +
    2053  WMPolarGraphSetVar(graphname, "doMinorAngleTicks", 1)
    +
    2054  else
    +
    2055  WMPolarGraphSetVar(graphname, "doMinorAngleTicks", 0)
    +
    2056  endif
    +
    2057 
    +
    2058  DoWindow /T $graphname, graphname
    +
    2059 
    +
    2060  // cursor info in angles
    +
    2061  string graphdf = "root:packages:WMPolarGraphs:" + graphname
    +
    2062  setdatafolder graphdf
    +
    2063  // current theta, phi coordinates are stored in global variables in the package folder of the graph
    +
    2064  variable /g csrA_theta
    +
    2065  variable /g csrA_phi
    +
    2066  variable /g csrB_theta
    +
    2067  variable /g csrB_phi
    +
    2068  // the text box is hidden initially. it shows up and hides with the cursor info box.
    +
    2069  string tb
    +
    2070  tb = "\\{"
    +
    2071  tb = tb + "\"A = (%.1f, %.1f)\","
    +
    2072  tb = tb + graphdf + ":csrA_theta,"
    +
    2073  tb = tb + graphdf + ":csrA_phi"
    +
    2074  tb = tb + "}"
    +
    2075  TextBox /W=$graphname /A=LT /B=1 /E=2 /F=0 /N=tb_angles /X=1 /Y=1 /V=0 tb
    +
    2076  tb = "\\{"
    +
    2077  tb = tb + "\"B = (%.1f, %.1f)\","
    +
    2078  tb = tb + graphdf + ":csrB_theta,"
    +
    2079  tb = tb + graphdf + ":csrB_phi"
    +
    2080  tb = tb + "}"
    +
    2081  AppendText /W=$graphname /N=tb_angles tb
    +
    2082  // updates are triggered by a window hook
    +
    2083  SetWindow $graphname, hook(polar_graph_hook)=PearlAnglescanProcess#polar_graph_hook
    +
    2084  else
    +
    2085  // graph window exists
    +
    2086  DoWindow /F $graphname
    +
    2087  endif
    +
    2088 
    +
    2089  setdatafolder savedf
    +
    2090  return graphname
    +
    2091 end
    +
    2092 
    +
    2118 static function /s draw_hemi_axes(graphname, [do_grids])
    +
    2119  string graphname
    +
    2120  variable do_grids
    +
    2121 
    +
    2122  if (ParamIsDefault(do_grids))
    +
    2123  do_grids = 3
    +
    2124  endif
    +
    2125 
    +
    2126  dfref savedf = GetDataFolderDFR()
    +
    2127 
    +
    2128  string sproj = GetUserData(graphname, "", "projection")
    +
    2129  variable projection = str2num("0" + sproj)
    +
    2130 
    +
    2131  SetDrawLayer /W=$graphname ProgFront
    +
    2132 
    +
    2133  // polar axis
    +
    2134  SetDrawEnv /W=$graphname xcoord=HorizCrossing, ycoord=VertCrossing
    +
    2135  SetDrawEnv /W=$graphname linethick= 0.5
    +
    2136  SetDrawEnv /W=$graphname dash=2
    +
    2137  SetDrawEnv /W=$graphname fillpat=0
    +
    2138  SetDrawEnv /W=$graphname fname="default", fsize=7
    +
    2139  SetDrawEnv /W=$graphname textxjust=1, textyjust=1
    +
    2140  //SetDrawEnv /W=$graphname linefgc=(65535,65535,65535)
    +
    2141  SetDrawEnv /W=$graphname save
    +
    2142 
    +
    2143  if (do_grids & 1)
    +
    2144  DrawLine /W=$graphname 0, -2, 0, 2
    +
    2145  DrawLine /W=$graphname -2, 0, 2, 0
    +
    2146  endif
    +
    2147 
    +
    2148  variable radi
    +
    2149  if (do_grids & 2)
    +
    2150  radi = calc_graph_radius(0.5, projection=projection)
    +
    2151  DrawOval /W=$graphname -radi, radi, radi, -radi
    +
    2152  radi = calc_graph_radius(30, projection=projection)
    +
    2153  DrawOval /W=$graphname -radi, radi, radi, -radi
    +
    2154  radi = calc_graph_radius(60, projection=projection)
    +
    2155  DrawOval /W=$graphname -radi, radi, radi, -radi
    +
    2156 
    +
    2157  SetDrawEnv /W=$graphname textxjust= 1,textyjust= 2
    +
    2158  SetDrawEnv /W=$graphname save
    +
    2159  radi = calc_graph_radius(30, projection=projection)
    +
    2160  DrawText /W=$graphname radi, -0.1, "30°"
    +
    2161  radi = calc_graph_radius(60, projection=projection)
    +
    2162  DrawText /W=$graphname radi, -0.1, "60°"
    +
    2163  endif
    +
    2164 
    +
    2165  setdatafolder savedf
    +
    2166 end
    +
    2167 
    +
    2190 function draw_diffraction_cone(graphname, groupname, theta_axis, theta_inner, phi)
    +
    2191  string graphname
    +
    2192  string groupname
    +
    2193 
    +
    2194  variable theta_axis
    +
    2195  variable theta_inner
    +
    2196  variable phi
    +
    2197 
    +
    2198  variable r_axis = calc_graph_radius(theta_axis)
    +
    2199  variable r_inner = calc_graph_radius(theta_inner)
    +
    2200  variable r_outer = calc_graph_radius(2 * theta_axis - theta_inner)
    +
    2201 
    +
    2202  SetDrawEnv push
    +
    2203  SetDrawLayer UserFront
    +
    2204  DrawAction getgroup=$groupname, delete
    +
    2205  SetDrawEnv gstart, gname=$groupname
    +
    2206  variable xc, yc, xr, yr
    +
    2207 
    +
    2208  // cone periphery
    +
    2209  variable r_center = (r_outer + r_inner) / 2
    +
    2210  variable r_radius = (r_outer - r_inner) / 2
    +
    2211  xc = r_center * cos(phi * pi / 180)
    +
    2212  yc = r_center * sin(phi * pi / 180)
    +
    2213  xr = r_radius
    +
    2214  yr = r_radius
    +
    2215  SetDrawEnv xcoord=HorizCrossing, ycoord=VertCrossing
    +
    2216  SetDrawEnv dash=11, fillpat=0
    +
    2217  DrawOval xc - xr, yc - yr, xc + xr, yc + yr
    +
    2218 
    +
    2219  // cone axis
    +
    2220  xc = r_axis * cos(phi * pi / 180)
    +
    2221  yc = r_axis * sin(phi * pi / 180)
    +
    2222  r_radius = calc_graph_radius(2)
    +
    2223  xr = r_radius
    +
    2224  yr = r_radius
    +
    2225  SetDrawEnv xcoord=HorizCrossing, ycoord=VertCrossing
    +
    2226  SetDrawEnv fillfgc=(0,0,0)
    +
    2227  DrawOval xc - xr, yc - yr, xc + xr, yc + yr
    +
    2228 
    +
    2229  SetDrawEnv gstop
    +
    2230  SetDrawEnv pop
    +
    2231 end
    +
    2232 
    +
    2254 function /s display_scanlines(nickname, alpha_lo, alpha_hi, m_theta, m_tilt, m_phi, [folding, projection])
    +
    2255  string nickname
    +
    2256  variable alpha_lo
    +
    2257  variable alpha_hi
    +
    2258  wave m_theta
    +
    2259  wave m_tilt
    +
    2260  wave m_phi
    +
    2261  variable folding
    +
    2262  variable projection
    +
    2263 
    +
    2264  if (ParamIsDefault(folding))
    +
    2265  folding = 1
    +
    2266  endif
    +
    2267  if (ParamIsDefault(projection))
    +
    2268  projection = 1
    +
    2269  endif
    +
    2270 
    +
    2271  // sort out data folder structure
    +
    2272  dfref saveDF = GetDataFolderDFR()
    +
    2273  newdatafolder /s/o $nickname
    +
    2274  string graphname = "graph_" + nickname
    +
    2275 
    +
    2276  duplicate /free m_tilt, loc_m_tilt
    +
    2277  loc_m_tilt = -m_tilt
    +
    2278 
    +
    2279  make /n=1 /d /free d_polar, d_azi
    +
    2280  variable n_alpha = round(alpha_hi - alpha_lo) + 1
    +
    2281  make /n=(n_alpha) /d /free analyser
    +
    2282  setscale /i x alpha_lo, alpha_hi, "°", analyser
    +
    2283  analyser = x
    +
    2284 
    +
    2285  convert_angles_ttpa2polar(m_theta, loc_m_tilt, m_phi, analyser, d_polar, d_azi)
    +
    2286  duplicate /free d_polar, d_radius
    +
    2287  d_radius = calc_graph_radius(d_polar, projection=projection)
    +
    2288  d_azi += 180 // changed 151030 (v1.6)
    +
    2289 
    +
    2290  graphname = display_polar_graph(graphname)
    +
    2291  SetWindow $graphname, userdata(projection)=num2str(projection)
    +
    2292 
    +
    2293  variable ifold
    +
    2294  variable iang
    +
    2295  variable nang = numpnts(m_theta)
    +
    2296  string s_rad
    +
    2297  string s_azi
    +
    2298  string s_trace
    +
    2299  for (ifold = 0; ifold < folding; ifold += 1)
    +
    2300  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
    +
    2301  for (iang = 0; iang < nang; iang += 1)
    +
    2302  sprintf s_rad, "rad_%d_%d", ifold, iang
    +
    2303  duplicate /o analyser, $s_rad
    +
    2304  wave w_rad = $s_rad
    +
    2305  w_rad = d_radius[p][iang]
    +
    2306 
    +
    2307  sprintf s_azi, "azi_%d_%d", ifold, iang
    +
    2308  duplicate /o analyser, $s_azi
    +
    2309  wave w_azi = $s_azi
    +
    2310  w_azi = d_azi[p][iang]
    +
    2311 
    +
    2312  if (numtype(sum(w_rad)) == 0)
    +
    2313  s_trace = WMPolarAppendTrace(graphname, w_rad, w_azi, 360)
    +
    2314  ModifyGraph /w=$graphname mode($s_trace)=0, lsize($s_trace)=0.5
    +
    2315  endif
    +
    2316  endfor
    +
    2317  d_azi += 360 / folding
    +
    2318  endfor
    +
    2319 
    +
    2320  draw_hemi_axes(graphname)
    +
    2321 
    +
    2322  setdatafolder saveDF
    +
    2323  return graphname
    +
    2324 end
    +
    2325 
    +
    2342 constant kProjDist = 0
    +
    2343 constant kProjStereo = 1
    +
    2344 constant kProjArea = 2
    +
    2345 constant kProjGnom = 3
    +
    2346 constant kProjOrtho = 4
    +
    2347 
    +
    2348 static constant kProjScaleDist = 2
    +
    2349 static constant kProjScaleStereo = 2
    +
    2350 static constant kProjScaleArea = 2
    +
    2351 // scaled so that radius(gnom) = radius(stereo) for polar = 88
    +
    2352 static constant kProjScaleGnom = 0.06744519021
    +
    2353 static constant kProjScaleOrtho = 2
    +
    2354 
    +
    2369 threadsafe function calc_graph_radius(polar, [projection])
    +
    2370  variable polar
    +
    2371  variable projection
    +
    2372 
    +
    2373  if (ParamIsDefault(projection))
    +
    2374  projection = 1
    +
    2375  endif
    +
    2376 
    +
    2377  variable radius
    +
    2378  switch(projection)
    +
    2379  case kProjStereo: // stereographic
    +
    2380  radius = kProjScaleStereo * tan(polar / 2 * pi / 180)
    +
    2381  break
    +
    2382  case kProjArea: // equal area
    +
    2383  radius = kProjScaleArea * sin(polar / 2 * pi / 180)
    +
    2384  break
    +
    2385  case kProjGnom: // gnomonic
    +
    2386  radius = polar < 90 ? kProjScaleGnom * tan(polar * pi / 180) : inf
    +
    2387  break
    +
    2388  case kProjOrtho: // orthographic
    +
    2389  radius = kProjScaleOrtho * sin(polar * pi / 180)
    +
    2390  break
    +
    2391  default: // equidistant
    +
    2392  radius = kProjScaleDist * polar / 90
    +
    2393  endswitch
    +
    2394 
    +
    2395  return radius
    +
    2396 end
    +
    2397 
    +
    2414 threadsafe function calc_graph_polar(x, y, [projection])
    +
    2415  variable x
    +
    2416  variable y
    +
    2417  variable projection
    +
    2418 
    +
    2419  if (ParamIsDefault(projection))
    +
    2420  projection = 1
    +
    2421  endif
    +
    2422 
    +
    2423  variable radius
    +
    2424  variable polar
    +
    2425 
    +
    2426  radius = sqrt(x^2 + y^2)
    +
    2427  switch(projection)
    +
    2428  case kProjStereo: // stereographic
    +
    2429  polar = 2 * atan(radius / kProjScaleStereo) * 180 / pi
    +
    2430  break
    +
    2431  case kProjArea: // equal area
    +
    2432  polar = 2 * asin(radius / kProjScaleArea) * 180 / pi
    +
    2433  break
    +
    2434  case kProjGnom: // gnomonic
    +
    2435  polar = atan(radius / kProjScaleGnom) * 180 / pi
    +
    2436  break
    +
    2437  case kProjOrtho: // orthographic
    +
    2438  polar = asin(radius / kProjScaleOrtho) * 180 / pi
    +
    2439  break
    +
    2440  default: // equidistant
    +
    2441  polar = 90 * radius / kProjScaleDist
    +
    2442  endswitch
    +
    2443 
    +
    2444  return polar
    +
    2445 end
    +
    2446 
    +
    2467 threadsafe function calc_graph_azi(x, y, [projection,zeroAngle])
    +
    2468  variable x
    +
    2469  variable y
    +
    2470  variable projection
    +
    2471  variable zeroAngle
    +
    2472 
    +
    2473  if (ParamIsDefault(projection))
    +
    2474  projection = 1
    +
    2475  endif
    +
    2476  if (ParamIsDefault(zeroAngle))
    +
    2477  zeroAngle = 0
    +
    2478  endif
    +
    2479 
    +
    2480  variable azi
    +
    2481  if (x > 0)
    +
    2482  azi = atan(y / x) * 180 / pi
    +
    2483  else
    +
    2484  azi = atan(y / x) * 180 / pi + 180
    +
    2485  endif
    +
    2486 
    +
    2487  azi += zeroAngle
    +
    2488  if (azi < 0)
    +
    2489  azi += 360
    +
    2490  endif
    +
    2491  if (azi >= 360)
    +
    2492  azi -= 360
    +
    2493  endif
    +
    2494  if (numtype(azi) != 0)
    +
    2495  azi = 0
    +
    2496  endif
    +
    2497 
    +
    2498  return azi
    +
    2499 end
    +
    2500 
    +
    2512 static function update_polar_info(graphname)
    +
    2513  string graphname
    +
    2514 
    +
    2515  dfref savedf = GetDataFolderDFR()
    +
    2516 
    +
    2517  string graphdf = "root:packages:WMPolarGraphs:" + graphname
    +
    2518  setdatafolder graphdf
    +
    2519 
    +
    2520  nvar csrA_theta
    +
    2521  nvar csrA_phi
    +
    2522  nvar csrB_theta
    +
    2523  nvar csrB_phi
    +
    2524 
    +
    2525  string sproj = GetUserData(graphname, "", "projection")
    +
    2526  variable projection = str2num("0" + sproj)
    +
    2527  nvar zeroAngleWhere
    +
    2528 
    +
    2529  variable x = hcsr(A, graphname)
    +
    2530  variable y = vcsr(A, graphname)
    +
    2531  csrA_theta = calc_graph_polar(x, y, projection=projection)
    +
    2532  csrA_phi = calc_graph_azi(x, y, projection=projection, zeroAngle=zeroAngleWhere)
    +
    2533 
    +
    2534  x = hcsr(B, graphname)
    +
    2535  y = vcsr(B, graphname)
    +
    2536  csrB_theta = calc_graph_polar(x, y, projection=projection)
    +
    2537  csrB_phi = calc_graph_azi(x, y, projection=projection, zeroAngle=zeroAngleWhere)
    +
    2538 
    +
    2539  setdatafolder savedf
    +
    2540 end
    +
    2541 
    +
    2547 static function polar_graph_hook(s)
    +
    2548  STRUCT WMWinHookStruct &s
    +
    2549 
    +
    2550  Variable hookResult = 0
    +
    2551 
    +
    2552  switch(s.eventCode)
    +
    2553  case 7: // cursor moved
    +
    2554  update_polar_info(s.winname)
    +
    2555  break
    +
    2556  case 20: // show info
    +
    2557  TextBox /W=$s.winname /N=tb_angles /C /V=1
    +
    2558  break
    +
    2559  case 21: // hide info
    +
    2560  TextBox /W=$s.winname /N=tb_angles /C /V=0
    +
    2561  break
    +
    2562  endswitch
    +
    2563 
    +
    2564  return hookResult // 0 if nothing done, else 1
    +
    2565 end
    +
    2566 
    +
    2567 function set_polar_graph_cursor(nickname, cursorname, polar_angle, azim_angle, [graphname])
    +
    2568  string nickname
    +
    2569  string cursorname
    +
    2570  variable polar_angle
    +
    2571  variable azim_angle
    +
    2572  string graphname
    +
    2573 
    +
    2574  if (ParamIsDefault(graphname))
    +
    2575  if (strlen(nickname) > 0)
    +
    2576  graphname = nickname
    +
    2577  else
    +
    2578  graphname = GetDataFolder(0)
    +
    2579  endif
    +
    2580  endif
    +
    2581 
    +
    2582  string s_prefix = ""
    +
    2583  string s_int = "values"
    +
    2584  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    2585 
    +
    2586  string s_polar = s_prefix + "pol"
    +
    2587  string s_azim = s_prefix + "az"
    +
    2588  wave /sdfr=df /z azim = $s_azim
    +
    2589  wave /sdfr=df /z polar = $s_polar
    +
    2590 
    +
    2591  FindLevel /P /Q polar, polar_angle
    +
    2592  if (v_flag == 0)
    +
    2593  variable polar_level = floor(v_levelx)
    +
    2594  FindLevel /P /Q /R=[polar_level] azim, azim_angle
    +
    2595  if (v_flag == 0)
    +
    2596  variable azim_level = round(v_levelx)
    +
    2597  string tracename = "polarY0"
    +
    2598  Cursor /W=$graphname /P $cursorname $traceName azim_level
    +
    2599  endif
    +
    2600  endif
    +
    2601 end
    +
    2602 
    +
    2603 
    +
    2637 function hemi_add_anglescan(nickname, values, polar, azi, [weights])
    +
    2638  string nickname
    +
    2639  wave values
    +
    2640  wave polar
    +
    2641  wave azi
    +
    2642  wave weights
    +
    2643 
    +
    2644  dfref savedf = GetDataFolderDFR()
    +
    2645 
    +
    2646  if (ParamIsDefault(weights))
    +
    2647  duplicate /free values, weights
    +
    2648  weights = 1
    +
    2649  endif
    +
    2650 
    +
    2651  string s_prefix = ""
    +
    2652  string s_int = "values"
    +
    2653  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    2654 
    +
    2655  string s_totals = s_prefix + "tot"
    +
    2656  string s_weights = s_prefix + "wt"
    +
    2657  string s_polar = s_prefix + "pol"
    +
    2658  string s_azim = s_prefix + "az"
    +
    2659  string s_index = s_prefix + "index"
    +
    2660  string s_theta = s_prefix + "th"
    +
    2661  string s_dphi = s_prefix + "dphi"
    +
    2662  string s_nphis = s_prefix + "nphis"
    +
    2663 
    +
    2664  wave /sdfr=df w_polar = $s_polar
    +
    2665  wave /sdfr=df w_azim = $s_azim
    +
    2666  wave /sdfr=df w_values = $s_int
    +
    2667  wave /sdfr=df w_totals = $s_totals
    +
    2668  wave /sdfr=df w_weights = $s_weights
    +
    2669  wave /sdfr=df w_index = $s_index
    +
    2670  wave /sdfr=df w_theta = $s_theta
    +
    2671  wave /sdfr=df w_dphi = $s_dphi
    +
    2672  wave /sdfr=df w_nphis = $s_nphis
    +
    2673 
    +
    2674  // make internal copies of input, one-dimensional, ordered in theta
    +
    2675  duplicate /free values, values_copy
    +
    2676  duplicate /free polar, polar_copy
    +
    2677  duplicate /free azi, azi_copy
    +
    2678  duplicate /free weights, weights_copy
    +
    2679  variable nn = dimsize(values, 0) * max(dimsize(values, 1), 1)
    +
    2680  redimension /n=(nn) values_copy, polar_copy, azi_copy, weights_copy
    +
    2681  sort /r polar_copy, polar_copy, azi_copy, values_copy, weights_copy
    +
    2682 
    +
    2683  make /n=(numpnts(w_theta)) /free /df dfw
    +
    2684  // for debugging: remove the MultiThread keyword and the ThreadSafe keywords of sub-functions
    +
    2685  MultiThread dfw = add_anglescan_worker(p, values_copy, weights_copy, polar_copy, azi_copy, w_polar, w_azim, w_theta, w_index, w_dphi, w_nphis)
    +
    2686 
    +
    2687  variable pp
    +
    2688  for (pp = 0; pp < numpnts(dfw); pp += 1)
    +
    2689  dfref tdf= dfw[pp]
    +
    2690  wave df_totals = tdf:w_totals
    +
    2691  wave df_weights = tdf:w_weights
    +
    2692  w_totals += df_totals
    +
    2693  w_weights += df_weights
    +
    2694  endfor
    +
    2695  w_values = w_weights > 0 ? w_totals / w_weights : nan
    +
    2696 
    +
    2697  SetDataFolder savedf
    +
    2698 end
    +
    2699 
    +
    2711 threadsafe static function /df add_anglescan_worker(ith, values, weights, polar, azi, w_polar, w_azim, w_theta, w_index, w_dphi, w_nphis)
    +
    2712  variable ith // index into w_theta
    +
    2713  wave values // input data: intensity/counts
    +
    2714  wave weights // input data: weights/dwell time
    +
    2715  wave polar // input data: polar angles
    +
    2716  wave azi // input data: azimuthal angles
    +
    2717  wave w_polar // hemi grid
    +
    2718  wave w_azim // hemi grid
    +
    2719  wave w_theta // hemi grid
    +
    2720  wave w_index // hemi grid
    +
    2721  wave w_dphi // hemi grid
    +
    2722  wave w_nphis // hemi grid
    +
    2723 
    +
    2724  dfref savedf= GetDataFolderDFR()
    +
    2725  dfref freedf= NewFreeDataFolder()
    +
    2726  SetDataFolder freedf
    +
    2727  make /n=(numpnts(w_polar)) /d w_totals, w_weights
    +
    2728 
    +
    2729  variable pol = w_theta[ith]
    +
    2730  variable pol_st = abs(w_theta[1] - w_theta[0])
    +
    2731  variable pol1 = pol - pol_st / 2
    +
    2732  variable pol2 = pol + pol_st / 2
    +
    2733 
    +
    2734  extract /free /indx polar, sel, (pol1 < polar) && (polar <= pol2) && (numtype(values) == 0) && (weights > 0)
    +
    2735  if (numpnts(sel) > 0)
    +
    2736  duplicate /free /r=[0, numpnts(sel)-1] azi, azi_slice
    +
    2737  duplicate /free /r=[0, numpnts(sel)-1] values, values_slice
    +
    2738  duplicate /free /r=[0, numpnts(sel)-1] weights, weights_slice
    +
    2739  azi_slice = azi[sel]
    +
    2740  values_slice = values[sel]
    +
    2741  weights_slice = weights[sel]
    +
    2742  add_aziscan_core(values_slice, weights_slice, pol, azi_slice, w_theta, w_azim, w_index, w_dphi, w_totals, w_weights)
    +
    2743  endif
    +
    2744 
    +
    2745  SetDataFolder savedf
    +
    2746  return freedf
    +
    2747 end
    +
    2748 
    +
    2761 threadsafe static function add_aziscan_core(values, weights, polar, azi, w_theta, w_azim, w_index, w_dphi, w_totals, w_weights)
    +
    2762  wave values // input data: intensity/counts
    +
    2763  wave weights // input data: weights/dwell time
    +
    2764  variable polar // input data: polar angle
    +
    2765  wave azi // input data: angle positions of the azimuthal scan
    +
    2766  // acceptable range: >= -360 and < +360
    +
    2767  // no specific order required, the function sorts the array in place (!)
    +
    2768  wave w_theta // hemi grid
    +
    2769  wave w_azim // hemi grid
    +
    2770  wave w_index // hemi grid
    +
    2771  wave w_dphi // hemi grid
    +
    2772  wave w_totals // output data: total counts in hemi grid order
    +
    2773  wave w_weights // output data: total weights in hemi grid order
    +
    2774 
    +
    2775  // destination slice coordinates
    +
    2776  variable ipol = BinarySearch(w_theta, polar)
    +
    2777  if (ipol < 0)
    +
    2778  return -1
    +
    2779  endif
    +
    2780 
    +
    2781  variable d1, d2
    +
    2782  if (ipol >= 1)
    +
    2783  d1 = w_index[ipol - 1]
    +
    2784  else
    +
    2785  d1 = 0
    +
    2786  endif
    +
    2787  d2 = w_index[ipol] - 1
    +
    2788  variable nd = d2 - d1 + 1
    +
    2789  variable dphi = w_dphi[ipol]
    +
    2790  make /n=(nd+1) /free bin_index
    +
    2791  setscale /i x w_azim[d1] - dphi/2, w_azim[d2] + dphi/2, "deg", bin_index
    +
    2792 
    +
    2793  // source slice coordinates
    +
    2794  // order the slice from -dphi/2 to 360-dphi/2
    +
    2795  azi = azi < 0 ? azi + 360 : azi
    +
    2796  azi = azi >= 360 - dphi/2 ? azi - 360 : azi
    +
    2797  sort azi, values, weights, azi
    +
    2798  setscale /p x 0, 1, "", values, weights, azi
    +
    2799 
    +
    2800  bin_index = BinarySearch(azi, x) + 1
    +
    2801  bin_index = bin_index == -2 ? 0 : bin_index[p]
    +
    2802  bin_index = bin_index == -1 ? numpnts(azi) : bin_index[p]
    +
    2803  bin_index[nd] = numpnts(azi)
    +
    2804 
    +
    2805  // loop over destination
    +
    2806  variable id
    +
    2807  variable v1, v2, w1, w2
    +
    2808  for (id = 0; id < nd; id += 1)
    +
    2809  if (bin_index[id+1] > bin_index[id])
    +
    2810  v1 = w_totals[d1 + id]
    +
    2811  w1 = w_weights[d1 + id]
    +
    2812  if ((numtype(v1) == 2) || (w1 <= 0))
    +
    2813  v1 = 0
    +
    2814  w1 = 0
    +
    2815  endif
    +
    2816  v2 = sum(values, bin_index[id], bin_index[id+1] - 1)
    +
    2817  w2 = sum(weights, bin_index[id], bin_index[id+1] - 1)
    +
    2818  w_totals[d1 + id] = v1 + v2
    +
    2819  w_weights[d1 + id] = w1 + w2
    +
    2820  endif
    +
    2821  endfor
    +
    2822 end
    +
    2823 
    +
    2844 function hemi_add_aziscan(nickname, values, polar, azi, [weights])
    +
    2845  string nickname
    +
    2846  wave values
    +
    2847  variable polar
    +
    2848  wave azi
    +
    2849  wave weights
    +
    2850 
    +
    2851  dfref savedf = GetDataFolderDFR()
    +
    2852 
    +
    2853  duplicate /free values, values_copy
    +
    2854  duplicate /free azi, azi_copy
    +
    2855  if (ParamIsDefault(weights))
    +
    2856  duplicate /free values, weights_copy
    +
    2857  weights_copy = 1
    +
    2858  else
    +
    2859  duplicate /free weights, weights_copy
    +
    2860  endif
    +
    2861 
    +
    2862  // hemi grid waves
    +
    2863  string s_prefix = ""
    +
    2864  string s_int = "values"
    +
    2865  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    2866 
    +
    2867  string s_totals = s_prefix + "tot"
    +
    2868  string s_weights = s_prefix + "wt"
    +
    2869  string s_polar = s_prefix + "pol"
    +
    2870  string s_azim = s_prefix + "az"
    +
    2871  string s_index = s_prefix + "index"
    +
    2872  string s_theta = s_prefix + "th"
    +
    2873  string s_dphi = s_prefix + "dphi"
    +
    2874  string s_nphis = s_prefix + "nphis"
    +
    2875 
    +
    2876  wave /sdfr=df w_polar = $s_polar
    +
    2877  wave /sdfr=df w_azim = $s_azim
    +
    2878  wave /sdfr=df w_values = $s_int
    +
    2879  wave /sdfr=df w_totals = $s_totals
    +
    2880  wave /sdfr=df w_weights = $s_weights
    +
    2881  wave /sdfr=df w_index = $s_index
    +
    2882  wave /sdfr=df w_theta = $s_theta
    +
    2883  wave /sdfr=df w_dphi = $s_dphi
    +
    2884  wave /sdfr=df w_nphis = $s_nphis
    +
    2885 
    +
    2886  add_aziscan_core(values_copy, weights_copy, polar, azi_copy, w_theta, w_azim, w_index, w_dphi, w_totals, w_weights)
    +
    2887 
    +
    2888  w_values = w_weights > 0 ? w_totals / w_weights : nan
    +
    2889 
    +
    2890  SetDataFolder savedf
    +
    2891 end
    +
    2892 
    +
    2920 function interpolate_hemi_scan(nickname, [projection])
    +
    2921  string nickname
    +
    2922  variable projection
    +
    2923 
    +
    2924  dfref savedf = GetDataFolderDFR()
    +
    2925 
    +
    2926  if (ParamIsDefault(projection))
    +
    2927  projection = 1
    +
    2928  endif
    +
    2929 
    +
    2930  string s_prefix = ""
    +
    2931  string s_int = "values"
    +
    2932  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    2933  prepare_hemi_scan_display(nickname, projection=projection)
    +
    2934 
    +
    2935  string s_polar = s_prefix + "pol"
    +
    2936  string s_azim = s_prefix + "az"
    +
    2937  string s_matrix = s_prefix + "matrix"
    +
    2938  string s_ster_rad = s_prefix + "ster_rad"
    +
    2939  string s_ster_x = s_prefix + "ster_x"
    +
    2940  string s_ster_y = s_prefix + "ster_y"
    +
    2941 
    +
    2942  wave /sdfr=df /z values = $s_int
    +
    2943  wave /sdfr=df /z azim = $s_azim
    +
    2944  wave /sdfr=df /z polar = $s_polar
    +
    2945  wave /sdfr=df /z ster_rad = $s_ster_rad
    +
    2946  wave /sdfr=df /z ster_x = $s_ster_x
    +
    2947  wave /sdfr=df /z ster_y = $s_ster_y
    +
    2948 
    +
    2949  variable min_ster_x = wavemin(ster_x)
    +
    2950  variable max_ster_x = wavemax(ster_x)
    +
    2951  variable x0 = min_ster_x
    +
    2952  variable xn = 181
    +
    2953  variable dx = (max_ster_x - min_ster_x) / (xn - 1)
    +
    2954  make /n=(numpnts(ster_x), 3) /free triplet
    +
    2955  triplet[][0] = ster_x[p]
    +
    2956  triplet[][1] = ster_y[p]
    +
    2957  triplet[][2] = values[p]
    +
    2958 
    +
    2959  variable size = 181
    +
    2960  setdatafolder df
    +
    2961  make /n=(size, size) /d /o $(s_prefix + "matrix") /wave=matrix
    +
    2962  make /n=(size, size) /free mnorm
    +
    2963  ImageFromXYZ /as {ster_x, ster_y, values}, matrix, mnorm
    +
    2964  matrix /= mnorm
    +
    2965  matrixfilter NanZapMedian, matrix
    +
    2966  matrixfilter gauss, matrix
    +
    2967 
    +
    2968  duplicate /free values, ster_finite
    +
    2969  ster_finite = (numtype(values) == 0) * (ster_x^2 + ster_y^2)
    +
    2970  variable ster_max = wavemax(ster_finite)
    +
    2971  matrix = (x^2 + y^2) <= ster_max ? matrix : nan
    +
    2972 
    +
    2973  setdatafolder savedf
    +
    2974 end
    +
    2975 
    +
    2986 function quick_pizza_image(data, nickname, theta_offset, tilt_offset, phi_offset, [npolar, nograph, folding])
    +
    2987  wave data // 2D intensity wave, see requirements above
    +
    2988  string nickname // nick name for output data
    +
    2989  // in default mode, this will be the name of a child folder containing the output
    +
    2990  // in XPDplot mode, this will be a prefix of the generated data in the root folder
    +
    2991  variable theta_offset // manipulator theta angle corresponding to normal emission
    +
    2992  variable tilt_offset // manipulator tilt angle corresponding to normal emission
    +
    2993  variable phi_offset // manipulator phi angle corresponding to phi_result = 0
    +
    2994  variable npolar // number of polar angles, determines polar and azimuthal step size
    +
    2995  // default = 91 (1 degree steps)
    +
    2996  variable nograph // 0 (default) = display a new polar graph
    +
    2997  // 1 = don't display a new graph (if a graph is existing from a previous call, it will update)
    +
    2998  variable folding // rotational averaging, default = 1
    +
    2999 
    +
    3000  if (ParamIsDefault(npolar))
    +
    3001  npolar = 91
    +
    3002  endif
    +
    3003  if (ParamIsDefault(nograph))
    +
    3004  nograph = 0
    +
    3005  endif
    +
    3006  if (ParamIsDefault(folding))
    +
    3007  folding = 1
    +
    3008  endif
    +
    3009  string graphname = "graph_" + nickname
    +
    3010  string s_prefix = ""
    +
    3011 
    +
    3012  // sort out data folder structure
    +
    3013  dfref saveDF = GetDataFolderDFR()
    +
    3014  dfref dataDF = GetWavesDataFolderDFR(data)
    +
    3015  setdatafolder dataDF
    +
    3016  if (DataFolderExists(":attr"))
    +
    3017  setdatafolder :attr
    +
    3018  endif
    +
    3019  dfref attrDF = GetDataFolderDFR()
    +
    3020  setdatafolder dataDF
    +
    3021  newdatafolder /s/o $nickname
    +
    3022  dfref destDF = GetDataFolderDFR()
    +
    3023 
    +
    3024  // performance monitoring
    +
    3025  variable timerRefNum
    +
    3026  variable /g xyz_perf_secs
    +
    3027  timerRefNum = startMSTimer
    +
    3028 
    +
    3029  wave /sdfr=attrDF ManipulatorTheta
    +
    3030  wave /sdfr=attrDF ManipulatorTilt
    +
    3031  wave /sdfr=attrDF ManipulatorPhi
    +
    3032  duplicate /free ManipulatorTheta, m_theta
    +
    3033  duplicate /free ManipulatorTilt, m_tilt
    +
    3034  duplicate /free ManipulatorPhi, m_phi
    +
    3035  m_theta -= theta_offset
    +
    3036  m_tilt -= tilt_offset
    +
    3037  m_tilt *= -1 // checked 140702
    +
    3038  m_phi -= phi_offset
    +
    3039  //m_phi *= -1 // checked 140702
    +
    3040 
    +
    3041  make /n=1/d/free d_polar, d_azi
    +
    3042  convert_angles_ttpd2polar(m_theta, m_tilt, m_phi, data, d_polar, d_azi)
    +
    3043  d_azi += 180 // changed 151030 (v1.6)
    +
    3044  d_azi = d_azi >= 360 ? d_azi - 360 : d_azi
    +
    3045 
    +
    3046  duplicate /free data, values
    +
    3047  variable nn = dimsize(values, 0) * max(dimsize(values, 1), 1)
    +
    3048  redimension /n=(nn) values, d_polar, d_azi
    +
    3049  duplicate /o d_polar, ster_rad, ster_x, ster_y
    +
    3050 
    +
    3051  variable projection = 1
    +
    3052  switch(projection)
    +
    3053  case 1: // stereographic
    +
    3054  ster_rad = 2 * tan(d_polar / 2 * pi / 180)
    +
    3055  break
    +
    3056  case 2: // azimuthal
    +
    3057  ster_rad = 2 * cos((180 - d_polar) / 2 * pi / 180)
    +
    3058  break
    +
    3059  endswitch
    +
    3060  string s_ster_x = s_prefix + "ster_x"
    +
    3061  string s_ster_y = s_prefix + "ster_y"
    +
    3062 
    +
    3063  nn = 401
    +
    3064  make /n=(nn, nn) /d /o matrix
    +
    3065  make /n=(nn, nn) /free mnorm
    +
    3066  setscale /i x -2, +2, matrix, mnorm
    +
    3067  setscale /i y -2, +2, matrix, mnorm
    +
    3068  matrix = 0
    +
    3069  mnorm = 0
    +
    3070 
    +
    3071  variable ifold
    +
    3072  for (ifold = 0; ifold < folding; ifold += 1)
    +
    3073  ster_x = ster_rad * cos(d_azi * pi / 180)
    +
    3074  ster_y = ster_rad * sin(d_azi * pi / 180)
    +
    3075  ImageFromXYZ {ster_x, ster_y, values}, matrix, mnorm
    +
    3076  d_azi = d_azi >= 180 ? d_azi + 360 / folding - 180 : d_azi + 360 / folding
    +
    3077  endfor
    +
    3078 
    +
    3079  matrix /= mnorm
    +
    3080  matrixfilter /n=5 NanZapMedian matrix
    +
    3081  matrixfilter /n=3 gauss matrix
    +
    3082 
    +
    3083  if (!nograph)
    +
    3084  display /k=1
    +
    3085  appendimage matrix
    +
    3086  modifygraph width={Plan,1,bottom,left}
    +
    3087  endif
    +
    3088 
    +
    3089  if (timerRefNum >= 0)
    +
    3090  xyz_perf_secs = stopMSTimer(timerRefNum) / 1e6
    +
    3091  endif
    +
    3092 
    +
    3093  setdatafolder saveDF
    +
    3094 end
    +
    3095 
    +
    3097 function save_hemi_scan(nickname, pathname, filename)
    +
    3098  string nickname
    +
    3099  string pathname
    +
    3100  string filename
    +
    3101 
    +
    3102  dfref savedf = getdatafolderdfr()
    +
    3103 
    +
    3104  // source data
    +
    3105  string s_prefix = ""
    +
    3106  string s_int = "values"
    +
    3107  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    3108 
    +
    3109  string s_polar = s_prefix + "pol"
    +
    3110  string s_azim = s_prefix + "az"
    +
    3111  string s_theta = s_prefix + "th"
    +
    3112  string s_tot = s_prefix + "tot"
    +
    3113  string s_weight = s_prefix + "wt"
    +
    3114 
    +
    3115  wave /sdfr=df theta1 = $s_theta
    +
    3116  wave /sdfr=df polar1 = $s_polar
    +
    3117  wave /sdfr=df azim1 = $s_azim
    +
    3118  wave /sdfr=df tot1 = $s_tot
    +
    3119  wave /sdfr=df weight1 = $s_weight
    +
    3120  wave /sdfr=df values1 = $s_int
    +
    3121 
    +
    3122  save /m="\r\n" /o /p=$pathname /t theta1, polar1, azim1, tot1, weight1, values1 as filename
    +
    3123 
    +
    3124  setdatafolder saveDF
    +
    3125 end
    +
    3126 
    +
    3130 function load_hemi_scan(nickname, pathname, filename)
    +
    3131  string nickname
    +
    3132  string pathname
    +
    3133  string filename
    +
    3134 
    +
    3135  dfref savedf = getdatafolderdfr()
    +
    3136 
    +
    3137  //loadwave /p=$pathname /t theta1, polar1, azim1, tot1, weight1, values1 as filename
    +
    3138  //LoadWave /t/p=pearl_explorer_filepath/q filename
    +
    3139  //svar waves = s_wavenames
    +
    3140  //if (v_flag > 0)
    +
    3141  // string /g pearl_explorer_import = "load_itx_file"
    +
    3142  //endif
    +
    3143 
    +
    3144  setdatafolder saveDF
    +
    3145 end
    +
    3146 
    +
    3179 function import_tpi_scan(nickname, theta, phi, intensity, [folding, npolar, nograph, xpdplot])
    +
    3180  string nickname
    +
    3181  wave theta
    +
    3182  wave phi
    +
    3183  wave intensity
    +
    3184 
    +
    3185  variable folding
    +
    3186  variable npolar
    +
    3187  variable nograph
    +
    3188  variable xpdplot
    +
    3189 
    +
    3190  if (ParamIsDefault(npolar))
    +
    3191  npolar = 91
    +
    3192  endif
    +
    3193  if (ParamIsDefault(nograph))
    +
    3194  nograph = 0
    +
    3195  endif
    +
    3196  if (ParamIsDefault(folding))
    +
    3197  folding = 1
    +
    3198  endif
    +
    3199  if (ParamIsDefault(xpdplot))
    +
    3200  xpdplot = 0
    +
    3201  endif
    +
    3202 
    +
    3203  make_hemi_grid(npolar, nickname, xpdplot=xpdplot)
    +
    3204 
    +
    3205  variable ifold
    +
    3206  duplicate /free phi, fold_phi
    +
    3207  for (ifold = 0; ifold < folding; ifold += 1)
    +
    3208  fold_phi = fold_phi >= 360 ? fold_phi - 360 : fold_phi
    +
    3209  hemi_add_anglescan(nickname, intensity, theta, fold_phi)
    +
    3210  fold_phi += 360 / folding
    +
    3211  endfor
    +
    3212 
    +
    3213  if (nograph==0)
    +
    3214  display_hemi_scan(nickname)
    +
    3215  endif
    +
    3216 end
    +
    3217 
    +
    3229 function trim_hemi_scan(nickname, theta_max)
    +
    3230  string nickname
    +
    3231  variable theta_max
    +
    3232 
    +
    3233  string s_prefix = ""
    +
    3234  string s_int = "values"
    +
    3235  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    3236 
    +
    3237  string s_totals = s_prefix + "tot"
    +
    3238  string s_weights = s_prefix + "wt"
    +
    3239  string s_polar = s_prefix + "pol"
    +
    3240 
    +
    3241  wave /sdfr=df w_polar = $s_polar
    +
    3242  wave /sdfr=df w_values = $s_int
    +
    3243  wave /sdfr=df w_totals = $s_totals
    +
    3244  wave /sdfr=df w_weights = $s_weights
    +
    3245 
    +
    3246  w_values = w_polar <= theta_max ? w_totals / w_weights : nan
    +
    3247 end
    +
    3248 
    +
    3268 function /wave hemi_polar_cut(nickname, azim)
    +
    3269  string nickname
    +
    3270  variable azim
    +
    3271 
    +
    3272  dfref savedf = getdatafolderdfr()
    +
    3273  string s_prefix = ""
    +
    3274  string s_int = "values"
    +
    3275  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    3276 
    +
    3277  string s_totals = s_prefix + "tot"
    +
    3278  string s_weights = s_prefix + "wt"
    +
    3279  string s_polar = s_prefix + "pol"
    +
    3280  string s_azim = s_prefix + "az"
    +
    3281  string s_index = s_prefix + "index"
    +
    3282  string s_theta = s_prefix + "th"
    +
    3283  string s_dphi = s_prefix + "dphi"
    +
    3284  string s_nphis = s_prefix + "nphis"
    +
    3285  string s_cut
    +
    3286  sprintf s_cut, "%s_azi%03u", s_int, round(azim)
    +
    3287 
    +
    3288  wave /sdfr=df w_polar = $s_polar
    +
    3289  wave /sdfr=df w_azim = $s_azim
    +
    3290  wave /sdfr=df w_values = $s_int
    +
    3291  wave /sdfr=df w_totals = $s_totals
    +
    3292  wave /sdfr=df w_weights = $s_weights
    +
    3293  wave /sdfr=df w_index = $s_index
    +
    3294  wave /sdfr=df w_theta = $s_theta
    +
    3295  wave /sdfr=df w_dphi = $s_dphi
    +
    3296  wave /sdfr=df w_nphis = $s_nphis
    +
    3297 
    +
    3298  variable npol = numpnts(w_theta)
    +
    3299  variable ipol
    +
    3300  variable pol_st = abs(w_theta[1] - w_theta[0])
    +
    3301  variable pol
    +
    3302  variable pol1, pol2
    +
    3303  variable nsel
    +
    3304 
    +
    3305  setdatafolder df
    +
    3306  make /n=(npol) /o $s_cut
    +
    3307  wave w_cut = $s_cut
    +
    3308  setscale /i x w_theta[0], w_theta[numpnts(w_theta)-1], "deg", w_cut
    +
    3309  make /n=1 /free azi_slice
    +
    3310  make /n=1 /free values_slice
    +
    3311 
    +
    3312  for (ipol = 0; ipol < npol; ipol += 1)
    +
    3313  pol = w_theta[ipol]
    +
    3314  pol1 = pol - pol_st / 2
    +
    3315  pol2 = pol + pol_st / 2
    +
    3316  extract /free /indx w_polar, sel, (pol1 < w_polar) && (w_polar <= pol2)
    +
    3317  nsel = numpnts(sel)
    +
    3318  if (nsel > 0)
    +
    3319  redimension /n=(nsel+2) azi_slice, values_slice
    +
    3320  azi_slice[1, nsel] = w_azim[sel[p-1]]
    +
    3321  azi_slice[0] = azi_slice[nsel] - 360
    +
    3322  azi_slice[nsel+1] = azi_slice[1] + 360
    +
    3323  values_slice[1, nsel] = w_values[sel[p-1]]
    +
    3324  values_slice[0] = values_slice[nsel]
    +
    3325  values_slice[nsel+1] = values_slice[1]
    +
    3326  w_cut[ipol] = interp(azim, azi_slice, values_slice)
    +
    3327  else
    +
    3328  w_cut[ipol] = nan
    +
    3329  endif
    +
    3330  endfor
    +
    3331 
    +
    3332  setdatafolder savedf
    +
    3333  return w_cut
    +
    3334 end
    +
    3335 
    +
    3354 function /wave hemi_azi_cut(nickname, pol)
    +
    3355  string nickname
    +
    3356  variable pol
    +
    3357 
    +
    3358  dfref savedf = getdatafolderdfr()
    +
    3359  string s_prefix = ""
    +
    3360  string s_int = "values"
    +
    3361  dfref df = find_hemi_data(nickname, s_prefix, s_int)
    +
    3362 
    +
    3363  string s_totals = s_prefix + "tot"
    +
    3364  string s_weights = s_prefix + "wt"
    +
    3365  string s_polar = s_prefix + "pol"
    +
    3366  string s_azim = s_prefix + "az"
    +
    3367  string s_index = s_prefix + "index"
    +
    3368  string s_theta = s_prefix + "th"
    +
    3369  string s_dphi = s_prefix + "dphi"
    +
    3370  string s_nphis = s_prefix + "nphis"
    +
    3371  string s_cut
    +
    3372  sprintf s_cut, "%s_pol%03u", s_int, round(pol)
    +
    3373 
    +
    3374  wave /sdfr=df w_polar = $s_polar
    +
    3375  wave /sdfr=df w_azim = $s_azim
    +
    3376  wave /sdfr=df w_values = $s_int
    +
    3377  wave /sdfr=df w_totals = $s_totals
    +
    3378  wave /sdfr=df w_weights = $s_weights
    +
    3379  wave /sdfr=df w_index = $s_index
    +
    3380  wave /sdfr=df w_theta = $s_theta
    +
    3381  wave /sdfr=df w_dphi = $s_dphi
    +
    3382  wave /sdfr=df w_nphis = $s_nphis
    +
    3383 
    +
    3384  variable pol_st = abs(w_theta[1] - w_theta[0])
    +
    3385  variable pol1, pol2
    +
    3386  variable nsel
    +
    3387 
    +
    3388  pol1 = pol - pol_st / 2
    +
    3389  pol2 = pol + pol_st / 2
    +
    3390  extract /free /indx w_polar, sel, (pol1 < w_polar) && (w_polar <= pol2)
    +
    3391  nsel = numpnts(sel)
    +
    3392  if (nsel > 0)
    +
    3393  setdatafolder df
    +
    3394  make /n=(nsel) /o $s_cut
    +
    3395  wave w_cut = $s_cut
    +
    3396  w_cut = w_values[sel]
    +
    3397  setscale /i x w_azim[sel[0]], w_azim[sel[nsel-1]], "°", w_cut
    +
    3398  setdatafolder savedf
    +
    3399  return w_cut
    +
    3400  else
    +
    3401  setdatafolder savedf
    +
    3402  return $""
    +
    3403  endif
    +
    3404  setdatafolder savedf
    +
    3405 end
    +
    3406 
    +
    3407 static function check_contrast(values, pcmin, pcmax, vmin, vmax, sym)
    +
    3408  wave values
    +
    3409  variable pcmin
    +
    3410  variable pcmax
    +
    3411  variable &vmin
    +
    3412  variable &vmax
    +
    3413  variable sym
    +
    3414 
    +
    3415  dfref save_df = GetDataFolderDFR()
    +
    3416  dfref dfr = NewFreeDataFolder()
    +
    3417  setdatafolder dfr
    +
    3418  StatsQuantiles /inan /iw /q /z values
    +
    3419  wave /z index = w_quantilesindex
    +
    3420  setdatafolder save_df
    +
    3421 
    +
    3422  if (waveexists(index))
    +
    3423  variable imin = round(numpnts(index) * pcmin / 100)
    +
    3424  variable imax = round(numpnts(index) * (100 - pcmax) / 100)
    +
    3425  vmin = values[index[imin]]
    +
    3426  vmax = values[index[imax]]
    +
    3427  if (sym)
    +
    3428  variable d = vmax - vmin
    +
    3429  if ((vmax >= d/4) && (-vmin >= d/4))
    +
    3430  vmax = min(abs(vmin), abs(vmax))
    +
    3431  vmin = -vmax
    +
    3432  endif
    +
    3433  endif
    +
    3434  else
    +
    3435  vmin = wavemin(values)
    +
    3436  vmax = wavemax(values)
    +
    3437  endif
    +
    3438 end
    +
    3439 
    +
    3463 function set_contrast(pcmin, pcmax, [graphname, colortable, reversecolors, symmetric])
    +
    3464  variable pcmin
    +
    3465  variable pcmax
    +
    3466  string graphname
    +
    3467  string colortable
    +
    3468  variable reversecolors
    +
    3469  variable symmetric
    +
    3470 
    +
    3471  if (ParamIsDefault(graphname))
    +
    3472  graphname = ""
    +
    3473  endif
    +
    3474  if (ParamIsDefault(colortable))
    +
    3475  colortable = ""
    +
    3476  endif
    +
    3477  if (ParamIsDefault(reversecolors))
    +
    3478  reversecolors = 0
    +
    3479  endif
    +
    3480  if (ParamIsDefault(symmetric))
    +
    3481  symmetric = 0
    +
    3482  endif
    +
    3483 
    +
    3484  dfref save_df = GetDataFolderDFR()
    +
    3485 
    +
    3486  string objname
    +
    3487  string info
    +
    3488  string wname
    +
    3489  string ctab
    +
    3490  variable rev
    +
    3491  variable n
    +
    3492  variable i
    +
    3493  variable vmin
    +
    3494  variable vmax
    +
    3495 
    +
    3496  string traces = TraceNameList(graphname, ";", 1+4)
    +
    3497  n = ItemsInList(traces, ";")
    +
    3498  for (i = 0; i < n; i += 1)
    +
    3499  objname = StringFromList(i, traces, ";")
    +
    3500  info = TraceInfo(graphname, objname, 0)
    +
    3501  if (strlen(info) > 0)
    +
    3502  info = StringByKey("RECREATION", info, ":", ";")
    +
    3503  info = StringByKey("zColor(x)", info, "=", ";")
    +
    3504  if (strlen(info) > 2)
    +
    3505  info = info[1,strlen(info)-2]
    +
    3506  wname = StringFromList(0, info, ",")
    +
    3507  wave w = $wname
    +
    3508  ctab = StringFromList(3, info, ",")
    +
    3509  rev = str2num("0" + StringFromList(4, info, ","))
    +
    3510  if (strlen(colortable) > 0)
    +
    3511  ctab = colortable
    +
    3512  rev = reversecolors
    +
    3513  endif
    +
    3514  check_contrast(w, pcmin, pcmax, vmin, vmax, symmetric)
    +
    3515  if (vmax > vmin)
    +
    3516  ModifyGraph /w=$graphname zColor($objname)={w, vmin, vmax, $ctab, rev}
    +
    3517  endif
    +
    3518  endif
    +
    3519  endif
    +
    3520  endfor
    +
    3521 
    +
    3522  string images = ImageNameList(graphname, ";")
    +
    3523  n = ItemsInList(images, ";")
    +
    3524  for (i = 0; i < n; i += 1)
    +
    3525  objname = StringFromList(i, images, ";")
    +
    3526  wave w = ImageNameToWaveRef(graphname, objname)
    +
    3527  info = ImageInfo(graphname, objname, 0)
    +
    3528  if (strlen(info) > 0)
    +
    3529  info = StringByKey("RECREATION", info, ":", ";")
    +
    3530  info = StringByKey("ctab", info, "=", ";")
    +
    3531  if (strlen(info) > 2)
    +
    3532  info = info[1,strlen(info)-2]
    +
    3533  ctab = StringFromList(2, info, ",")
    +
    3534  rev = str2num("0" + StringFromList(3, info, ","))
    +
    3535  if (strlen(colortable) > 0)
    +
    3536  ctab = colortable
    +
    3537  rev = reversecolors
    +
    3538  endif
    +
    3539  check_contrast(w, pcmin, pcmax, vmin, vmax, symmetric)
    +
    3540  if (vmax > vmin)
    +
    3541  ModifyImage /w=$graphname $objname ctab={vmin, vmax, $ctab, rev}
    +
    3542  endif
    +
    3543  endif
    +
    3544  endif
    +
    3545  endfor
    +
    3546 
    +
    3547  setdatafolder save_df
    +
    3548 end
    +
    3549 
    +
    3562 Function AngleToK(inwave)
    +
    3563  Wave inwave
    +
    3564  String newname = NameofWave(inwave)+"_k"
    +
    3565  Duplicate/O inwave, $newname
    +
    3566  Wave outwave = $newname
    +
    3567  Variable rows,columns,xdelta,xoffset,ydelta,yoffset,kmin,kmax,Emax
    +
    3568  // inwave parameters
    +
    3569  rows = DimSize(inwave,0)
    +
    3570  columns = DimSize(inwave,1)
    +
    3571  xdelta = DimDelta(inwave,0)
    +
    3572  xoffset = DimOffset(inwave,0)
    +
    3573  ydelta = DimDelta(inwave,1)
    +
    3574  yoffset = DimOffset(inwave,1)
    +
    3575  Emax= xoffset + xdelta*(rows-1)
    +
    3576  kmin = 0.5123*sqrt(Emax)*sin(pi/180*(yoffset)) // calculate the k boundaries
    +
    3577  kmax = 0.5123*sqrt(Emax)*sin(pi/180*(yoffset+(columns-1)*ydelta))
    +
    3578  SetScale/I y kmin,kmax,"Ang^-1", outwave
    +
    3579  // scale the y axis
    +
    3580  outwave = interp2D(inwave, x, 180/pi*asin(y/ (0.5123*sqrt(x)))) // recalculate to k
    +
    3581  outwave = (NumType(outwave)==2) ? 0 : outwave // replace NaNs (optional)
    +
    3582 End
    +
    variable crop_strip(wave strip, variable xlo, variable xhi)
    crop a strip at the sides.
    +
    const variable kProjGnom
    +
    variable trim_hemi_scan(string nickname, variable theta_max)
    trim a hemispherical scan at grazing angle
    +
    variable hemi_add_anglescan(string nickname, wave values, wave polar, wave azi, wave weights=defaultValue)
    add arbitrary angle scan data to a hemispherical scan grid.
    +
    static variable CalcN_Theta(string HoloMode, variable Theta_in, variable Theta_ran, variable Theta_st)
    calculate the number of thetas for a pattern
    +
    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
    +
    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
    +
    variable load_hemi_scan(string nickname, string pathname, string filename)
    load a hemispherical scan from an Igor text file
    +
    variable normalize_strip_theta(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by the average polar distribution.
    +
    variable normalize_strip_x(wave strip, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by the average X distribution.
    +
    static variable check_contrast(wave values, variable pcmin, variable pcmax, variable *vmin, variable *vmax, variable sym)
    +
    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.
    +
    string get_hemi_prefix(wave w)
    finds the prefix given any hemi wave
    +
    variable make_hemi_grid(variable npol, string nickname, variable xpdplot=defaultValue)
    create a hemispherical, constant solid angle grid
    +
    variable clear_hemi_grid(string nickname)
    clear a hemispherical scan grid
    +
    variable rotate_y_wave(wave inout, variable angle)
    rotates a wave of 3-vectors about the y axis
    +
    threadsafe variable calc_graph_polar(variable x, variable y, variable projection=defaultValue)
    calculate polar angle from Cartesian coordinate
    +
    static const variable kProjScaleOrtho
    +
    const variable kProjArea
    +
    string get_hemi_nickname(wave w)
    finds the nick name given any hemi wave
    +
    wave hemi_azi_cut(string nickname, variable pol)
    extract an azimuthal cut from a hemispherical scan
    +
    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.
    +
    static variable line_average(wave source, wave dest)
    +
    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.
    +
    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.
    +
    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.
    +
    variable normalize_strip_theta_scans(wave strip, wave theta, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip piecewise by a smooth polar distribution.
    +
    static variable Calc_The_step(variable th, variable Theta_st, string Holomode)
    calculate delta-theta for a given theta
    +
    variable crop_strip_theta(wave strip, variable theta_lo, variable theta_hi, wave theta, wave tilt, wave phi)
    crop a strip in theta.
    +
    threadsafe variable calc_graph_radius(variable polar, variable projection=defaultValue)
    calculate the projected polar angle
    +
    static threadsafe dfr add_anglescan_worker(variable ith, wave values, wave weights, wave polar, wave azi, wave w_polar, wave w_azim, wave w_theta, wave w_index, wave w_dphi, wave w_nphis)
    thread worker for hemi_add_anglescan
    +
    dfr find_hemi_data(string nickname, string *prefix, string *intwave)
    finds the folder, prefix and name of holo waves given their nick name
    +
    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
    +
    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.
    +
    variable interpolate_hemi_scan(string nickname, variable projection=defaultValue)
    interpolate a hemispherical scan onto a rectangular grid
    +
    static const variable kProjScaleDist
    +
    variable cart2polar_wave(wave in, wave out)
    +
    variable rotate_hemi_scan(string nickname, variable angle)
    azimuthally rotate a hemispherical scan dataset.
    +
    const variable kProjDist
    +
    static string display_polar_graph(string graphname, variable angle_offset=defaultValue, variable do_ticks=defaultValue)
    displays an empty polar graph
    +
    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
    +
    variable set_contrast(variable pcmin, variable pcmax, string graphname=defaultValue, string colortable=defaultValue, variable reversecolors=defaultValue, variable symmetric=defaultValue)
    set the pseudocolor contrast by percentile.
    +
    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
    +
    variable hemi_add_aziscan(string nickname, wave values, variable polar, wave azi, wave weights=defaultValue)
    add azimuthal data to a hemispherical scan grid.
    +
    static threadsafe variable add_aziscan_core(wave values, wave weights, variable polar, wave azi, wave w_theta, wave w_azim, wave w_index, wave w_dphi, wave w_totals, wave w_weights)
    thread worker for hemi_add_anglescan and hemi_add_aziscan
    +
    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.
    +
    static const variable kProjScaleGnom
    +
    variable save_hemi_scan(string nickname, string pathname, string filename)
    save a hemispherical scan to an Igor text file
    +
    processing and holographic mapping of angle scanned XPD data.
    +
    variable rotate_x_wave(wave inout, variable angle)
    rotate a wave of 3-vectors about the x axis.
    +
    threadsafe variable calc_graph_azi(variable x, variable y, variable projection=defaultValue, variable zeroAngle=defaultValue)
    calculate azimuthal angle from Cartesian coordinate
    +
    const variable kProjStereo
    +
    variable normalize_strip_thetaphi(wave strip, wave theta, wave phi, variable theta_offset=defaultValue, variable smooth_method=defaultValue, variable smooth_factor=defaultValue, variable check=defaultValue)
    divide the strip by a smooth polar-azimuthal distribution.
    +
    variable rotate_z_wave(wave inout, variable angle)
    rotates a wave of 3-vectors about the z axis
    +
    static const variable kProjScaleStereo
    +
    static const variable kProjScaleArea
    +
    variable duplicate_hemi_scan(string source_nickname, dfref dest_folder, string dest_nickname, variable xpdplot=defaultValue)
    duplicate a hemispherical scan dataset.
    +
    variable set_polar_graph_cursor(string nickname, string cursorname, variable polar_angle, variable azim_angle, string graphname=defaultValue)
    +
    const variable kProjOrtho
    +
    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).
    +
    variable polar2cart_wave(wave in, wave out)
    +
    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
    +
    static variable polar_graph_hook(WMWinHookStruct *s)
    polar graph window hook
    +
    string prepare_hemi_scan_display(string nickname, variable projection=defaultValue)
    create waves for plotting a hemispherical angle scan.
    +
    wave hemi_polar_cut(string nickname, variable azim)
    extract a polar cut from a hemispherical scan.
    + +
    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
    +
    string strip_append(wave strip1, wave strip2)
    append an angle scan strip to another one
    +
    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.
    +
    variable AngleToK(wave inwave)
    k-space mapping of 2D angle-energy distribution (scienta image)
    +
    static variable update_polar_info(string graphname)
    update the angles info based on cursors A and B of a given polar graph window
    +
    static string draw_hemi_axes(string graphname, variable do_grids=defaultValue)
    draw polar and azimuthal grids in an existing polar graph.
    +
    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.
    diff --git a/doc/html/pearl-anglescan-tracker_8ipf.html b/doc/html/pearl-anglescan-tracker_8ipf.html index 7fa0887..1e2a085 100644 --- a/doc/html/pearl-anglescan-tracker_8ipf.html +++ b/doc/html/pearl-anglescan-tracker_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-anglescan-tracker.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -99,84 +101,84 @@ $(document).ready(function(){initNavTree('pearl-anglescan-tracker_8ipf.html','')

    Functions

    static variable AfterCompiledHook () - initialize package data once when the procedure is first loaded More...
    + initialize package data once when the procedure is first loaded More...
      static variable init_package ()   static variable save_prefs () - save persistent package data to the preferences file. More...
    + save persistent package data to the preferences file. More...
      static variable load_prefs () - load persistent package data from the preferences file. More...
    + load persistent package data from the preferences file. More...
      static variable IgorQuitHook (string app) - disconnect EPICS channels before Igor quits. More...
    + disconnect EPICS channels before Igor quits. More...
      variable ast_setup () - set up data structures, display graph, and try to connect to analyser. More...
    + set up data structures, display graph, and try to connect to analyser. More...
      variable ast_prepare (variable theta_offset=defaultValue, variable tilt_offset=defaultValue, variable phi_offset=defaultValue) - prepare for new measurement and clear the data buffer. More...
    + prepare for new measurement and clear the data buffer. More...
      variable ast_set_processing (string reduction_func, string reduction_params) - set the data processing parameters More...
    + set the data processing parameters More...
      variable ast_add_image (wave image, variable theta, variable tilt, variable phi) - process and add a detector image to the tracker scan. More...
    + process and add a detector image to the tracker scan. More...
      variable ast_export (dfref folder, string nickname, variable xpdplot=defaultValue) - export tracker data to a separate, independent data set. More...
    + export tracker data to a separate, independent data set. More...
      variable ast_import (string nickname) - import tracker data from an existing angle scan dataset. More...
    + import tracker data from an existing angle scan dataset. More...
      variable ast_update_detector (variable theta, variable tilt, variable phi, variable range) - update the current position indicator. More...
    + update the current position indicator. More...
      variable ast_close () - stop tracker, close graph, release data structures. More...
    + stop tracker, close graph, release data structures. More...
      static variable setup_data ()   static variable extend_data (variable num_slices) - extend the data buffer for the next polar scan More...
    + extend the data buffer for the next polar scan More...
      static variable setup_detector ()   static variable add_image_data (wave image, variable theta, variable tilt, variable phi) - reduce a detector image and add the result to the data buffer. More...
    + reduce a detector image and add the result to the data buffer. More...
      static variable process_image_data () - process the data buffer to generate the tracker dataset. More...
    + process the data buffer to generate the tracker dataset. More...
      static variable update_detector (variable theta, variable tilt, variable phi, variable range) - update the current position indicator. More...
    + update the current position indicator. More...
      static variable setup_graph () - create the graph window. More...
    + create the graph window. More...
      static variable update_data_graph ()   static variable update_detector_graph ()   static variable epics_connect () - connect the angle scan tracker to EPICS More...
    + connect the angle scan tracker to EPICS More...
      static variable epics_disconnect_chid (string chid_var_name)   static variable epics_disconnect ()   static variable ast_window_hook (WMWinHookStruct *s) - window hook More...
    + window hook More...
      variable ast_callback_data (variable chan) - callback function for new analyser data from EPICS. More...
    + callback function for new analyser data from EPICS. More...
      variable ast_callback_detector (variable chan) - callback function for new detector state from EPICS. More...
    + callback function for new detector state from EPICS. More...
      variable ast_callback_manip (variable chan) - callback function for new manipulator position from EPICS. More...
    + callback function for new manipulator position from EPICS. More...
      static variable bp_capture (WMButtonAction *ba)   @@ -189,16 +191,16 @@ Functions static variable pmp_data_mouseup (WMPopupAction *pa)   static variable export_tracker_data () - export tracker data (with prompt) More...
    + export tracker data (with prompt) More...
      static variable import_tracker_data () - import tracker data (with prompt) More...
    + import tracker data (with prompt) More...
      static variable save_tracker_data () - save tracker data to file (with prompt) More...
    + save tracker data to file (with prompt) More...
      static variable load_tracker_data () - import tracker data from file (with prompt) More...
    + import tracker data from file (with prompt) More...
      static variable pmp_parameters (WMPopupAction *pa)   @@ -214,10 +216,10 @@ Variables  version   static const string package_path = "root:packages:pearl_anglescan_tracker:" - data folder path More...
    + data folder path More...
      static const string prefs_objects = "projection;theta_offset;tilt_offset;phi_offset;reduction_func;reduction_params" - semicolon-separated list of persistent variable, string, and wave names More...
    + semicolon-separated list of persistent variable, string, and wave names More...
     

    Function Documentation

    @@ -279,7 +281,7 @@ Variables

    the manipulator angles are corrected by the preset offsets internally.

    -

    Definition at line 453 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 454 of file pearl-anglescan-tracker.ipf.

    @@ -308,7 +310,7 @@ Variables

    initialize package data once when the procedure is first loaded

    -

    Definition at line 73 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 74 of file pearl-anglescan-tracker.ipf.

    @@ -362,7 +364,7 @@ Variables

    the manipulator angles are corrected by the preset offsets internally.

    -

    Definition at line 285 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 286 of file pearl-anglescan-tracker.ipf.

    @@ -384,7 +386,7 @@ Variables

    callback function for new analyser data from EPICS.

    -

    Definition at line 856 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 857 of file pearl-anglescan-tracker.ipf.

    @@ -405,9 +407,9 @@ Variables

    callback function for new detector state from EPICS.

    -

    save the manipulator position at the beginning of image acquisition. it is used by ast_callback_data().

    +

    save the manipulator position at the beginning of image acquisition. it is used by ast_callback_data().

    -

    Definition at line 961 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 962 of file pearl-anglescan-tracker.ipf.

    @@ -429,7 +431,7 @@ Variables

    callback function for new manipulator position from EPICS.

    -

    Definition at line 990 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 991 of file pearl-anglescan-tracker.ipf.

    @@ -450,7 +452,7 @@ Variables

    stop tracker, close graph, release data structures.

    -

    Definition at line 360 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 361 of file pearl-anglescan-tracker.ipf.

    @@ -492,7 +494,7 @@ Variables - -

    Definition at line 307 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 308 of file pearl-anglescan-tracker.ipf.

    @@ -529,7 +531,7 @@ Variables -

    Definition at line 329 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 330 of file pearl-anglescan-tracker.ipf.

    @@ -576,7 +578,7 @@ Variables -

    Definition at line 211 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 212 of file pearl-anglescan-tracker.ipf.

    @@ -610,13 +612,13 @@ Variables

    the parameters will be effective for subsequent measurements only. previously acquired data is not affected. the processing parameters are saved with the preferences.

    Parameters
    folderdestination folder path
    nicknamename prefix for waves
    xpdplotxpdplot compatibility, see make_hemi_grid() for details
      +
    xpdplotxpdplot compatibility, see make_hemi_grid() for details
    • 0 (default)
    • 1 create additional waves and notebook required by XPDplot
    @@ -501,7 +503,7 @@ Variables
    - +
    reduction_funcname of custom reduction function, e.g. "int_linbg_reduction". any user-defined function with the same signature as adh5_default_reduction() is allowed.
    reduction_funcname of custom reduction function, e.g. "int_linbg_reduction". any user-defined function with the same signature as adh5_default_reduction() is allowed.
    reduction_paramsparameter string for the reduction function. the format depends on the actual function. for int_linbg_reduction, e.g., "Lcrop=0.1;Hcrop=0.1;Lsize=0.2;Hsize=0.2;Cpos=0.5;Csize=0.4".
    -

    Definition at line 261 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 262 of file pearl-anglescan-tracker.ipf.

    @@ -637,7 +639,7 @@ Variables

    set up data structures, display graph, and try to connect to analyser.

    -

    Definition at line 194 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 195 of file pearl-anglescan-tracker.ipf.

    @@ -691,7 +693,7 @@ Variables

    the manipulator angles are corrected by the preset offsets internally.

    -

    Definition at line 349 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 350 of file pearl-anglescan-tracker.ipf.

    @@ -722,7 +724,7 @@ Variables

    window hook

    disconnects from EPICS when the window is closed.

    -

    Definition at line 841 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 842 of file pearl-anglescan-tracker.ipf.

    @@ -750,7 +752,7 @@ Variables
    -

    Definition at line 1023 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1024 of file pearl-anglescan-tracker.ipf.

    @@ -777,7 +779,7 @@ Variables
    -

    Definition at line 1244 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1245 of file pearl-anglescan-tracker.ipf.

    @@ -804,7 +806,7 @@ Variables
    -

    Definition at line 1228 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1229 of file pearl-anglescan-tracker.ipf.

    @@ -837,7 +839,7 @@ Variables
    Returns
    zero if successful, non-zero if an error occurred
    Todo:
    the X03DA channel names are hard-coded.
    -

    Definition at line 680 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 681 of file pearl-anglescan-tracker.ipf.

    @@ -864,7 +866,7 @@ Variables
    -

    Definition at line 806 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 807 of file pearl-anglescan-tracker.ipf.

    @@ -892,7 +894,7 @@ Variables
    -

    Definition at line 792 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 793 of file pearl-anglescan-tracker.ipf.

    @@ -921,7 +923,7 @@ Variables

    export tracker data (with prompt)

    -

    Definition at line 1105 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1106 of file pearl-anglescan-tracker.ipf.

    @@ -958,7 +960,7 @@ Variables -

    Definition at line 402 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 403 of file pearl-anglescan-tracker.ipf.

    @@ -988,7 +990,7 @@ Variables

    disconnect EPICS channels before Igor quits.

    -

    Definition at line 188 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 189 of file pearl-anglescan-tracker.ipf.

    @@ -1017,7 +1019,7 @@ Variables

    import tracker data (with prompt)

    -

    Definition at line 1135 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1136 of file pearl-anglescan-tracker.ipf.

    @@ -1044,7 +1046,7 @@ Variables
    -

    Definition at line 98 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 99 of file pearl-anglescan-tracker.ipf.

    @@ -1075,7 +1077,7 @@ Variables

    the preferences file is an Igor packed experiment file in a special preferences folder.

    this function is called automatically when the procedure is first compiled, or whenever the user clicks the corresponding button.

    -

    Definition at line 163 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 164 of file pearl-anglescan-tracker.ipf.

    @@ -1104,7 +1106,7 @@ Variables

    import tracker data from file (with prompt)

    -

    Definition at line 1175 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1176 of file pearl-anglescan-tracker.ipf.

    @@ -1132,7 +1134,7 @@ Variables
    -

    Definition at line 1071 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1072 of file pearl-anglescan-tracker.ipf.

    @@ -1160,7 +1162,7 @@ Variables
    -

    Definition at line 1085 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1086 of file pearl-anglescan-tracker.ipf.

    @@ -1188,7 +1190,7 @@ Variables
    -

    Definition at line 1194 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1195 of file pearl-anglescan-tracker.ipf.

    @@ -1216,7 +1218,7 @@ Variables
    -

    Definition at line 1208 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1209 of file pearl-anglescan-tracker.ipf.

    @@ -1245,7 +1247,7 @@ Variables

    process the data buffer to generate the tracker dataset.

    -

    Definition at line 507 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 508 of file pearl-anglescan-tracker.ipf.

    @@ -1275,7 +1277,7 @@ Variables

    save persistent package data to the preferences file.

    this function is called when the user clicks the corresponding button.

    -

    Definition at line 139 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 140 of file pearl-anglescan-tracker.ipf.

    @@ -1304,7 +1306,7 @@ Variables

    save tracker data to file (with prompt)

    -

    Definition at line 1164 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1165 of file pearl-anglescan-tracker.ipf.

    @@ -1331,7 +1333,7 @@ Variables
    -

    Definition at line 372 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 373 of file pearl-anglescan-tracker.ipf.

    @@ -1358,7 +1360,7 @@ Variables
    -

    Definition at line 434 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 435 of file pearl-anglescan-tracker.ipf.

    @@ -1387,7 +1389,7 @@ Variables

    create the graph window.

    -

    Definition at line 594 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 595 of file pearl-anglescan-tracker.ipf.

    @@ -1414,7 +1416,7 @@ Variables
    -

    Definition at line 1037 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1038 of file pearl-anglescan-tracker.ipf.

    @@ -1441,7 +1443,7 @@ Variables
    -

    Definition at line 1055 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 1056 of file pearl-anglescan-tracker.ipf.

    @@ -1468,7 +1470,7 @@ Variables
    -

    Definition at line 645 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 646 of file pearl-anglescan-tracker.ipf.

    @@ -1530,7 +1532,7 @@ Variables

    the manipulator angles are corrected by the preset offsets internally.

    -

    Definition at line 559 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 560 of file pearl-anglescan-tracker.ipf.

    @@ -1557,7 +1559,7 @@ Variables
    -

    Definition at line 657 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 658 of file pearl-anglescan-tracker.ipf.

    @@ -1584,7 +1586,7 @@ Variables

    data folder path

    -

    Definition at line 68 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 69 of file pearl-anglescan-tracker.ipf.

    @@ -1610,7 +1612,7 @@ Variables

    semicolon-separated list of persistent variable, string, and wave names

    -

    Definition at line 70 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 71 of file pearl-anglescan-tracker.ipf.

    @@ -1625,21 +1627,40 @@ Variables
    -Initial value:
    = 1.6
    static const string package_name = "pearl_anglescan_tracker"
    static const string package_name
    package name is used as data folder name
    +Initial value:
    = 1.6
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    static const string package_name = "pearl_anglescan_tracker"
    -

    Definition at line 5 of file pearl-anglescan-tracker.ipf.

    +

    Definition at line 6 of file pearl-anglescan-tracker.ipf.

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

    visualization tools for 2D and 3D data. More...

    #include "pearl-compat"
    +#include "pearl-area-profiles"

    Go to the source code of this file.

    @@ -104,43 +107,43 @@ Namespaces - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -149,75 +152,75 @@ Functions - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +

    Functions

    static string graphname_from_dfref (dfref df, string prefix)
     compose a valid and unique graph name from a data folder reference More...
     compose a valid and unique graph name from a data folder reference More...
     
    string ad_display (wave image)
     open a new graph window with a 2D image. More...
     open a new graph window with a 2D image. More...
     
    string ad_display_histogram (wave image)
     display the histogram of a 2D image. More...
     display the histogram of a 2D image. More...
     
    string ad_display_profiles (wave image, string filter=defaultValue)
     open a new profiles graph window. More...
     open a new profiles graph window. More...
     
    wave ad_add_overlay (wave image, string rgba=defaultValue)
     add an overlay on top of the displayed image More...
     add an overlay on top of the displayed image More...
     
    variable ad_update_profiles (wave image)
     update a profiles graph with new data. More...
     update a profiles graph with new data. More...
     
    variable ad_profiles_cursor_mode (wave image, variable mode)
     switch cursors on a profiles graph More...
     switch cursors on a profiles graph More...
     
    variable ad_profiles_set_cursor (wave image, string cursorname, variable xa, variable ya, variable pscale=defaultValue)
     move a cursor to the specified position in a profiles graph. More...
     move a cursor to the specified position in a profiles graph. More...
     
    variable ad_profiles_crosshairs (wave image, variable clear=defaultValue)
     draw permanent crosshairs in a profiles graph. More...
     draw permanent crosshairs in a profiles graph. More...
     
    static wave get_source_image (wave view)
     find the source image wave corresponding to the given view. More...
     find the source image wave corresponding to the given view. More...
     
    static dfr make_view_folder (wave source)
     create a view data folder. More...
     create a view data folder. More...
     
    static dfr get_view_folder (wave source)
     find the view data folder corresponding to the given source. More...
     find the view data folder corresponding to the given source. More...
     
    static wave get_view_image (wave source)
     find the view image wave corresponding to the given source. More...
     find the view image wave corresponding to the given source. More...
     
    static variable bp_reset_cursors (WMButtonAction *ba)
     
    static variable pmp_export (WMPopupAction *pa)
     
    variable ad_profiles_hook (WMWinHookStruct *s)
     hook function for user events in the profiles window. More...
     hook function for user events in the profiles window. More...
     
    variable ad_calc_cursor_profiles (wave image)
     calculate profiles, statistics, and histogram of a cross-hair delimited region of interest. More...
     calculate profiles, statistics, and histogram of a cross-hair delimited region of interest. More...
     
    variable ad_calc_profiles (wave image, variable pa, variable qa, variable pb, variable qb)
     calculate profiles, statistics, and histogram of a rectangular region of interest. More...
     calculate profiles, statistics, and histogram of a rectangular region of interest. More...
     
    variable ad_export_profile (wave view_image, variable dim, variable trace=defaultValue, variable show=defaultValue, variable overwrite=defaultValue)
     export a profile from a profiles graph to the source data folder. More...
     export a profile from a profiles graph to the source data folder. More...
     
    static variable set_trace_colors (string graphname)
     
    variable ad_calc_histogram (wave image)
     calculate the histogram. More...
     calculate the histogram. More...
     
    variable ad_default_image_filter (wave image, string options)
     abstract filter function for image display. More...
     abstract filter function for image display. More...
     
    variable ad_box_filter (wave image, string options)
     boxcar smoothing filter. More...
     boxcar smoothing filter. More...
     
    variable ad_transpose_filter (wave image, string options)
     transpose image filter. More...
     transpose image filter. More...
     
    string ad_display_brick (wave data)
     open a new "gizmo" window with three-dimensional data. More...
     open a new "gizmo" window with three-dimensional data. More...
     
    variable ad_brick_slicer (wave data)
     open a slicer panel for 3D data. More...
     open a slicer panel for 3D data. More...
     
    string ad_display_slice (wave data)
     display three-dimensional data by 2D slice. More...
     display three-dimensional data by 2D slice. More...
     
    static variable update_slice_info ()
     update controls with data scale limits. More...
     update controls with data scale limits. More...
     
    variable ad_gizmo_set_plane (wave brick, variable dim, variable value)
     set the position of a slicing plane of a 3D brick in a Gizmo window. More...
     set the position of a slicing plane of a 3D brick in a Gizmo window. More...
     
    variable ad_profiles_set_slice (wave brick, variable dim, variable value)
     set the position of the slicing plane of a 3D brick in a profiles window. More...
     set the position of the slicing plane of a 3D brick in a profiles window. More...
     
    static variable slp_slice_position (WMSliderAction *sa)
     set slice coordinate (slider procedure). More...
     set slice coordinate (slider procedure). More...
     
    static variable svp_slice_position (WMSetVariableAction *sva)
     set slice coordinate (button procedure). More...
     set slice coordinate (button procedure). More...
     
    static variable bp_move_slice (WMButtonAction *ba)
     move slice (button procedure). More...
     move slice (button procedure). More...
     
    static variable bp_extract_slice (WMButtonAction *ba)
     export a slice (button procedure). More...
     export a slice (button procedure). More...
     
    static variable bp_move_slice_center (wave brick, variable dim, string posvariable)
     move the slice to the center of the dimension (button procedure). More...
     move the slice to the center of the dimension (button procedure). More...
     
    static variable ad_slicer_move_bg (WMBackgroundStruct *s)
     move a slice by one step (background task). More...
     move a slice by one step (background task). More...
     
    variable ad_slicer_init_bg ()
     initialize the slice animation background task. More...
     initialize the slice animation background task. More...
     
    variable ad_slicer_start_bg (wave brick, variable dimension, string posvariable, variable delta)
     start the animation. More...
     start the animation. More...
     
    variable ad_slicer_stop_bg (string posvariable)
     stop the animation. More...
     stop the animation. More...
     

    Detailed Description

    @@ -267,7 +270,7 @@ Functions
    Returns
    overlay overlay wave. same dimensions and scales as image, but unsigned binary. pixels that are 0 are overlaid with semi-transparent color. other pixels should be 64 (igor's mask convention).
    -

    Definition at line 329 of file pearl-area-display.ipf.

    +

    Definition at line 331 of file pearl-area-display.ipf.

    @@ -311,7 +314,7 @@ Functions -

    Definition at line 1103 of file pearl-area-display.ipf.

    +

    Definition at line 1105 of file pearl-area-display.ipf.

    @@ -340,7 +343,7 @@ Functions -

    Definition at line 1256 of file pearl-area-display.ipf.

    +

    Definition at line 1258 of file pearl-area-display.ipf.

    @@ -367,9 +370,9 @@ Functions -

    the function expects further objects as created by ad_display_profiles() in the same data folder as the image wave. the most recent profiles graph of the image must exist, and the cursors A and B must be set on the image.

    +

    the function expects further objects as created by ad_display_profiles() in the same data folder as the image wave. the most recent profiles graph of the image must exist, and the cursors A and B must be set on the image.

    -

    Definition at line 785 of file pearl-area-display.ipf.

    +

    Definition at line 787 of file pearl-area-display.ipf.

    @@ -392,12 +395,12 @@ Functions

    calculate the histogram.

    Parameters
    - +
    imagewave which contains the image data from the detector. the function expects further objects as created by ad_display_histogram() in the same data folder as the image wave.
    imagewave which contains the image data from the detector. the function expects further objects as created by ad_display_histogram() in the same data folder as the image wave.
    -

    Definition at line 1066 of file pearl-area-display.ipf.

    +

    Definition at line 1068 of file pearl-area-display.ipf.

    @@ -457,10 +460,10 @@ Functions -

    the function expects further objects as created by ad_display_profiles() in the same data folder as the image wave.

    +

    the function expects further objects as created by ad_display_profiles() in the same data folder as the image wave.

    this function does not require that the graph exists as long as the data folder is complete.

    -

    Definition at line 832 of file pearl-area-display.ipf.

    +

    Definition at line 834 of file pearl-area-display.ipf.

    @@ -501,7 +504,7 @@ Functions
    Returns
    the result must be written to the incoming image wave.
    -

    Definition at line 1089 of file pearl-area-display.ipf.

    +

    Definition at line 1091 of file pearl-area-display.ipf.

    @@ -531,7 +534,7 @@ Functions
    Returns
    (string) name of the graph window
    -

    Definition at line 85 of file pearl-area-display.ipf.

    +

    Definition at line 87 of file pearl-area-display.ipf.

    @@ -560,7 +563,7 @@ Functions
    Returns
    name of the gizmo window.
    -

    Definition at line 1141 of file pearl-area-display.ipf.

    +

    Definition at line 1143 of file pearl-area-display.ipf.

    @@ -581,7 +584,7 @@ Functions

    display the histogram of a 2D image.

    -

    the function will create additional objects in the same data folder as the image. this objects are displayed in the graph and are updated by calling ad_calc_profiles(). see the code.

    +

    the function will create additional objects in the same data folder as the image. this objects are displayed in the graph and are updated by calling ad_calc_profiles(). see the code.

    Parameters
    @@ -590,7 +593,7 @@ Functions
    Returns
    (string) name of the graph window
    -

    Definition at line 115 of file pearl-area-display.ipf.

    +

    Definition at line 117 of file pearl-area-display.ipf.

    @@ -621,17 +624,17 @@ Functions

    open a new profiles graph window.

    -

    opens an extended graph window with profiles for the specified image. the function copies/creates all necessary data structures in a subfolder of the one which contains the image wave. the data folder name is derived from the image wave name by prefixing with "view_". there can be at most one profiles window of each image wave. the original wave must not be renamed while the graph window is used. to update the graph after modifying the original wave, call ad_update_profiles().

    +

    opens an extended graph window with profiles for the specified image. the function copies/creates all necessary data structures in a subfolder of the one which contains the image wave. the data folder name is derived from the image wave name by prefixing with "view_". there can be at most one profiles window of each image wave. the original wave must not be renamed while the graph window is used. to update the graph after modifying the original wave, call ad_update_profiles().

    Parameters
    imagewave which contains the image data from the detector.
    - +
    imagewave which contains the image data.
    filtername of a filter function which maps the original data to the displayed data. the function must have the same parameters as ad_default_image_filter(). default: boxcar average (ad_box_filter()) using parameters view_filter_smoothing_x and _y.
    filtername of a filter function which maps the original data to the displayed data. the function must have the same parameters as ad_default_image_filter(). default: boxcar average (ad_box_filter()) using parameters view_filter_smoothing_x and _y.
    Returns
    name of the graph window
    -

    Definition at line 166 of file pearl-area-display.ipf.

    +

    Definition at line 168 of file pearl-area-display.ipf.

    @@ -652,7 +655,7 @@ Functions

    display three-dimensional data by 2D slice.

    -

    to select the slice data to display, call ad_profiles_set_slice(), or open a ad_brick_slicer() panel. do not modify the content of the created view_ data folder.

    +

    to select the slice data to display, call ad_profiles_set_slice(), or open a ad_brick_slicer() panel. do not modify the content of the created view_ data folder.

    Parameters
    @@ -661,7 +664,7 @@ Functions
    Returns
    name of the graph window.
    -

    Definition at line 1404 of file pearl-area-display.ipf.

    +

    Definition at line 1406 of file pearl-area-display.ipf.

    @@ -713,7 +716,7 @@ Functions

    this function does not require that the show exists as long as the view data folder is complete.

    Parameters
    datathree-dimensional wave.
    - + -

    Definition at line 934 of file pearl-area-display.ipf.

    +

    Definition at line 936 of file pearl-area-display.ipf.

    @@ -783,7 +786,7 @@ Functions
    Returns
    0 if successful, non-zero otherwise
    -

    Definition at line 1481 of file pearl-area-display.ipf.

    +

    Definition at line 1483 of file pearl-area-display.ipf.

    @@ -823,7 +826,7 @@ Functions -

    Definition at line 540 of file pearl-area-display.ipf.

    +

    Definition at line 542 of file pearl-area-display.ipf.

    @@ -868,7 +871,7 @@ Functions -

    Definition at line 427 of file pearl-area-display.ipf.

    +

    Definition at line 429 of file pearl-area-display.ipf.

    @@ -890,7 +893,7 @@ Functions

    hook function for user events in the profiles window.

    -

    Definition at line 745 of file pearl-area-display.ipf.

    +

    Definition at line 747 of file pearl-area-display.ipf.

    @@ -955,7 +958,7 @@ Functions -

    Definition at line 488 of file pearl-area-display.ipf.

    +

    Definition at line 490 of file pearl-area-display.ipf.

    @@ -1002,7 +1005,7 @@ Functions
    Returns
    0 if successful, non-zero otherwise
    -

    Definition at line 1517 of file pearl-area-display.ipf.

    +

    Definition at line 1519 of file pearl-area-display.ipf.

    @@ -1023,7 +1026,7 @@ Functions

    initialize the slice animation background task.

    -

    Definition at line 1776 of file pearl-area-display.ipf.

    +

    Definition at line 1778 of file pearl-area-display.ipf.

    @@ -1053,7 +1056,7 @@ Functions

    move a slice by one step (background task).

    -

    Definition at line 1737 of file pearl-area-display.ipf.

    +

    Definition at line 1739 of file pearl-area-display.ipf.

    @@ -1106,7 +1109,7 @@ Functions -

    Definition at line 1800 of file pearl-area-display.ipf.

    +

    Definition at line 1802 of file pearl-area-display.ipf.

    @@ -1134,7 +1137,7 @@ Functions -

    Definition at line 1842 of file pearl-area-display.ipf.

    +

    Definition at line 1844 of file pearl-area-display.ipf.

    @@ -1174,7 +1177,7 @@ Functions -

    Definition at line 1125 of file pearl-area-display.ipf.

    +

    Definition at line 1127 of file pearl-area-display.ipf.

    @@ -1197,12 +1200,12 @@ Functions

    update a profiles graph with new data.

    Parameters
    view_imagewave which contains the view image (image wave on display in profiles window). the function expects further objects as created by ad_display_profiles() in the same data folder as the view_image wave.
    view_imagewave which contains the view image (image wave on display in profiles window). the function expects further objects as created by ad_display_profiles() in the same data folder as the view_image wave.
    dimdimension index (0 = x, 1 = y).
    traceselect profile trace:
    • 0 = cursor A
    • @@ -736,7 +739,7 @@ Functions
    - +
    imagewave which contains the image data. must be the same (by data folder and name) wave used with ad_display_profiles().
    imagewave which contains the image data. must be the same (by data folder and name) wave used with ad_display_profiles().
    -

    Definition at line 375 of file pearl-area-display.ipf.

    +

    Definition at line 377 of file pearl-area-display.ipf.

    @@ -1233,7 +1236,7 @@ Functions

    export a slice (button procedure).

    extract a slice and saves it in a separate wave.

    -

    Definition at line 1671 of file pearl-area-display.ipf.

    +

    Definition at line 1673 of file pearl-area-display.ipf.

    @@ -1263,7 +1266,7 @@ Functions

    move slice (button procedure).

    -

    Definition at line 1622 of file pearl-area-display.ipf.

    +

    Definition at line 1624 of file pearl-area-display.ipf.

    @@ -1309,7 +1312,7 @@ Functions

    move the slice to the center of the dimension (button procedure).

    -

    Definition at line 1725 of file pearl-area-display.ipf.

    +

    Definition at line 1727 of file pearl-area-display.ipf.

    @@ -1337,7 +1340,7 @@ Functions
    -

    Definition at line 677 of file pearl-area-display.ipf.

    +

    Definition at line 679 of file pearl-area-display.ipf.

    @@ -1368,7 +1371,7 @@ Functions

    find the source image wave corresponding to the given view.

    Returns
    wave reference of the original data wave. the reference may be invalid if the source wave cannot be found.
    -

    Definition at line 606 of file pearl-area-display.ipf.

    +

    Definition at line 608 of file pearl-area-display.ipf.

    @@ -1400,12 +1403,12 @@ Functions

    the result data folder reference may be invalid if no view is currently open. use the built-in DataFolderRefStatus function to check for validity.

    Parameters
    - +
    sourcewave which contains the image data. must be the same (by data folder and name) wave used with ad_display_profiles().
    sourcewave which contains the image data. must be the same (by data folder and name) wave used with ad_display_profiles().
    -

    Definition at line 644 of file pearl-area-display.ipf.

    +

    Definition at line 646 of file pearl-area-display.ipf.

    @@ -1436,12 +1439,12 @@ Functions

    find the view image wave corresponding to the given source.

    Parameters
    - +
    sourcewave which contains the image data. must be the same (by data folder and name) wave used with ad_display_profiles().
    sourcewave which contains the image data. must be the same (by data folder and name) wave used with ad_display_profiles().
    -

    Definition at line 667 of file pearl-area-display.ipf.

    +

    Definition at line 669 of file pearl-area-display.ipf.

    @@ -1481,7 +1484,7 @@ Functions

    compose a valid and unique graph name from a data folder reference

    -

    Definition at line 57 of file pearl-area-display.ipf.

    +

    Definition at line 59 of file pearl-area-display.ipf.

    @@ -1511,7 +1514,7 @@ Functions

    create a view data folder.

    -

    Definition at line 620 of file pearl-area-display.ipf.

    +

    Definition at line 622 of file pearl-area-display.ipf.

    @@ -1539,7 +1542,7 @@ Functions
    -

    Definition at line 721 of file pearl-area-display.ipf.

    +

    Definition at line 723 of file pearl-area-display.ipf.

    @@ -1567,7 +1570,7 @@ Functions
    -

    Definition at line 1045 of file pearl-area-display.ipf.

    +

    Definition at line 1047 of file pearl-area-display.ipf.

    @@ -1597,7 +1600,7 @@ Functions

    set slice coordinate (slider procedure).

    -

    Definition at line 1558 of file pearl-area-display.ipf.

    +

    Definition at line 1560 of file pearl-area-display.ipf.

    @@ -1627,7 +1630,7 @@ Functions

    set slice coordinate (button procedure).

    -

    Definition at line 1590 of file pearl-area-display.ipf.

    +

    Definition at line 1592 of file pearl-area-display.ipf.

    @@ -1655,7 +1658,7 @@ Functions
    -

    Definition at line 696 of file pearl-area-display.ipf.

    +

    Definition at line 698 of file pearl-area-display.ipf.

    @@ -1685,7 +1688,7 @@ Functions

    update controls with data scale limits.

    current folder must be slicer info

    -

    Definition at line 1445 of file pearl-area-display.ipf.

    +

    Definition at line 1447 of file pearl-area-display.ipf.

    @@ -1695,9 +1698,9 @@ Functions diff --git a/doc/html/pearl-area-display_8ipf_source.html b/doc/html/pearl-area-display_8ipf_source.html index 692424d..92bf0d6 100644 --- a/doc/html/pearl-area-display_8ipf_source.html +++ b/doc/html/pearl-area-display_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-area-display.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,44 +87,1585 @@ $(document).ready(function(){initNavTree('pearl-area-display_8ipf_source.html','
    pearl-area-display.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.2
    3 #pragma ModuleName = PearlAreaDisplay
    4 #pragma version = 1.04
    5 #include "pearl-compat"
    6 
    20 // 3D data is handled by 3 windows. they don't have to be visible all at the same time.
    49 
    55 
    57 static function /s graphname_from_dfref(df, prefix)
    58  dfref df
    59  string prefix
    60 
    61  string name
    62 
    63  name = GetDataFolder(1, df)
    64  name = ReplaceString("root:", name, "")
    65  name = name[0, strlen(name) - 2]
    66  name = ReplaceString(" ", name, "")
    67  name = PearlCleanupName(prefix + name)
    68  if (CheckName(name, 6))
    69  name = UniqueName(name, 6, 0)
    70  endif
    71 
    72  return name
    73 end
    74 
    85 function /s ad_display(image)
    86  wave image // wave which contains the image data from the detector
    87  // returns the name of the graph window
    88 
    89  dfref savedf = GetDataFolderDFR()
    90  dfref imagedf = GetWavesDataFolderDFR(image)
    91  setdatafolder imagedf
    92 
    93  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
    94  string graphtitle = dfname + " View"
    95  string /g view_graphname = graphname_from_dfref(imagedf, "view_")
    96  svar graphname = view_graphname
    97  display /k=1/n=$graphname as graphtitle
    98  graphname = s_name
    99  appendimage /w=$graphname image
    100 
    101  setdatafolder savedf
    102  return graphname
    103 end
    104 
    115 function /s ad_display_histogram(image)
    116  wave image
    117 
    118  dfref savedf = GetDataFolderDFR()
    119  dfref imagedf = GetWavesDataFolderDFR(image)
    120  string s_imagedf = GetDataFolder(1, imagedf)
    121  setdatafolder imagedf
    122 
    123  make /n=(1)/o hist // histogram
    124 
    125  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
    126  string graphtitle = dfname + " Histogram"
    127  string /g hist_graphname = graphname_from_dfref(imagedf, "hist_")
    128  svar graphname = hist_graphname
    129  display /k=1/n=$graphname as graphtitle
    130  graphname = s_name
    131  appendtograph /w=$graphname hist
    132 
    133  ModifyGraph /w=$graphname rgb(hist)=(39168,0,0)
    134  ModifyGraph /w=$graphname mode=6
    135  ModifyGraph /w=$graphname mirror=1
    136  ModifyGraph /w=$graphname minor=1
    137  ModifyGraph /w=$graphname axThick=0.5
    138  ModifyGraph /w=$graphname lblPosMode=1,lblPos=30,lblMargin=0
    139  ModifyGraph /w=$graphname btLen=4
    140  ModifyGraph /w=$graphname margin(left)=45,margin(bottom)=35,margin(top)=10,margin(right)=10
    141  ModifyGraph /w=$graphname gfSize=10
    142  Label /w=$graphname bottom "value"
    143  Label /w=$graphname left "# pixels"
    144 
    145  ad_calc_histogram(image)
    146 
    147  setdatafolder savedf
    148  return graphname
    149 end
    150 
    166 function /s ad_display_profiles(image, [filter])
    167  wave image
    168  string filter
    169  variable show_legend = 0 // currently not supported
    170 
    171  if (WaveDims(image) != 2)
    172  abort "ad_display_profiles: image wave must be two-dimensional."
    173  endif
    174  if (ParamIsDefault(filter))
    175  filter = "ad_box_filter"
    176  endif
    177 
    178  // data folders and references
    179  dfref savedf = GetDataFolderDFR()
    180  dfref imagedf = GetWavesDataFolderDFR(image)
    181  string s_imagedf = GetDataFolder(1, imagedf)
    182  setdatafolder imagedf
    183  string s_viewdf = PearlCleanupName("view_" + NameOfWave(image))
    184  newdatafolder /o/s $s_viewdf
    185  dfref viewdf = GetDataFolderDFR()
    186  s_viewdf = GetDataFolder(1, viewdf)
    187 
    188  // data structures
    189  string /g sourcepath = GetWavesDataFolder(image, 2)
    190  string viewname = "view_image"
    191  duplicate /o image, $viewname /wave=view
    192  make /n=(3,3)/o xprofiles // NX x 3 wave with 3 one-dimensional profiles along Y dimension
    193  make /n=(3,3)/o yprofiles // NY x 3 wave with 3 one-dimensional profiles along X dimension
    194  string /g view_filter
    195  string /g view_filter_options
    196  view_filter = filter
    197  view_filter_options = ""
    198  variable /g view_filter_smoothing_x = 1
    199  variable /g view_filter_smoothing_y = 1
    200  variable /g view_cursor_mode = 0
    201  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
    202  string graphtitle = dfname + NameOfWave(image) + " Profiles"
    203  string /g prof_graphname = graphname_from_dfref(imagedf, "prof_")
    204  svar graphname = prof_graphname
    205  variable /g graph_avg // average value in ROI (ROI is defined by the crosshairs A and B)
    206  variable /g graph_min // minimum value in ROI
    207  variable /g graph_max // maximum value in ROI
    208  variable /g graph_sum // sum of all values in ROI
    209  variable /g graph_sdev // standard deviation of all values in ROI
    210 
    211  // graph setup
    212  display /k=1 /n=$graphname /w=(100,100,500,400) as graphtitle
    213  graphname = s_name
    214  AppendToGraph /w=$graphname /L=xprofiles xprofiles[*][0],xprofiles[*][1],xprofiles[*][2]
    215  AppendToGraph /w=$graphname /VERT/B=yprofiles yprofiles[*][0],yprofiles[*][1],yprofiles[*][2]
    216  AppendImage /w=$graphname view
    217  string imgname = StringFromList(0, ImageNameList(graphname, ";"))
    218  ModifyImage /w=$graphname $imgname ctab= {*,*,BlueGreenOrange,0}
    219  ModifyGraph /w=$graphname rgb(xprofiles)=(39168,0,0),rgb(yprofiles)=(39168,0,0)
    220  ModifyGraph /w=$graphname rgb(xprofiles#1)=(0,26112,0),rgb(yprofiles#1)=(0,26112,0)
    221  ModifyGraph /w=$graphname rgb(xprofiles#2)=(0,9472,39168),rgb(yprofiles#2)=(0,9472,39168)
    222  ModifyGraph /w=$graphname mirror(xprofiles)=2,mirror(bottom)=3,mirror(yprofiles)=2,mirror(left)=3
    223  ModifyGraph /w=$graphname nticks=3
    224  ModifyGraph /w=$graphname minor=1
    225  ModifyGraph /w=$graphname axThick=0.5
    226  ModifyGraph /w=$graphname lblPosMode=1,lblPos=30,lblMargin=0
    227  ModifyGraph /w=$graphname btLen=4
    228  ModifyGraph /w=$graphname freePos(xprofiles)=0
    229  ModifyGraph /w=$graphname freePos(yprofiles)=0
    230  ModifyGraph /w=$graphname axisEnab(xprofiles)={0.64,1}
    231  ModifyGraph /w=$graphname axisEnab(bottom)={0,0.6}
    232  ModifyGraph /w=$graphname axisEnab(yprofiles)={0.64,1}
    233  ModifyGraph /w=$graphname axisEnab(left)={0,0.6}
    234  ModifyGraph /w=$graphname zero(left)=8
    235  ModifyGraph /w=$graphname margin(left)=40,margin(bottom)=30,margin(top)=20,margin(right)=40
    236  ModifyGraph /w=$graphname gfSize=10
    237 
    238  // axis labels
    239  string labels = note(image)
    240  string lab
    241  lab = StringByKey("AxisLabelX", labels, "=", "\r")
    242  if (!strlen(lab))
    243  lab = "X"
    244  endif
    245  Label /w=$graphname bottom lab + " (\\U)"
    246  lab = StringByKey("AxisLabelY", labels, "=", "\r")
    247  if (!strlen(lab))
    248  lab = "Y"
    249  endif
    250  Label /w=$graphname left lab + " (\\U)"
    251  lab = StringByKey("AxisLabelD", labels, "=", "\r")
    252  if (!strlen(lab))
    253  lab = "value"
    254  endif
    255  Label /w=$graphname xprofiles lab + " (\\U)"
    256  Label /w=$graphname yprofiles lab + " (\\U)"
    257 
    258  // legend
    259  if (show_legend)
    260  Legend /w=$graphname/C/N=text0/J/F=2/D=0.5/T={28}/A=RT/X=0.00/Y=0.00 "\\s(xprofiles)\tprofile A"
    261  AppendText /w=$graphname "\\s(xprofiles#1)\tprofile B"
    262  AppendText /w=$graphname "\\s(xprofiles#2)\tROI average"
    263  AppendText /w=$graphname "min\t\\{" + s_viewdf + "graph_min}"
    264  AppendText /w=$graphname "max\t\\{" + s_viewdf + "graph_max}"
    265  AppendText /w=$graphname "sum\t\\{" + s_viewdf + "graph_sum}"
    266  AppendText /w=$graphname "avg\t\\{" + s_viewdf + "graph_avg}"
    267  AppendText /w=$graphname "sdev\t\\{" + s_viewdf + "graph_sdev}"
    268  else
    269  TextBox /w=$graphname /C/N=text0 /F=0 /B=1 /X=1.00 /Y=1.00
    270  lab = StringByKey("Dataset", labels, "=", "\r")
    271  if (strlen(lab))
    272  AppendText /w=$graphname lab
    273  endif
    274  AppendText /w=$graphname "sum\t\\{" + s_viewdf + "graph_sum}"
    275  AppendText /w=$graphname "avg\t\\{" + s_viewdf + "graph_avg}"
    276  AppendText /w=$graphname "sdev\t\\{" + s_viewdf + "graph_sdev}"
    277  endif
    278 
    279  // interactive elements
    280  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 A $imgname 0,0
    281  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 B $imgname DimSize(view, 0)-1, DimSize(view, 1)-1
    282  variable pcurs
    283  pcurs = floor(DimSize(xprofiles, 0) / 3)
    284  Cursor /w=$graphname /A=0 /P /S=1 /H=0 C xprofiles#2 pcurs
    285  pcurs = floor(DimSize(xprofiles, 0) * 2 / 3)
    286  Cursor /w=$graphname /A=0 /P /S=1 /H=0 D xprofiles#2 pcurs
    287  pcurs = floor(DimSize(yprofiles, 0) / 3)
    288  Cursor /w=$graphname /A=0 /P /S=1 /H=0 E yprofiles#2 pcurs
    289  pcurs = floor(DimSize(yprofiles, 0) * 2 / 3)
    290  Cursor /w=$graphname /A=0 /P /S=1 /H=0 F yprofiles#2 pcurs
    291  ShowInfo /w=$graphname /CP=0
    292 
    293  SetWindow $graphname, hook(ad_profiles_hook)=ad_profiles_hook
    294  ControlBar /w=$graphname 21
    295  Button b_reset_cursors win=$graphname, title="reset cursors",pos={0,0},size={70,20},proc=PearlAreaDisplay#bp_reset_cursors
    296  Button b_reset_cursors win=$graphname, fColor=(65535,65535,65535),fSize=10
    297 
    298  SetVariable sv_smoothing_x win=$graphname, title="X smoothing",pos={130,2},bodyWidth=40
    299  SetVariable sv_smoothing_x win=$graphname, value=view_filter_smoothing_x,limits={1,100,1}
    300  SetVariable sv_smoothing_x win=$graphname, proc=PearlAreaDisplay#svp_smoothing
    301  SetVariable sv_smooting_y win=$graphname, title="Y smoothing",pos={240,2},bodyWidth=40
    302  SetVariable sv_smooting_y win=$graphname, value=view_filter_smoothing_y,limits={1,100,1}
    303  SetVariable sv_smooting_y win=$graphname, proc=PearlAreaDisplay#svp_smoothing
    304 
    305  PopupMenu pm_export win=$graphname, mode=0,title="Export"
    306  PopupMenu pm_export win=$graphname, value="X profile;Y profile;X profile (collate);Y profile (collate)"
    307  PopupMenu pm_export win=$graphname, pos={308,0},bodyWidth=60,proc=PearlAreaDisplay#pmp_export
    308  PopupMenu pm_export win=$graphname, help={"Export profile of selected area and display in graph. Collate mode = display all profiles in same graph."}
    309 
    310  // data processing
    311  ad_update_profiles(image)
    312 
    313  setdatafolder savedf
    314  return graphname
    315 end
    316 
    329 function /wave ad_add_overlay(image, [rgba])
    330  wave image
    331  string rgba
    332 
    333  if (ParamIsDefault(rgba))
    334  rgba = "65535,65532,16385,32767"
    335  elseif (ItemsInList(rgba, ",") == 3)
    336  rgba += ",32767"
    337  endif
    338 
    339  dfref savedf = GetDataFolderDFR()
    340  wave view_image = get_view_image(image)
    341  dfref viewdf = GetWavesDataFolderDFR(view_image)
    342  svar /sdfr=viewdf graphname = prof_graphname
    343  setdatafolder viewdf
    344 
    345  string overlayname = "view_overlay"
    346  duplicate /o image, $overlayname /wave=overlay
    347  redimension /b/u overlay
    348  overlay = 64
    349 
    350  string imagenames = ImageNameList(graphname, ";")
    351  if (whichlistItem(overlayname, imagenames, ";") < 0)
    352  AppendImage /w=$graphname $overlayname
    353  rgba = replacestring("(", rgba, "")
    354  rgba = replacestring(")", rgba, "")
    355  variable rr = str2num(StringFromList(0, rgba, ","))
    356  variable gg = str2num(StringFromList(1, rgba, ","))
    357  variable bb = str2num(StringFromList(2, rgba, ","))
    358  variable aa = str2num(StringFromList(3, rgba, ","))
    359 #if IgorVersion() >= 8
    360  ModifyImage /w=$graphname $overlayname explicit=1,eval={0,rr,gg,bb,aa},eval={255,-1,-1,-1}
    361 #else
    362  ModifyImage /w=$graphname $overlayname explicit=1,eval={0,rr,gg,bb},eval={255,-1,-1,-1}
    363 #endif
    364  endif
    365 
    366  setdatafolder savedf
    367  return overlay
    368 end
    369 
    375 function ad_update_profiles(image)
    376  wave image
    377 
    378  // data folders and references
    379  dfref viewdf = get_view_folder(image)
    380  if (DataFolderRefStatus(viewdf) == 0)
    381  return -1 // data folder not found
    382  endif
    383  dfref savedf = GetDataFolderDFR()
    384  setdatafolder viewdf
    385 
    386  // data structures
    387  string viewname = "view_image"
    388  duplicate /o image, $viewname /wave=view
    389  string overlayname = "view_overlay"
    390  wave /z overlay = $overlayname
    391  if (waveexists(overlay))
    392  redimension /n=(dimsize(view,0), dimsize(view,1)) overlay
    393  endif
    394 
    395  // data processing
    396  svar view_filter
    397  svar view_filter_options
    398  nvar smoothing_x = view_filter_smoothing_x
    399  nvar smoothing_y = view_filter_smoothing_y
    400  funcref ad_default_image_filter filterfunc = $view_filter
    401  view_filter_options = ReplaceNumberByKey("SmoothingX", view_filter_options, smoothing_x, "=", ";")
    402  view_filter_options = ReplaceNumberByKey("SmoothingY", view_filter_options, smoothing_y, "=", ";")
    403  filterfunc(view, view_filter_options)
    404 
    406 
    407  setdatafolder savedf
    408  return 0
    409 end
    410 
    427 function ad_profiles_cursor_mode(image, mode)
    428  wave image
    429  variable mode
    430 
    431  dfref savedf = GetDataFolderDFR()
    432  wave view_image = get_view_image(image)
    433  dfref viewdf = GetWavesDataFolderDFR(view_image)
    434  svar /sdfr=viewdf graphname = prof_graphname
    435  nvar /sdfr=viewdf cursor_mode = view_cursor_mode
    436  wave /sdfr=viewdf xprofiles, yprofiles
    437 
    438  variable dx = DimSize(view_image, 0)
    439  variable dy = DimSize(view_image, 1)
    440  switch(mode)
    441  case 1: // background selection
    442  Cursor /w=$graphname /A=0 /P /I /S=2 /H=1 /L=1 A view_image 0, 0
    443  Cursor /w=$graphname /A=0 /P /I /S=2 /H=1 /L=1 B view_image dx-1, dy-1
    444  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 C view_image round(0.2 * dx) -1, 0
    445  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 D view_image round(0.8 * dx) -1, 0
    446  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 E view_image round(0.4 * dx) -1, 0
    447  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 F view_image round(0.6 * dx) -1, 0
    448 
    449  ShowInfo /w=$graphname /CP=0
    450  cursor_mode = mode
    451  break
    452  default:
    453  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 A view_image 0,0
    454  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 B view_image dx-1, dy-1
    455  variable pcurs
    456  pcurs = floor(DimSize(xprofiles, 0) / 3)
    457  Cursor /w=$graphname /A=0 /P /S=1 /H=0 C xprofiles#2 pcurs
    458  pcurs = floor(DimSize(xprofiles, 0) * 2 / 3)
    459  Cursor /w=$graphname /A=0 /P /S=1 /H=0 D xprofiles#2 pcurs
    460  pcurs = floor(DimSize(yprofiles, 0) / 3)
    461  Cursor /w=$graphname /A=0 /P /S=1 /H=0 E yprofiles#2 pcurs
    462  pcurs = floor(DimSize(yprofiles, 0) * 2 / 3)
    463  Cursor /w=$graphname /A=0 /P /S=1 /H=0 F yprofiles#2 pcurs
    464  ShowInfo /w=$graphname /CP=0
    465  cursor_mode = 0
    466  endswitch
    467 
    468  setdatafolder savedf
    469  return 0
    470 end
    471 
    488 function ad_profiles_set_cursor(image, cursorname, xa, ya, [pscale])
    489  wave image
    490  string cursorname
    491  variable xa, ya
    492  variable pscale
    493 
    494  if (ParamIsDefault(pscale))
    495  pscale = 0
    496  endif
    497 
    498  // data folders and references
    499  dfref savedf = GetDataFolderDFR()
    500  wave view_image = get_view_image(image)
    501  dfref viewdf = GetWavesDataFolderDFR(view_image)
    502  svar /sdfr=viewdf graphname = prof_graphname
    503 
    504  variable pa, qa
    505  if (pscale)
    506  pa = xa
    507  qa = ya
    508  else
    509  pa = round((xa - DimOffset(view_image, 0)) / DimDelta(view_image, 0))
    510  qa = round((ya - DimOffset(view_image, 1)) / DimDelta(view_image, 1))
    511  endif
    512 
    513  pa = min(pa, DimSize(view_image, 0) - 1)
    514  pa = max(pa, 0)
    515  qa = min(qa, DimSize(view_image, 1) - 1)
    516  qa = max(qa, 0)
    517  Cursor /i /p /w=$graphname $cursorname view_image pa, qa
    518 
    519  setdatafolder savedf
    520  return 0
    521 End
    522 
    533 // the lines can be removed manually using the draw toolbox, or by calling this function with @c clean=1.
    540 function ad_profiles_crosshairs(image, [clear])
    541  wave image
    542  variable clear
    543 
    544  if (ParamIsDefault(clear))
    545  clear = 0
    546  endif
    547 
    548  // data folders and references
    549  wave view_image = get_view_image(image)
    550  dfref viewdf = GetWavesDataFolderDFR(view_image)
    551  svar /sdfr=viewdf graphname = prof_graphname
    552 
    553  string cursors = "A;B"
    554  string colors = "39168,0,0;0,26112,0"
    555  string color
    556  variable ncursors
    557  variable icursor
    558  string cursorname
    559  string groupname = "crosshairs"
    560  variable xx, yy
    561  struct RGBColor rgb
    562 
    563  if (clear == 0)
    564  SetDrawEnv /W=$graphname push
    565  DrawAction /w=$graphname getgroup=$groupname, delete, begininsert
    566  SetDrawEnv /w=$graphname gstart, gname=$groupname
    567 
    568  SetDrawEnv /W=$graphname dash=4
    569  SetDrawEnv /W=$graphname linethick=0.5
    570 
    571  ncursors = ItemsInList(cursors, ";")
    572  for (icursor=0; icursor < ncursors; icursor += 1)
    573  cursorname = StringFromList(icursor, cursors, ";")
    574  color = StringFromList(icursor, colors, ";")
    575  rgb.red = str2num(StringFromList(0, color, ","))
    576  rgb.green = str2num(StringFromList(1, color, ","))
    577  rgb.blue = str2num(StringFromList(2, color, ","))
    578  if (strlen(CsrInfo($cursorname, graphname)) > 0)
    579  xx = hcsr($cursorname, graphname)
    580  yy = vcsr($cursorname, graphname)
    581  SetDrawEnv /W=$graphname linefgc=(rgb.red, rgb.green, rgb.blue)
    582  SetDrawEnv /W=$graphname save
    583  SetDrawEnv /W=$graphname xcoord=bottom, ycoord=prel
    584  DrawLine /W=$graphname xx, 0, xx, 1
    585  SetDrawEnv /W=$graphname xcoord=prel, ycoord=left
    586  DrawLine /W=$graphname 0, yy, 1, yy
    587  endif
    588  endfor
    589 
    590  SetDrawEnv /w=$graphname gstop
    591  DrawAction /w=$graphname endinsert
    592  SetDrawEnv /W=$graphname pop
    593  SetDrawEnv /W=$graphname save
    594  else
    595  DrawAction /w=$graphname getgroup=$groupname, delete
    596  endif
    597 
    598  return 0
    599 end
    600 
    606 static function /wave get_source_image(view)
    607  wave view // image wave displayed in a profiles window
    608 
    609  dfref viewdf = GetWavesDataFolderDFR(view)
    610  svar /z /sdfr=viewdf sourcepath
    611  if (svar_exists(sourcepath))
    612  wave /z img = $sourcepath
    613  else
    614  wave /z img = $""
    615  endif
    616  return img
    617 end
    618 
    620 static function /df make_view_folder(source)
    621  wave source // wave which contains the raw data from the detector.
    622 
    623  // data folders and references
    624  dfref savedf = GetDataFolderDFR()
    625  dfref imagedf = GetWavesDataFolderDFR(source)
    626  string s_imagedf = GetDataFolder(1, imagedf)
    627  setdatafolder imagedf
    628  string s_viewdf = PearlCleanupName("view_" + NameOfWave(source))
    629  newdatafolder /o/s $s_viewdf
    630  dfref viewdf = GetDataFolderDFR()
    631 
    632  setdatafolder savedf
    633  return viewdf
    634 end
    635 
    644 static function /df get_view_folder(source)
    645  wave source
    646 
    647  // data folders and references
    648  dfref savedf = GetDataFolderDFR()
    649  dfref imagedf = GetWavesDataFolderDFR(source)
    650  dfref viewdf
    651  setdatafolder imagedf
    652  string s_viewdf = PearlCleanupName("view_" + NameOfWave(source))
    653  if (DataFolderExists(s_viewdf))
    654  setdatafolder $s_viewdf
    655  viewdf = GetDataFolderDFR()
    656  endif
    657 
    658  setdatafolder savedf
    659  return viewdf
    660 end
    661 
    667 static function /wave get_view_image(source)
    668  wave source
    669 
    670  dfref viewdf = get_view_folder(source)
    671  string viewname = "view_image"
    672  wave /sdfr=viewdf view = $viewname
    673 
    674  return view
    675 end
    676 
    677 static function bp_reset_cursors(ba) : ButtonControl
    678  STRUCT WMButtonAction &ba
    679 
    680  switch( ba.eventCode )
    681  case 2: // mouse up
    682  string imgname = StringFromList(0, ImageNameList(ba.win, ";"))
    683  wave /z image = ImageNameToWaveRef(ba.win, imgname)
    684  if (waveexists(image))
    685  Cursor /i/p A $imgname 0,0
    686  Cursor /i/p B $imgname DimSize(image, 0)-1, DimSize(image, 1)-1
    687  endif
    688  break
    689  case -1: // control being killed
    690  break
    691  endswitch
    692 
    693  return 0
    694 End
    695 
    696 static function svp_smoothing(sva) : SetVariableControl
    697  STRUCT WMSetVariableAction &sva
    698 
    699  string imglist
    700 
    701  switch( sva.eventCode )
    702  case 1: // mouse up
    703  case 2: // Enter key
    704  case 3: // Live update
    705  imglist = ImageNameList(sva.win, ";")
    706  wave /z img = ImageNameToWaveRef(sva.win, StringFromList(0, imglist))
    707  if (WaveExists(img))
    708  wave source = get_source_image(img)
    709  if (WaveExists(source))
    710  ad_update_profiles(source)
    711  endif
    712  endif
    713  break
    714  case -1: // control being killed
    715  break
    716  endswitch
    717 
    718  return 0
    719 end
    720 
    721 static function pmp_export(pa) : PopupMenuControl
    722  STRUCT WMPopupAction &pa
    723 
    724  switch( pa.eventCode )
    725  case 2: // mouse up
    726  variable popNum = pa.popNum
    727 
    728  string imgname = StringFromList(0, ImageNameList(pa.win, ";"))
    729  wave /z image = ImageNameToWaveRef(pa.win, imgname)
    730  if (waveexists(image) && (popNum >= 1) && (popNum <= 2))
    731  ad_export_profile(image, popNum - 1, show=1)
    732  elseif (waveexists(image) && (popNum >= 3) && (popNum <= 4))
    733  ad_export_profile(image, popNum - 3, show=2)
    734  endif
    735 
    736  break
    737  case -1: // control being killed
    738  break
    739  endswitch
    740 
    741  return 0
    742 End
    743 
    745 function ad_profiles_hook(s)
    746  struct WMWinHookStruct &s
    747  variable hookresult = 0
    748  string imglist
    749  string cmd
    750  dfref viewdf
    751 
    752  switch(s.eventCode)
    753  case 2: // delete data folder after window is killed
    754  imglist = ImageNameList(s.winName, ";")
    755  wave /z img = ImageNameToWaveRef(s.winName, StringFromList(0, imglist))
    756  if (WaveExists(img))
    757  viewdf = GetWavesDataFolderDFR(img)
    758  cmd = "killdatafolder /z " + GetDataFolder(1, viewdf)
    759  Execute /P/Q/Z cmd
    760  endif
    761  break
    762  case 7: // update profiles when cursor is moved
    763  imglist = ImageNameList(s.winName, ";")
    764  wave /z img = ImageNameToWaveRef(s.winName, StringFromList(0, imglist))
    765  if (WaveExists(img))
    767  hookresult = 1
    768  else
    769  hookresult = 0
    770  endif
    771  break
    772  endswitch
    773 
    774  return hookresult
    775 end
    776 
    785 function ad_calc_cursor_profiles(image)
    786  wave image
    787 
    788  dfref savedf = GetDataFolderDFR()
    789  dfref imagedf = GetWavesDataFolderDFR(image)
    790  setdatafolder imagedf
    791 
    792  svar graphname = prof_graphname
    793 
    794  variable pa, qa // point coordinates cursor A
    795  if (strlen(CsrInfo(A, graphname)) > 0)
    796  pa = pcsr(A, graphname)
    797  qa = qcsr(A, graphname)
    798  else
    799  pa = 0
    800  qa = 0
    801  endif
    802 
    803  variable pb, qb // point coordinates cursor B
    804  if (strlen(CsrInfo(B, graphname)) > 0)
    805  pb = pcsr(B, graphname)
    806  qb = qcsr(B, graphname)
    807  else
    808  pb = DimSize(image, 0) - 1
    809  qb = DimSize(image, 1) - 1
    810  endif
    811 
    812  ad_calc_profiles(image, pa, qa, pb, qb)
    813  setdatafolder savedf
    814 end
    815 
    832 function ad_calc_profiles(image, pa, qa, pb, qb)
    833  wave image
    834  variable pa, qa
    835  variable pb, qb
    836 
    837  dfref savedf = GetDataFolderDFR()
    838  dfref imagedf = GetWavesDataFolderDFR(image)
    839  setdatafolder imagedf
    840 
    841  wave xprofiles
    842  wave yprofiles
    843  nvar graph_avg
    844  nvar graph_min
    845  nvar graph_max
    846  nvar graph_sum
    847  nvar graph_sdev
    848 
    849  // horizontal profiles at crosshairs
    850  redimension /n=(dimsize(image,0), 3) xprofiles
    851  setscale /p x dimoffset(image,0), dimdelta(image,0), WaveUnits(image,0), xprofiles
    852  setscale d 0, 0, waveunits(image,-1), xprofiles
    853  xprofiles[][0] = image[p][qa]
    854  xprofiles[][1] = image[p][qb]
    855 
    856  note /k xprofiles
    857  note xprofiles, "SourceWave=" + nameofwave(image)
    858  note xprofiles, "SourceDimension=0"
    859  note xprofiles, "SourceIndex0=" + num2str(qa)
    860  note xprofiles, "SourceIndex1=" + num2str(qb)
    861 
    862  // average horizontal profile between crosshairs
    863  variable qq, q0, q1
    864  q0 = min(qa, qb)
    865  q1 = max(qa, qb)
    866  xprofiles[][2] = 0
    867  for (qq = q0; qq <= q1; qq += 1)
    868  xprofiles[][2] += image[p][qq]
    869  endfor
    870  xprofiles[][2] /= q1 - q0 + 1
    871 
    872  // vertical profiles at crosshairs
    873  redimension /n=(dimsize(image,1), 3) yprofiles
    874  setscale /p x dimoffset(image,1), dimdelta(image,1), WaveUnits(image,1), yprofiles
    875  setscale d 0, 0, waveunits(image,-1), yprofiles
    876  yprofiles[][0] = image[pa][p]
    877  yprofiles[][1] = image[pb][p]
    878 
    879  note /k yprofiles
    880  note yprofiles, "SourceWave=" + nameofwave(image)
    881  note yprofiles, "SourceDimension=1"
    882  note yprofiles, "SourceIndex0=" + num2str(pa)
    883  note yprofiles, "SourceIndex1=" + num2str(pb)
    884 
    885  // average vertical profile between crosshairs
    886  variable pp, p0, p1
    887  p0 = min(pa, pb)
    888  p1 = max(pa, pb)
    889  yprofiles[][2] = 0
    890  for (pp = p0; pp <= p1; pp += 1)
    891  yprofiles[][2] += image[pp][p]
    892  endfor
    893  yprofiles[][2] /= p1 - p0 + 1
    894 
    895  // statistics between crosshairs
    896  Duplicate /r=[p0,p1][q0,q1]/o image, roi_image
    897  WaveStats /Q roi_image
    898  graph_avg = v_avg
    899  graph_min = v_min
    900  graph_max = v_max
    901  graph_sum = v_avg * v_npnts
    902  graph_sdev = v_sdev
    903 
    904  // histogram
    905  wave /z hist
    906  if (waveexists(hist))
    907  Histogram /B=3 roi_image, hist
    908  endif
    909 
    910  setdatafolder savedf
    911 end
    912 
    934 function ad_export_profile(view_image, dim, [trace, show, overwrite])
    935  wave view_image
    936  variable dim
    937  variable trace
    938  variable show
    939  variable overwrite
    940 
    941  dfref savedf = GetDataFolderDFR()
    942 
    943  if (ParamIsDefault(trace))
    944  trace = 2
    945  endif
    946  if (ParamIsDefault(show))
    947  show = 0
    948  endif
    949  if (ParamIsDefault(overwrite))
    950  overwrite = 0
    951  endif
    952 
    953  // view folder
    954  dfref imagedf = GetWavesDataFolderDFR(view_image)
    955  string dim_label
    956  switch(dim)
    957  case 0:
    958  wave /sdfr=imagedf profiles=xprofiles
    959  dim_label = "x"
    960  break
    961  case 1:
    962  wave /sdfr=imagedf profiles=yprofiles
    963  dim_label = "y"
    964  break
    965  default:
    966  return -1 // invalid argument
    967  endswitch
    968  string graphname_string = "export_graph_" + dim_label
    969  svar /z /sdfr=imagedf linked_graphname = $graphname_string
    970 
    971  // source folder
    972  wave /z source_image = get_source_image(view_image)
    973  if (WaveExists(source_image))
    974  dfref sourcedf = GetWavesDataFolderDFR(source_image)
    975  setdatafolder sourcedf
    976  else
    977  return -2 // invalid source data folder
    978  endif
    979 
    980  // format dest wave name
    981  string profile_note = note(profiles)
    982  string name_base
    983  string name_dim
    984  string name_index
    985  string profile_name
    986  variable index_width = ceil(log(DimSize(view_image, 1 - dim)))
    987  variable index0 = NumberByKey("SourceIndex0", profile_note, "=", "\r")
    988  variable index1 = NumberByKey("SourceIndex1", profile_note, "=", "\r")
    989  name_dim = "_" + dim_label
    990  sprintf name_index, "%0*u_%0*u", index_width, index0, index_width, index1
    991  name_base = NameOfWave(source_image)
    992  name_base = name_base[0, min(strlen(name_base), 31 - strlen(name_index) - strlen(name_dim) - 1)]
    993  profile_name = name_base + name_dim + name_index
    994  if ((overwrite == 0) && (CheckName(profile_name, 1)))
    995  profile_name = UniqueName(profile_name + "_", 1, 0)
    996  endif
    997 
    998  // create dest wave
    999  duplicate /o /r=[][trace] profiles, $profile_name /wave=dest_profile
    1000  redimension /n=(dimsize(profiles, 0)) dest_profile
    1001  profile_note = ReplaceStringByKey("SourceWave", profile_note, NameOfWave(source_image), "=", "\r")
    1002  note /k dest_profile
    1003  note dest_profile, profile_note
    1004  print "created", GetWavesDataFolder(dest_profile, 2)
    1005 
    1006  if (show)
    1007  string graphname
    1008  string graphtitle
    1009  if (show == 2)
    1010  // common graph for all profiles of a dimension
    1011  graphname = "export_profiles_" + dim_label
    1012  graphtitle = UpperStr(dim_label) + " Profiles"
    1013  else
    1014  // one graph per source image
    1015  if (svar_exists(linked_graphname) && (ItemsInList(WinList(linked_graphname, ";", "WIN:1"), ";") >= 1))
    1016  graphname = linked_graphname
    1017  else
    1018  graphname = GetWavesDataFolder(source_image, 0) + name_dim
    1019  endif
    1020  graphtitle = UpperStr(dim_label) + " Profiles: " + GetWavesDataFolder(source_image, 2)
    1021  endif
    1022 
    1023  if ((ItemsInList(WinList(graphname, ";", "WIN:1"), ";") >= 1))
    1024  appendtograph /w=$graphname dest_profile
    1025  else
    1026  setdatafolder imagedf
    1027  display /k=1 /n=$graphname dest_profile as graphtitle
    1028  graphname = s_name
    1029  ModifyGraph /w=$graphname mirror=1,nticks=3,minor=1
    1030  ModifyGraph /w=$graphname axThick=0.5,btLen=4
    1031  ModifyGraph /w=$graphname gfSize=10
    1032  ModifyGraph /w=$graphname grid=2,gridHair=0,gridRGB=(52224,52224,52224)
    1033  Legend /w=$graphname /C/N=legend0/F=0/B=1/A=LT/X=0.00/Y=0.00
    1034 
    1035  if (show != 2)
    1036  string /g $graphname_string = graphname
    1037  endif
    1038  endif
    1039  endif
    1040 
    1041  setdatafolder savedf
    1042  return 0
    1043 end
    1044 
    1045 static function set_trace_colors(graphname)
    1046  string graphname
    1047 
    1048  ModifyGraph /w=$graphname /z rgb[0]=(0, 0, 0)
    1049  ModifyGraph /w=$graphname /z rgb[1]=(65535, 16385, 16385)
    1050  ModifyGraph /w=$graphname /z rgb[2]=(2, 39321, 1)
    1051  ModifyGraph /w=$graphname /z rgb[3]=(0, 0, 65535)
    1052  ModifyGraph /w=$graphname /z rgb[4]=(39321, 1, 31457)
    1053  ModifyGraph /w=$graphname /z rgb[5]=(48059, 48059, 48059)
    1054  ModifyGraph /w=$graphname /z rgb[6]=(65535, 32768, 32768)
    1055  ModifyGraph /w=$graphname /z rgb[7]=(0, 65535, 0)
    1056  ModifyGraph /w=$graphname /z rgb[8]=(16385,65535,65535)
    1057  ModifyGraph /w=$graphname /z rgb[9]=(65535, 32768, 58981)
    1058 end
    1059 
    1066 function ad_calc_histogram(image)
    1067  wave image
    1068 
    1069  dfref savedf = GetDataFolderDFR()
    1070  dfref imagedf = GetWavesDataFolderDFR(image)
    1071  setdatafolder imagedf
    1072 
    1073  wave hist
    1074  Histogram /B=3 image, hist
    1075 
    1076  setdatafolder savedf
    1077 end
    1078 
    1089 function ad_default_image_filter(image, options)
    1090  wave image
    1091  string options
    1092 end
    1093 
    1103 function ad_box_filter(image, options)
    1104  wave image
    1105  string options
    1106 
    1107  variable xsmoothing = NumberByKey("SmoothingX", options, "=", ";")
    1108  variable ysmoothing = NumberByKey("SmoothingY", options, "=", ";")
    1109 
    1110  if ((NumType(xsmoothing) == 0) && (xsmoothing >= 2))
    1111  Smooth /B /DIM=0 /E=3 xsmoothing, image
    1112  endif
    1113  if ((NumType(ysmoothing) == 0) && (ysmoothing >= 2))
    1114  Smooth /B /DIM=1 /E=3 ysmoothing, image
    1115  endif
    1116 end
    1117 
    1125 function ad_transpose_filter(image, options)
    1126  wave image
    1127  string options
    1128 
    1129  MatrixTranspose image
    1130 end
    1131 
    1132 
    1133 // ################### 3D DATA ##################
    1134 
    1141 function /s ad_display_brick(data)
    1142  wave data
    1143 
    1144  if(exists("NewGizmo") != 4)
    1145  abort "Gizmo XOP must be installed."
    1146  endif
    1147  if (WaveDims(data) != 3)
    1148  abort "ad_display_brick: data must be three-dimensional."
    1149  endif
    1150 
    1151  dfref savedf = GetDataFolderDFR()
    1152  dfref datadf = GetWavesDataFolderDFR(data)
    1153  string s_datadf = GetDataFolder(1, datadf)
    1154  dfref viewdf = make_view_folder(data)
    1155 
    1156  setdatafolder viewdf
    1157  string dfname = ReplaceString("root:", s_datadf, "")
    1158  string graphtitle = dfname + " Gizmo"
    1159  string /g gizmo_graphname = graphname_from_dfref(datadf, "giz_")
    1160  svar graphname = gizmo_graphname
    1161 
    1162  if ((strlen(graphname) > 0) && (wintype(graphname) == 13))
    1163  setdatafolder savedf
    1164  return graphname // gizmo window exists
    1165  endif
    1166 
    1167  variable nx = dimsize(data, 0)
    1168  variable ny = dimsize(data, 1)
    1169  variable nz = dimsize(data, 2)
    1170 
    1171  variable pp
    1172  string obj
    1173  string cmd
    1174 
    1175  // igor does not allow calling gizmo functions directly
    1176  setdatafolder datadf
    1177  sprintf cmd, "NewGizmo /k=1 /n=%s /w=(100,100,500,400) /t=\"%s\"", graphname, graphtitle
    1178  execute /q cmd
    1179  cmd = "AppendToGizmo /D Axes=BoxAxes, name=axes0"
    1180  execute /q cmd
    1181 
    1182  obj = "surface_xmid"
    1183  pp = round(nx / 2 - 1)
    1184  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
    1185  execute /q cmd
    1186  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 128}", obj
    1187  execute /q cmd
    1188  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
    1189  execute /q cmd
    1190  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
    1191  execute /q cmd
    1192  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
    1193  execute /q cmd
    1194  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
    1195  execute /q cmd
    1196 
    1197  obj = "surface_ymid"
    1198  pp = round(ny / 2 - 1)
    1199  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
    1200  execute /q cmd
    1201  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 64}", obj
    1202  execute /q cmd
    1203  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
    1204  execute /q cmd
    1205  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
    1206  execute /q cmd
    1207  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
    1208  execute /q cmd
    1209  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
    1210  execute /q cmd
    1211 
    1212  obj = "surface_zmid"
    1213  pp = round(nz / 2 - 1)
    1214  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
    1215  execute /q cmd
    1216  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 32}", obj
    1217  execute /q cmd
    1218  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
    1219  execute /q cmd
    1220  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
    1221  execute /q cmd
    1222  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
    1223  execute /q cmd
    1224  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
    1225  execute /q cmd
    1226 
    1227  obj = "axes0"
    1228  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={-1,axisScalingMode,1}", obj
    1229  execute /q cmd
    1230  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={-1,axisColor,0,0,0,1}", obj
    1231  execute /q cmd
    1232  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={0,ticks,3}", obj
    1233  execute /q cmd
    1234  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={1,ticks,3}", obj
    1235  execute /q cmd
    1236  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={2,ticks,3}", obj
    1237  execute /q cmd
    1238  sprintf cmd, "ModifyGizmo modifyObject=%s property={Clipped,0}", obj
    1239  execute /q cmd
    1240  sprintf cmd, "ModifyGizmo modifyObject=%s property={-1,fontScaleFactor,2}", obj
    1241  execute /q cmd
    1242 
    1243  sprintf cmd, "ModifyGizmo showAxisCue=1"
    1244  execute /q cmd
    1245 
    1246  setdatafolder savedf
    1247  return graphname
    1248 end
    1249 
    1256 function ad_brick_slicer(data)
    1257  wave data
    1258 
    1259  // data folders and references
    1260  dfref savedf = GetDataFolderDFR()
    1261  dfref datadf = GetWavesDataFolderDFR(data)
    1262  string s_datadf = GetDataFolder(1, datadf)
    1263  dfref viewdf = make_view_folder(data)
    1264 
    1265  setdatafolder viewdf
    1266  svar /z ex_panel = slicer_panelname
    1267  if (svar_exists(ex_panel))
    1268  string panels = WinList("SlicerPanel*", ";", "WIN:64")
    1269  if (WhichListItem(ex_panel, panels, ";") >= 0)
    1270  dowindow /f $(StringFromList(0, panels, ";"))
    1271  return 0
    1272  endif
    1273  endif
    1274 
    1275  variable /g x_slice_pos
    1276  variable /g y_slice_pos
    1277  variable /g z_slice_pos
    1278  variable /g slab_thickness
    1279  string /g brick_path = getwavesdatafolder(data, 2)
    1280  variable /g x_autoinc = 0
    1281  variable /g y_autoinc = 0
    1282  variable /g z_autoinc = 0
    1283 
    1284  // axis labels
    1285  string labels = note(data)
    1286  string xlabel = StringByKey("AxisLabelX", labels, "=", "\r")
    1287  if (!strlen(xlabel))
    1288  xlabel = "X"
    1289  endif
    1290  string ylabel = StringByKey("AxisLabelY", labels, "=", "\r")
    1291  if (!strlen(ylabel))
    1292  ylabel = "Y"
    1293  endif
    1294  string zlabel = StringByKey("AxisLabelZ", labels, "=", "\r")
    1295  if (!strlen(zlabel))
    1296  zlabel = "Z"
    1297  endif
    1298  string dlabel = StringByKey("Dataset", labels, "=", "\r")
    1299  if (!strlen(dlabel))
    1300  dlabel = NameOfWave(data)
    1301  endif
    1302 
    1303  // this section copied from slicer panel
    1304  NewPanel /k=1 /W=(500,600,890,940) /N=SlicerPanel as "Brick Slicer"
    1305  string /g slicer_panelname = S_name
    1306  string panel = s_name
    1307 
    1308  GroupBox g_xslice win=$panel,pos={8,8},size={376,96},title=xlabel
    1309  Slider sl_xslice_position win=$panel,pos={16,32},size={240,56},proc=PearlAreaDisplay#slp_slice_position
    1310  Slider sl_xslice_position win=$panel,limits={0,100,1},variable=x_slice_pos,vert= 0
    1311  SetVariable sv_xslice_position win=$panel,pos={20,80},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="X"
    1312  SetVariable sv_xslice_position win=$panel,limits={0,100,1},value=x_slice_pos
    1313  Button b_xslice_center win=$panel,pos={122,80},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
    1314  Button b_xslice_center win=$panel,help={"reset to center position"}
    1315  Button b_xslice_extract win=$panel,pos={288,80},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
    1316  Button b_xslice_extract win=$panel,help={"extract this slice to a separate wave"}
    1317  //CheckBox cb_xslab_active win=$panel,pos={288,80},size={80,16},title="Display X Slab"
    1318  //CheckBox cb_xslab_active win=$panel,value= 0
    1319  TitleBox tb_xslice_animation win=$panel,pos={288,32},size={356,16},title="animation",frame=0
    1320  TitleBox tb_xslice_animation win=$panel,anchor= MC
    1321  Button b_xslice_back win=$panel,pos={288,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
    1322  Button b_xslice_back win=$panel,help={"animate backwards"}
    1323  Button b_xslice_forward win=$panel,pos={312,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
    1324  Button b_xslice_forward win=$panel,help={"animate forward"}
    1325  Button b_xslice_stop win=$panel,pos={336,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
    1326  Button b_xslice_stop win=$panel,help={"stop animation"}
    1327 
    1328  GroupBox g_yslice win=$panel,pos={8,108},size={376,96},title=ylabel
    1329  Slider sl_yslice_position win=$panel,pos={16,132},size={240,56},proc=PearlAreaDisplay#slp_slice_position
    1330  Slider sl_yslice_position win=$panel,limits={0,100,1},variable=y_slice_pos,vert= 0
    1331  SetVariable sv_yslice_position win=$panel,pos={20,180},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="Y"
    1332  SetVariable sv_yslice_position win=$panel,limits={0,100,1},value=y_slice_pos
    1333  Button b_yslice_center win=$panel,pos={122,180},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
    1334  Button b_yslice_center win=$panel,help={"reset to center position"}
    1335  Button b_yslice_extract win=$panel,pos={288,180},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
    1336  Button b_yslice_extract win=$panel,help={"extract this slice to a separate wave"}
    1337  //CheckBox cb_yslab_active win=$panel,pos={288,180},size={80,16},title="Display Y Slab"
    1338  //CheckBox cb_yslab_active win=$panel,value= 0
    1339  TitleBox tb_yslice_animation win=$panel,pos={288,132},size={356,16},title="animation",frame=0
    1340  TitleBox tb_yslice_animation win=$panel,anchor= MC
    1341  Button b_yslice_back win=$panel,pos={288,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
    1342  Button b_yslice_back win=$panel,help={"animate backwards"}
    1343  Button b_yslice_forward win=$panel,pos={312,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
    1344  Button b_yslice_forward win=$panel,help={"animate forward"}
    1345  Button b_yslice_stop win=$panel,pos={336,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
    1346  Button b_yslice_stop win=$panel,help={"stop animation"}
    1347 
    1348  GroupBox g_zslice win=$panel,pos={8,208},size={376,96},title=zlabel
    1349  Slider sl_zslice_position win=$panel,pos={16,232},size={240,56},proc=PearlAreaDisplay#slp_slice_position
    1350  Slider sl_zslice_position win=$panel,limits={0,100,1},variable=z_slice_pos,vert= 0
    1351  SetVariable sv_zslice_position win=$panel,pos={20,280},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="Z"
    1352  SetVariable sv_zslice_position win=$panel,limits={0,100,1},value=z_slice_pos
    1353  Button b_zslice_center win=$panel,pos={122,280},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
    1354  Button b_zslice_center win=$panel,help={"reset to center position"}
    1355  Button b_zslice_extract win=$panel,pos={288,280},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
    1356  Button b_zslice_extract win=$panel,help={"extract this slice to a separate wave"}
    1357  //CheckBox cb_zslab_active win=$panel,pos={288,280},size={80,16},title="Display Z Slab"
    1358  //CheckBox cb_zslab_active win=$panel,value= 0
    1359  TitleBox tb_zslice_animation win=$panel,pos={288,232},size={356,16},title="animation",frame=0
    1360  TitleBox tb_zslice_animation win=$panel,anchor= MC
    1361  Button b_zslice_back win=$panel,pos={288,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
    1362  Button b_zslice_back win=$panel,help={"animate backwards"}
    1363  Button b_zslice_forward win=$panel,pos={312,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
    1364  Button b_zslice_forward win=$panel,help={"animate forward"}
    1365  Button b_zslice_stop win=$panel,pos={336,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
    1366  Button b_zslice_stop win=$panel,help={"stop animation"}
    1367 
    1368  TitleBox t_slicerpath win=$panel,pos={8,316},size={128,20},disable=2,title=dlabel
    1369  //SetVariable setvar0 win=$panel,pos={240,316},size={120,16},title="slab thickness"
    1370  //SetVariable setvar0 win=$panel,limits={1,inf,1},value=slab_thickness
    1371 
    1372  // update control limits and move slicing planes to the center
    1373  setwindow $panel, userdata(control_datafolder) = GetDataFolder(1, viewdf)
    1374  setwindow $panel, userdata(brick_path) = brick_path
    1375  update_slice_info()
    1376  x_slice_pos = dimoffset(data, 0) + dimsize(data, 0) * dimdelta(data, 0) / 2
    1377  y_slice_pos = dimoffset(data, 1) + dimsize(data, 1) * dimdelta(data, 1) / 2
    1378  z_slice_pos = dimoffset(data, 2) + dimsize(data, 2) * dimdelta(data, 2) / 2
    1379 
    1380  svar /z /sdfr=viewdf gizmo_graphname
    1381  if (svar_exists(gizmo_graphname) && (strlen(gizmo_graphname) > 0) && (wintype(gizmo_graphname) == 13))
    1382  ad_gizmo_set_plane(data, 0, x_slice_pos)
    1383  ad_gizmo_set_plane(data, 1, y_slice_pos)
    1384  ad_gizmo_set_plane(data, 2, z_slice_pos)
    1385  endif
    1386  svar /z /sdfr=viewdf slice_graphname
    1387  if (svar_exists(slice_graphname) && (strlen(slice_graphname) > 0) && (wintype(slice_graphname) == 1))
    1388  ad_profiles_set_slice(data, 2, z_slice_pos)
    1389  endif
    1390 
    1391  ad_slicer_init_bg()
    1392  setdatafolder savedf
    1393 end
    1394 
    1404 function /s ad_display_slice(data)
    1405  wave data
    1406 
    1407  if (WaveDims(data) != 3)
    1408  abort "ad_display_slice: data must be three-dimensional."
    1409  endif
    1410 
    1411  dfref savedf = GetDataFolderDFR()
    1412  dfref datadf = GetWavesDataFolderDFR(data)
    1413  string s_datadf = GetDataFolder(1, datadf)
    1414  dfref viewdf = make_view_folder(data)
    1415 
    1416  setdatafolder viewdf
    1417  string dfname = ReplaceString("root:", s_datadf, "")
    1418  dfname = dfname[0, strlen(dfname) - 2]
    1419  string graphtitle = dfname + " Slice"
    1420 
    1421  if (exists("slice_graphname") != 2)
    1422  string /g slice_graphname = ""
    1423  endif
    1424  string /g slice_wavename = PearlCleanupName("slice_" + NameOfWave(data))
    1425  svar graphname = slice_graphname
    1426  svar slicename = slice_wavename
    1427 
    1428  make /n=(1,1)/o $slicename
    1429  wave slice = $slicename
    1430  if ((strlen(graphname) == 0) || (wintype(graphname) != 1))
    1431  graphname = ad_display_profiles(slice)
    1432  endif
    1433  variable z_slice_pos = dimoffset(data, 2) + dimsize(data, 2) * dimdelta(data, 2) / 2
    1434  ad_profiles_set_slice(data, 2, z_slice_pos)
    1435  ad_profiles_set_cursor(slice, "A", -inf, -inf, pscale=1)
    1436  ad_profiles_set_cursor(slice, "B", +inf, +inf, pscale=1)
    1437 
    1438  setdatafolder savedf
    1439  return graphname
    1440 end
    1441 
    1445 static function update_slice_info()
    1446  dfref savedf = GetDataFolderDFR()
    1447 
    1448  svar brick_path
    1449  //svar slicer_panelname
    1450  wave brick = $brick_path
    1451 
    1452  //dowindow /F $slicer_panelname
    1453  variable lo, hi, inc
    1454  lo = dimoffset(brick, 0)
    1455  inc = dimdelta(brick, 0)
    1456  hi = lo + inc * (dimsize(brick, 0) - 1)
    1457  Slider sl_xslice_position,limits={lo,hi,inc}
    1458  SetVariable sv_xslice_position,limits={lo,hi,inc}
    1459  lo = dimoffset(brick, 1)
    1460  inc = dimdelta(brick, 1)
    1461  hi = lo + inc * (dimsize(brick, 1) - 1)
    1462  Slider sl_yslice_position,limits={lo,hi,inc}
    1463  SetVariable sv_yslice_position,limits={lo,hi,inc}
    1464  lo = dimoffset(brick, 2)
    1465  inc = dimdelta(brick, 2)
    1466  hi = lo + inc * (dimsize(brick, 2) - 1)
    1467  Slider sl_zslice_position,limits={lo,hi,inc}
    1468  SetVariable sv_zslice_position,limits={lo,hi,inc}
    1469 
    1470  setdatafolder savedf
    1471 end
    1472 
    1481 function ad_gizmo_set_plane(brick, dim, value)
    1482  wave brick
    1483  variable dim
    1484  variable value
    1485 
    1486  dfref savedf = GetDataFolderDFR()
    1487  dfref datadf = GetWavesDataFolderDFR(brick)
    1488  dfref viewdf = get_view_folder(brick)
    1489  svar /z /sdfr=viewdf graphname=gizmo_graphname
    1490 
    1491  variable pp = round((value - dimoffset(brick, dim)) / dimdelta(brick, dim))
    1492  if ((pp < 0) || (pp >= dimsize(brick, dim)))
    1493  return -1 // requested value out of range
    1494  endif
    1495 
    1496  if (svar_exists(graphname) && (strlen(graphname) > 0) && (wintype(graphname) == 13))
    1497  string axes = "xyz"
    1498  string obj = "surface_" + axes[dim] + "mid"
    1499  string cmd
    1500  sprintf cmd, "ModifyGizmo /N=%s ModifyObject=%s, property={plane, %d}", graphname, obj, pp
    1501  execute /q cmd
    1502  else
    1503  return -2 // gizmo window not found
    1504  endif
    1505 
    1506  return 0
    1507 end
    1508 
    1517 function ad_profiles_set_slice(brick, dim, value)
    1518  wave brick
    1519  variable dim
    1520  variable value
    1521 
    1522  dfref savedf = GetDataFolderDFR()
    1523  dfref datadf = GetWavesDataFolderDFR(brick)
    1524  dfref viewdf = get_view_folder(brick)
    1525  svar /z /sdfr=viewdf graphname = slice_graphname
    1526  svar /z /sdfr=viewdf slicename = slice_wavename
    1527 
    1528  variable pp = round((value - dimoffset(brick, dim)) / dimdelta(brick, dim))
    1529  if ((pp < 0) || (pp >= dimsize(brick, dim)))
    1530  return -1 // requested value out of range
    1531  endif
    1532 
    1533  if (svar_exists(graphname) && (strlen(graphname) > 0) && (wintype(graphname) == 1))
    1534  setdatafolder viewdf
    1535  switch(dim)
    1536  case 0: // X
    1537  wave wdest = ad_extract_slab_x(brick, pp, pp, slicename)
    1538  ad_update_profiles(wdest)
    1539  break
    1540  case 1: // Y
    1541  wave wdest = ad_extract_slab_y(brick, pp, pp, slicename)
    1542  ad_update_profiles(wdest)
    1543  break
    1544  case 2: // Z
    1545  wave wdest = ad_extract_slab_z(brick, pp, pp, slicename)
    1546  ad_update_profiles(wdest)
    1547  break
    1548  endswitch
    1549  else
    1550  return -2 // graph window not found
    1551  endif
    1552 
    1553  setdatafolder savedf
    1554  return 0
    1555 end
    1556 
    1558 static function slp_slice_position(sa) : SliderControl
    1559  STRUCT WMSliderAction &sa
    1560 
    1561  dfref savedf = GetDataFolderDFR()
    1562 
    1563  switch( sa.eventCode )
    1564  case -1: // control being killed
    1565  break
    1566  default:
    1567  if( sa.eventCode & 1 ) // value set
    1568  string control_datafolder = GetUserData(sa.win, "", "control_datafolder")
    1569  setdatafolder control_datafolder
    1570  string brick_path = GetUserData(sa.win, "", "brick_path")
    1571  string axis = StringFromList(1, sa.ctrlName, "_")
    1572  variable dim = char2num(axis[0]) - char2num("x")
    1573 
    1574  wave /z brick = $brick_path
    1575  if (WaveExists(brick))
    1576  ad_gizmo_set_plane(brick, dim, sa.curval)
    1577  ad_profiles_set_slice(brick, dim, sa.curval)
    1578  else
    1579  Abort "can't find original wave " + brick_path
    1580  endif
    1581  endif
    1582  break
    1583  endswitch
    1584 
    1585  setdatafolder savedf
    1586  return 0
    1587 End
    1588 
    1590 static function svp_slice_position(sva) : SetVariableControl
    1591  STRUCT WMSetVariableAction &sva
    1592 
    1593  dfref savedf = GetDataFolderDFR()
    1594 
    1595  switch( sva.eventCode )
    1596  case 1: // mouse up
    1597  case 2: // Enter key
    1598  case 3: // Live update
    1599  string control_datafolder = GetUserData(sva.win, "", "control_datafolder")
    1600  setdatafolder control_datafolder
    1601  string brick_path = GetUserData(sva.win, "", "brick_path")
    1602  string axis = StringFromList(1, sva.ctrlName, "_")
    1603  variable dim = char2num(axis[0]) - char2num("x")
    1604 
    1605  wave /z brick = $brick_path
    1606  if (WaveExists(brick))
    1607  ad_gizmo_set_plane(brick, dim, sva.dval)
    1608  ad_profiles_set_slice(brick, dim, sva.dval)
    1609  else
    1610  Abort "can't find original wave " + brick_path
    1611  endif
    1612  break
    1613  case -1: // control being killed
    1614  break
    1615  endswitch
    1616 
    1617  setdatafolder savedf
    1618  return 0
    1619 End
    1620 
    1622 static function bp_move_slice(ba) : ButtonControl
    1623  STRUCT WMButtonAction &ba
    1624 
    1625  dfref savedf = GetDataFolderDFR()
    1626 
    1627  switch( ba.eventCode )
    1628  case 2: // mouse up
    1629  string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
    1630  setdatafolder control_datafolder
    1631  string brick_path = GetUserData(ba.win, "", "brick_path")
    1632  string axis = StringFromList(1, ba.ctrlName, "_")
    1633  string cmd = StringFromList(2, ba.ctrlName, "_")
    1634  variable dim = char2num(axis[0]) - char2num("x")
    1635  string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
    1636  nvar pos = $(posvariable)
    1637 
    1638  wave /z brick = $brick_path
    1639  if (WaveExists(brick))
    1640  strswitch (cmd)
    1641  case "forward":
    1642  ad_slicer_start_bg(brick, dim, posvariable, dimdelta(brick, dim))
    1643  break
    1644  case "back":
    1645  ad_slicer_start_bg(brick, dim, posvariable, -dimdelta(brick, dim))
    1646  break
    1647  case "center":
    1648  ad_slicer_stop_bg(posvariable)
    1649  bp_move_slice_center(brick, dim, posvariable)
    1650  break
    1651  case "stop":
    1652  ad_slicer_stop_bg(posvariable)
    1653  break
    1654  endswitch
    1655  else
    1656  ad_slicer_stop_bg(posvariable)
    1657  Abort "can't find original wave " + brick_path
    1658  endif
    1659  break
    1660  case -1: // control being killed
    1661  break
    1662  endswitch
    1663 
    1664  setdatafolder savedf
    1665  return 0
    1666 End
    1667 
    1671 static function bp_extract_slice(ba) : ButtonControl
    1672  STRUCT WMButtonAction &ba
    1673 
    1674  dfref savedf = GetDataFolderDFR()
    1675 
    1676  switch( ba.eventCode )
    1677  case 2: // mouse up
    1678  string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
    1679  setdatafolder control_datafolder
    1680  string brick_path = GetUserData(ba.win, "", "brick_path")
    1681  wave brick = $brick_path
    1682  dfref brickdf = GetWavesDataFolderDFR(brick)
    1683 
    1684  string axis = StringFromList(1, ba.ctrlName, "_")
    1685  string cmd = StringFromList(2, ba.ctrlName, "_")
    1686  variable dim = char2num(axis[0]) - char2num("x")
    1687  string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
    1688 
    1689  nvar pos = $(posvariable)
    1690  variable pp = round((pos - dimoffset(brick, dim)) / dimdelta(brick, dim))
    1691  if ((pp < 0) || (pp >= dimsize(brick, dim)))
    1692  return -1 // requested value out of range
    1693  endif
    1694 
    1695  variable dig = ceil(log(dimsize(brick, dim)))
    1696  string slicename
    1697  sprintf slicename, "%s_%s%0*u", NameOfWave(brick), axis[0], dig, pp
    1698  setdatafolder brickdf
    1699  switch(dim)
    1700  case 0: // X
    1701  wave wdest = ad_extract_slab_x(brick, pp, pp, slicename)
    1702  break
    1703  case 1: // Y
    1704  wave wdest = ad_extract_slab_y(brick, pp, pp, slicename)
    1705  break
    1706  case 2: // Z
    1707  wave wdest = ad_extract_slab_z(brick, pp, pp, slicename)
    1708  break
    1709  endswitch
    1710 
    1711  string msg
    1712  sprintf msg, "%s=%g", axis[0], pos
    1713  note wdest, msg
    1714 
    1715  break
    1716  case -1: // control being killed
    1717  break
    1718  endswitch
    1719 
    1720  setdatafolder savedf
    1721  return 0
    1722 End
    1723 
    1725 static function bp_move_slice_center(brick, dim, posvariable)
    1726  wave brick
    1727  variable dim
    1728  string posvariable
    1729 
    1730  nvar pos = $posvariable
    1731  pos = dimoffset(brick, dim) + dimdelta(brick, dim) * dimsize(brick, dim) / 2
    1732  ad_gizmo_set_plane(brick, dim, pos)
    1733  ad_profiles_set_slice(brick, dim, pos)
    1734 end
    1735 
    1737 static function ad_slicer_move_bg(s)
    1738  STRUCT WMBackgroundStruct &s
    1739 
    1740  dfref savedf = GetDataFolderDFR()
    1741  setdatafolder root:pearl_area:slicer
    1742  wave /t bg_brickpaths
    1743  wave /t bg_graphnames
    1744  wave /t bg_variablepaths
    1745  wave bg_dimensions
    1746  wave bg_increments
    1747 
    1748  variable ii
    1749  variable nn = numpnts(bg_brickpaths)
    1750  variable dim
    1751  variable pp
    1752 
    1753  for (ii = 0; ii < nn; ii += 1)
    1754  wave /z brick = $bg_brickpaths[ii]
    1755  nvar /z pos = $bg_variablepaths[ii]
    1756  dim = bg_dimensions[0]
    1757  pos += bg_increments[ii]
    1758  // wrap around at limits
    1759  pp = round((pos - dimoffset(brick, dim)) / dimdelta(brick, dim))
    1760  if (pp <= -0.5)
    1761  pos = dimoffset(brick, dim) + dimdelta(brick, dim) * (dimsize(brick, dim) - 1)
    1762  elseif (pp >= dimsize(brick, dim) - 0.5)
    1763  pos = dimoffset(brick, dim)
    1764  endif
    1765  if (waveexists(brick))
    1766  ad_gizmo_set_plane(brick, dim, pos)
    1767  ad_profiles_set_slice(brick, dim, pos)
    1768  endif
    1769  endfor
    1770 
    1771  setdatafolder savedf
    1772  return 0
    1773 End
    1774 
    1776 function ad_slicer_init_bg()
    1777  dfref savedf = GetDataFolderDFR()
    1778  setdatafolder root:
    1779  newdatafolder /o/s pearl_area
    1780  newdatafolder /o/s slicer
    1781 
    1782  make /n=0/o/t bg_brickpaths
    1783  make /n=0/o/t bg_variablepaths
    1784  make /n=0/o/i/u bg_dimensions
    1785  make /n=0/o bg_increments
    1786 
    1787  CtrlNamedBackground ad_slicer, period = 30, proc = PearlAreaDisplay#ad_slicer_move_bg
    1788 
    1789  setdatafolder savedf
    1790  return 0
    1791 end
    1792 
    1800 function ad_slicer_start_bg(brick, dimension, posvariable, delta)
    1801  wave brick // 3D data wave
    1802  variable dimension // dimension to animate, 0, 1, or 2
    1803  string posvariable // full path to the global position variable
    1804  variable delta // step increment, should be +/- dimdelta
    1805 
    1806  dfref savedf = GetDataFolderDFR()
    1807  setdatafolder root:pearl_area:slicer
    1808  wave /t bg_brickpaths
    1809  wave /t bg_variablepaths
    1810  wave bg_dimensions
    1811  wave bg_increments
    1812 
    1813  // create entry in ad_slicer background task table
    1814  variable idx
    1815  FindValue /TEXT=posvariable /TXOP=4 /Z bg_variablepaths
    1816  if (v_value >= 0)
    1817  idx = v_value
    1818  else
    1819  idx = numpnts(bg_variablepaths)
    1820  InsertPoints idx, 1, bg_brickpaths, bg_variablepaths, bg_dimensions, bg_increments
    1821  endif
    1822 
    1823  // set background task
    1824  bg_brickpaths[idx] = GetWavesDataFolder(brick, 2)
    1825  bg_variablepaths[idx] = posvariable
    1826  bg_dimensions[idx] = dimension
    1827  bg_increments[idx] = delta
    1828 
    1829  // start background task
    1830  if (numpnts(bg_variablepaths) > 0)
    1831  CtrlNamedBackground ad_slicer, start
    1832  endif
    1833 
    1834  setdatafolder savedf
    1835  return 0
    1836 end
    1837 
    1842 function ad_slicer_stop_bg(posvariable)
    1843  string posvariable
    1844 
    1845  dfref savedf = GetDataFolderDFR()
    1846  setdatafolder root:pearl_area:slicer
    1847  wave /t bg_brickpaths
    1848  wave /t bg_variablepaths
    1849  wave bg_dimensions
    1850  wave bg_increments
    1851 
    1852  // find entry in ad_slicer background task table
    1853  FindValue /TEXT=posvariable /TXOP=4 /Z bg_variablepaths
    1854  if (v_value >= 0)
    1855  DeletePoints v_value, 1, bg_brickpaths, bg_variablepaths, bg_dimensions, bg_increments
    1856  endif
    1857 
    1858  // stop background task if task table is empty
    1859  if (numpnts(bg_variablepaths) == 0)
    1860  CtrlNamedBackground ad_slicer, stop
    1861  endif
    1862 
    1863  setdatafolder savedf
    1864  return 0
    1865 end
    variable ad_profiles_cursor_mode(wave image, variable mode)
    switch cursors on a profiles graph
    -
    static variable set_trace_colors(string graphname)
    -
    variable ad_profiles_crosshairs(wave image, variable clear=defaultValue)
    draw permanent crosshairs in a profiles graph.
    -
    variable ad_update_profiles(wave image)
    update a profiles graph with new data.
    -
    variable ad_default_image_filter(wave image, string options)
    abstract filter function for image display.
    -
    static variable svp_smoothing(WMSetVariableAction *sva)
    -
    static dfr get_view_folder(wave source)
    find the view data folder corresponding to the given source.
    -
    variable ad_calc_histogram(wave image)
    calculate the histogram.
    -
    static dfr make_view_folder(wave source)
    create a view data folder.
    -
    string PearlCleanupName(string name)
    -
    variable ad_calc_profiles(wave image, variable pa, variable qa, variable pb, variable qb)
    calculate profiles, statistics, and histogram of a rectangular region of interest.
    -
    variable ad_profiles_set_cursor(wave image, string cursorname, variable xa, variable ya, variable pscale=defaultValue)
    move a cursor to the specified position in a profiles graph.
    -
    static wave get_view_image(wave source)
    find the view image wave corresponding to the given source.
    -
    instant visualization of angle scan and manipulator position.
    -
    static variable pmp_export(WMPopupAction *pa)
    -
    static wave get_source_image(wave view)
    find the source image wave corresponding to the given view.
    -
    string ad_display_histogram(wave image)
    display the histogram of a 2D image.
    -
    string ad_display(wave image)
    open a new graph window with a 2D image.
    -
    static string graphname_from_dfref(dfref df, string prefix)
    compose a valid and unique graph name from a data folder reference
    -
    wave ad_add_overlay(wave image, string rgba=defaultValue)
    add an overlay on top of the displayed image
    -
    variable ad_calc_cursor_profiles(wave image)
    calculate profiles, statistics, and histogram of a cross-hair delimited region of interest...
    -
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    -
    static variable bp_reset_cursors(WMButtonAction *ba)
    -
    variable ad_export_profile(wave view_image, variable dim, variable trace=defaultValue, variable show=defaultValue, variable overwrite=defaultValue)
    export a profile from a profiles graph to the source data folder.
    -
    variable ad_transpose_filter(wave image, string options)
    transpose image filter.
    -
    string ad_display_slice(wave data)
    display three-dimensional data by 2D slice.
    -
    variable ad_box_filter(wave image, string options)
    boxcar smoothing filter.
    -
    string ad_display_brick(wave data)
    open a new "gizmo" window with three-dimensional data.
    -
    variable ad_profiles_hook(WMWinHookStruct *s)
    hook function for user events in the profiles window.
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.2
    +
    4 #pragma ModuleName = PearlAreaDisplay
    +
    5 #pragma version = 1.04
    +
    6 #include "pearl-compat"
    +
    7 #include "pearl-area-profiles"
    +
    8 
    +
    22 // 3D data is handled by 3 windows. they don't have to be visible all at the same time.
    +
    51 
    +
    57 
    +
    59 static function /s graphname_from_dfref(df, prefix)
    +
    60  dfref df
    +
    61  string prefix
    +
    62 
    +
    63  string name
    +
    64 
    +
    65  name = GetDataFolder(1, df)
    +
    66  name = ReplaceString("root:", name, "")
    +
    67  name = name[0, strlen(name) - 2]
    +
    68  name = ReplaceString(" ", name, "")
    +
    69  name = PearlCleanupName(prefix + name)
    +
    70  if (CheckName(name, 6))
    +
    71  name = UniqueName(name, 6, 0)
    +
    72  endif
    +
    73 
    +
    74  return name
    +
    75 end
    +
    76 
    +
    87 function /s ad_display(image)
    +
    88  wave image // wave which contains the image data from the detector
    +
    89  // returns the name of the graph window
    +
    90 
    +
    91  dfref savedf = GetDataFolderDFR()
    +
    92  dfref imagedf = GetWavesDataFolderDFR(image)
    +
    93  setdatafolder imagedf
    +
    94 
    +
    95  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
    +
    96  string graphtitle = dfname + " View"
    +
    97  string /g view_graphname = graphname_from_dfref(imagedf, "view_")
    +
    98  svar graphname = view_graphname
    +
    99  display /k=1/n=$graphname as graphtitle
    +
    100  graphname = s_name
    +
    101  appendimage /w=$graphname image
    +
    102 
    +
    103  setdatafolder savedf
    +
    104  return graphname
    +
    105 end
    +
    106 
    +
    117 function /s ad_display_histogram(image)
    +
    118  wave image
    +
    119 
    +
    120  dfref savedf = GetDataFolderDFR()
    +
    121  dfref imagedf = GetWavesDataFolderDFR(image)
    +
    122  string s_imagedf = GetDataFolder(1, imagedf)
    +
    123  setdatafolder imagedf
    +
    124 
    +
    125  make /n=(1)/o hist // histogram
    +
    126 
    +
    127  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
    +
    128  string graphtitle = dfname + " Histogram"
    +
    129  string /g hist_graphname = graphname_from_dfref(imagedf, "hist_")
    +
    130  svar graphname = hist_graphname
    +
    131  display /k=1/n=$graphname as graphtitle
    +
    132  graphname = s_name
    +
    133  appendtograph /w=$graphname hist
    +
    134 
    +
    135  ModifyGraph /w=$graphname rgb(hist)=(39168,0,0)
    +
    136  ModifyGraph /w=$graphname mode=6
    +
    137  ModifyGraph /w=$graphname mirror=1
    +
    138  ModifyGraph /w=$graphname minor=1
    +
    139  ModifyGraph /w=$graphname axThick=0.5
    +
    140  ModifyGraph /w=$graphname lblPosMode=1,lblPos=30,lblMargin=0
    +
    141  ModifyGraph /w=$graphname btLen=4
    +
    142  ModifyGraph /w=$graphname margin(left)=45,margin(bottom)=35,margin(top)=10,margin(right)=10
    +
    143  ModifyGraph /w=$graphname gfSize=10
    +
    144  Label /w=$graphname bottom "value"
    +
    145  Label /w=$graphname left "# pixels"
    +
    146 
    +
    147  ad_calc_histogram(image)
    +
    148 
    +
    149  setdatafolder savedf
    +
    150  return graphname
    +
    151 end
    +
    152 
    +
    168 function /s ad_display_profiles(image, [filter])
    +
    169  wave image
    +
    170  string filter
    +
    171  variable show_legend = 0 // currently not supported
    +
    172 
    +
    173  if (WaveDims(image) != 2)
    +
    174  abort "ad_display_profiles: image wave must be two-dimensional."
    +
    175  endif
    +
    176  if (ParamIsDefault(filter))
    +
    177  filter = "ad_box_filter"
    +
    178  endif
    +
    179 
    +
    180  // data folders and references
    +
    181  dfref savedf = GetDataFolderDFR()
    +
    182  dfref imagedf = GetWavesDataFolderDFR(image)
    +
    183  string s_imagedf = GetDataFolder(1, imagedf)
    +
    184  setdatafolder imagedf
    +
    185  string s_viewdf = PearlCleanupName("view_" + NameOfWave(image))
    +
    186  newdatafolder /o/s $s_viewdf
    +
    187  dfref viewdf = GetDataFolderDFR()
    +
    188  s_viewdf = GetDataFolder(1, viewdf)
    +
    189 
    +
    190  // data structures
    +
    191  string /g sourcepath = GetWavesDataFolder(image, 2)
    +
    192  string viewname = "view_image"
    +
    193  duplicate /o image, $viewname /wave=view
    +
    194  make /n=(3,3)/o xprofiles // NX x 3 wave with 3 one-dimensional profiles along Y dimension
    +
    195  make /n=(3,3)/o yprofiles // NY x 3 wave with 3 one-dimensional profiles along X dimension
    +
    196  string /g view_filter
    +
    197  string /g view_filter_options
    +
    198  view_filter = filter
    +
    199  view_filter_options = ""
    +
    200  variable /g view_filter_smoothing_x = 1
    +
    201  variable /g view_filter_smoothing_y = 1
    +
    202  variable /g view_cursor_mode = 0
    +
    203  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
    +
    204  string graphtitle = dfname + NameOfWave(image) + " Profiles"
    +
    205  string /g prof_graphname = graphname_from_dfref(imagedf, "prof_")
    +
    206  svar graphname = prof_graphname
    +
    207  variable /g graph_avg // average value in ROI (ROI is defined by the crosshairs A and B)
    +
    208  variable /g graph_min // minimum value in ROI
    +
    209  variable /g graph_max // maximum value in ROI
    +
    210  variable /g graph_sum // sum of all values in ROI
    +
    211  variable /g graph_sdev // standard deviation of all values in ROI
    +
    212 
    +
    213  // graph setup
    +
    214  display /k=1 /n=$graphname /w=(100,100,500,400) as graphtitle
    +
    215  graphname = s_name
    +
    216  AppendToGraph /w=$graphname /L=xprofiles xprofiles[*][0],xprofiles[*][1],xprofiles[*][2]
    +
    217  AppendToGraph /w=$graphname /VERT/B=yprofiles yprofiles[*][0],yprofiles[*][1],yprofiles[*][2]
    +
    218  AppendImage /w=$graphname view
    +
    219  string imgname = StringFromList(0, ImageNameList(graphname, ";"))
    +
    220  ModifyImage /w=$graphname $imgname ctab= {*,*,BlueGreenOrange,0}
    +
    221  ModifyGraph /w=$graphname rgb(xprofiles)=(39168,0,0),rgb(yprofiles)=(39168,0,0)
    +
    222  ModifyGraph /w=$graphname rgb(xprofiles#1)=(0,26112,0),rgb(yprofiles#1)=(0,26112,0)
    +
    223  ModifyGraph /w=$graphname rgb(xprofiles#2)=(0,9472,39168),rgb(yprofiles#2)=(0,9472,39168)
    +
    224  ModifyGraph /w=$graphname mirror(xprofiles)=2,mirror(bottom)=3,mirror(yprofiles)=2,mirror(left)=3
    +
    225  ModifyGraph /w=$graphname nticks=3
    +
    226  ModifyGraph /w=$graphname minor=1
    +
    227  ModifyGraph /w=$graphname axThick=0.5
    +
    228  ModifyGraph /w=$graphname lblPosMode=1,lblPos=30,lblMargin=0
    +
    229  ModifyGraph /w=$graphname btLen=4
    +
    230  ModifyGraph /w=$graphname freePos(xprofiles)=0
    +
    231  ModifyGraph /w=$graphname freePos(yprofiles)=0
    +
    232  ModifyGraph /w=$graphname axisEnab(xprofiles)={0.64,1}
    +
    233  ModifyGraph /w=$graphname axisEnab(bottom)={0,0.6}
    +
    234  ModifyGraph /w=$graphname axisEnab(yprofiles)={0.64,1}
    +
    235  ModifyGraph /w=$graphname axisEnab(left)={0,0.6}
    +
    236  ModifyGraph /w=$graphname zero(left)=8
    +
    237  ModifyGraph /w=$graphname margin(left)=40,margin(bottom)=30,margin(top)=20,margin(right)=40
    +
    238  ModifyGraph /w=$graphname gfSize=10
    +
    239 
    +
    240  // axis labels
    +
    241  string labels = note(image)
    +
    242  string lab
    +
    243  lab = StringByKey("AxisLabelX", labels, "=", "\r")
    +
    244  if (!strlen(lab))
    +
    245  lab = "X"
    +
    246  endif
    +
    247  Label /w=$graphname bottom lab + " (\\U)"
    +
    248  lab = StringByKey("AxisLabelY", labels, "=", "\r")
    +
    249  if (!strlen(lab))
    +
    250  lab = "Y"
    +
    251  endif
    +
    252  Label /w=$graphname left lab + " (\\U)"
    +
    253  lab = StringByKey("AxisLabelD", labels, "=", "\r")
    +
    254  if (!strlen(lab))
    +
    255  lab = "value"
    +
    256  endif
    +
    257  Label /w=$graphname xprofiles lab + " (\\U)"
    +
    258  Label /w=$graphname yprofiles lab + " (\\U)"
    +
    259 
    +
    260  // legend
    +
    261  if (show_legend)
    +
    262  Legend /w=$graphname/C/N=text0/J/F=2/D=0.5/T={28}/A=RT/X=0.00/Y=0.00 "\\s(xprofiles)\tprofile A"
    +
    263  AppendText /w=$graphname "\\s(xprofiles#1)\tprofile B"
    +
    264  AppendText /w=$graphname "\\s(xprofiles#2)\tROI average"
    +
    265  AppendText /w=$graphname "min\t\\{" + s_viewdf + "graph_min}"
    +
    266  AppendText /w=$graphname "max\t\\{" + s_viewdf + "graph_max}"
    +
    267  AppendText /w=$graphname "sum\t\\{" + s_viewdf + "graph_sum}"
    +
    268  AppendText /w=$graphname "avg\t\\{" + s_viewdf + "graph_avg}"
    +
    269  AppendText /w=$graphname "sdev\t\\{" + s_viewdf + "graph_sdev}"
    +
    270  else
    +
    271  TextBox /w=$graphname /C/N=text0 /F=0 /B=1 /X=1.00 /Y=1.00
    +
    272  lab = StringByKey("Dataset", labels, "=", "\r")
    +
    273  if (strlen(lab))
    +
    274  AppendText /w=$graphname lab
    +
    275  endif
    +
    276  AppendText /w=$graphname "sum\t\\{" + s_viewdf + "graph_sum}"
    +
    277  AppendText /w=$graphname "avg\t\\{" + s_viewdf + "graph_avg}"
    +
    278  AppendText /w=$graphname "sdev\t\\{" + s_viewdf + "graph_sdev}"
    +
    279  endif
    +
    280 
    +
    281  // interactive elements
    +
    282  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 A $imgname 0,0
    +
    283  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 B $imgname DimSize(view, 0)-1, DimSize(view, 1)-1
    +
    284  variable pcurs
    +
    285  pcurs = floor(DimSize(xprofiles, 0) / 3)
    +
    286  Cursor /w=$graphname /A=0 /P /S=1 /H=0 C xprofiles#2 pcurs
    +
    287  pcurs = floor(DimSize(xprofiles, 0) * 2 / 3)
    +
    288  Cursor /w=$graphname /A=0 /P /S=1 /H=0 D xprofiles#2 pcurs
    +
    289  pcurs = floor(DimSize(yprofiles, 0) / 3)
    +
    290  Cursor /w=$graphname /A=0 /P /S=1 /H=0 E yprofiles#2 pcurs
    +
    291  pcurs = floor(DimSize(yprofiles, 0) * 2 / 3)
    +
    292  Cursor /w=$graphname /A=0 /P /S=1 /H=0 F yprofiles#2 pcurs
    +
    293  ShowInfo /w=$graphname /CP=0
    +
    294 
    +
    295  SetWindow $graphname, hook(ad_profiles_hook)=ad_profiles_hook
    +
    296  ControlBar /w=$graphname 21
    +
    297  Button b_reset_cursors win=$graphname, title="reset cursors",pos={0,0},size={70,20},proc=PearlAreaDisplay#bp_reset_cursors
    +
    298  Button b_reset_cursors win=$graphname, fColor=(65535,65535,65535),fSize=10
    +
    299 
    +
    300  SetVariable sv_smoothing_x win=$graphname, title="X smoothing",pos={130,2},bodyWidth=40
    +
    301  SetVariable sv_smoothing_x win=$graphname, value=view_filter_smoothing_x,limits={1,100,1}
    +
    302  SetVariable sv_smoothing_x win=$graphname, proc=PearlAreaDisplay#svp_smoothing
    +
    303  SetVariable sv_smooting_y win=$graphname, title="Y smoothing",pos={240,2},bodyWidth=40
    +
    304  SetVariable sv_smooting_y win=$graphname, value=view_filter_smoothing_y,limits={1,100,1}
    +
    305  SetVariable sv_smooting_y win=$graphname, proc=PearlAreaDisplay#svp_smoothing
    +
    306 
    +
    307  PopupMenu pm_export win=$graphname, mode=0,title="Export"
    +
    308  PopupMenu pm_export win=$graphname, value="X profile;Y profile;X profile (collate);Y profile (collate)"
    +
    309  PopupMenu pm_export win=$graphname, pos={308,0},bodyWidth=60,proc=PearlAreaDisplay#pmp_export
    +
    310  PopupMenu pm_export win=$graphname, help={"Export profile of selected area and display in graph. Collate mode = display all profiles in same graph."}
    +
    311 
    +
    312  // data processing
    +
    313  ad_update_profiles(image)
    +
    314 
    +
    315  setdatafolder savedf
    +
    316  return graphname
    +
    317 end
    +
    318 
    +
    331 function /wave ad_add_overlay(image, [rgba])
    +
    332  wave image
    +
    333  string rgba
    +
    334 
    +
    335  if (ParamIsDefault(rgba))
    +
    336  rgba = "65535,65532,16385,32767"
    +
    337  elseif (ItemsInList(rgba, ",") == 3)
    +
    338  rgba += ",32767"
    +
    339  endif
    +
    340 
    +
    341  dfref savedf = GetDataFolderDFR()
    +
    342  wave view_image = get_view_image(image)
    +
    343  dfref viewdf = GetWavesDataFolderDFR(view_image)
    +
    344  svar /sdfr=viewdf graphname = prof_graphname
    +
    345  setdatafolder viewdf
    +
    346 
    +
    347  string overlayname = "view_overlay"
    +
    348  duplicate /o image, $overlayname /wave=overlay
    +
    349  redimension /b/u overlay
    +
    350  overlay = 64
    +
    351 
    +
    352  string imagenames = ImageNameList(graphname, ";")
    +
    353  if (whichlistItem(overlayname, imagenames, ";") < 0)
    +
    354  AppendImage /w=$graphname $overlayname
    +
    355  rgba = replacestring("(", rgba, "")
    +
    356  rgba = replacestring(")", rgba, "")
    +
    357  variable rr = str2num(StringFromList(0, rgba, ","))
    +
    358  variable gg = str2num(StringFromList(1, rgba, ","))
    +
    359  variable bb = str2num(StringFromList(2, rgba, ","))
    +
    360  variable aa = str2num(StringFromList(3, rgba, ","))
    +
    361 #if IgorVersion() >= 8
    +
    362  ModifyImage /w=$graphname $overlayname explicit=1,eval={0,rr,gg,bb,aa},eval={255,-1,-1,-1}
    +
    363 #else
    +
    364  ModifyImage /w=$graphname $overlayname explicit=1,eval={0,rr,gg,bb},eval={255,-1,-1,-1}
    +
    365 #endif
    +
    366  endif
    +
    367 
    +
    368  setdatafolder savedf
    +
    369  return overlay
    +
    370 end
    +
    371 
    +
    377 function ad_update_profiles(image)
    +
    378  wave image
    +
    379 
    +
    380  // data folders and references
    +
    381  dfref viewdf = get_view_folder(image)
    +
    382  if (DataFolderRefStatus(viewdf) == 0)
    +
    383  return -1 // data folder not found
    +
    384  endif
    +
    385  dfref savedf = GetDataFolderDFR()
    +
    386  setdatafolder viewdf
    +
    387 
    +
    388  // data structures
    +
    389  string viewname = "view_image"
    +
    390  duplicate /o image, $viewname /wave=view
    +
    391  string overlayname = "view_overlay"
    +
    392  wave /z overlay = $overlayname
    +
    393  if (waveexists(overlay))
    +
    394  redimension /n=(dimsize(view,0), dimsize(view,1)) overlay
    +
    395  endif
    +
    396 
    +
    397  // data processing
    +
    398  svar view_filter
    +
    399  svar view_filter_options
    +
    400  nvar smoothing_x = view_filter_smoothing_x
    +
    401  nvar smoothing_y = view_filter_smoothing_y
    +
    402  funcref ad_default_image_filter filterfunc = $view_filter
    +
    403  view_filter_options = ReplaceNumberByKey("SmoothingX", view_filter_options, smoothing_x, "=", ";")
    +
    404  view_filter_options = ReplaceNumberByKey("SmoothingY", view_filter_options, smoothing_y, "=", ";")
    +
    405  filterfunc(view, view_filter_options)
    +
    406 
    +
    407  ad_calc_cursor_profiles(view)
    +
    408 
    +
    409  setdatafolder savedf
    +
    410  return 0
    +
    411 end
    +
    412 
    +
    429 function ad_profiles_cursor_mode(image, mode)
    +
    430  wave image
    +
    431  variable mode
    +
    432 
    +
    433  dfref savedf = GetDataFolderDFR()
    +
    434  wave view_image = get_view_image(image)
    +
    435  dfref viewdf = GetWavesDataFolderDFR(view_image)
    +
    436  svar /sdfr=viewdf graphname = prof_graphname
    +
    437  nvar /sdfr=viewdf cursor_mode = view_cursor_mode
    +
    438  wave /sdfr=viewdf xprofiles, yprofiles
    +
    439 
    +
    440  variable dx = DimSize(view_image, 0)
    +
    441  variable dy = DimSize(view_image, 1)
    +
    442  switch(mode)
    +
    443  case 1: // background selection
    +
    444  Cursor /w=$graphname /A=0 /P /I /S=2 /H=1 /L=1 A view_image 0, 0
    +
    445  Cursor /w=$graphname /A=0 /P /I /S=2 /H=1 /L=1 B view_image dx-1, dy-1
    +
    446  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 C view_image round(0.2 * dx) -1, 0
    +
    447  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 D view_image round(0.8 * dx) -1, 0
    +
    448  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 E view_image round(0.4 * dx) -1, 0
    +
    449  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 F view_image round(0.6 * dx) -1, 0
    +
    450 
    +
    451  ShowInfo /w=$graphname /CP=0
    +
    452  cursor_mode = mode
    +
    453  break
    +
    454  default:
    +
    455  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 A view_image 0,0
    +
    456  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 B view_image dx-1, dy-1
    +
    457  variable pcurs
    +
    458  pcurs = floor(DimSize(xprofiles, 0) / 3)
    +
    459  Cursor /w=$graphname /A=0 /P /S=1 /H=0 C xprofiles#2 pcurs
    +
    460  pcurs = floor(DimSize(xprofiles, 0) * 2 / 3)
    +
    461  Cursor /w=$graphname /A=0 /P /S=1 /H=0 D xprofiles#2 pcurs
    +
    462  pcurs = floor(DimSize(yprofiles, 0) / 3)
    +
    463  Cursor /w=$graphname /A=0 /P /S=1 /H=0 E yprofiles#2 pcurs
    +
    464  pcurs = floor(DimSize(yprofiles, 0) * 2 / 3)
    +
    465  Cursor /w=$graphname /A=0 /P /S=1 /H=0 F yprofiles#2 pcurs
    +
    466  ShowInfo /w=$graphname /CP=0
    +
    467  cursor_mode = 0
    +
    468  endswitch
    +
    469 
    +
    470  setdatafolder savedf
    +
    471  return 0
    +
    472 end
    +
    473 
    +
    490 function ad_profiles_set_cursor(image, cursorname, xa, ya, [pscale])
    +
    491  wave image
    +
    492  string cursorname
    +
    493  variable xa, ya
    +
    494  variable pscale
    +
    495 
    +
    496  if (ParamIsDefault(pscale))
    +
    497  pscale = 0
    +
    498  endif
    +
    499 
    +
    500  // data folders and references
    +
    501  dfref savedf = GetDataFolderDFR()
    +
    502  wave view_image = get_view_image(image)
    +
    503  dfref viewdf = GetWavesDataFolderDFR(view_image)
    +
    504  svar /sdfr=viewdf graphname = prof_graphname
    +
    505 
    +
    506  variable pa, qa
    +
    507  if (pscale)
    +
    508  pa = xa
    +
    509  qa = ya
    +
    510  else
    +
    511  pa = round((xa - DimOffset(view_image, 0)) / DimDelta(view_image, 0))
    +
    512  qa = round((ya - DimOffset(view_image, 1)) / DimDelta(view_image, 1))
    +
    513  endif
    +
    514 
    +
    515  pa = min(pa, DimSize(view_image, 0) - 1)
    +
    516  pa = max(pa, 0)
    +
    517  qa = min(qa, DimSize(view_image, 1) - 1)
    +
    518  qa = max(qa, 0)
    +
    519  Cursor /i /p /w=$graphname $cursorname view_image pa, qa
    +
    520 
    +
    521  setdatafolder savedf
    +
    522  return 0
    +
    523 End
    +
    524 
    +
    535 // the lines can be removed manually using the draw toolbox, or by calling this function with @c clean=1.
    +
    542 function ad_profiles_crosshairs(image, [clear])
    +
    543  wave image
    +
    544  variable clear
    +
    545 
    +
    546  if (ParamIsDefault(clear))
    +
    547  clear = 0
    +
    548  endif
    +
    549 
    +
    550  // data folders and references
    +
    551  wave view_image = get_view_image(image)
    +
    552  dfref viewdf = GetWavesDataFolderDFR(view_image)
    +
    553  svar /sdfr=viewdf graphname = prof_graphname
    +
    554 
    +
    555  string cursors = "A;B"
    +
    556  string colors = "39168,0,0;0,26112,0"
    +
    557  string color
    +
    558  variable ncursors
    +
    559  variable icursor
    +
    560  string cursorname
    +
    561  string groupname = "crosshairs"
    +
    562  variable xx, yy
    +
    563  struct RGBColor rgb
    +
    564 
    +
    565  if (clear == 0)
    +
    566  SetDrawEnv /W=$graphname push
    +
    567  DrawAction /w=$graphname getgroup=$groupname, delete, begininsert
    +
    568  SetDrawEnv /w=$graphname gstart, gname=$groupname
    +
    569 
    +
    570  SetDrawEnv /W=$graphname dash=4
    +
    571  SetDrawEnv /W=$graphname linethick=0.5
    +
    572 
    +
    573  ncursors = ItemsInList(cursors, ";")
    +
    574  for (icursor=0; icursor < ncursors; icursor += 1)
    +
    575  cursorname = StringFromList(icursor, cursors, ";")
    +
    576  color = StringFromList(icursor, colors, ";")
    +
    577  rgb.red = str2num(StringFromList(0, color, ","))
    +
    578  rgb.green = str2num(StringFromList(1, color, ","))
    +
    579  rgb.blue = str2num(StringFromList(2, color, ","))
    +
    580  if (strlen(CsrInfo($cursorname, graphname)) > 0)
    +
    581  xx = hcsr($cursorname, graphname)
    +
    582  yy = vcsr($cursorname, graphname)
    +
    583  SetDrawEnv /W=$graphname linefgc=(rgb.red, rgb.green, rgb.blue)
    +
    584  SetDrawEnv /W=$graphname save
    +
    585  SetDrawEnv /W=$graphname xcoord=bottom, ycoord=prel
    +
    586  DrawLine /W=$graphname xx, 0, xx, 1
    +
    587  SetDrawEnv /W=$graphname xcoord=prel, ycoord=left
    +
    588  DrawLine /W=$graphname 0, yy, 1, yy
    +
    589  endif
    +
    590  endfor
    +
    591 
    +
    592  SetDrawEnv /w=$graphname gstop
    +
    593  DrawAction /w=$graphname endinsert
    +
    594  SetDrawEnv /W=$graphname pop
    +
    595  SetDrawEnv /W=$graphname save
    +
    596  else
    +
    597  DrawAction /w=$graphname getgroup=$groupname, delete
    +
    598  endif
    +
    599 
    +
    600  return 0
    +
    601 end
    +
    602 
    +
    608 static function /wave get_source_image(view)
    +
    609  wave view // image wave displayed in a profiles window
    +
    610 
    +
    611  dfref viewdf = GetWavesDataFolderDFR(view)
    +
    612  svar /z /sdfr=viewdf sourcepath
    +
    613  if (svar_exists(sourcepath))
    +
    614  wave /z img = $sourcepath
    +
    615  else
    +
    616  wave /z img = $""
    +
    617  endif
    +
    618  return img
    +
    619 end
    +
    620 
    +
    622 static function /df make_view_folder(source)
    +
    623  wave source // wave which contains the raw data from the detector.
    +
    624 
    +
    625  // data folders and references
    +
    626  dfref savedf = GetDataFolderDFR()
    +
    627  dfref imagedf = GetWavesDataFolderDFR(source)
    +
    628  string s_imagedf = GetDataFolder(1, imagedf)
    +
    629  setdatafolder imagedf
    +
    630  string s_viewdf = PearlCleanupName("view_" + NameOfWave(source))
    +
    631  newdatafolder /o/s $s_viewdf
    +
    632  dfref viewdf = GetDataFolderDFR()
    +
    633 
    +
    634  setdatafolder savedf
    +
    635  return viewdf
    +
    636 end
    +
    637 
    +
    646 static function /df get_view_folder(source)
    +
    647  wave source
    +
    648 
    +
    649  // data folders and references
    +
    650  dfref savedf = GetDataFolderDFR()
    +
    651  dfref imagedf = GetWavesDataFolderDFR(source)
    +
    652  dfref viewdf
    +
    653  setdatafolder imagedf
    +
    654  string s_viewdf = PearlCleanupName("view_" + NameOfWave(source))
    +
    655  if (DataFolderExists(s_viewdf))
    +
    656  setdatafolder $s_viewdf
    +
    657  viewdf = GetDataFolderDFR()
    +
    658  endif
    +
    659 
    +
    660  setdatafolder savedf
    +
    661  return viewdf
    +
    662 end
    +
    663 
    +
    669 static function /wave get_view_image(source)
    +
    670  wave source
    +
    671 
    +
    672  dfref viewdf = get_view_folder(source)
    +
    673  string viewname = "view_image"
    +
    674  wave /sdfr=viewdf view = $viewname
    +
    675 
    +
    676  return view
    +
    677 end
    +
    678 
    +
    679 static function bp_reset_cursors(ba) : ButtonControl
    +
    680  STRUCT WMButtonAction &ba
    +
    681 
    +
    682  switch( ba.eventCode )
    +
    683  case 2: // mouse up
    +
    684  string imgname = StringFromList(0, ImageNameList(ba.win, ";"))
    +
    685  wave /z image = ImageNameToWaveRef(ba.win, imgname)
    +
    686  if (waveexists(image))
    +
    687  Cursor /i/p A $imgname 0,0
    +
    688  Cursor /i/p B $imgname DimSize(image, 0)-1, DimSize(image, 1)-1
    +
    689  endif
    +
    690  break
    +
    691  case -1: // control being killed
    +
    692  break
    +
    693  endswitch
    +
    694 
    +
    695  return 0
    +
    696 End
    +
    697 
    +
    698 static function svp_smoothing(sva) : SetVariableControl
    +
    699  STRUCT WMSetVariableAction &sva
    +
    700 
    +
    701  string imglist
    +
    702 
    +
    703  switch( sva.eventCode )
    +
    704  case 1: // mouse up
    +
    705  case 2: // Enter key
    +
    706  case 3: // Live update
    +
    707  imglist = ImageNameList(sva.win, ";")
    +
    708  wave /z img = ImageNameToWaveRef(sva.win, StringFromList(0, imglist))
    +
    709  if (WaveExists(img))
    +
    710  wave source = get_source_image(img)
    +
    711  if (WaveExists(source))
    +
    712  ad_update_profiles(source)
    +
    713  endif
    +
    714  endif
    +
    715  break
    +
    716  case -1: // control being killed
    +
    717  break
    +
    718  endswitch
    +
    719 
    +
    720  return 0
    +
    721 end
    +
    722 
    +
    723 static function pmp_export(pa) : PopupMenuControl
    +
    724  STRUCT WMPopupAction &pa
    +
    725 
    +
    726  switch( pa.eventCode )
    +
    727  case 2: // mouse up
    +
    728  variable popNum = pa.popNum
    +
    729 
    +
    730  string imgname = StringFromList(0, ImageNameList(pa.win, ";"))
    +
    731  wave /z image = ImageNameToWaveRef(pa.win, imgname)
    +
    732  if (waveexists(image) && (popNum >= 1) && (popNum <= 2))
    +
    733  ad_export_profile(image, popNum - 1, show=1)
    +
    734  elseif (waveexists(image) && (popNum >= 3) && (popNum <= 4))
    +
    735  ad_export_profile(image, popNum - 3, show=2)
    +
    736  endif
    +
    737 
    +
    738  break
    +
    739  case -1: // control being killed
    +
    740  break
    +
    741  endswitch
    +
    742 
    +
    743  return 0
    +
    744 End
    +
    745 
    +
    747 function ad_profiles_hook(s)
    +
    748  struct WMWinHookStruct &s
    +
    749  variable hookresult = 0
    +
    750  string imglist
    +
    751  string cmd
    +
    752  dfref viewdf
    +
    753 
    +
    754  switch(s.eventCode)
    +
    755  case 2: // delete data folder after window is killed
    +
    756  imglist = ImageNameList(s.winName, ";")
    +
    757  wave /z img = ImageNameToWaveRef(s.winName, StringFromList(0, imglist))
    +
    758  if (WaveExists(img))
    +
    759  viewdf = GetWavesDataFolderDFR(img)
    +
    760  cmd = "killdatafolder /z " + GetDataFolder(1, viewdf)
    +
    761  Execute /P/Q/Z cmd
    +
    762  endif
    +
    763  break
    +
    764  case 7: // update profiles when cursor is moved
    +
    765  imglist = ImageNameList(s.winName, ";")
    +
    766  wave /z img = ImageNameToWaveRef(s.winName, StringFromList(0, imglist))
    +
    767  if (WaveExists(img))
    +
    768  ad_calc_cursor_profiles(img)
    +
    769  hookresult = 1
    +
    770  else
    +
    771  hookresult = 0
    +
    772  endif
    +
    773  break
    +
    774  endswitch
    +
    775 
    +
    776  return hookresult
    +
    777 end
    +
    778 
    +
    787 function ad_calc_cursor_profiles(image)
    +
    788  wave image
    +
    789 
    +
    790  dfref savedf = GetDataFolderDFR()
    +
    791  dfref imagedf = GetWavesDataFolderDFR(image)
    +
    792  setdatafolder imagedf
    +
    793 
    +
    794  svar graphname = prof_graphname
    +
    795 
    +
    796  variable pa, qa // point coordinates cursor A
    +
    797  if (strlen(CsrInfo(A, graphname)) > 0)
    +
    798  pa = pcsr(A, graphname)
    +
    799  qa = qcsr(A, graphname)
    +
    800  else
    +
    801  pa = 0
    +
    802  qa = 0
    +
    803  endif
    +
    804 
    +
    805  variable pb, qb // point coordinates cursor B
    +
    806  if (strlen(CsrInfo(B, graphname)) > 0)
    +
    807  pb = pcsr(B, graphname)
    +
    808  qb = qcsr(B, graphname)
    +
    809  else
    +
    810  pb = DimSize(image, 0) - 1
    +
    811  qb = DimSize(image, 1) - 1
    +
    812  endif
    +
    813 
    +
    814  ad_calc_profiles(image, pa, qa, pb, qb)
    +
    815  setdatafolder savedf
    +
    816 end
    +
    817 
    +
    834 function ad_calc_profiles(image, pa, qa, pb, qb)
    +
    835  wave image
    +
    836  variable pa, qa
    +
    837  variable pb, qb
    +
    838 
    +
    839  dfref savedf = GetDataFolderDFR()
    +
    840  dfref imagedf = GetWavesDataFolderDFR(image)
    +
    841  setdatafolder imagedf
    +
    842 
    +
    843  wave xprofiles
    +
    844  wave yprofiles
    +
    845  nvar graph_avg
    +
    846  nvar graph_min
    +
    847  nvar graph_max
    +
    848  nvar graph_sum
    +
    849  nvar graph_sdev
    +
    850 
    +
    851  // horizontal profiles at crosshairs
    +
    852  redimension /n=(dimsize(image,0), 3) xprofiles
    +
    853  setscale /p x dimoffset(image,0), dimdelta(image,0), WaveUnits(image,0), xprofiles
    +
    854  setscale d 0, 0, waveunits(image,-1), xprofiles
    +
    855  xprofiles[][0] = image[p][qa]
    +
    856  xprofiles[][1] = image[p][qb]
    +
    857 
    +
    858  note /k xprofiles
    +
    859  note xprofiles, "SourceWave=" + nameofwave(image)
    +
    860  note xprofiles, "SourceDimension=0"
    +
    861  note xprofiles, "SourceIndex0=" + num2str(qa)
    +
    862  note xprofiles, "SourceIndex1=" + num2str(qb)
    +
    863 
    +
    864  // average horizontal profile between crosshairs
    +
    865  variable qq, q0, q1
    +
    866  q0 = min(qa, qb)
    +
    867  q1 = max(qa, qb)
    +
    868  xprofiles[][2] = 0
    +
    869  for (qq = q0; qq <= q1; qq += 1)
    +
    870  xprofiles[][2] += image[p][qq]
    +
    871  endfor
    +
    872  xprofiles[][2] /= q1 - q0 + 1
    +
    873 
    +
    874  // vertical profiles at crosshairs
    +
    875  redimension /n=(dimsize(image,1), 3) yprofiles
    +
    876  setscale /p x dimoffset(image,1), dimdelta(image,1), WaveUnits(image,1), yprofiles
    +
    877  setscale d 0, 0, waveunits(image,-1), yprofiles
    +
    878  yprofiles[][0] = image[pa][p]
    +
    879  yprofiles[][1] = image[pb][p]
    +
    880 
    +
    881  note /k yprofiles
    +
    882  note yprofiles, "SourceWave=" + nameofwave(image)
    +
    883  note yprofiles, "SourceDimension=1"
    +
    884  note yprofiles, "SourceIndex0=" + num2str(pa)
    +
    885  note yprofiles, "SourceIndex1=" + num2str(pb)
    +
    886 
    +
    887  // average vertical profile between crosshairs
    +
    888  variable pp, p0, p1
    +
    889  p0 = min(pa, pb)
    +
    890  p1 = max(pa, pb)
    +
    891  yprofiles[][2] = 0
    +
    892  for (pp = p0; pp <= p1; pp += 1)
    +
    893  yprofiles[][2] += image[pp][p]
    +
    894  endfor
    +
    895  yprofiles[][2] /= p1 - p0 + 1
    +
    896 
    +
    897  // statistics between crosshairs
    +
    898  Duplicate /r=[p0,p1][q0,q1]/o image, roi_image
    +
    899  WaveStats /Q roi_image
    +
    900  graph_avg = v_avg
    +
    901  graph_min = v_min
    +
    902  graph_max = v_max
    +
    903  graph_sum = v_avg * v_npnts
    +
    904  graph_sdev = v_sdev
    +
    905 
    +
    906  // histogram
    +
    907  wave /z hist
    +
    908  if (waveexists(hist))
    +
    909  Histogram /B=3 roi_image, hist
    +
    910  endif
    +
    911 
    +
    912  setdatafolder savedf
    +
    913 end
    +
    914 
    +
    936 function ad_export_profile(view_image, dim, [trace, show, overwrite])
    +
    937  wave view_image
    +
    938  variable dim
    +
    939  variable trace
    +
    940  variable show
    +
    941  variable overwrite
    +
    942 
    +
    943  dfref savedf = GetDataFolderDFR()
    +
    944 
    +
    945  if (ParamIsDefault(trace))
    +
    946  trace = 2
    +
    947  endif
    +
    948  if (ParamIsDefault(show))
    +
    949  show = 0
    +
    950  endif
    +
    951  if (ParamIsDefault(overwrite))
    +
    952  overwrite = 0
    +
    953  endif
    +
    954 
    +
    955  // view folder
    +
    956  dfref imagedf = GetWavesDataFolderDFR(view_image)
    +
    957  string dim_label
    +
    958  switch(dim)
    +
    959  case 0:
    +
    960  wave /sdfr=imagedf profiles=xprofiles
    +
    961  dim_label = "x"
    +
    962  break
    +
    963  case 1:
    +
    964  wave /sdfr=imagedf profiles=yprofiles
    +
    965  dim_label = "y"
    +
    966  break
    +
    967  default:
    +
    968  return -1 // invalid argument
    +
    969  endswitch
    +
    970  string graphname_string = "export_graph_" + dim_label
    +
    971  svar /z /sdfr=imagedf linked_graphname = $graphname_string
    +
    972 
    +
    973  // source folder
    +
    974  wave /z source_image = get_source_image(view_image)
    +
    975  if (WaveExists(source_image))
    +
    976  dfref sourcedf = GetWavesDataFolderDFR(source_image)
    +
    977  setdatafolder sourcedf
    +
    978  else
    +
    979  return -2 // invalid source data folder
    +
    980  endif
    +
    981 
    +
    982  // format dest wave name
    +
    983  string profile_note = note(profiles)
    +
    984  string name_base
    +
    985  string name_dim
    +
    986  string name_index
    +
    987  string profile_name
    +
    988  variable index_width = ceil(log(DimSize(view_image, 1 - dim)))
    +
    989  variable index0 = NumberByKey("SourceIndex0", profile_note, "=", "\r")
    +
    990  variable index1 = NumberByKey("SourceIndex1", profile_note, "=", "\r")
    +
    991  name_dim = "_" + dim_label
    +
    992  sprintf name_index, "%0*u_%0*u", index_width, index0, index_width, index1
    +
    993  name_base = NameOfWave(source_image)
    +
    994  name_base = name_base[0, min(strlen(name_base), 31 - strlen(name_index) - strlen(name_dim) - 1)]
    +
    995  profile_name = name_base + name_dim + name_index
    +
    996  if ((overwrite == 0) && (CheckName(profile_name, 1)))
    +
    997  profile_name = UniqueName(profile_name + "_", 1, 0)
    +
    998  endif
    +
    999 
    +
    1000  // create dest wave
    +
    1001  duplicate /o /r=[][trace] profiles, $profile_name /wave=dest_profile
    +
    1002  redimension /n=(dimsize(profiles, 0)) dest_profile
    +
    1003  profile_note = ReplaceStringByKey("SourceWave", profile_note, NameOfWave(source_image), "=", "\r")
    +
    1004  note /k dest_profile
    +
    1005  note dest_profile, profile_note
    +
    1006  print "created", GetWavesDataFolder(dest_profile, 2)
    +
    1007 
    +
    1008  if (show)
    +
    1009  string graphname
    +
    1010  string graphtitle
    +
    1011  if (show == 2)
    +
    1012  // common graph for all profiles of a dimension
    +
    1013  graphname = "export_profiles_" + dim_label
    +
    1014  graphtitle = UpperStr(dim_label) + " Profiles"
    +
    1015  else
    +
    1016  // one graph per source image
    +
    1017  if (svar_exists(linked_graphname) && (ItemsInList(WinList(linked_graphname, ";", "WIN:1"), ";") >= 1))
    +
    1018  graphname = linked_graphname
    +
    1019  else
    +
    1020  graphname = GetWavesDataFolder(source_image, 0) + name_dim
    +
    1021  endif
    +
    1022  graphtitle = UpperStr(dim_label) + " Profiles: " + GetWavesDataFolder(source_image, 2)
    +
    1023  endif
    +
    1024 
    +
    1025  if ((ItemsInList(WinList(graphname, ";", "WIN:1"), ";") >= 1))
    +
    1026  appendtograph /w=$graphname dest_profile
    +
    1027  else
    +
    1028  setdatafolder imagedf
    +
    1029  display /k=1 /n=$graphname dest_profile as graphtitle
    +
    1030  graphname = s_name
    +
    1031  ModifyGraph /w=$graphname mirror=1,nticks=3,minor=1
    +
    1032  ModifyGraph /w=$graphname axThick=0.5,btLen=4
    +
    1033  ModifyGraph /w=$graphname gfSize=10
    +
    1034  ModifyGraph /w=$graphname grid=2,gridHair=0,gridRGB=(52224,52224,52224)
    +
    1035  Legend /w=$graphname /C/N=legend0/F=0/B=1/A=LT/X=0.00/Y=0.00
    +
    1036 
    +
    1037  if (show != 2)
    +
    1038  string /g $graphname_string = graphname
    +
    1039  endif
    +
    1040  endif
    +
    1041  endif
    +
    1042 
    +
    1043  setdatafolder savedf
    +
    1044  return 0
    +
    1045 end
    +
    1046 
    +
    1047 static function set_trace_colors(graphname)
    +
    1048  string graphname
    +
    1049 
    +
    1050  ModifyGraph /w=$graphname /z rgb[0]=(0, 0, 0)
    +
    1051  ModifyGraph /w=$graphname /z rgb[1]=(65535, 16385, 16385)
    +
    1052  ModifyGraph /w=$graphname /z rgb[2]=(2, 39321, 1)
    +
    1053  ModifyGraph /w=$graphname /z rgb[3]=(0, 0, 65535)
    +
    1054  ModifyGraph /w=$graphname /z rgb[4]=(39321, 1, 31457)
    +
    1055  ModifyGraph /w=$graphname /z rgb[5]=(48059, 48059, 48059)
    +
    1056  ModifyGraph /w=$graphname /z rgb[6]=(65535, 32768, 32768)
    +
    1057  ModifyGraph /w=$graphname /z rgb[7]=(0, 65535, 0)
    +
    1058  ModifyGraph /w=$graphname /z rgb[8]=(16385,65535,65535)
    +
    1059  ModifyGraph /w=$graphname /z rgb[9]=(65535, 32768, 58981)
    +
    1060 end
    +
    1061 
    +
    1068 function ad_calc_histogram(image)
    +
    1069  wave image
    +
    1070 
    +
    1071  dfref savedf = GetDataFolderDFR()
    +
    1072  dfref imagedf = GetWavesDataFolderDFR(image)
    +
    1073  setdatafolder imagedf
    +
    1074 
    +
    1075  wave hist
    +
    1076  Histogram /B=3 image, hist
    +
    1077 
    +
    1078  setdatafolder savedf
    +
    1079 end
    +
    1080 
    +
    1091 function ad_default_image_filter(image, options)
    +
    1092  wave image
    +
    1093  string options
    +
    1094 end
    +
    1095 
    +
    1105 function ad_box_filter(image, options)
    +
    1106  wave image
    +
    1107  string options
    +
    1108 
    +
    1109  variable xsmoothing = NumberByKey("SmoothingX", options, "=", ";")
    +
    1110  variable ysmoothing = NumberByKey("SmoothingY", options, "=", ";")
    +
    1111 
    +
    1112  if ((NumType(xsmoothing) == 0) && (xsmoothing >= 2))
    +
    1113  Smooth /B /DIM=0 /E=3 xsmoothing, image
    +
    1114  endif
    +
    1115  if ((NumType(ysmoothing) == 0) && (ysmoothing >= 2))
    +
    1116  Smooth /B /DIM=1 /E=3 ysmoothing, image
    +
    1117  endif
    +
    1118 end
    +
    1119 
    +
    1127 function ad_transpose_filter(image, options)
    +
    1128  wave image
    +
    1129  string options
    +
    1130 
    +
    1131  MatrixTranspose image
    +
    1132 end
    +
    1133 
    +
    1134 
    +
    1135 // ################### 3D DATA ##################
    +
    1136 
    +
    1143 function /s ad_display_brick(data)
    +
    1144  wave data
    +
    1145 
    +
    1146  if(exists("NewGizmo") != 4)
    +
    1147  abort "Gizmo XOP must be installed."
    +
    1148  endif
    +
    1149  if (WaveDims(data) != 3)
    +
    1150  abort "ad_display_brick: data must be three-dimensional."
    +
    1151  endif
    +
    1152 
    +
    1153  dfref savedf = GetDataFolderDFR()
    +
    1154  dfref datadf = GetWavesDataFolderDFR(data)
    +
    1155  string s_datadf = GetDataFolder(1, datadf)
    +
    1156  dfref viewdf = make_view_folder(data)
    +
    1157 
    +
    1158  setdatafolder viewdf
    +
    1159  string dfname = ReplaceString("root:", s_datadf, "")
    +
    1160  string graphtitle = dfname + " Gizmo"
    +
    1161  string /g gizmo_graphname = graphname_from_dfref(datadf, "giz_")
    +
    1162  svar graphname = gizmo_graphname
    +
    1163 
    +
    1164  if ((strlen(graphname) > 0) && (wintype(graphname) == 13))
    +
    1165  setdatafolder savedf
    +
    1166  return graphname // gizmo window exists
    +
    1167  endif
    +
    1168 
    +
    1169  variable nx = dimsize(data, 0)
    +
    1170  variable ny = dimsize(data, 1)
    +
    1171  variable nz = dimsize(data, 2)
    +
    1172 
    +
    1173  variable pp
    +
    1174  string obj
    +
    1175  string cmd
    +
    1176 
    +
    1177  // igor does not allow calling gizmo functions directly
    +
    1178  setdatafolder datadf
    +
    1179  sprintf cmd, "NewGizmo /k=1 /n=%s /w=(100,100,500,400) /t=\"%s\"", graphname, graphtitle
    +
    1180  execute /q cmd
    +
    1181  cmd = "AppendToGizmo /D Axes=BoxAxes, name=axes0"
    +
    1182  execute /q cmd
    +
    1183 
    +
    1184  obj = "surface_xmid"
    +
    1185  pp = round(nx / 2 - 1)
    +
    1186  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
    +
    1187  execute /q cmd
    +
    1188  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 128}", obj
    +
    1189  execute /q cmd
    +
    1190  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
    +
    1191  execute /q cmd
    +
    1192  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
    +
    1193  execute /q cmd
    +
    1194  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
    +
    1195  execute /q cmd
    +
    1196  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
    +
    1197  execute /q cmd
    +
    1198 
    +
    1199  obj = "surface_ymid"
    +
    1200  pp = round(ny / 2 - 1)
    +
    1201  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
    +
    1202  execute /q cmd
    +
    1203  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 64}", obj
    +
    1204  execute /q cmd
    +
    1205  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
    +
    1206  execute /q cmd
    +
    1207  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
    +
    1208  execute /q cmd
    +
    1209  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
    +
    1210  execute /q cmd
    +
    1211  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
    +
    1212  execute /q cmd
    +
    1213 
    +
    1214  obj = "surface_zmid"
    +
    1215  pp = round(nz / 2 - 1)
    +
    1216  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
    +
    1217  execute /q cmd
    +
    1218  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 32}", obj
    +
    1219  execute /q cmd
    +
    1220  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
    +
    1221  execute /q cmd
    +
    1222  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
    +
    1223  execute /q cmd
    +
    1224  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
    +
    1225  execute /q cmd
    +
    1226  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
    +
    1227  execute /q cmd
    +
    1228 
    +
    1229  obj = "axes0"
    +
    1230  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={-1,axisScalingMode,1}", obj
    +
    1231  execute /q cmd
    +
    1232  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={-1,axisColor,0,0,0,1}", obj
    +
    1233  execute /q cmd
    +
    1234  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={0,ticks,3}", obj
    +
    1235  execute /q cmd
    +
    1236  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={1,ticks,3}", obj
    +
    1237  execute /q cmd
    +
    1238  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={2,ticks,3}", obj
    +
    1239  execute /q cmd
    +
    1240  sprintf cmd, "ModifyGizmo modifyObject=%s property={Clipped,0}", obj
    +
    1241  execute /q cmd
    +
    1242  sprintf cmd, "ModifyGizmo modifyObject=%s property={-1,fontScaleFactor,2}", obj
    +
    1243  execute /q cmd
    +
    1244 
    +
    1245  sprintf cmd, "ModifyGizmo showAxisCue=1"
    +
    1246  execute /q cmd
    +
    1247 
    +
    1248  setdatafolder savedf
    +
    1249  return graphname
    +
    1250 end
    +
    1251 
    +
    1258 function ad_brick_slicer(data)
    +
    1259  wave data
    +
    1260 
    +
    1261  // data folders and references
    +
    1262  dfref savedf = GetDataFolderDFR()
    +
    1263  dfref datadf = GetWavesDataFolderDFR(data)
    +
    1264  string s_datadf = GetDataFolder(1, datadf)
    +
    1265  dfref viewdf = make_view_folder(data)
    +
    1266 
    +
    1267  setdatafolder viewdf
    +
    1268  svar /z ex_panel = slicer_panelname
    +
    1269  if (svar_exists(ex_panel))
    +
    1270  string panels = WinList("SlicerPanel*", ";", "WIN:64")
    +
    1271  if (WhichListItem(ex_panel, panels, ";") >= 0)
    +
    1272  dowindow /f $(StringFromList(0, panels, ";"))
    +
    1273  return 0
    +
    1274  endif
    +
    1275  endif
    +
    1276 
    +
    1277  variable /g x_slice_pos
    +
    1278  variable /g y_slice_pos
    +
    1279  variable /g z_slice_pos
    +
    1280  variable /g slab_thickness
    +
    1281  string /g brick_path = getwavesdatafolder(data, 2)
    +
    1282  variable /g x_autoinc = 0
    +
    1283  variable /g y_autoinc = 0
    +
    1284  variable /g z_autoinc = 0
    +
    1285 
    +
    1286  // axis labels
    +
    1287  string labels = note(data)
    +
    1288  string xlabel = StringByKey("AxisLabelX", labels, "=", "\r")
    +
    1289  if (!strlen(xlabel))
    +
    1290  xlabel = "X"
    +
    1291  endif
    +
    1292  string ylabel = StringByKey("AxisLabelY", labels, "=", "\r")
    +
    1293  if (!strlen(ylabel))
    +
    1294  ylabel = "Y"
    +
    1295  endif
    +
    1296  string zlabel = StringByKey("AxisLabelZ", labels, "=", "\r")
    +
    1297  if (!strlen(zlabel))
    +
    1298  zlabel = "Z"
    +
    1299  endif
    +
    1300  string dlabel = StringByKey("Dataset", labels, "=", "\r")
    +
    1301  if (!strlen(dlabel))
    +
    1302  dlabel = NameOfWave(data)
    +
    1303  endif
    +
    1304 
    +
    1305  // this section copied from slicer panel
    +
    1306  NewPanel /k=1 /W=(500,600,890,940) /N=SlicerPanel as "Brick Slicer"
    +
    1307  string /g slicer_panelname = S_name
    +
    1308  string panel = s_name
    +
    1309 
    +
    1310  GroupBox g_xslice win=$panel,pos={8,8},size={376,96},title=xlabel
    +
    1311  Slider sl_xslice_position win=$panel,pos={16,32},size={240,56},proc=PearlAreaDisplay#slp_slice_position
    +
    1312  Slider sl_xslice_position win=$panel,limits={0,100,1},variable=x_slice_pos,vert= 0
    +
    1313  SetVariable sv_xslice_position win=$panel,pos={20,80},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="X"
    +
    1314  SetVariable sv_xslice_position win=$panel,limits={0,100,1},value=x_slice_pos
    +
    1315  Button b_xslice_center win=$panel,pos={122,80},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
    +
    1316  Button b_xslice_center win=$panel,help={"reset to center position"}
    +
    1317  Button b_xslice_extract win=$panel,pos={288,80},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
    +
    1318  Button b_xslice_extract win=$panel,help={"extract this slice to a separate wave"}
    +
    1319  //CheckBox cb_xslab_active win=$panel,pos={288,80},size={80,16},title="Display X Slab"
    +
    1320  //CheckBox cb_xslab_active win=$panel,value= 0
    +
    1321  TitleBox tb_xslice_animation win=$panel,pos={288,32},size={356,16},title="animation",frame=0
    +
    1322  TitleBox tb_xslice_animation win=$panel,anchor= MC
    +
    1323  Button b_xslice_back win=$panel,pos={288,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
    +
    1324  Button b_xslice_back win=$panel,help={"animate backwards"}
    +
    1325  Button b_xslice_forward win=$panel,pos={312,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
    +
    1326  Button b_xslice_forward win=$panel,help={"animate forward"}
    +
    1327  Button b_xslice_stop win=$panel,pos={336,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
    +
    1328  Button b_xslice_stop win=$panel,help={"stop animation"}
    +
    1329 
    +
    1330  GroupBox g_yslice win=$panel,pos={8,108},size={376,96},title=ylabel
    +
    1331  Slider sl_yslice_position win=$panel,pos={16,132},size={240,56},proc=PearlAreaDisplay#slp_slice_position
    +
    1332  Slider sl_yslice_position win=$panel,limits={0,100,1},variable=y_slice_pos,vert= 0
    +
    1333  SetVariable sv_yslice_position win=$panel,pos={20,180},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="Y"
    +
    1334  SetVariable sv_yslice_position win=$panel,limits={0,100,1},value=y_slice_pos
    +
    1335  Button b_yslice_center win=$panel,pos={122,180},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
    +
    1336  Button b_yslice_center win=$panel,help={"reset to center position"}
    +
    1337  Button b_yslice_extract win=$panel,pos={288,180},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
    +
    1338  Button b_yslice_extract win=$panel,help={"extract this slice to a separate wave"}
    +
    1339  //CheckBox cb_yslab_active win=$panel,pos={288,180},size={80,16},title="Display Y Slab"
    +
    1340  //CheckBox cb_yslab_active win=$panel,value= 0
    +
    1341  TitleBox tb_yslice_animation win=$panel,pos={288,132},size={356,16},title="animation",frame=0
    +
    1342  TitleBox tb_yslice_animation win=$panel,anchor= MC
    +
    1343  Button b_yslice_back win=$panel,pos={288,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
    +
    1344  Button b_yslice_back win=$panel,help={"animate backwards"}
    +
    1345  Button b_yslice_forward win=$panel,pos={312,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
    +
    1346  Button b_yslice_forward win=$panel,help={"animate forward"}
    +
    1347  Button b_yslice_stop win=$panel,pos={336,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
    +
    1348  Button b_yslice_stop win=$panel,help={"stop animation"}
    +
    1349 
    +
    1350  GroupBox g_zslice win=$panel,pos={8,208},size={376,96},title=zlabel
    +
    1351  Slider sl_zslice_position win=$panel,pos={16,232},size={240,56},proc=PearlAreaDisplay#slp_slice_position
    +
    1352  Slider sl_zslice_position win=$panel,limits={0,100,1},variable=z_slice_pos,vert= 0
    +
    1353  SetVariable sv_zslice_position win=$panel,pos={20,280},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="Z"
    +
    1354  SetVariable sv_zslice_position win=$panel,limits={0,100,1},value=z_slice_pos
    +
    1355  Button b_zslice_center win=$panel,pos={122,280},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
    +
    1356  Button b_zslice_center win=$panel,help={"reset to center position"}
    +
    1357  Button b_zslice_extract win=$panel,pos={288,280},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
    +
    1358  Button b_zslice_extract win=$panel,help={"extract this slice to a separate wave"}
    +
    1359  //CheckBox cb_zslab_active win=$panel,pos={288,280},size={80,16},title="Display Z Slab"
    +
    1360  //CheckBox cb_zslab_active win=$panel,value= 0
    +
    1361  TitleBox tb_zslice_animation win=$panel,pos={288,232},size={356,16},title="animation",frame=0
    +
    1362  TitleBox tb_zslice_animation win=$panel,anchor= MC
    +
    1363  Button b_zslice_back win=$panel,pos={288,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
    +
    1364  Button b_zslice_back win=$panel,help={"animate backwards"}
    +
    1365  Button b_zslice_forward win=$panel,pos={312,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
    +
    1366  Button b_zslice_forward win=$panel,help={"animate forward"}
    +
    1367  Button b_zslice_stop win=$panel,pos={336,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
    +
    1368  Button b_zslice_stop win=$panel,help={"stop animation"}
    +
    1369 
    +
    1370  TitleBox t_slicerpath win=$panel,pos={8,316},size={128,20},disable=2,title=dlabel
    +
    1371  //SetVariable setvar0 win=$panel,pos={240,316},size={120,16},title="slab thickness"
    +
    1372  //SetVariable setvar0 win=$panel,limits={1,inf,1},value=slab_thickness
    +
    1373 
    +
    1374  // update control limits and move slicing planes to the center
    +
    1375  setwindow $panel, userdata(control_datafolder) = GetDataFolder(1, viewdf)
    +
    1376  setwindow $panel, userdata(brick_path) = brick_path
    +
    1377  update_slice_info()
    +
    1378  x_slice_pos = dimoffset(data, 0) + dimsize(data, 0) * dimdelta(data, 0) / 2
    +
    1379  y_slice_pos = dimoffset(data, 1) + dimsize(data, 1) * dimdelta(data, 1) / 2
    +
    1380  z_slice_pos = dimoffset(data, 2) + dimsize(data, 2) * dimdelta(data, 2) / 2
    +
    1381 
    +
    1382  svar /z /sdfr=viewdf gizmo_graphname
    +
    1383  if (svar_exists(gizmo_graphname) && (strlen(gizmo_graphname) > 0) && (wintype(gizmo_graphname) == 13))
    +
    1384  ad_gizmo_set_plane(data, 0, x_slice_pos)
    +
    1385  ad_gizmo_set_plane(data, 1, y_slice_pos)
    +
    1386  ad_gizmo_set_plane(data, 2, z_slice_pos)
    +
    1387  endif
    +
    1388  svar /z /sdfr=viewdf slice_graphname
    +
    1389  if (svar_exists(slice_graphname) && (strlen(slice_graphname) > 0) && (wintype(slice_graphname) == 1))
    +
    1390  ad_profiles_set_slice(data, 2, z_slice_pos)
    +
    1391  endif
    +
    1392 
    +
    1393  ad_slicer_init_bg()
    +
    1394  setdatafolder savedf
    +
    1395 end
    +
    1396 
    +
    1406 function /s ad_display_slice(data)
    +
    1407  wave data
    +
    1408 
    +
    1409  if (WaveDims(data) != 3)
    +
    1410  abort "ad_display_slice: data must be three-dimensional."
    +
    1411  endif
    +
    1412 
    +
    1413  dfref savedf = GetDataFolderDFR()
    +
    1414  dfref datadf = GetWavesDataFolderDFR(data)
    +
    1415  string s_datadf = GetDataFolder(1, datadf)
    +
    1416  dfref viewdf = make_view_folder(data)
    +
    1417 
    +
    1418  setdatafolder viewdf
    +
    1419  string dfname = ReplaceString("root:", s_datadf, "")
    +
    1420  dfname = dfname[0, strlen(dfname) - 2]
    +
    1421  string graphtitle = dfname + " Slice"
    +
    1422 
    +
    1423  if (exists("slice_graphname") != 2)
    +
    1424  string /g slice_graphname = ""
    +
    1425  endif
    +
    1426  string /g slice_wavename = PearlCleanupName("slice_" + NameOfWave(data))
    +
    1427  svar graphname = slice_graphname
    +
    1428  svar slicename = slice_wavename
    +
    1429 
    +
    1430  make /n=(1,1)/o $slicename
    +
    1431  wave slice = $slicename
    +
    1432  if ((strlen(graphname) == 0) || (wintype(graphname) != 1))
    +
    1433  graphname = ad_display_profiles(slice)
    +
    1434  endif
    +
    1435  variable z_slice_pos = dimoffset(data, 2) + dimsize(data, 2) * dimdelta(data, 2) / 2
    +
    1436  ad_profiles_set_slice(data, 2, z_slice_pos)
    +
    1437  ad_profiles_set_cursor(slice, "A", -inf, -inf, pscale=1)
    +
    1438  ad_profiles_set_cursor(slice, "B", +inf, +inf, pscale=1)
    +
    1439 
    +
    1440  setdatafolder savedf
    +
    1441  return graphname
    +
    1442 end
    +
    1443 
    +
    1447 static function update_slice_info()
    +
    1448  dfref savedf = GetDataFolderDFR()
    +
    1449 
    +
    1450  svar brick_path
    +
    1451  //svar slicer_panelname
    +
    1452  wave brick = $brick_path
    +
    1453 
    +
    1454  //dowindow /F $slicer_panelname
    +
    1455  variable lo, hi, inc
    +
    1456  lo = dimoffset(brick, 0)
    +
    1457  inc = dimdelta(brick, 0)
    +
    1458  hi = lo + inc * (dimsize(brick, 0) - 1)
    +
    1459  Slider sl_xslice_position,limits={lo,hi,inc}
    +
    1460  SetVariable sv_xslice_position,limits={lo,hi,inc}
    +
    1461  lo = dimoffset(brick, 1)
    +
    1462  inc = dimdelta(brick, 1)
    +
    1463  hi = lo + inc * (dimsize(brick, 1) - 1)
    +
    1464  Slider sl_yslice_position,limits={lo,hi,inc}
    +
    1465  SetVariable sv_yslice_position,limits={lo,hi,inc}
    +
    1466  lo = dimoffset(brick, 2)
    +
    1467  inc = dimdelta(brick, 2)
    +
    1468  hi = lo + inc * (dimsize(brick, 2) - 1)
    +
    1469  Slider sl_zslice_position,limits={lo,hi,inc}
    +
    1470  SetVariable sv_zslice_position,limits={lo,hi,inc}
    +
    1471 
    +
    1472  setdatafolder savedf
    +
    1473 end
    +
    1474 
    +
    1483 function ad_gizmo_set_plane(brick, dim, value)
    +
    1484  wave brick
    +
    1485  variable dim
    +
    1486  variable value
    +
    1487 
    +
    1488  dfref savedf = GetDataFolderDFR()
    +
    1489  dfref datadf = GetWavesDataFolderDFR(brick)
    +
    1490  dfref viewdf = get_view_folder(brick)
    +
    1491  svar /z /sdfr=viewdf graphname=gizmo_graphname
    +
    1492 
    +
    1493  variable pp = round((value - dimoffset(brick, dim)) / dimdelta(brick, dim))
    +
    1494  if ((pp < 0) || (pp >= dimsize(brick, dim)))
    +
    1495  return -1 // requested value out of range
    +
    1496  endif
    +
    1497 
    +
    1498  if (svar_exists(graphname) && (strlen(graphname) > 0) && (wintype(graphname) == 13))
    +
    1499  string axes = "xyz"
    +
    1500  string obj = "surface_" + axes[dim] + "mid"
    +
    1501  string cmd
    +
    1502  sprintf cmd, "ModifyGizmo /N=%s ModifyObject=%s, property={plane, %d}", graphname, obj, pp
    +
    1503  execute /q cmd
    +
    1504  else
    +
    1505  return -2 // gizmo window not found
    +
    1506  endif
    +
    1507 
    +
    1508  return 0
    +
    1509 end
    +
    1510 
    +
    1519 function ad_profiles_set_slice(brick, dim, value)
    +
    1520  wave brick
    +
    1521  variable dim
    +
    1522  variable value
    +
    1523 
    +
    1524  dfref savedf = GetDataFolderDFR()
    +
    1525  dfref datadf = GetWavesDataFolderDFR(brick)
    +
    1526  dfref viewdf = get_view_folder(brick)
    +
    1527  svar /z /sdfr=viewdf graphname = slice_graphname
    +
    1528  svar /z /sdfr=viewdf slicename = slice_wavename
    +
    1529 
    +
    1530  variable pp = round((value - dimoffset(brick, dim)) / dimdelta(brick, dim))
    +
    1531  if ((pp < 0) || (pp >= dimsize(brick, dim)))
    +
    1532  return -1 // requested value out of range
    +
    1533  endif
    +
    1534 
    +
    1535  if (svar_exists(graphname) && (strlen(graphname) > 0) && (wintype(graphname) == 1))
    +
    1536  setdatafolder viewdf
    +
    1537  switch(dim)
    +
    1538  case 0: // X
    +
    1539  wave wdest = ad_extract_slab_x(brick, pp, pp, slicename)
    +
    1540  ad_update_profiles(wdest)
    +
    1541  break
    +
    1542  case 1: // Y
    +
    1543  wave wdest = ad_extract_slab_y(brick, pp, pp, slicename)
    +
    1544  ad_update_profiles(wdest)
    +
    1545  break
    +
    1546  case 2: // Z
    +
    1547  wave wdest = ad_extract_slab_z(brick, pp, pp, slicename)
    +
    1548  ad_update_profiles(wdest)
    +
    1549  break
    +
    1550  endswitch
    +
    1551  else
    +
    1552  return -2 // graph window not found
    +
    1553  endif
    +
    1554 
    +
    1555  setdatafolder savedf
    +
    1556  return 0
    +
    1557 end
    +
    1558 
    +
    1560 static function slp_slice_position(sa) : SliderControl
    +
    1561  STRUCT WMSliderAction &sa
    +
    1562 
    +
    1563  dfref savedf = GetDataFolderDFR()
    +
    1564 
    +
    1565  switch( sa.eventCode )
    +
    1566  case -1: // control being killed
    +
    1567  break
    +
    1568  default:
    +
    1569  if( sa.eventCode & 1 ) // value set
    +
    1570  string control_datafolder = GetUserData(sa.win, "", "control_datafolder")
    +
    1571  setdatafolder control_datafolder
    +
    1572  string brick_path = GetUserData(sa.win, "", "brick_path")
    +
    1573  string axis = StringFromList(1, sa.ctrlName, "_")
    +
    1574  variable dim = char2num(axis[0]) - char2num("x")
    +
    1575 
    +
    1576  wave /z brick = $brick_path
    +
    1577  if (WaveExists(brick))
    +
    1578  ad_gizmo_set_plane(brick, dim, sa.curval)
    +
    1579  ad_profiles_set_slice(brick, dim, sa.curval)
    +
    1580  else
    +
    1581  Abort "can't find original wave " + brick_path
    +
    1582  endif
    +
    1583  endif
    +
    1584  break
    +
    1585  endswitch
    +
    1586 
    +
    1587  setdatafolder savedf
    +
    1588  return 0
    +
    1589 End
    +
    1590 
    +
    1592 static function svp_slice_position(sva) : SetVariableControl
    +
    1593  STRUCT WMSetVariableAction &sva
    +
    1594 
    +
    1595  dfref savedf = GetDataFolderDFR()
    +
    1596 
    +
    1597  switch( sva.eventCode )
    +
    1598  case 1: // mouse up
    +
    1599  case 2: // Enter key
    +
    1600  case 3: // Live update
    +
    1601  string control_datafolder = GetUserData(sva.win, "", "control_datafolder")
    +
    1602  setdatafolder control_datafolder
    +
    1603  string brick_path = GetUserData(sva.win, "", "brick_path")
    +
    1604  string axis = StringFromList(1, sva.ctrlName, "_")
    +
    1605  variable dim = char2num(axis[0]) - char2num("x")
    +
    1606 
    +
    1607  wave /z brick = $brick_path
    +
    1608  if (WaveExists(brick))
    +
    1609  ad_gizmo_set_plane(brick, dim, sva.dval)
    +
    1610  ad_profiles_set_slice(brick, dim, sva.dval)
    +
    1611  else
    +
    1612  Abort "can't find original wave " + brick_path
    +
    1613  endif
    +
    1614  break
    +
    1615  case -1: // control being killed
    +
    1616  break
    +
    1617  endswitch
    +
    1618 
    +
    1619  setdatafolder savedf
    +
    1620  return 0
    +
    1621 End
    +
    1622 
    +
    1624 static function bp_move_slice(ba) : ButtonControl
    +
    1625  STRUCT WMButtonAction &ba
    +
    1626 
    +
    1627  dfref savedf = GetDataFolderDFR()
    +
    1628 
    +
    1629  switch( ba.eventCode )
    +
    1630  case 2: // mouse up
    +
    1631  string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
    +
    1632  setdatafolder control_datafolder
    +
    1633  string brick_path = GetUserData(ba.win, "", "brick_path")
    +
    1634  string axis = StringFromList(1, ba.ctrlName, "_")
    +
    1635  string cmd = StringFromList(2, ba.ctrlName, "_")
    +
    1636  variable dim = char2num(axis[0]) - char2num("x")
    +
    1637  string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
    +
    1638  nvar pos = $(posvariable)
    +
    1639 
    +
    1640  wave /z brick = $brick_path
    +
    1641  if (WaveExists(brick))
    +
    1642  strswitch (cmd)
    +
    1643  case "forward":
    +
    1644  ad_slicer_start_bg(brick, dim, posvariable, dimdelta(brick, dim))
    +
    1645  break
    +
    1646  case "back":
    +
    1647  ad_slicer_start_bg(brick, dim, posvariable, -dimdelta(brick, dim))
    +
    1648  break
    +
    1649  case "center":
    +
    1650  ad_slicer_stop_bg(posvariable)
    +
    1651  bp_move_slice_center(brick, dim, posvariable)
    +
    1652  break
    +
    1653  case "stop":
    +
    1654  ad_slicer_stop_bg(posvariable)
    +
    1655  break
    +
    1656  endswitch
    +
    1657  else
    +
    1658  ad_slicer_stop_bg(posvariable)
    +
    1659  Abort "can't find original wave " + brick_path
    +
    1660  endif
    +
    1661  break
    +
    1662  case -1: // control being killed
    +
    1663  break
    +
    1664  endswitch
    +
    1665 
    +
    1666  setdatafolder savedf
    +
    1667  return 0
    +
    1668 End
    +
    1669 
    +
    1673 static function bp_extract_slice(ba) : ButtonControl
    +
    1674  STRUCT WMButtonAction &ba
    +
    1675 
    +
    1676  dfref savedf = GetDataFolderDFR()
    +
    1677 
    +
    1678  switch( ba.eventCode )
    +
    1679  case 2: // mouse up
    +
    1680  string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
    +
    1681  setdatafolder control_datafolder
    +
    1682  string brick_path = GetUserData(ba.win, "", "brick_path")
    +
    1683  wave brick = $brick_path
    +
    1684  dfref brickdf = GetWavesDataFolderDFR(brick)
    +
    1685 
    +
    1686  string axis = StringFromList(1, ba.ctrlName, "_")
    +
    1687  string cmd = StringFromList(2, ba.ctrlName, "_")
    +
    1688  variable dim = char2num(axis[0]) - char2num("x")
    +
    1689  string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
    +
    1690 
    +
    1691  nvar pos = $(posvariable)
    +
    1692  variable pp = round((pos - dimoffset(brick, dim)) / dimdelta(brick, dim))
    +
    1693  if ((pp < 0) || (pp >= dimsize(brick, dim)))
    +
    1694  return -1 // requested value out of range
    +
    1695  endif
    +
    1696 
    +
    1697  variable dig = ceil(log(dimsize(brick, dim)))
    +
    1698  string slicename
    +
    1699  sprintf slicename, "%s_%s%0*u", NameOfWave(brick), axis[0], dig, pp
    +
    1700  setdatafolder brickdf
    +
    1701  switch(dim)
    +
    1702  case 0: // X
    +
    1703  wave wdest = ad_extract_slab_x(brick, pp, pp, slicename)
    +
    1704  break
    +
    1705  case 1: // Y
    +
    1706  wave wdest = ad_extract_slab_y(brick, pp, pp, slicename)
    +
    1707  break
    +
    1708  case 2: // Z
    +
    1709  wave wdest = ad_extract_slab_z(brick, pp, pp, slicename)
    +
    1710  break
    +
    1711  endswitch
    +
    1712 
    +
    1713  string msg
    +
    1714  sprintf msg, "%s=%g", axis[0], pos
    +
    1715  note wdest, msg
    +
    1716 
    +
    1717  break
    +
    1718  case -1: // control being killed
    +
    1719  break
    +
    1720  endswitch
    +
    1721 
    +
    1722  setdatafolder savedf
    +
    1723  return 0
    +
    1724 End
    +
    1725 
    +
    1727 static function bp_move_slice_center(brick, dim, posvariable)
    +
    1728  wave brick
    +
    1729  variable dim
    +
    1730  string posvariable
    +
    1731 
    +
    1732  nvar pos = $posvariable
    +
    1733  pos = dimoffset(brick, dim) + dimdelta(brick, dim) * dimsize(brick, dim) / 2
    +
    1734  ad_gizmo_set_plane(brick, dim, pos)
    +
    1735  ad_profiles_set_slice(brick, dim, pos)
    +
    1736 end
    +
    1737 
    +
    1739 static function ad_slicer_move_bg(s)
    +
    1740  STRUCT WMBackgroundStruct &s
    +
    1741 
    +
    1742  dfref savedf = GetDataFolderDFR()
    +
    1743  setdatafolder root:pearl_area:slicer
    +
    1744  wave /t bg_brickpaths
    +
    1745  wave /t bg_graphnames
    +
    1746  wave /t bg_variablepaths
    +
    1747  wave bg_dimensions
    +
    1748  wave bg_increments
    +
    1749 
    +
    1750  variable ii
    +
    1751  variable nn = numpnts(bg_brickpaths)
    +
    1752  variable dim
    +
    1753  variable pp
    +
    1754 
    +
    1755  for (ii = 0; ii < nn; ii += 1)
    +
    1756  wave /z brick = $bg_brickpaths[ii]
    +
    1757  nvar /z pos = $bg_variablepaths[ii]
    +
    1758  dim = bg_dimensions[0]
    +
    1759  pos += bg_increments[ii]
    +
    1760  // wrap around at limits
    +
    1761  pp = round((pos - dimoffset(brick, dim)) / dimdelta(brick, dim))
    +
    1762  if (pp <= -0.5)
    +
    1763  pos = dimoffset(brick, dim) + dimdelta(brick, dim) * (dimsize(brick, dim) - 1)
    +
    1764  elseif (pp >= dimsize(brick, dim) - 0.5)
    +
    1765  pos = dimoffset(brick, dim)
    +
    1766  endif
    +
    1767  if (waveexists(brick))
    +
    1768  ad_gizmo_set_plane(brick, dim, pos)
    +
    1769  ad_profiles_set_slice(brick, dim, pos)
    +
    1770  endif
    +
    1771  endfor
    +
    1772 
    +
    1773  setdatafolder savedf
    +
    1774  return 0
    +
    1775 End
    +
    1776 
    +
    1778 function ad_slicer_init_bg()
    +
    1779  dfref savedf = GetDataFolderDFR()
    +
    1780  setdatafolder root:
    +
    1781  newdatafolder /o/s pearl_area
    +
    1782  newdatafolder /o/s slicer
    +
    1783 
    +
    1784  make /n=0/o/t bg_brickpaths
    +
    1785  make /n=0/o/t bg_variablepaths
    +
    1786  make /n=0/o/i/u bg_dimensions
    +
    1787  make /n=0/o bg_increments
    +
    1788 
    +
    1789  CtrlNamedBackground ad_slicer, period = 30, proc = PearlAreaDisplay#ad_slicer_move_bg
    +
    1790 
    +
    1791  setdatafolder savedf
    +
    1792  return 0
    +
    1793 end
    +
    1794 
    +
    1802 function ad_slicer_start_bg(brick, dimension, posvariable, delta)
    +
    1803  wave brick // 3D data wave
    +
    1804  variable dimension // dimension to animate, 0, 1, or 2
    +
    1805  string posvariable // full path to the global position variable
    +
    1806  variable delta // step increment, should be +/- dimdelta
    +
    1807 
    +
    1808  dfref savedf = GetDataFolderDFR()
    +
    1809  setdatafolder root:pearl_area:slicer
    +
    1810  wave /t bg_brickpaths
    +
    1811  wave /t bg_variablepaths
    +
    1812  wave bg_dimensions
    +
    1813  wave bg_increments
    +
    1814 
    +
    1815  // create entry in ad_slicer background task table
    +
    1816  variable idx
    +
    1817  FindValue /TEXT=posvariable /TXOP=4 /Z bg_variablepaths
    +
    1818  if (v_value >= 0)
    +
    1819  idx = v_value
    +
    1820  else
    +
    1821  idx = numpnts(bg_variablepaths)
    +
    1822  InsertPoints idx, 1, bg_brickpaths, bg_variablepaths, bg_dimensions, bg_increments
    +
    1823  endif
    +
    1824 
    +
    1825  // set background task
    +
    1826  bg_brickpaths[idx] = GetWavesDataFolder(brick, 2)
    +
    1827  bg_variablepaths[idx] = posvariable
    +
    1828  bg_dimensions[idx] = dimension
    +
    1829  bg_increments[idx] = delta
    +
    1830 
    +
    1831  // start background task
    +
    1832  if (numpnts(bg_variablepaths) > 0)
    +
    1833  CtrlNamedBackground ad_slicer, start
    +
    1834  endif
    +
    1835 
    +
    1836  setdatafolder savedf
    +
    1837  return 0
    +
    1838 end
    +
    1839 
    +
    1844 function ad_slicer_stop_bg(posvariable)
    +
    1845  string posvariable
    +
    1846 
    +
    1847  dfref savedf = GetDataFolderDFR()
    +
    1848  setdatafolder root:pearl_area:slicer
    +
    1849  wave /t bg_brickpaths
    +
    1850  wave /t bg_variablepaths
    +
    1851  wave bg_dimensions
    +
    1852  wave bg_increments
    +
    1853 
    +
    1854  // find entry in ad_slicer background task table
    +
    1855  FindValue /TEXT=posvariable /TXOP=4 /Z bg_variablepaths
    +
    1856  if (v_value >= 0)
    +
    1857  DeletePoints v_value, 1, bg_brickpaths, bg_variablepaths, bg_dimensions, bg_increments
    +
    1858  endif
    +
    1859 
    +
    1860  // stop background task if task table is empty
    +
    1861  if (numpnts(bg_variablepaths) == 0)
    +
    1862  CtrlNamedBackground ad_slicer, stop
    +
    1863  endif
    +
    1864 
    +
    1865  setdatafolder savedf
    +
    1866  return 0
    +
    1867 end
    +
    string ad_display_slice(wave data)
    display three-dimensional data by 2D slice.
    +
    static string graphname_from_dfref(dfref df, string prefix)
    compose a valid and unique graph name from a data folder reference
    +
    variable ad_calc_histogram(wave image)
    calculate the histogram.
    +
    string ad_display_histogram(wave image)
    display the histogram of a 2D image.
    +
    string ad_display(wave image)
    open a new graph window with a 2D image.
    +
    string PearlCleanupName(string name)
    +
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    diff --git a/doc/html/pearl-area-import_8ipf.html b/doc/html/pearl-area-import_8ipf.html index cb6cbc2..7d6053c 100644 --- a/doc/html/pearl-area-import_8ipf.html +++ b/doc/html/pearl-area-import_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-area-import.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -106,83 +108,83 @@ Namespaces

    Functions

    static variable BeforeFileOpenHook (variable refNum, string fileName, string path, string type, string creator, variable kind) - callback function for drag&drop of HDF5 files into Igor. More...
    + callback function for drag&drop of HDF5 files into Igor. More...
      string ad_suggest_foldername (string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue) - generate the name of a data folder based on a file name. More...
    + generate the name of a data folder based on a file name. More...
      variable ad_load_dialog (string APathName) - load area detector data files selected in a file dialog window More...
    + load area detector data files selected in a file dialog window More...
      string adh5_load_complete (string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue) - import everything from a HDF5 file created by the Area Detector software. More...
    + import everything from a HDF5 file created by the Area Detector software. More...
      string adh5_load_reduced (string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable load_data=defaultValue, variable load_attr=defaultValue, variable progress=defaultValue) - load and reduce a dataset from a HDF5 file created by the Area Detector software. More...
    + load and reduce a dataset from a HDF5 file created by the Area Detector software. More...
      string adh5_load_preview (string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue) - load a single image from a HDF5 file created by the Area Detector software. More...
    + load a single image from a HDF5 file created by the Area Detector software. More...
      string adh5_load_info (string APathName, string AFileName) - load descriptive info from a HDF5 file created by the Area Detector software. More...
    + load descriptive info from a HDF5 file created by the Area Detector software. More...
      variable adh5_load_detector (variable fileID, string detectorpath) - load the detector dataset from the open HDF5 file. More...
    + load the detector dataset from the open HDF5 file. More...
      variable adh5_redim (wave data) - redimension a multi-dimensional area detector array loaded from HDF5. More...
    + redimension a multi-dimensional area detector array loaded from HDF5. More...
      static dfr GetAttrDataFolderDFR (wave data) - find the attributes data folder of an area detector dataset. More...
    + find the attributes data folder of an area detector dataset. More...
      variable adh5_scale (wave data, string source=defaultValue) - set the dimension scales of an area detector dataset. More...
    + set the dimension scales of an area detector dataset. More...
      variable adh5_load_detector_slabs (variable fileID, string detectorpath, variable progress=defaultValue) - load the detector dataset from the open HDF5 file. More...
    + load the detector dataset from the open HDF5 file. More...
      variable adh5_load_detector_image (variable fileID, string detectorpath, variable dim2start, variable dim2count, variable dim3start, variable dim3count) - load a single image from the detector dataset of the open HDF5 file More...
    + load a single image from the detector dataset of the open HDF5 file More...
      string adh5_list_reduction_funcs () - get a list of functions which can be used as reduction functions. More...
    + get a list of functions which can be used as reduction functions. More...
      threadsafe wave adh5_default_reduction (wave source, string *param) - function prototype for adh5_load_reduced_detector More...
    + function prototype for adh5_load_reduced_detector More...
      threadsafe variable adh5_setup_profile (wave image, wave profile, variable dim) - set up a one-dimensional wave for a line profile based on a 2D original wave. More...
    + set up a one-dimensional wave for a line profile based on a 2D original wave. More...
      string adh5_test_reduction_func (wave source, funcref reduction_func, string reduction_param, string result_prefix) - wrapper function for testing reduction functions from the command line. More...
    + wrapper function for testing reduction functions from the command line. More...
      variable adh5_reduce_brick (wave source, funcref reduction_func, string reduction_param, string result_prefix, variable progress=defaultValue, variable nthreads=defaultValue) - reduce a three-dimensional intensity distribution More...
    + reduce a three-dimensional intensity distribution More...
      static threadsafe variable reduce_brick_worker (funcref reduction_func) - thread worker for adh5_reduce_brick More...
    + thread worker for adh5_reduce_brick More...
      threadsafe variable adh5_get_result_waves (wave results, string result_prefix, variable start_index) - copy waves from wave reference wave into current data folder More...
    + copy waves from wave reference wave into current data folder More...
      variable adh5_load_reduced_detector (variable fileID, string detectorpath, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue) - load a reduced detector dataset from the open HDF5 file. More...
    + load a reduced detector dataset from the open HDF5 file. More...
      static threadsafe variable reduce_slab_worker (funcref reduction_func)   static threadsafe wave reduce_slab_image (wave slabdata, wave image, funcref reduction_func, string reduction_param)   variable adh5_loadattr_all (variable fileID, string attributespath) - load an NDAttributes group from an open HDF5 file into the current data folder. More...
    + load an NDAttributes group from an open HDF5 file into the current data folder. More...
      static variable read_attribute_info (string datawavename, string source, variable *idest) - sub-function of adh5_loadattr_all. More...
    + sub-function of adh5_loadattr_all. More...
      variable adh5_scale_scienta (wave data) - set the energy and angle scales of an area detector dataset from the Scienta analyser. More...
    + set the energy and angle scales of an area detector dataset from the Scienta analyser. More...
      variable adh5_scale_scan (wave data) - scales the extra dimensions of an area detector dataset according to the EPICS scan More...
    + scales the extra dimensions of an area detector dataset according to the EPICS scan More...
     

    Detailed Description

    @@ -190,9 +192,9 @@ Functions

    HDF5 file import from EPICS area detectors such as CCD cameras, 2D electron analysers

    as of Igor 6.3, Igor can open datasets of up to rank 4. i.e. the extra dimension Y of the file plugin cannot be used. the extra dimensions N and X are supported.

    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    - -

    Definition at line 167 of file pearl-area-import.ipf.

    +

    Definition at line 171 of file pearl-area-import.ipf.

    @@ -276,7 +278,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 106 of file pearl-area-import.ipf.

    +

    Definition at line 110 of file pearl-area-import.ipf.

    @@ -309,7 +311,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    function prototype for adh5_load_reduced_detector

    this is a prototype of custom functions that convert (reduce) a two-dimensional detector image into one or more one-dimensional waves. data processing can be tuned with a set of parameters.

    reduction functions have a fixed signature (function arguments) so that the file import functions can call them efficiently on a series of detector images. pearl procedures comes with a number of pre-defined reduction functions but you may as well implement your own functions. if you write your own function, you must use the same declaration and arguments as this function except for the function name. you can do many things in a reduction function, e.g. integration over a region of interest, curve fitting, etc.

    -

    each destination wave is a one-dimensional intensity distribution. the function must redimension each of these waves to one of the image dimensions by calling the adh5_setup_profile() function. this function will also copy the scale information and dimension labels, which is important for the proper scaling of the result.

    +

    each destination wave is a one-dimensional intensity distribution. the function must redimension each of these waves to one of the image dimensions by calling the adh5_setup_profile() function. this function will also copy the scale information and dimension labels, which is important for the proper scaling of the result.

    the meaning of the data in the result waves is up to the particular function, e.g. dest1 could hold the mean value and dest2 the one-sigma error, or dest1 could hold the X-profile, and dest2 the Y-profile.

    Parameters
    @@ -320,7 +322,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    a free wave containing references of the result waves. the result waves should as well be free waves. if an error occurred, the reference wave is empty.
    -

    Definition at line 1111 of file pearl-area-import.ipf.

    +

    Definition at line 1115 of file pearl-area-import.ipf.

    @@ -367,7 +369,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1430 of file pearl-area-import.ipf.

    +

    Definition at line 1463 of file pearl-area-import.ipf.

    @@ -389,7 +391,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    get a list of functions which can be used as reduction functions.

    the function evaluates only the function arguments, it may thus include functions which are not suitable as reduction functions.

    -

    Definition at line 1041 of file pearl-area-import.ipf.

    +

    Definition at line 1045 of file pearl-area-import.ipf.

    @@ -450,7 +452,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 207 of file pearl-area-import.ipf.

    +

    Definition at line 211 of file pearl-area-import.ipf.

    @@ -490,7 +492,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 581 of file pearl-area-import.ipf.

    +

    Definition at line 585 of file pearl-area-import.ipf.

    @@ -558,7 +560,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 945 of file pearl-area-import.ipf.

    +

    Definition at line 949 of file pearl-area-import.ipf.

    @@ -606,7 +608,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    0 if successful, non-zero if an error occurred.
    -

    Definition at line 780 of file pearl-area-import.ipf.

    +

    Definition at line 784 of file pearl-area-import.ipf.

    @@ -647,7 +649,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 497 of file pearl-area-import.ipf.

    +

    Definition at line 501 of file pearl-area-import.ipf.

    @@ -709,7 +711,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 387 of file pearl-area-import.ipf.

    +

    Definition at line 391 of file pearl-area-import.ipf.

    @@ -784,7 +786,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    - + @@ -793,7 +795,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 302 of file pearl-area-import.ipf.

    +

    Definition at line 306 of file pearl-area-import.ipf.

    @@ -854,7 +856,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    ANickNamedestination folder name (top level under root)
    APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
    AFileNameif empty a dialog box shows up
    reduction_funccustom reduction function (any user-defined function which has the same parameters as adh5_default_reduction())
    reduction_funccustom reduction function (any user-defined function which has the same parameters as adh5_default_reduction())
    reduction_paramparameter string for the reduction function
    load_data1 (default): load data; 0: do not load data
    load_attr1 (default): load attributes; 0: do not load attributes for proper wave scaling, the attributes must be loaded
    - + @@ -862,7 +864,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1466 of file pearl-area-import.ipf.

    +

    Definition at line 1499 of file pearl-area-import.ipf.

    @@ -902,7 +904,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1790 of file pearl-area-import.ipf.

    +

    Definition at line 1823 of file pearl-area-import.ipf.

    @@ -932,7 +934,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 626 of file pearl-area-import.ipf.

    +

    Definition at line 630 of file pearl-area-import.ipf.

    @@ -993,12 +995,13 @@ Licensed under the Apache License, Version 2.0 (the "License");
    - +
    fileIDID of open HDF5 file from HDF5OpenFile
    detectorpathpath to detector group in the HDF5 file
    reduction_funccustom reduction function (any user-defined function which has the same parameters as adh5_default_reduction())
    reduction_funccustom reduction function (any user-defined function which has the same parameters as adh5_default_reduction())
    reduction_paramparameter string for the reduction function
    progress1 (default): show progress window; 0: do not show progress window
    nthreads-1 (default): use as many threads as there are processor cores (in addition to main thread) 0: use main thread only (e.g. for debugging the reduction function) >= 1: use a fixed number of (additional) threads
    sourcesource wave. three-dimensional intensity distribution (image). the scales are carried over to the result waves.
    reduction_funcname of the reduction function to apply to the source data.
    reduction_paramstring with reduction parameters as required by the specific reduction function.
    result_prefixname prefix of result waves. a numeric index is appended to distinguish the results. the index starts at 1. existing waves are overwritten.
    result_prefixname prefix of result waves. a numeric index is appended to distinguish the results. the index starts at 1. existing waves are overwritten.
    +
    Returns
    result code: 0 for success, < 0 for error
    -

    Definition at line 1198 of file pearl-area-import.ipf.

    +

    Definition at line 1203 of file pearl-area-import.ipf.

    @@ -1031,7 +1034,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    set the dimension scales of an area detector dataset.

    the intrinsic dimensions 0 and 1 are scaled according to the data source (currently supported: Prosilica cameras, Scienta electron analyser). the extra dimensions are scaled according to the scan. the latter requires that the positioner names and position values are available.

    -

    Definition at line 726 of file pearl-area-import.ipf.

    +

    Definition at line 730 of file pearl-area-import.ipf.

    @@ -1055,7 +1058,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    the scan positioner name and its values must be available

    Todo:
    incomplete
    -

    Definition at line 2030 of file pearl-area-import.ipf.

    +

    Definition at line 2063 of file pearl-area-import.ipf.

    @@ -1078,7 +1081,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    set the energy and angle scales of an area detector dataset from the Scienta analyser.

    the dimension labels of the energy and angle scales must be set correctly: AD_Dim0 = energy dimension; AD_Dim1 = angle dimension. these dimensions must be the first two dimensions of a multi-dimensional dataset. normally, AD_Dim0 is the X dimension, and AD_Dim1 the Y dimension.

    -

    Definition at line 1925 of file pearl-area-import.ipf.

    +

    Definition at line 1958 of file pearl-area-import.ipf.

    @@ -1117,7 +1120,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    set up a one-dimensional wave for a line profile based on a 2D original wave.

    redimensions the profile wave to the given dimension. copies the scale and dimension label of the given dimension.

    -

    Definition at line 1134 of file pearl-area-import.ipf.

    +

    Definition at line 1138 of file pearl-area-import.ipf.

    @@ -1172,7 +1175,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    a copy of the reduction_param string, possibly modified by the reduction function.
    -

    Definition at line 1167 of file pearl-area-import.ipf.

    +

    Definition at line 1171 of file pearl-area-import.ipf.

    @@ -1236,7 +1239,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    callback function for drag&drop of HDF5 files into Igor.

    -

    Definition at line 42 of file pearl-area-import.ipf.

    +

    Definition at line 46 of file pearl-area-import.ipf.

    @@ -1274,7 +1277,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    data folder reference of the attributes folder. the reference may be invalid (and default to root) if the folder cannot be found, cf. built-in DataFolderRefStatus function.
    -

    Definition at line 707 of file pearl-area-import.ipf.

    +

    Definition at line 711 of file pearl-area-import.ipf.

    @@ -1329,7 +1332,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1872 of file pearl-area-import.ipf.

    +

    Definition at line 1905 of file pearl-area-import.ipf.

    @@ -1360,7 +1363,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    thread worker for adh5_reduce_brick

    this function polls job data folders from thread group 0 and calls the reduction function on their contents. the result waves have prefix "redw_" and are saved in the job folder.

    -

    Definition at line 1377 of file pearl-area-import.ipf.

    +

    Definition at line 1410 of file pearl-area-import.ipf.

    @@ -1410,7 +1413,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1757 of file pearl-area-import.ipf.

    +

    Definition at line 1790 of file pearl-area-import.ipf.

    @@ -1438,7 +1441,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1718 of file pearl-area-import.ipf.

    +

    Definition at line 1751 of file pearl-area-import.ipf.

    @@ -1448,9 +1451,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
    diff --git a/doc/html/pearl-area-import_8ipf_source.html b/doc/html/pearl-area-import_8ipf_source.html index e154ccd..eca1006 100644 --- a/doc/html/pearl-area-import_8ipf_source.html +++ b/doc/html/pearl-area-import_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-area-import.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,49 +87,1791 @@ $(document).ready(function(){initNavTree('pearl-area-import_8ipf_source.html',''
    pearl-area-import.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.2
    3 #pragma ModuleName = PearlAreaImport
    4 #include <HDF5 Browser>
    5 #include "pearl-compat"
    6 #include "pearl-gui-tools"
    7 
    8 // copyright (c) 2013-18 Paul Scherrer Institut
    9 //
    10 // Licensed under the Apache License, Version 2.0 (the "License");
    11 // you may not use this file except in compliance with the License.
    12 // You may obtain a copy of the License at
    13 // http:///www.apache.org/licenses/LICENSE-2.0
    14 
    34 
    39 
    42 static function BeforeFileOpenHook(refNum,fileName,path,type,creator,kind)
    43  variable refNum, kind
    44  string fileName, path, type, creator
    45 
    46  variable handledOpen = 0
    47 
    48  //PathInfo $path
    49  //string FilePath = s_path + filename
    50  string NickName = PearlCleanupName(ParseFilePath(3, FileName, ":", 0, 0))
    51  string FileExt = LowerStr(ParseFilePath(4, FileName, ":", 0, 0))
    52  string result = ""
    53 
    54  // override nickname with custom setting
    55  svar /z cnn = gsCustomNickName
    56  if (svar_exists(cnn))
    57  if (exists("gvNickNameIndex") != 2)
    58  variable/g gvNickNameIndex = 1
    59  endif
    60  nvar nni = gvNickNameIndex
    61  NickName = cnn + num2str(nni)
    62  nni += 1
    63  endif
    64 
    65  if (stringmatch(FileExt, "h5") == 1)
    66  result = adh5_load_complete(NickName, path, FileName)
    67  endif
    68 
    69  string/g s_latest_datafile = result
    70  string/g s_latest_nickname = nickname
    71 
    72  handledOpen = strlen(result) > 0
    73  if (handledOpen)
    74  close refnum
    75  endif
    76 
    77  return handledOpen // 1 tells Igor not to open the file
    78 End
    79 
    106 function /s ad_suggest_foldername(filename, [ignoredate,sourcename,unique])
    107  string filename
    108  variable ignoredate
    109  string sourcename
    110  variable unique
    111 
    112  if (ParamIsDefault(ignoredate))
    113  ignoredate = 0
    114  endif
    115  if (ParamIsDefault(unique))
    116  unique = 0
    117  endif
    118 
    119  string basename = ParseFilePath(3, filename, ":", 0, 0)
    120  string extension = ParseFilePath(4, filename, ":", 0, 0)
    121  string nickname
    122 
    123  string autosource
    124  if (strsearch(basename, "scienta", 0, 2) >= 0)
    125  autosource = "sci"
    126  elseif (strsearch(basename, "pshell", 0, 2) >= 0)
    127  autosource = "psh"
    128  elseif (strsearch(basename, "OP-SL", 0, 2) >= 0)
    129  autosource = "sl"
    130  elseif (strsearch(basename, "ES-PS", 0, 2) >= 0)
    131  autosource = "es"
    132  else
    133  autosource = "xy"
    134  endif
    135  if (ParamIsDefault(sourcename))
    136  sourcename = autosource
    137  endif
    138 
    139  variable nparts = ItemsInList(basename, "-")
    140  if (nparts >= 3)
    141  string datepart = StringFromList(1, basename, "-")
    142  variable l_datepart = strlen(datepart)
    143  if (l_datepart == 8)
    144  datepart = datepart[l_datepart-6, l_datepart-1]
    145  endif
    146  string indexpart = StringFromList(2, basename, "-")
    147  if (ignoredate)
    148  sprintf nickname, "%s_%s", sourcename, indexpart
    149  else
    150  sprintf nickname, "%s_%s_%s", sourcename, datepart, indexpart
    151  endif
    152  else
    153  nickname = PearlCleanupName(basename)
    154  endif
    155 
    156  if (unique && CheckName(nickname, 11))
    157  nickname = UniqueName(nickname + "_", 11, 0)
    158  endif
    159 
    160  return nickname
    161 end
    162 
    167 function ad_load_dialog(APathName)
    168  string APathName
    169 
    170  variable refNum
    171  string message = "Select data files"
    172  string filepaths
    173  string filefilters = "Area Detector HDF5 Files (*.h5):.h5;"
    174  filefilters += "All Files:.*;"
    175 
    176  PathInfo /S $APathName
    177  Open /D /R /F=filefilters /M=message /MULT=1 refNum
    178  filepaths = S_fileName
    179 
    180  dfref saveDF = GetDataFolderDFR()
    181  setdatafolder root:
    182 
    183  if (strlen(filepaths) > 0)
    184  variable nfiles = ItemsInList(filepaths, "\r")
    185  variable ifile
    186  for(ifile = 0; ifile < nfiles; ifile += 1)
    187  String path = StringFromList(ifile, filepaths, "\r")
    188  string nickname = ad_suggest_foldername(path)
    189  adh5_load_complete(nickname, "", path)
    190  endfor
    191  endif
    192 
    193  setdatafolder saveDF
    194 end
    195 
    207 function /s adh5_load_complete(ANickName, APathName, AFileName, [load_data, load_attr])
    208  string ANickName
    209  string APathName
    210  string AFileName
    211  variable load_data
    212  variable load_attr
    213 
    214  if (ParamIsDefault(load_data))
    215  load_data = 1
    216  endif
    217  if (ParamIsDefault(load_attr))
    218  load_attr = 1
    219  endif
    220 
    221  dfref saveDF = GetDataFolderDFR()
    222  setdatafolder root:
    223  newdatafolder /s/o $("root:" + ANickName)
    224 
    225  // open file
    226  variable fileID
    227  string instrumentpath = "/entry/instrument/"
    228  string detectorpath = instrumentpath + "detector/"
    229  string attributespath = instrumentpath + "NDAttributes/"
    230  string datasetname
    231  string datawavename
    232 
    233  // performance monitoring
    234  variable timerRefNum
    235  variable /g adh5_perf_secs
    236  timerRefNum = startMSTimer
    237 
    238  // avoid compilation error if HDF5 XOP has not been loaded
    239  #if Exists("HDF5OpenFile")
    240  HDF5OpenFile /P=$APathName/R fileID as AFileName
    241  if (v_flag == 0)
    242  AFileName = s_path + s_filename
    243  print "loading " + s_filename + "\r"
    244 
    245  if (load_data)
    246  adh5_load_detector_slabs(fileID, detectorpath)
    247  endif
    248  if (load_attr)
    249  newdatafolder /o/s attr
    250  adh5_loadattr_all(fileID, attributespath)
    251  setdatafolder ::
    252  endif
    253 
    254  wave /z data
    255  if (waveexists(data))
    256  //adh5_redim(data) // not to be used with adh5_load_detector_slabs
    257  adh5_scale(data)
    258  endif
    259 
    260  HDF5CloseFile fileID
    261  else
    262  AFileName = ""
    263  endif
    264  #else
    265  Abort "HDF5 XOP not loaded."
    266  #endif
    267 
    268  if (timerRefNum >= 0)
    269  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    270  endif
    271 
    272  setdatafolder saveDF
    273  return AFileName
    274 end
    275 
    302 function /s adh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [load_data, load_attr, progress])
    303  string ANickName
    304  string APathName
    305  string AFileName
    306 
    307  funcref adh5_default_reduction reduction_func
    308  string reduction_param
    309 
    310  variable load_data
    311  variable load_attr
    312  variable progress
    313 
    314  if (ParamIsDefault(load_data))
    315  load_data = 1
    316  endif
    317  if (ParamIsDefault(load_attr))
    318  load_attr = 1
    319  endif
    320  if (ParamIsDefault(progress))
    321  progress = 1
    322  endif
    323 
    324  dfref saveDF = GetDataFolderDFR()
    325  setdatafolder root:
    326  newdatafolder /s/o $("root:" + ANickName)
    327 
    328  // open file
    329  variable fileID
    330  string instrumentpath = "/entry/instrument/"
    331  string detectorpath = instrumentpath + "detector/"
    332  string attributespath = instrumentpath + "NDAttributes/"
    333  string datasetname
    334  string datawavename
    335 
    336  // performance monitoring
    337  variable timerRefNum
    338  variable /g adh5_perf_secs
    339  timerRefNum = startMSTimer
    340 
    341  // avoid compilation error if HDF5 XOP has not been loaded
    342  #if Exists("HDF5OpenFile")
    343  HDF5OpenFile /P=$APathName/R fileID as AFileName
    344  if (v_flag == 0)
    345  AFileName = s_path + s_filename
    346  print "loading " + s_filename + "\r"
    347 
    348  if (load_attr)
    349  newdatafolder /o/s attr
    350  adh5_loadattr_all(fileID, attributespath)
    351  setdatafolder ::
    352  endif
    353  if (load_data)
    354  adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduction_param, progress=progress)
    355  endif
    356 
    357  HDF5CloseFile fileID
    358  else
    359  AFileName = ""
    360  endif
    361  #else
    362  Abort "HDF5 XOP not loaded."
    363  #endif
    364 
    365  if (timerRefNum >= 0)
    366  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    367  endif
    368 
    369  setdatafolder saveDF
    370  return AFileName
    371 end
    372 
    387 function /s adh5_load_preview(ANickName, APathName, AFileName, [load_data, load_attr])
    388  string ANickName
    389  string APathName
    390  string AFileName
    391  variable load_data
    392  variable load_attr
    393 
    394  if (ParamIsDefault(load_data))
    395  load_data = 1
    396  endif
    397  if (ParamIsDefault(load_attr))
    398  load_attr = 1
    399  endif
    400 
    401  dfref saveDF = GetDataFolderDFR()
    402  setdatafolder root:
    403  newdatafolder /o/s pearl_area
    404  newdatafolder /o/s preview
    405 
    406  // open file
    407  variable fileID
    408  string instrumentpath = "/entry/instrument/"
    409  string detectorpath = instrumentpath + "detector/"
    410  string attributespath = instrumentpath + "NDAttributes/"
    411  string datasetname
    412  string datawavename
    413 
    414  // performance monitoring
    415  variable timerRefNum
    416  variable /g adh5_perf_secs
    417  timerRefNum = startMSTimer
    418 
    419  // avoid compilation error if HDF5 XOP has not been loaded
    420  #if Exists("HDF5OpenFile")
    421  HDF5OpenFile /P=$APathName/R/Z fileID as AFileName
    422  if (v_flag == 0)
    423  AFileName = s_path + s_filename
    424 
    425  // detector data
    426  datasetname = detectorpath + "data"
    427  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    428  InitHDF5DataInfo(di)
    429  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    430  if (err != 0)
    431  print "error accessing detector/data"
    432  return ""
    433  endif
    434  if (di.ndims < 2)
    435  print "error: rank of dataset < 2"
    436  return ""
    437  endif
    438 
    439  variable dim2start = 0, dim2count = 1, dim3start = 0, dim3count = 1
    440  if (di.ndims >= 3)
    441  dim2start = floor(di.dims[di.ndims - 3] / 2)
    442  dim2count = 1
    443  endif
    444  if (di.ndims >= 4)
    445  dim3start = floor(di.dims[di.ndims - 4] / 2)
    446  dim3count = 1
    447  endif
    448 
    449  if (load_data)
    450  adh5_load_detector_image(fileID, detectorpath, dim2start, dim2count, dim3start, dim3count)
    451  wave /z data
    452  string destpath = GetDataFolder(1, saveDF) + ANickName
    453  if (waveexists(data))
    454  duplicate /o data, $destpath
    455  wave /z data = $destpath
    456  endif
    457  endif
    458 
    459  if (load_attr)
    460  setdatafolder saveDF
    461  newdatafolder /o/s attr
    462  killwaves /a/z
    463  adh5_loadattr_all(fileID, attributespath)
    464  setdatafolder ::
    465  if (waveexists(data))
    466  adh5_scale(data)
    467  endif
    468  endif
    469 
    470  HDF5CloseFile fileID
    471  else
    472  print "error opening file " + AFileName
    473  AFileName = ""
    474  endif
    475  #else
    476  Abort "HDF5 XOP not loaded."
    477  #endif
    478 
    479  if (timerRefNum >= 0)
    480  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    481  endif
    482 
    483  setdatafolder saveDF
    484  return AFileName
    485 end
    486 
    497 function /s adh5_load_info(APathName, AFileName)
    498  string APathName
    499  string AFileName
    500 
    501  dfref saveDF = GetDataFolderDFR()
    502 
    503  // open file
    504  variable fileID
    505  string instrumentpath = "/entry/instrument/"
    506  string detectorpath = instrumentpath + "detector/"
    507  string attributespath = instrumentpath + "NDAttributes/"
    508  string datasetname
    509  string datawavename
    510 
    511  string s_info = ""
    512  string s
    513 
    514  variable idim
    515 
    516  // avoid compilation error if HDF5 XOP has not been loaded
    517  #if Exists("HDF5OpenFile")
    518  HDF5OpenFile /P=$APathName/R/Z fileID as AFileName
    519  if (v_flag == 0)
    520  AFileName = s_path + s_filename
    521 
    522  // detector data
    523  datasetname = detectorpath + "data"
    524  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    525  InitHDF5DataInfo(di)
    526  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    527  if (err != 0)
    528  print "error accessing detector/data"
    529  return ""
    530  endif
    531 
    532  for (idim = 0; idim < di.ndims; idim += 1)
    533  sprintf s, "dim %u: %u points", idim, di.dims[idim]
    534  if (strlen(s_info) > 0)
    535  s_info = s_info + "\r" + s
    536  else
    537  s_info = s
    538  endif
    539  endfor
    540 
    541  dfref df = NewFreeDataFolder()
    542  setdatafolder df
    543  adh5_loadattr_all(fileID, attributespath)
    544 
    545  for (idim = 1; idim < 5; idim += 1)
    546  sprintf s, "Scan%uActive", idim
    547  wave /z w = $s
    548  if (waveexists(w) && (numpnts(w) > 0) && (w[0] > 0))
    549  sprintf s, "Scan%uPositioner1", idim
    550  wave /t wt = $s
    551  sprintf s, "scan %u: %s", idim, wt[0]
    552  if (strlen(s_info) > 0)
    553  s_info = s_info + "\r" + s
    554  else
    555  s_info = s
    556  endif
    557  endif
    558  endfor
    559 
    560  HDF5CloseFile fileID
    561  else
    562  print "error opening file " + AFileName
    563  AFileName = ""
    564  endif
    565  #else
    566  Abort "HDF5 XOP not loaded."
    567  #endif
    568 
    569  setdatafolder saveDF
    570  return s_info
    571 end
    572 
    581 function adh5_load_detector(fileID, detectorpath)
    582  variable fileID
    583  string detectorpath
    584 
    585  // avoid compilation error if HDF5 XOP has not been loaded
    586  #if Exists("HDF5LoadData")
    587  string datasetname
    588  string datawavename
    589 
    590  // detector data
    591  datasetname = detectorpath + "data"
    592  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    593  InitHDF5DataInfo(di)
    594  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    595  if (err != 0)
    596  print "error accessing detector/data"
    597  return -1
    598  endif
    599  if (di.ndims < 2)
    600  print "error: rank of dataset < 2"
    601  return -2
    602  endif
    603 
    604  HDF5LoadData /O /Q /Z fileID, datasetname
    605  wave data
    606 
    607  #else
    608  Abort "HDF5 XOP not loaded."
    609  #endif
    610 end
    611 
    626 function adh5_redim(data)
    627  wave data
    628 
    629  duplicate /free data, tempdata
    630  variable nd = wavedims(tempdata)
    631  variable nx = dimsize(tempdata, nd - 1)
    632  variable ny = dimsize(tempdata, nd - 2)
    633  variable nz = dimsize(tempdata, nd - 3)
    634  variable nt = dimsize(tempdata, nd - 4)
    635 
    636  switch (nd)
    637  case 2:
    638  if (nx <= 1)
    639  redimension /n=(ny) data
    640  setdimlabel 0, -1, AD_Dim1, data
    641  data = tempdata[p][0]
    642  elseif (ny <= 1)
    643  redimension /n=(nx) data
    644  setdimlabel 0, -1, AD_Dim0, data
    645  data = tempdata[0][p]
    646  else
    647  redimension /n=(nx,ny) data
    648  setdimlabel 0, -1, AD_Dim0, data
    649  setdimlabel 1, -1, AD_Dim1, data
    650  data = tempdata[q][p]
    651  endif
    652  break
    653  case 3:
    654  if (nx <= 1)
    655  redimension /n=(ny,nz) data
    656  setdimlabel 0, -1, AD_Dim1, data
    657  setdimlabel 1, -1, AD_DimN, data
    658  multithread data = tempdata[q][p][0]
    659  elseif (ny <= 1)
    660  redimension /n=(nx,nz) data
    661  setdimlabel 0, -1, AD_Dim0, data
    662  setdimlabel 1, -1, AD_DimN, data
    663  multithread data = tempdata[q][0][p]
    664  elseif (nz <= 1)
    665  redimension /n=(nx,ny) data
    666  setdimlabel 0, -1, AD_Dim0, data
    667  setdimlabel 1, -1, AD_Dim1, data
    668  multithread data = tempdata[0][q][p]
    669  else
    670  redimension /n=(nx,ny,nz) data
    671  setdimlabel 0, -1, AD_Dim0, data
    672  setdimlabel 1, -1, AD_Dim1, data
    673  setdimlabel 2, -1, AD_DimN, data
    674  multithread data = tempdata[r][q][p]
    675  endif
    676  break
    677  case 4:
    678  if (nz <= 1)
    679  // singleton "frame number" dimension
    680  redimension /n=(nx,ny,nt) data
    681  setdimlabel 0, -1, AD_Dim0, data
    682  setdimlabel 1, -1, AD_Dim1, data
    683  setdimlabel 2, -1, AD_DimX, data
    684  multithread data = tempdata[r][0][q][p]
    685  else
    686  redimension /n=(nx,ny,nz,nt) data
    687  setdimlabel 0, -1, AD_Dim0, data
    688  setdimlabel 1, -1, AD_Dim1, data
    689  setdimlabel 2, -1, AD_DimN, data
    690  setdimlabel 3, -1, AD_DimX, data
    691  multithread data = tempdata[s][r][q][p]
    692  endif
    693  break
    694  endswitch
    695 end
    696 
    707 static function /DF GetAttrDataFolderDFR(data)
    708  wave data
    709 
    710  dfref dataDF = GetWavesDataFolderDFR(data)
    711  dfref attrDF = dataDF:attr
    712  if (DataFolderRefStatus(attrDF) == 0)
    713  attrDF = dataDF
    714  endif
    715 
    716  return attrDF
    717 end
    718 
    726 function adh5_scale(data,[source])
    727  wave data
    728  string source
    729 
    730  dfref saveDF = GetDataFolderDFR()
    731  dfref dataDF = GetWavesDataFolderDFR(data)
    732  dfref attrDF = GetAttrDataFolderDFR(data)
    733 
    734  if (ParamIsDefault(source))
    735  // is the source a Scienta analyser?
    736  wave /SDFR=attrDF /Z AcquisitionMode
    737  wave /SDFR=attrDF /T /Z Manufacturer
    738  source = "unknown"
    739  if (waveexists(Manufacturer) && (numpnts(Manufacturer) >= 1))
    740  strswitch(Manufacturer[0])
    741  case "VG Scienta":
    742  source = "scienta"
    743  break
    744  case "Prosilica":
    745  source = "prosilica"
    746  break
    747  endswitch
    748  elseif (waveexists(AcquisitionMode) && (numpnts(AcquisitionMode) >= 1))
    749  if (stringmatch(note(AcquisitionMode), "*SCIENTA*"))
    750  source = "scienta"
    751  endif
    752  endif
    753  endif
    754 
    755  strswitch(source)
    756  case "prosilica":
    757  // pixel scale - nothing to do
    758  break
    759  case "scienta":
    760  adh5_scale_scienta(data)
    761  break
    762  endswitch
    763 
    764  setdatafolder saveDF
    765 end
    766 
    780 function adh5_load_detector_slabs(fileID, detectorpath, [progress])
    781  variable fileID
    782  string detectorpath
    783  variable progress
    784 
    785  if (ParamIsDefault(progress))
    786  progress = 1
    787  endif
    788  variable result = 0
    789 
    790  // avoid compilation error if HDF5 XOP has not been loaded
    791  #if Exists("HDF5LoadData")
    792  string datasetname
    793  string datawavename
    794 
    795  // detector data
    796  datasetname = detectorpath + "data"
    797  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    798  InitHDF5DataInfo(di)
    799  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    800  if (err != 0)
    801  print "error accessing detector/data"
    802  return -1
    803  endif
    804  if (di.ndims < 2)
    805  print "error: rank of dataset < 2"
    806  return -2
    807  endif
    808 
    809  // nx and nz are the image dimensions
    810  variable idx, idy, idz, idt, izt
    811  idx = di.ndims - 1
    812  idy = di.ndims - 2
    813  idz = -1
    814  idt = -1
    815 
    816  variable nx, ny, nz, nt, nzt
    817  nx = di.dims[idx]
    818  ny = di.dims[idy]
    819  nz = 1
    820  nt = 1
    821 
    822  make /n=(nx,ny,nz,nt) /o data
    823  string dim_labels = "AD_Dim0;AD_Dim1;AD_DimN;AD_DimX;AD_DimY"
    824  string dim_label
    825  dim_label = StringFromList(0, dim_labels, ";")
    826  setdimlabel 0, -1, $dim_label, data
    827  dim_labels = RemoveFromList(dim_label, dim_labels, ";")
    828  dim_label = StringFromList(0, dim_labels, ";")
    829  setdimlabel 1, -1, $dim_label, data
    830  dim_labels = RemoveFromList(dim_label, dim_labels, ";")
    831 
    832  // find additional dimensions, ignore singletons
    833  variable id
    834  for (id = idy - 1; (id >= 0) && (nz == 1); id -= 1)
    835  if (di.dims[id] > 1)
    836  idz = id
    837  nz = di.dims[id]
    838  dim_label = StringFromList(0, dim_labels, ";")
    839  setdimlabel 2, -1, $dim_label, data
    840  endif
    841  dim_labels = RemoveListItem(0, dim_labels, ";")
    842  endfor
    843  for (id = idz - 1; (id >= 0) && (nt == 1); id -= 1)
    844  if (di.dims[id] > 1)
    845  idt = id
    846  nt = di.dims[id]
    847  dim_label = StringFromList(0, dim_labels, ";")
    848  setdimlabel 3, -1, $dim_label, data
    849  endif
    850  dim_labels = RemoveListItem(0, dim_labels, ";")
    851  endfor
    852  redimension /n=(nx,ny,nz,nt) data
    853 
    854  // default values if dimensions are not present in dataset
    855  if (idz < 0)
    856  idz = idx + 1
    857  idt = idz + 1
    858  elseif (idt < 0)
    859  idt = idx + 1
    860  endif
    861 
    862  nzt = nz * nt
    863  izt = 0
    864  if (progress)
    865  display_progress_panel("HDF5 Import", "Loading data...", nzt)
    866  endif
    867 
    868  // load data image by image
    869  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
    870  wave slab
    871  slab[][%Start] = 0
    872  slab[][%Stride] = 1
    873  slab[][%Count] = 1
    874  slab[][%Block] = 1
    875  slab[idx][%Block] = nx
    876  slab[idy][%Block] = ny
    877 
    878  variable iz, it
    879  for (iz = 0; iz < nz; iz += 1)
    880  for (it = 0; it < nt; it += 1)
    881  slab[idz][%Start] = iz
    882  slab[idt][%Start] = it
    883  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
    884  wave slabdata // 2D, 3D, or 4D with singletons
    885  switch (WaveDims(slabdata))
    886  case 2:
    887  data[][][iz][it] = slabdata[q][p]
    888  break
    889  case 3:
    890  data[][][iz][it] = slabdata[0][q][p]
    891  break
    892  case 4:
    893  data[][][iz][it] = slabdata[0][0][q][p]
    894  break
    895  endswitch
    896  // progress window
    897  izt += 1
    898  if (progress)
    899  if (update_progress_panel(izt))
    900  result = -4 // user abort
    901  break
    902  endif
    903  endif
    904  endfor
    905  if (result < 0)
    906  break
    907  endif
    908  endfor
    909 
    910  if (nz == 1)
    911  redimension /n=(nx,ny) data
    912  elseif (nt == 1)
    913  redimension /n=(nx,ny,nz) data
    914  endif
    915 
    916  if (progress)
    918  endif
    919  #else
    920  Abort "HDF5 XOP not loaded."
    921  #endif
    922 
    923  return result
    924 end
    925 
    945 function adh5_load_detector_image(fileID, detectorpath, dim2start, dim2count, dim3start, dim3count)
    946  variable fileID
    947  string detectorpath
    948  variable dim2start
    949  variable dim2count
    950  variable dim3start
    951  variable dim3count
    952 
    953  // avoid compilation error if HDF5 XOP has not been loaded
    954  #if Exists("HDF5LoadData")
    955  string datasetname
    956  string datawavename
    957 
    958  // detector data
    959  datasetname = detectorpath + "data"
    960  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    961  InitHDF5DataInfo(di)
    962  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    963  if (err != 0)
    964  print "error accessing detector/data"
    965  return -1
    966  endif
    967  if (di.ndims < 1)
    968  print "error: rank of dataset < 1"
    969  return -2
    970  endif
    971 
    972  // nx and nz are the image dimensions
    973  variable idx, idy, idz, idt
    974  idx = di.ndims - 1
    975  idy = di.ndims >= 2 ? di.ndims - 2 : 1
    976  idz = di.ndims >= 3 ? di.ndims - 3 : 2
    977  idt = di.ndims >= 4 ? di.ndims - 4 : 3
    978 
    979  variable nx, ny
    980  nx = di.dims[idx]
    981  ny = di.ndims >= 2 ? di.dims[idy] : 1
    982 
    983  variable dim2end = dim2start + dim2count - 1
    984  variable dim3end = dim3start + dim3count - 1
    985 
    986  // the slab wave is at least 4-dimensional
    987  // it will also load lower-dimensional datasets
    988  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
    989  wave slab
    990  slab[][%Start] = 0
    991  slab[][%Stride] = 1
    992  slab[][%Count] = 1
    993  slab[][%Block] = 1
    994  slab[idx][%Block] = nx
    995  slab[idy][%Block] = ny
    996 
    997  make /n=(nx,ny)/o/d data
    998  data = 0
    999  variable iz, it
    1000  variable navg = 0
    1001  for (iz = dim2start; iz <= dim2end; iz += 1)
    1002  for (it = dim3start; it <= dim3end; it += 1)
    1003  slab[idz][%Start] = iz
    1004  slab[idt][%Start] = it
    1005  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
    1006  wave slabdata // 2D, 3D, or 4D with singletons
    1007  switch (WaveDims(slabdata))
    1008  case 1:
    1009  data += slabdata[p]
    1010  navg += 1
    1011  break
    1012  case 2:
    1013  data += slabdata[q][p]
    1014  navg += 1
    1015  break
    1016  case 3:
    1017  data += slabdata[0][q][p]
    1018  navg += 1
    1019  break
    1020  case 4:
    1021  data += slabdata[0][0][q][p]
    1022  navg += 1
    1023  break
    1024  endswitch
    1025  endfor
    1026  endfor
    1027  data /= navg
    1028  setdimlabel 0, -1, AD_Dim0, data
    1029  setdimlabel 1, -1, AD_Dim1, data
    1030 
    1031  #else
    1032  Abort "HDF5 XOP not loaded."
    1033  #endif
    1034 end
    1035 
    1042  string all_funcs = FunctionList("*", ";", "KIND:6,NPARAMS:2,VALTYPE:8")
    1043  string result = ""
    1044 
    1045  variable ii
    1046  variable nn = ItemsInList(all_funcs, ";")
    1047 
    1048  string funcname
    1049  string info
    1050  variable nparams
    1051  variable accept
    1052 
    1053  for (ii = 0; ii < nn; ii += 1)
    1054  funcname = StringFromList(ii, all_funcs, ";")
    1055  info = FunctionInfo(funcname)
    1056  accept = (NumberByKey("RETURNTYPE", info, ":", ";") == 0x4000)
    1057  accept = accept && (cmpstr(StringByKey("THREADSAFE", info, ":", ";"), "yes") == 0)
    1058  accept = accept && (NumberByKey("N_PARAMS", info, ":", ";") == 2)
    1059  accept = accept && (NumberByKey("N_OPT_PARAMS", info, ":", ";") == 0)
    1060  if (accept)
    1061  // one numeric wave and one pass-by-reference string
    1062  accept = accept && (NumberByKey("PARAM_0_TYPE", info, ":", ";") == 0x4002)
    1063  accept = accept && (NumberByKey("PARAM_1_TYPE", info, ":", ";") == 0x3000)
    1064  endif
    1065  if (accept)
    1066  result = AddListItem(funcname, result, ";")
    1067  endif
    1068  endfor
    1069 
    1070  result = SortList(result, ";", 4)
    1071  return result
    1072 end
    1073 
    1111 threadsafe function /wave adh5_default_reduction(source, param)
    1112  wave source
    1113  string &param
    1114 
    1115  // demo code
    1116  // integrate along the dimensions
    1117  make /n=0 /free dest1, dest2
    1118  adh5_setup_profile(source, dest1, 0)
    1119  ad_profile_x_w(source, 0, -1, dest1)
    1120  adh5_setup_profile(source, dest2, 1)
    1121  ad_profile_y_w(source, 0, -1, dest2)
    1122 
    1123  make /n=2 /free /wave results
    1124  results[0] = dest1
    1125  results[1] = dest2
    1126  return results
    1127 end
    1128 
    1134 threadsafe function adh5_setup_profile(image, profile, dim)
    1135  wave image // prototype
    1136  wave profile // destination wave
    1137  variable dim // which dimension to keep: 0 = X, 1 = Y
    1138 
    1139  redimension /n=(dimsize(image, dim)) profile
    1140  setscale /p x dimoffset(image, dim), dimdelta(image, dim), waveunits(image, dim), profile
    1141  setscale d 0, 0, waveunits(image, -1), profile
    1142  setdimlabel 0, -1, $getdimlabel(image, dim, -1), profile
    1143 end
    1144 
    1167 function /s adh5_test_reduction_func(source, reduction_func, reduction_param, result_prefix)
    1168  wave source
    1169  funcref adh5_default_reduction reduction_func
    1170  string reduction_param
    1171  string result_prefix
    1172 
    1173  wave /wave results = reduction_func(source, reduction_param)
    1174  adh5_get_result_waves(results, result_prefix, 1)
    1175 
    1176  return reduction_param
    1177 end
    1178 
    1198 function adh5_reduce_brick(source, reduction_func, reduction_param, result_prefix, [progress, nthreads])
    1199  wave source
    1200  funcref adh5_default_reduction reduction_func
    1201  string reduction_param
    1202  string result_prefix
    1203 
    1204  variable progress
    1205  variable nthreads
    1206 
    1207  if (ParamIsDefault(progress))
    1208  progress = 1
    1209  endif
    1210  if (ParamIsDefault(nthreads))
    1211  nthreads = -1
    1212  endif
    1213  variable result = 0
    1214 
    1215  // nx and nz are the image dimensions
    1216  variable nx, ny, nz, nt
    1217  nx = dimsize(source, 0)
    1218  ny = dimsize(source, 1)
    1219  nz = dimsize(source, 2)
    1220  // force 4th dimension to singleton (ad_extract_slab handles 3 dimensions only)
    1221  nt = 0
    1222 
    1223  variable nzt = max(nz, 1) * max(nt, 1)
    1224  variable izt
    1225 
    1226  // set up multi threading
    1227  if (nthreads < 0)
    1228  nthreads = ThreadProcessorCount
    1229  endif
    1230  if (nthreads > 0)
    1231  variable threadGroupID = ThreadGroupCreate(nthreads)
    1232  variable ithread
    1233  for (ithread = 0; ithread < nthreads; ithread += 1)
    1234  ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
    1235  endfor
    1236  else
    1237  make /n=(nzt) /df /free processing_folders
    1238  endif
    1239 
    1240  if (progress)
    1241  display_progress_panel("data reduction", "extracting data (step 1 of 2)...", nzt)
    1242  endif
    1243 
    1244  variable iz, it
    1245  string dfname
    1246  variable iw, nw
    1247  string sw
    1248  make /n=0 /free /wave result_waves
    1249 
    1250  izt = 0
    1251  for (iz = 0; iz < max(nz, 1); iz += 1)
    1252  for (it = 0; it < max(nt, 1); it += 1)
    1253  dfname = "processing_" + num2str(izt)
    1254  newdatafolder /s $dfname
    1255  ad_extract_slab(source, nan, nan, nan, nan, iz, iz, "image", pscale=1)
    1256  wave image
    1257 
    1258  // send to processing queue
    1259  variable /g r_index = iz
    1260  variable /g s_index = it
    1261  string /g func_param = reduction_param
    1262 
    1263  if (nthreads > 0)
    1264  WaveClear image
    1265  ThreadGroupPutDF threadGroupID, :
    1266  else
    1267  processing_folders[izt] = GetDataFolderDFR()
    1268  string param = reduction_param
    1269  wave /wave reduced_waves = reduction_func(image, param)
    1270  variable /g func_result = numpnts(reduced_waves)
    1271  adh5_get_result_waves(reduced_waves, "redw_", 0)
    1272  WaveClear image, reduced_waves
    1273  setdatafolder ::
    1274  endif
    1275 
    1276  izt += 1
    1277  // progress window
    1278  if (progress)
    1279  if (update_progress_panel(izt))
    1280  result = -4 // user abort
    1281  break
    1282  endif
    1283  endif
    1284  endfor
    1285  endfor
    1286 
    1287  if (progress)
    1288  update_progress_panel(0, message="processing data (step 2 of 2)...")
    1289  endif
    1290 
    1291  dfref dfr
    1292  for (izt = 0; (izt < nzt) && (result == 0); izt += 1)
    1293  if (nthreads > 0)
    1294  do
    1295  dfr = ThreadGroupGetDFR(threadGroupID, 1000)
    1296  if (DatafolderRefStatus(dfr) != 0)
    1297  break
    1298  endif
    1299  if (progress)
    1300  if (update_progress_panel(izt))
    1301  result = -4 // user abort
    1302  break
    1303  endif
    1304  endif
    1305  while (1)
    1306  else
    1307  dfr = processing_folders[izt]
    1308  if (progress)
    1309  if (update_progress_panel(izt))
    1310  result = -4 // user abort
    1311  break
    1312  endif
    1313  endif
    1314  endif
    1315 
    1316  if (result != 0)
    1317  break
    1318  endif
    1319 
    1320  nvar rr = dfr:r_index
    1321  nvar ss = dfr:s_index
    1322  nvar func_result = dfr:func_result
    1323 
    1324  if (func_result < 1)
    1325  result = -3 // dimension reduction error
    1326  break
    1327  endif
    1328 
    1329  if (numpnts(result_waves) == 0)
    1330  redimension /n=(func_result) result_waves
    1331  for (iw = 0; iw < func_result; iw += 1)
    1332  sw = "redw_" + num2str(iw)
    1333  wave profile = dfr:$sw
    1334  sw = "ReducedData" + num2str(iw+1)
    1335  make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
    1336  wave data = $sw
    1337  setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
    1338  setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
    1339  setscale /p y dimoffset(source, 2), dimdelta(source, 2), waveunits(source, 2), data
    1340  setscale /p z dimoffset(source, 3), dimdelta(source, 3), waveunits(source, 3), data
    1341  setscale d 0, 0, waveunits(profile, -1), data
    1342  result_waves[iw] = data
    1343  endfor
    1344  endif
    1345  for (iw = 0; iw < func_result; iw += 1)
    1346  sw = "redw_" + num2str(iw)
    1347  wave profile = dfr:$sw
    1348  wave data = result_waves[iw]
    1349  data[][rr][ss] = profile[p]
    1350  endfor
    1351  endfor
    1352 
    1353  if (nthreads > 0)
    1354  variable tstatus = ThreadGroupRelease(threadGroupID)
    1355  if (tstatus == -2)
    1356  result = -5 // thread did not terminate properly
    1357  endif
    1358  else
    1359  for (izt = 0; izt < nzt; izt += 1)
    1360  KillDataFolder /Z processing_folders[izt]
    1361  endfor
    1362  endif
    1363 
    1364  if (progress)
    1366  endif
    1367 
    1368  return result
    1369 end
    1370 
    1377 threadsafe static function reduce_brick_worker(reduction_func)
    1378  funcref adh5_default_reduction reduction_func
    1379  do
    1380  // wait for job from main thread
    1381  do
    1382  dfref dfr = ThreadGroupGetDFR(0, 1000)
    1383  if (DataFolderRefStatus(dfr) == 0)
    1384  if (GetRTError(2))
    1385  return 0 // no more jobs
    1386  endif
    1387  else
    1388  break
    1389  endif
    1390  while (1)
    1391 
    1392  // get input data
    1393  wave image = dfr:image
    1394  svar func_param = dfr:func_param
    1395  nvar rr = dfr:r_index
    1396  nvar ss = dfr:s_index
    1397 
    1398  // do the work
    1399  newdatafolder /s outDF
    1400  variable /g r_index = rr
    1401  variable /g s_index = ss
    1402  string param = func_param
    1403  wave /wave reduced_waves = reduction_func(image, param)
    1404  variable /g func_result = numpnts(reduced_waves)
    1405 
    1406  // send output to queue and clean up
    1407  adh5_get_result_waves(reduced_waves, "redw_", 0)
    1408  WaveClear image, reduced_waves
    1409  ThreadGroupPutDF 0, :
    1410  KillDataFolder dfr
    1411  while (1)
    1412 
    1413  return 0
    1414 end
    1415 
    1430 threadsafe function adh5_get_result_waves(results, result_prefix, start_index)
    1431  wave /wave results
    1432  string result_prefix
    1433  variable start_index
    1434 
    1435  variable nw = numpnts(results)
    1436  variable iw
    1437  string sw
    1438  for (iw = 0; iw < nw; iw += 1)
    1439  sw = result_prefix + num2str(iw + start_index)
    1440  duplicate /o results[iw], $sw
    1441  endfor
    1442 end
    1443 
    1466 function adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduction_param, [progress, nthreads])
    1467  variable fileID
    1468  string detectorpath
    1469  funcref adh5_default_reduction reduction_func
    1470  string reduction_param
    1471  variable progress
    1472  variable nthreads
    1473 
    1474  if (ParamIsDefault(progress))
    1475  progress = 1
    1476  endif
    1477  if (ParamIsDefault(nthreads))
    1478  nthreads = -1
    1479  endif
    1480  variable result = 0
    1481 
    1482  // avoid compilation error if HDF5 XOP has not been loaded
    1483  #if Exists("HDF5LoadData")
    1484  string datasetname
    1485  string datawavename
    1486 
    1487  // detector data
    1488  datasetname = detectorpath + "data"
    1489  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    1490  InitHDF5DataInfo(di)
    1491  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    1492  if (err != 0)
    1493  print "error accessing detector/data"
    1494  return -1
    1495  endif
    1496  if (di.ndims < 2)
    1497  print "error: rank of dataset < 2"
    1498  return -2
    1499  endif
    1500 
    1501  // nx and nz are the image dimensions
    1502  variable idx, idy, idz, idt
    1503  idx = di.ndims - 1
    1504  idy = di.ndims - 2
    1505  idz = -1
    1506  idt = -1
    1507 
    1508  variable nx, ny, nz, nt
    1509  nx = di.dims[idx]
    1510  ny = di.dims[idy]
    1511  nz = 1
    1512  nt = 1
    1513 
    1514  // find additional dimensions, ignore singletons
    1515  variable id
    1516  for (id = idy - 1; (id >= 0) && (nz == 1); id -= 1)
    1517  if (di.dims[id] > 1)
    1518  idz = id
    1519  nz = di.dims[id]
    1520  endif
    1521  endfor
    1522  for (id = idz - 1; (id >= 0) && (nt == 1); id -= 1)
    1523  if (di.dims[id] > 1)
    1524  idt = id
    1525  nt = di.dims[id]
    1526  endif
    1527  endfor
    1528  // default values if dimensions are not present in dataset
    1529  if (idz < 0)
    1530  idz = idx + 1
    1531  idt = idz + 1
    1532  elseif (idt < 0)
    1533  idt = idx + 1
    1534  endif
    1535  variable nzt = nz * nt
    1536  variable izt
    1537 
    1538  // load data image by image
    1539  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
    1540  wave slab
    1541  slab[][%Start] = 0
    1542  slab[][%Stride] = 1
    1543  slab[][%Count] = 1
    1544  slab[][%Block] = 1
    1545  slab[idx][%Block] = nx
    1546  slab[idy][%Block] = ny
    1547 
    1548  // set up multi threading
    1549  if (nthreads < 0)
    1550  nthreads = ThreadProcessorCount
    1551  endif
    1552  if (nthreads > 0)
    1553  variable threadGroupID = ThreadGroupCreate(nthreads)
    1554  variable ithread
    1555  for (ithread = 0; ithread < nthreads; ithread += 1)
    1556  ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
    1557  endfor
    1558  else
    1559  make /n=(nzt) /df /free processing_folders
    1560  endif
    1561 
    1562  if (progress)
    1563  display_progress_panel("HDF5 Import", "Loading data (step 1 of 2)...", nzt)
    1564  endif
    1565 
    1566  make /n=(nx,ny)/d image_template
    1567  setdimlabel 0, -1, AD_Dim0, image_template
    1568  setdimlabel 1, -1, AD_Dim1, image_template
    1569  adh5_scale(image_template)
    1570 
    1571  variable iz, it
    1572  string dfname
    1573  variable iw, nw
    1574  string sw
    1575  make /n=0 /free /wave result_waves
    1576 
    1577  izt = 0
    1578  for (iz = 0; iz < nz; iz += 1)
    1579  for (it = 0; it < nt; it += 1)
    1580  // load hyperslab
    1581  slab[idz][%Start] = iz
    1582  slab[idt][%Start] = it
    1583  dfname = "processing_" + num2str(izt)
    1584  newdatafolder /s $dfname
    1585  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
    1586 
    1587  // send to processing queue
    1588  duplicate image_template, image
    1589  variable /g r_index = iz
    1590  variable /g s_index = it
    1591  string /g func_param = reduction_param
    1592 
    1593  if (nthreads > 0)
    1594  WaveClear image
    1595  ThreadGroupPutDF threadGroupID, :
    1596  else
    1597  processing_folders[izt] = GetDataFolderDFR()
    1598  wave slabdata
    1599  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
    1600  variable /g func_result = numpnts(reduced_waves)
    1601  adh5_get_result_waves(reduced_waves, "redw_", 0)
    1602  WaveClear slabdata, image, reduced_waves
    1603  setdatafolder ::
    1604  endif
    1605 
    1606  izt += 1
    1607  // progress window
    1608  if (progress)
    1609  if (update_progress_panel(izt))
    1610  result = -4 // user abort
    1611  break
    1612  endif
    1613  endif
    1614  endfor
    1615  endfor
    1616 
    1617  killwaves /z slab, image_template
    1618  if (progress)
    1619  update_progress_panel(0, message="Processing data (step 2 of 2)...")
    1620  endif
    1621 
    1622  dfref dfr
    1623  for (izt = 0; (izt < nzt) && (result == 0); izt += 1)
    1624  if (nthreads > 0)
    1625  do
    1626  dfr = ThreadGroupGetDFR(threadGroupID, 1000)
    1627  if (DatafolderRefStatus(dfr) != 0)
    1628  break
    1629  endif
    1630  if (progress)
    1631  if (update_progress_panel(izt))
    1632  result = -4 // user abort
    1633  break
    1634  endif
    1635  endif
    1636  while (1)
    1637  else
    1638  dfr = processing_folders[izt]
    1639  if (progress)
    1640  if (update_progress_panel(izt))
    1641  result = -4 // user abort
    1642  break
    1643  endif
    1644  endif
    1645  endif
    1646 
    1647  if (result != 0)
    1648  break
    1649  endif
    1650 
    1651  nvar rr = dfr:r_index
    1652  nvar ss = dfr:s_index
    1653  nvar func_result = dfr:func_result
    1654 
    1655  if (func_result < 1)
    1656  result = -3 // dimension reduction error
    1657  break
    1658  endif
    1659 
    1660  if (numpnts(result_waves) == 0)
    1661  redimension /n=(func_result) result_waves
    1662  for (iw = 0; iw < func_result; iw += 1)
    1663  sw = "redw_" + num2str(iw)
    1664  wave profile = dfr:$sw
    1665  sw = "ReducedData" + num2str(iw+1)
    1666  make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
    1667  wave data = $sw
    1668  setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
    1669  setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
    1670  setscale d 0, 0, waveunits(profile, -1), data
    1671  result_waves[iw] = data
    1672  endfor
    1673  endif
    1674  for (iw = 0; iw < func_result; iw += 1)
    1675  sw = "redw_" + num2str(iw)
    1676  wave profile = dfr:$sw
    1677  wave data = result_waves[iw]
    1678  data[][rr][ss] = profile[p]
    1679  endfor
    1680  endfor
    1681 
    1682  if (nthreads > 0)
    1683  variable tstatus = ThreadGroupRelease(threadGroupID)
    1684  if (tstatus == -2)
    1685  result = -5 // thread did not terminate properly
    1686  endif
    1687  else
    1688  for (izt = 0; izt < nzt; izt += 1)
    1689  KillDataFolder /Z processing_folders[izt]
    1690  endfor
    1691  endif
    1692 
    1693  if (result == 0)
    1694  nw = numpnts(result_waves)
    1695  for (iw = 0; iw < nw; iw += 1)
    1696  wave data = result_waves[iw]
    1697  if (nz == 1)
    1698  redimension /n=(dimsize(data, 0)) data
    1699  elseif (nt == 1)
    1700  redimension /n=(dimsize(data, 0),nz) data
    1701  setdimlabel 1, -1, AD_DimN, data
    1702  else
    1703  setdimlabel 1, -1, AD_DimN, data
    1704  setdimlabel 2, -1, AD_DimX, data
    1705  endif
    1706  endfor
    1707  endif
    1708  if (progress)
    1710  endif
    1711 
    1712  #else
    1713  Abort "HDF5 XOP not loaded."
    1714  #endif
    1715  return result
    1716 end
    1717 
    1718 threadsafe static function reduce_slab_worker(reduction_func)
    1719  funcref adh5_default_reduction reduction_func
    1720  do
    1721  // wait for job from main thread
    1722  do
    1723  dfref dfr = ThreadGroupGetDFR(0, 1000)
    1724  if (DataFolderRefStatus(dfr) == 0)
    1725  if (GetRTError(2))
    1726  return 0 // no more jobs
    1727  endif
    1728  else
    1729  break
    1730  endif
    1731  while (1)
    1732 
    1733  // get input data
    1734  wave slabdata = dfr:slabdata
    1735  wave image = dfr:image
    1736  svar func_param = dfr:func_param
    1737  nvar rr = dfr:r_index
    1738  nvar ss = dfr:s_index
    1739 
    1740  // do the work
    1741  newdatafolder /s outDF
    1742  variable /g r_index = rr
    1743  variable /g s_index = ss
    1744  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
    1745  variable /g func_result = numpnts(reduced_waves)
    1746 
    1747  // send output to queue and clean up
    1748  adh5_get_result_waves(reduced_waves, "redw_", 0)
    1749  WaveClear slabdata, image, reduced_waves
    1750  ThreadGroupPutDF 0, :
    1751  KillDataFolder dfr
    1752  while (1)
    1753 
    1754  return 0
    1755 end
    1756 
    1757 threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_param)
    1758  wave slabdata
    1759  wave image
    1760  funcref adh5_default_reduction reduction_func
    1761  string reduction_param
    1762 
    1763  switch (WaveDims(slabdata))
    1764  case 2:
    1765  image = slabdata[q][p]
    1766  break
    1767  case 3:
    1768  image = slabdata[0][q][p]
    1769  break
    1770  case 4:
    1771  image = slabdata[0][0][q][p]
    1772  break
    1773  endswitch
    1774 
    1775  return reduction_func(image, reduction_param)
    1776 end
    1777 
    1790 function adh5_loadattr_all(fileID, attributespath)
    1791  variable fileID
    1792  string attributespath
    1793 
    1794  string datasetname
    1795  string datawavename
    1796 
    1797  // avoid compilation error if HDF5 XOP has not been loaded
    1798  #if Exists("HDF5LoadData")
    1799 
    1800  // datasets in NDAttributes group
    1801  HDF5ListGroup /F /TYPE=2 fileID, attributespath
    1802  string h5datasets = S_HDF5ListGroup
    1803  HDF5ListAttributes /TYPE=1 /Z fileID, attributespath
    1804  string h5attributes = S_HDF5ListAttributes
    1805 
    1806  variable nds = ItemsInList(h5datasets, ";")
    1807  variable na = ItemsInList(h5attributes, ";")
    1808  variable ids
    1809  variable idest = 0
    1810  variable n_attr
    1811  string s_attr
    1812  string s_source
    1813 
    1814  make /n=(nds+na) /t /o IN, ID, IV, IU
    1815 
    1816  for (ids = 0; ids < nds; ids += 1)
    1817  datasetname = StringFromList(ids, h5datasets, ";")
    1818  HDF5LoadData /O/Q fileID, datasetname
    1819  if (v_flag == 0)
    1820  datawavename = StringFromList(0, s_wavenames)
    1821  else
    1822  datawavename = ""
    1823  endif
    1824  HDF5LoadData /A="source"/O/Q/TYPE=2 fileID, datasetname
    1825  if (v_flag == 0)
    1826  wave /t source
    1827  s_source = source[0]
    1828  else
    1829  s_source = ""
    1830  endif
    1831  read_attribute_info(datawavename, s_source, idest)
    1832  endfor
    1833 
    1834  // attributes of NDAttributes group
    1835  if (v_flag == 0)
    1836  nds = ItemsInList(h5attributes, ";")
    1837  else
    1838  nds = 0
    1839  endif
    1840  for (ids = 0; ids < nds; ids += 1)
    1841  datasetname = StringFromList(ids, h5attributes, ";")
    1842  HDF5LoadData /A=datasetname/O/Q/TYPE=1 fileID, attributespath
    1843  if (v_flag == 0)
    1844  datawavename = StringFromList(0, s_wavenames)
    1845  read_attribute_info(datawavename, "", idest) // we don't get the source of these attributes
    1846  endif
    1847  endfor
    1848 
    1849  redimension /n=(idest) IN, ID, IV, IU
    1850  sort {IN, ID}, IN, ID, IV, IU
    1851 
    1852  killwaves /z source
    1853  #else
    1854  Abort "HDF5 XOP not loaded."
    1855  #endif
    1856 
    1857 end
    1858 
    1872 static function read_attribute_info(datawavename, source, idest)
    1873  string datawavename // name of the attribute wave in the current folder.
    1874  // can be text or numeric.
    1875  string source
    1876  // source identifier (EPICS name) of the attribute.
    1877  variable &idest
    1878  // destination index in IN, ID, IV, IU where the results are written.
    1879  // the variable is incremented if data was written, otherwise it is left unchanged.
    1880  // make sure IN, ID, IV, IU have at least idest + 1 elements.
    1881 
    1882  wave /t IN
    1883  wave /t ID
    1884  wave /t IV
    1885  wave /t IU
    1886 
    1887  variable n_attr
    1888  string s_attr
    1889 
    1890  if (exists(datawavename) == 1)
    1891  if (strlen(source) > 0)
    1892  Note $datawavename, "PV=" + source
    1893  endif
    1894  switch(WaveType($datawavename, 1))
    1895  case 1: // numeric
    1896  wave w_attr = $datawavename
    1897  n_attr = numpnts(w_attr)
    1898  sprintf s_attr, "%.12g", w_attr[0]
    1899  break
    1900  case 2: // text
    1901  wave /t wt_attr = $datawavename
    1902  n_attr = numpnts(wt_attr)
    1903  s_attr = wt_attr[0]
    1904  break
    1905  default: // unknown
    1906  n_attr = 0
    1907  endswitch
    1908  if (n_attr == 1)
    1909  IN[idest] = source
    1910  ID[idest] = datawavename
    1911  IV[idest] = s_attr
    1912  IU[idest] = "" // we don't get the units
    1913  idest += 1
    1914  endif
    1915  endif
    1916 end
    1917 
    1925 function adh5_scale_scienta(data)
    1926  wave data
    1927 
    1928  dfref saveDF = GetDataFolderDFR()
    1929 
    1930  dfref dataDF = GetWavesDataFolderDFR(data)
    1931  dfref attrDF = GetAttrDataFolderDFR(data)
    1932 
    1933  wave /SDFR=attrDF LensMode
    1934  wave /SDFR=attrDF /Z ChannelBegin, ChannelEnd
    1935  wave /SDFR=attrDF /Z SliceBegin, SliceEnd
    1936 
    1937  variable EDim, ADim
    1938  variable ELow, EHigh, ALow, AHigh
    1939  string EUnit, AUnit
    1940 
    1941  // which dimension is angle and which one is energy?
    1942  strswitch(GetDimLabel(data, 0, -1))
    1943  case "AD_Dim0":
    1944  EDim = 0
    1945  break
    1946  case "AD_Dim1":
    1947  EDim = 1
    1948  break
    1949  default:
    1950  EDim = -1
    1951  endswitch
    1952  strswitch(GetDimLabel(data, 1, -1))
    1953  case "AD_Dim0":
    1954  ADim = 0
    1955  break
    1956  case "AD_Dim1":
    1957  ADim = 1
    1958  break
    1959  default:
    1960  ADim = -1
    1961  endswitch
    1962 
    1963  // defaults (point scaling)
    1964  if (EDim >= 0)
    1965  ELow = dimoffset(data, EDim)
    1966  EHigh = dimoffset(data, EDim) + dimdelta(data, EDim) * (dimsize(data, EDim) - 1)
    1967  EUnit = "eV"
    1968  endif
    1969  if (ADim >= 0)
    1970  ALow = dimoffset(data, ADim)
    1971  AHigh = dimoffset(data, ADim) + dimdelta(data, ADim) * (dimsize(data, ADim) - 1)
    1972  AUnit = "arb."
    1973  endif
    1974 
    1975  // lens mode can give more detail
    1976  if (waveexists(LensMode) && (numpnts(LensMode) >= 1))
    1977  switch(LensMode[0])
    1978  case 1: // Angular45
    1979  ALow = -45/2
    1980  AHigh = +45/2
    1981  AUnit = "°"
    1982  break
    1983  case 2: // Angular60
    1984  ALow = -60/2
    1985  AHigh = +60/2
    1986  AUnit = "°"
    1987  break
    1988  endswitch
    1989  endif
    1990 
    1991  // best option if scales are explicit in separate waves
    1992  if (waveexists(ChannelBegin) && waveexists(ChannelEnd) && (numpnts(ChannelBegin) >= 1) && (numpnts(ChannelEnd) >= 1))
    1993  ELow = ChannelBegin[0]
    1994  EHigh = ChannelEnd[0]
    1995  endif
    1996  if (waveexists(SliceBegin) && waveexists(SliceEnd) && (numpnts(SliceBegin) >= 1) && (numpnts(SliceEnd) >= 1))
    1997  ALow = SliceBegin[0]
    1998  AHigh = SliceEnd[0]
    1999  endif
    2000 
    2001  // apply new scales
    2002  switch(EDim)
    2003  case 0:
    2004  setscale /i x ELow, EHigh, EUnit, data
    2005  break
    2006  case 1:
    2007  setscale /i y ELow, EHigh, EUnit, data
    2008  break
    2009  endswitch
    2010  switch(ADim)
    2011  case 0:
    2012  setscale /i x ALow, AHigh, AUnit, data
    2013  break
    2014  case 1:
    2015  setscale /i y ALow, AHigh, AUnit, data
    2016  break
    2017  endswitch
    2018 
    2019  setscale d 0, 0, "arb.", data
    2020 
    2021  setdatafolder saveDF
    2022 end
    2023 
    2030 function adh5_scale_scan(data)
    2031  wave data
    2032 
    2033  dfref saveDF = GetDataFolderDFR()
    2034 
    2035  dfref dataDF = GetWavesDataFolderDFR(data)
    2036  wave /SDFR=dataDF AcquisitionMode, DetectorMode, EnergyMode
    2037 
    2038  wave /SDFR=dataDF /z Scan1Active, Scan2Active
    2039  wave /SDFR=dataDF /t /z Scan1Positioner1, Scan1Readback1
    2040  wave /SDFR=dataDF /t /z Scan1Positioner2, Scan1Readback2
    2041  wave /SDFR=dataDF /t /z Scan2Positioner1, Scan2Readback1
    2042  wave /SDFR=dataDF /t /z Scan2Positioner2, Scan2Readback2
    2043 
    2044  // TODO : search the data folder for positioner waves,
    2045  // i.e. waves with the PV name corresponding to Scan1Positioner1 in their wave note.
    2046  wave /z zscale
    2047 
    2048  strswitch(GetDimLabel(data, 0, -1))
    2049  case "AD_DimN":
    2050  setscale /i x zscale[0], zscale[numpnts(zscale)-1], "", data
    2051  break
    2052  endswitch
    2053  strswitch(GetDimLabel(data, 1, -1))
    2054  case "AD_DimN":
    2055  setscale /i y zscale[0], zscale[numpnts(zscale)-1], "", data
    2056  break
    2057  endswitch
    2058  strswitch(GetDimLabel(data, 2, -1))
    2059  case "AD_DimN":
    2060  setscale /i z zscale[0], zscale[numpnts(zscale)-1], "", data
    2061  break
    2062  endswitch
    2063 
    2064  setdatafolder saveDF
    2065 end
    string adh5_load_preview(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    load a single image from a HDF5 file created by the Area Detector software.
    -
    variable kill_progress_panel()
    -
    variable display_progress_panel(string title, string message, variable progress_max)
    -
    string adh5_load_info(string APathName, string AFileName)
    load descriptive info from a HDF5 file created by the Area Detector software.
    -
    variable ad_load_dialog(string APathName)
    load area detector data files selected in a file dialog window
    -
    threadsafe wave ad_profile_x_w(wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    -
    static variable read_attribute_info(string datawavename, string source, variable *idest)
    sub-function of adh5_loadattr_all.
    -
    string PearlCleanupName(string name)
    -
    static dfr GetAttrDataFolderDFR(wave data)
    find the attributes data folder of an area detector dataset.
    -
    threadsafe variable adh5_setup_profile(wave image, wave profile, variable dim)
    set up a one-dimensional wave for a line profile based on a 2D original wave.
    -
    threadsafe variable adh5_get_result_waves(wave results, string result_prefix, variable start_index)
    copy waves from wave reference wave into current data folder
    -
    variable adh5_scale_scienta(wave data)
    set the energy and angle scales of an area detector dataset from the Scienta analyser.
    -
    string adh5_test_reduction_func(wave source, funcref reduction_func, string reduction_param, string result_prefix)
    wrapper function for testing reduction functions from the command line.
    -
    variable adh5_loadattr_all(variable fileID, string attributespath)
    load an NDAttributes group from an open HDF5 file into the current data folder.
    -
    variable adh5_scale_scan(wave data)
    scales the extra dimensions of an area detector dataset according to the EPICS scan ...
    -
    static threadsafe variable reduce_brick_worker(funcref reduction_func)
    thread worker for adh5_reduce_brick
    -
    variable adh5_reduce_brick(wave source, funcref reduction_func, string reduction_param, string result_prefix, variable progress=defaultValue, variable nthreads=defaultValue)
    reduce a three-dimensional intensity distribution
    -
    string ad_suggest_foldername(string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
    generate the name of a data folder based on a file name.
    -
    threadsafe wave ad_profile_y_w(wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    -
    string adh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    import everything from a HDF5 file created by the Area Detector software.
    -
    variable adh5_load_reduced_detector(variable fileID, string detectorpath, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue)
    load a reduced detector dataset from the open HDF5 file.
    -
    string adh5_load_reduced(string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable load_data=defaultValue, variable load_attr=defaultValue, variable progress=defaultValue)
    load and reduce a dataset from a HDF5 file created by the Area Detector software. ...
    -
    variable adh5_redim(wave data)
    redimension a multi-dimensional area detector array loaded from HDF5.
    -
    threadsafe wave adh5_default_reduction(wave source, string *param)
    function prototype for adh5_load_reduced_detector
    -
    variable adh5_load_detector_slabs(variable fileID, string detectorpath, variable progress=defaultValue)
    load the detector dataset from the open HDF5 file.
    -
    variable adh5_scale(wave data, string source=defaultValue)
    set the dimension scales of an area detector dataset.
    -
    variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
    -
    variable adh5_load_detector(variable fileID, string detectorpath)
    load the detector dataset from the open HDF5 file.
    -
    static threadsafe wave reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param)
    -
    static variable BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind)
    callback function for drag&drop of HDF5 files into Igor.
    -
    string adh5_list_reduction_funcs()
    get a list of functions which can be used as reduction functions.
    -
    variable adh5_load_detector_image(variable fileID, string detectorpath, variable dim2start, variable dim2count, variable dim3start, variable dim3count)
    load a single image from the detector dataset of the open HDF5 file
    -
    threadsafe wave ad_extract_slab(wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable pscale=defaultValue)
    2D cut through 3D dataset, integrate in normal dimension
    -
    static threadsafe variable reduce_slab_worker(funcref reduction_func)
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.36
    +
    4 #pragma ModuleName = PearlAreaImport
    +
    5 #pragma version = 1.13
    +
    6 #if IgorVersion() < 9.00
    +
    7 #include <HDF5 Browser>
    +
    8 #endif
    +
    9 #include "pearl-compat"
    +
    10 #include "pearl-gui-tools"
    +
    11 
    +
    12 // copyright (c) 2013-21 Paul Scherrer Institut
    +
    13 //
    +
    14 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    15 // you may not use this file except in compliance with the License.
    +
    16 // You may obtain a copy of the License at
    +
    17 // http:///www.apache.org/licenses/LICENSE-2.0
    +
    18 
    +
    38 
    +
    43 
    +
    46 static function BeforeFileOpenHook(refNum,fileName,path,type,creator,kind)
    +
    47  variable refNum, kind
    +
    48  string fileName, path, type, creator
    +
    49 
    +
    50  variable handledOpen = 0
    +
    51 
    +
    52  //PathInfo $path
    +
    53  //string FilePath = s_path + filename
    +
    54  string NickName = PearlCleanupName(ParseFilePath(3, FileName, ":", 0, 0))
    +
    55  string FileExt = LowerStr(ParseFilePath(4, FileName, ":", 0, 0))
    +
    56  string result = ""
    +
    57 
    +
    58  // override nickname with custom setting
    +
    59  svar /z cnn = gsCustomNickName
    +
    60  if (svar_exists(cnn))
    +
    61  if (exists("gvNickNameIndex") != 2)
    +
    62  variable/g gvNickNameIndex = 1
    +
    63  endif
    +
    64  nvar nni = gvNickNameIndex
    +
    65  NickName = cnn + num2str(nni)
    +
    66  nni += 1
    +
    67  endif
    +
    68 
    +
    69  if (stringmatch(FileExt, "h5") == 1)
    +
    70  result = adh5_load_complete(NickName, path, FileName)
    +
    71  endif
    +
    72 
    +
    73  string/g s_latest_datafile = result
    +
    74  string/g s_latest_nickname = nickname
    +
    75 
    +
    76  handledOpen = strlen(result) > 0
    +
    77  if (handledOpen)
    +
    78  close refnum
    +
    79  endif
    +
    80 
    +
    81  return handledOpen // 1 tells Igor not to open the file
    +
    82 End
    +
    83 
    +
    110 function /s ad_suggest_foldername(filename, [ignoredate,sourcename,unique])
    +
    111  string filename
    +
    112  variable ignoredate
    +
    113  string sourcename
    +
    114  variable unique
    +
    115 
    +
    116  if (ParamIsDefault(ignoredate))
    +
    117  ignoredate = 0
    +
    118  endif
    +
    119  if (ParamIsDefault(unique))
    +
    120  unique = 0
    +
    121  endif
    +
    122 
    +
    123  string basename = ParseFilePath(3, filename, ":", 0, 0)
    +
    124  string extension = ParseFilePath(4, filename, ":", 0, 0)
    +
    125  string nickname
    +
    126 
    +
    127  string autosource
    +
    128  if (strsearch(basename, "scienta", 0, 2) >= 0)
    +
    129  autosource = "sci"
    +
    130  elseif (strsearch(basename, "pshell", 0, 2) >= 0)
    +
    131  autosource = "psh"
    +
    132  elseif (strsearch(basename, "OP-SL", 0, 2) >= 0)
    +
    133  autosource = "sl"
    +
    134  elseif (strsearch(basename, "ES-PS", 0, 2) >= 0)
    +
    135  autosource = "es"
    +
    136  else
    +
    137  autosource = "xy"
    +
    138  endif
    +
    139  if (ParamIsDefault(sourcename))
    +
    140  sourcename = autosource
    +
    141  endif
    +
    142 
    +
    143  variable nparts = ItemsInList(basename, "-")
    +
    144  if (nparts >= 3)
    +
    145  string datepart = StringFromList(1, basename, "-")
    +
    146  variable l_datepart = strlen(datepart)
    +
    147  if (l_datepart == 8)
    +
    148  datepart = datepart[l_datepart-6, l_datepart-1]
    +
    149  endif
    +
    150  string indexpart = StringFromList(2, basename, "-")
    +
    151  if (ignoredate)
    +
    152  sprintf nickname, "%s_%s", sourcename, indexpart
    +
    153  else
    +
    154  sprintf nickname, "%s_%s_%s", sourcename, datepart, indexpart
    +
    155  endif
    +
    156  else
    +
    157  nickname = PearlCleanupName(basename)
    +
    158  endif
    +
    159 
    +
    160  if (unique && CheckName(nickname, 11))
    +
    161  nickname = UniqueName(nickname + "_", 11, 0)
    +
    162  endif
    +
    163 
    +
    164  return nickname
    +
    165 end
    +
    166 
    +
    171 function ad_load_dialog(APathName)
    +
    172  string APathName
    +
    173 
    +
    174  variable refNum
    +
    175  string message = "Select data files"
    +
    176  string filepaths
    +
    177  string filefilters = "Area Detector HDF5 Files (*.h5):.h5;"
    +
    178  filefilters += "All Files:.*;"
    +
    179 
    +
    180  PathInfo /S $APathName
    +
    181  Open /D /R /F=filefilters /M=message /MULT=1 refNum
    +
    182  filepaths = S_fileName
    +
    183 
    +
    184  dfref saveDF = GetDataFolderDFR()
    +
    185  setdatafolder root:
    +
    186 
    +
    187  if (strlen(filepaths) > 0)
    +
    188  variable nfiles = ItemsInList(filepaths, "\r")
    +
    189  variable ifile
    +
    190  for(ifile = 0; ifile < nfiles; ifile += 1)
    +
    191  String path = StringFromList(ifile, filepaths, "\r")
    +
    192  string nickname = ad_suggest_foldername(path)
    +
    193  adh5_load_complete(nickname, "", path)
    +
    194  endfor
    +
    195  endif
    +
    196 
    +
    197  setdatafolder saveDF
    +
    198 end
    +
    199 
    +
    211 function /s adh5_load_complete(ANickName, APathName, AFileName, [load_data, load_attr])
    +
    212  string ANickName
    +
    213  string APathName
    +
    214  string AFileName
    +
    215  variable load_data
    +
    216  variable load_attr
    +
    217 
    +
    218  if (ParamIsDefault(load_data))
    +
    219  load_data = 1
    +
    220  endif
    +
    221  if (ParamIsDefault(load_attr))
    +
    222  load_attr = 1
    +
    223  endif
    +
    224 
    +
    225  dfref saveDF = GetDataFolderDFR()
    +
    226  setdatafolder root:
    +
    227  newdatafolder /s/o $("root:" + ANickName)
    +
    228 
    +
    229  // open file
    +
    230  variable fileID
    +
    231  string instrumentpath = "/entry/instrument/"
    +
    232  string detectorpath = instrumentpath + "detector/"
    +
    233  string attributespath = instrumentpath + "NDAttributes/"
    +
    234  string datasetname
    +
    235  string datawavename
    +
    236 
    +
    237  // performance monitoring
    +
    238  variable timerRefNum
    +
    239  variable /g adh5_perf_secs
    +
    240  timerRefNum = startMSTimer
    +
    241 
    +
    242  // avoid compilation error if HDF5 XOP has not been loaded
    +
    243  #if Exists("HDF5OpenFile")
    +
    244  HDF5OpenFile /P=$APathName/R fileID as AFileName
    +
    245  if (v_flag == 0)
    +
    246  AFileName = s_path + s_filename
    +
    247  print "loading " + s_filename + "\r"
    +
    248 
    +
    249  if (load_data)
    +
    250  adh5_load_detector_slabs(fileID, detectorpath)
    +
    251  endif
    +
    252  if (load_attr)
    +
    253  newdatafolder /o/s attr
    +
    254  adh5_loadattr_all(fileID, attributespath)
    +
    255  setdatafolder ::
    +
    256  endif
    +
    257 
    +
    258  wave /z data
    +
    259  if (waveexists(data))
    +
    260  //adh5_redim(data) // not to be used with adh5_load_detector_slabs
    +
    261  adh5_scale(data)
    +
    262  endif
    +
    263 
    +
    264  HDF5CloseFile fileID
    +
    265  else
    +
    266  AFileName = ""
    +
    267  endif
    +
    268  #else
    +
    269  Abort "HDF5 XOP not loaded."
    +
    270  #endif
    +
    271 
    +
    272  if (timerRefNum >= 0)
    +
    273  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    +
    274  endif
    +
    275 
    +
    276  setdatafolder saveDF
    +
    277  return AFileName
    +
    278 end
    +
    279 
    +
    306 function /s adh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [load_data, load_attr, progress])
    +
    307  string ANickName
    +
    308  string APathName
    +
    309  string AFileName
    +
    310 
    +
    311  funcref adh5_default_reduction reduction_func
    +
    312  string reduction_param
    +
    313 
    +
    314  variable load_data
    +
    315  variable load_attr
    +
    316  variable progress
    +
    317 
    +
    318  if (ParamIsDefault(load_data))
    +
    319  load_data = 1
    +
    320  endif
    +
    321  if (ParamIsDefault(load_attr))
    +
    322  load_attr = 1
    +
    323  endif
    +
    324  if (ParamIsDefault(progress))
    +
    325  progress = 1
    +
    326  endif
    +
    327 
    +
    328  dfref saveDF = GetDataFolderDFR()
    +
    329  setdatafolder root:
    +
    330  newdatafolder /s/o $("root:" + ANickName)
    +
    331 
    +
    332  // open file
    +
    333  variable fileID
    +
    334  string instrumentpath = "/entry/instrument/"
    +
    335  string detectorpath = instrumentpath + "detector/"
    +
    336  string attributespath = instrumentpath + "NDAttributes/"
    +
    337  string datasetname
    +
    338  string datawavename
    +
    339 
    +
    340  // performance monitoring
    +
    341  variable timerRefNum
    +
    342  variable /g adh5_perf_secs
    +
    343  timerRefNum = startMSTimer
    +
    344 
    +
    345  // avoid compilation error if HDF5 XOP has not been loaded
    +
    346  #if Exists("HDF5OpenFile")
    +
    347  HDF5OpenFile /P=$APathName/R fileID as AFileName
    +
    348  if (v_flag == 0)
    +
    349  AFileName = s_path + s_filename
    +
    350  print "loading " + s_filename + "\r"
    +
    351 
    +
    352  if (load_attr)
    +
    353  newdatafolder /o/s attr
    +
    354  adh5_loadattr_all(fileID, attributespath)
    +
    355  setdatafolder ::
    +
    356  endif
    +
    357  if (load_data)
    +
    358  adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduction_param, progress=progress)
    +
    359  endif
    +
    360 
    +
    361  HDF5CloseFile fileID
    +
    362  else
    +
    363  AFileName = ""
    +
    364  endif
    +
    365  #else
    +
    366  Abort "HDF5 XOP not loaded."
    +
    367  #endif
    +
    368 
    +
    369  if (timerRefNum >= 0)
    +
    370  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    +
    371  endif
    +
    372 
    +
    373  setdatafolder saveDF
    +
    374  return AFileName
    +
    375 end
    +
    376 
    +
    391 function /s adh5_load_preview(ANickName, APathName, AFileName, [load_data, load_attr])
    +
    392  string ANickName
    +
    393  string APathName
    +
    394  string AFileName
    +
    395  variable load_data
    +
    396  variable load_attr
    +
    397 
    +
    398  if (ParamIsDefault(load_data))
    +
    399  load_data = 1
    +
    400  endif
    +
    401  if (ParamIsDefault(load_attr))
    +
    402  load_attr = 1
    +
    403  endif
    +
    404 
    +
    405  dfref saveDF = GetDataFolderDFR()
    +
    406  setdatafolder root:
    +
    407  newdatafolder /o/s pearl_area
    +
    408  newdatafolder /o/s preview
    +
    409 
    +
    410  // open file
    +
    411  variable fileID
    +
    412  string instrumentpath = "/entry/instrument/"
    +
    413  string detectorpath = instrumentpath + "detector/"
    +
    414  string attributespath = instrumentpath + "NDAttributes/"
    +
    415  string datasetname
    +
    416  string datawavename
    +
    417 
    +
    418  // performance monitoring
    +
    419  variable timerRefNum
    +
    420  variable /g adh5_perf_secs
    +
    421  timerRefNum = startMSTimer
    +
    422 
    +
    423  // avoid compilation error if HDF5 XOP has not been loaded
    +
    424  #if Exists("HDF5OpenFile")
    +
    425  HDF5OpenFile /P=$APathName/R/Z fileID as AFileName
    +
    426  if (v_flag == 0)
    +
    427  AFileName = s_path + s_filename
    +
    428 
    +
    429  // detector data
    +
    430  datasetname = detectorpath + "data"
    +
    431  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    432  InitHDF5DataInfo(di)
    +
    433  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    +
    434  if (err != 0)
    +
    435  print "error accessing detector/data"
    +
    436  return ""
    +
    437  endif
    +
    438  if (di.ndims < 2)
    +
    439  print "error: rank of dataset < 2"
    +
    440  return ""
    +
    441  endif
    +
    442 
    +
    443  variable dim2start = 0, dim2count = 1, dim3start = 0, dim3count = 1
    +
    444  if (di.ndims >= 3)
    +
    445  dim2start = floor(di.dims[di.ndims - 3] / 2)
    +
    446  dim2count = 1
    +
    447  endif
    +
    448  if (di.ndims >= 4)
    +
    449  dim3start = floor(di.dims[di.ndims - 4] / 2)
    +
    450  dim3count = 1
    +
    451  endif
    +
    452 
    +
    453  if (load_data)
    +
    454  adh5_load_detector_image(fileID, detectorpath, dim2start, dim2count, dim3start, dim3count)
    +
    455  wave /z data
    +
    456  string destpath = GetDataFolder(1, saveDF) + ANickName
    +
    457  if (waveexists(data))
    +
    458  duplicate /o data, $destpath
    +
    459  wave /z data = $destpath
    +
    460  endif
    +
    461  endif
    +
    462 
    +
    463  if (load_attr)
    +
    464  setdatafolder saveDF
    +
    465  newdatafolder /o/s attr
    +
    466  killwaves /a/z
    +
    467  adh5_loadattr_all(fileID, attributespath)
    +
    468  setdatafolder ::
    +
    469  if (waveexists(data))
    +
    470  adh5_scale(data)
    +
    471  endif
    +
    472  endif
    +
    473 
    +
    474  HDF5CloseFile fileID
    +
    475  else
    +
    476  print "error opening file " + AFileName
    +
    477  AFileName = ""
    +
    478  endif
    +
    479  #else
    +
    480  Abort "HDF5 XOP not loaded."
    +
    481  #endif
    +
    482 
    +
    483  if (timerRefNum >= 0)
    +
    484  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    +
    485  endif
    +
    486 
    +
    487  setdatafolder saveDF
    +
    488  return AFileName
    +
    489 end
    +
    490 
    +
    501 function /s adh5_load_info(APathName, AFileName)
    +
    502  string APathName
    +
    503  string AFileName
    +
    504 
    +
    505  dfref saveDF = GetDataFolderDFR()
    +
    506 
    +
    507  // open file
    +
    508  variable fileID
    +
    509  string instrumentpath = "/entry/instrument/"
    +
    510  string detectorpath = instrumentpath + "detector/"
    +
    511  string attributespath = instrumentpath + "NDAttributes/"
    +
    512  string datasetname
    +
    513  string datawavename
    +
    514 
    +
    515  string s_info = ""
    +
    516  string s
    +
    517 
    +
    518  variable idim
    +
    519 
    +
    520  // avoid compilation error if HDF5 XOP has not been loaded
    +
    521  #if Exists("HDF5OpenFile")
    +
    522  HDF5OpenFile /P=$APathName/R/Z fileID as AFileName
    +
    523  if (v_flag == 0)
    +
    524  AFileName = s_path + s_filename
    +
    525 
    +
    526  // detector data
    +
    527  datasetname = detectorpath + "data"
    +
    528  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    529  InitHDF5DataInfo(di)
    +
    530  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    +
    531  if (err != 0)
    +
    532  print "error accessing detector/data"
    +
    533  return ""
    +
    534  endif
    +
    535 
    +
    536  for (idim = 0; idim < di.ndims; idim += 1)
    +
    537  sprintf s, "dim %u: %u points", idim, di.dims[idim]
    +
    538  if (strlen(s_info) > 0)
    +
    539  s_info = s_info + "\r" + s
    +
    540  else
    +
    541  s_info = s
    +
    542  endif
    +
    543  endfor
    +
    544 
    +
    545  dfref df = NewFreeDataFolder()
    +
    546  setdatafolder df
    +
    547  adh5_loadattr_all(fileID, attributespath)
    +
    548 
    +
    549  for (idim = 1; idim < 5; idim += 1)
    +
    550  sprintf s, "Scan%uActive", idim
    +
    551  wave /z w = $s
    +
    552  if (waveexists(w) && (numpnts(w) > 0) && (w[0] > 0))
    +
    553  sprintf s, "Scan%uPositioner1", idim
    +
    554  wave /t wt = $s
    +
    555  sprintf s, "scan %u: %s", idim, wt[0]
    +
    556  if (strlen(s_info) > 0)
    +
    557  s_info = s_info + "\r" + s
    +
    558  else
    +
    559  s_info = s
    +
    560  endif
    +
    561  endif
    +
    562  endfor
    +
    563 
    +
    564  HDF5CloseFile fileID
    +
    565  else
    +
    566  print "error opening file " + AFileName
    +
    567  AFileName = ""
    +
    568  endif
    +
    569  #else
    +
    570  Abort "HDF5 XOP not loaded."
    +
    571  #endif
    +
    572 
    +
    573  setdatafolder saveDF
    +
    574  return s_info
    +
    575 end
    +
    576 
    +
    585 function adh5_load_detector(fileID, detectorpath)
    +
    586  variable fileID
    +
    587  string detectorpath
    +
    588 
    +
    589  // avoid compilation error if HDF5 XOP has not been loaded
    +
    590  #if Exists("HDF5LoadData")
    +
    591  string datasetname
    +
    592  string datawavename
    +
    593 
    +
    594  // detector data
    +
    595  datasetname = detectorpath + "data"
    +
    596  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    597  InitHDF5DataInfo(di)
    +
    598  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    +
    599  if (err != 0)
    +
    600  print "error accessing detector/data"
    +
    601  return -1
    +
    602  endif
    +
    603  if (di.ndims < 2)
    +
    604  print "error: rank of dataset < 2"
    +
    605  return -2
    +
    606  endif
    +
    607 
    +
    608  HDF5LoadData /O /Q /Z fileID, datasetname
    +
    609  wave data
    +
    610 
    +
    611  #else
    +
    612  Abort "HDF5 XOP not loaded."
    +
    613  #endif
    +
    614 end
    +
    615 
    +
    630 function adh5_redim(data)
    +
    631  wave data
    +
    632 
    +
    633  duplicate /free data, tempdata
    +
    634  variable nd = wavedims(tempdata)
    +
    635  variable nx = dimsize(tempdata, nd - 1)
    +
    636  variable ny = dimsize(tempdata, nd - 2)
    +
    637  variable nz = dimsize(tempdata, nd - 3)
    +
    638  variable nt = dimsize(tempdata, nd - 4)
    +
    639 
    +
    640  switch (nd)
    +
    641  case 2:
    +
    642  if (nx <= 1)
    +
    643  redimension /n=(ny) data
    +
    644  setdimlabel 0, -1, AD_Dim1, data
    +
    645  data = tempdata[p][0]
    +
    646  elseif (ny <= 1)
    +
    647  redimension /n=(nx) data
    +
    648  setdimlabel 0, -1, AD_Dim0, data
    +
    649  data = tempdata[0][p]
    +
    650  else
    +
    651  redimension /n=(nx,ny) data
    +
    652  setdimlabel 0, -1, AD_Dim0, data
    +
    653  setdimlabel 1, -1, AD_Dim1, data
    +
    654  data = tempdata[q][p]
    +
    655  endif
    +
    656  break
    +
    657  case 3:
    +
    658  if (nx <= 1)
    +
    659  redimension /n=(ny,nz) data
    +
    660  setdimlabel 0, -1, AD_Dim1, data
    +
    661  setdimlabel 1, -1, AD_DimN, data
    +
    662  multithread data = tempdata[q][p][0]
    +
    663  elseif (ny <= 1)
    +
    664  redimension /n=(nx,nz) data
    +
    665  setdimlabel 0, -1, AD_Dim0, data
    +
    666  setdimlabel 1, -1, AD_DimN, data
    +
    667  multithread data = tempdata[q][0][p]
    +
    668  elseif (nz <= 1)
    +
    669  redimension /n=(nx,ny) data
    +
    670  setdimlabel 0, -1, AD_Dim0, data
    +
    671  setdimlabel 1, -1, AD_Dim1, data
    +
    672  multithread data = tempdata[0][q][p]
    +
    673  else
    +
    674  redimension /n=(nx,ny,nz) data
    +
    675  setdimlabel 0, -1, AD_Dim0, data
    +
    676  setdimlabel 1, -1, AD_Dim1, data
    +
    677  setdimlabel 2, -1, AD_DimN, data
    +
    678  multithread data = tempdata[r][q][p]
    +
    679  endif
    +
    680  break
    +
    681  case 4:
    +
    682  if (nz <= 1)
    +
    683  // singleton "frame number" dimension
    +
    684  redimension /n=(nx,ny,nt) data
    +
    685  setdimlabel 0, -1, AD_Dim0, data
    +
    686  setdimlabel 1, -1, AD_Dim1, data
    +
    687  setdimlabel 2, -1, AD_DimX, data
    +
    688  multithread data = tempdata[r][0][q][p]
    +
    689  else
    +
    690  redimension /n=(nx,ny,nz,nt) data
    +
    691  setdimlabel 0, -1, AD_Dim0, data
    +
    692  setdimlabel 1, -1, AD_Dim1, data
    +
    693  setdimlabel 2, -1, AD_DimN, data
    +
    694  setdimlabel 3, -1, AD_DimX, data
    +
    695  multithread data = tempdata[s][r][q][p]
    +
    696  endif
    +
    697  break
    +
    698  endswitch
    +
    699 end
    +
    700 
    +
    711 static function /DF GetAttrDataFolderDFR(data)
    +
    712  wave data
    +
    713 
    +
    714  dfref dataDF = GetWavesDataFolderDFR(data)
    +
    715  dfref attrDF = dataDF:attr
    +
    716  if (DataFolderRefStatus(attrDF) == 0)
    +
    717  attrDF = dataDF
    +
    718  endif
    +
    719 
    +
    720  return attrDF
    +
    721 end
    +
    722 
    +
    730 function adh5_scale(data,[source])
    +
    731  wave data
    +
    732  string source
    +
    733 
    +
    734  dfref saveDF = GetDataFolderDFR()
    +
    735  dfref dataDF = GetWavesDataFolderDFR(data)
    +
    736  dfref attrDF = GetAttrDataFolderDFR(data)
    +
    737 
    +
    738  if (ParamIsDefault(source))
    +
    739  // is the source a Scienta analyser?
    +
    740  wave /SDFR=attrDF /Z AcquisitionMode
    +
    741  wave /SDFR=attrDF /T /Z Manufacturer
    +
    742  source = "unknown"
    +
    743  if (waveexists(Manufacturer) && (numpnts(Manufacturer) >= 1))
    +
    744  strswitch(Manufacturer[0])
    +
    745  case "VG Scienta":
    +
    746  source = "scienta"
    +
    747  break
    +
    748  case "Prosilica":
    +
    749  source = "prosilica"
    +
    750  break
    +
    751  endswitch
    +
    752  elseif (waveexists(AcquisitionMode) && (numpnts(AcquisitionMode) >= 1))
    +
    753  if (stringmatch(note(AcquisitionMode), "*SCIENTA*"))
    +
    754  source = "scienta"
    +
    755  endif
    +
    756  endif
    +
    757  endif
    +
    758 
    +
    759  strswitch(source)
    +
    760  case "prosilica":
    +
    761  // pixel scale - nothing to do
    +
    762  break
    +
    763  case "scienta":
    +
    764  adh5_scale_scienta(data)
    +
    765  break
    +
    766  endswitch
    +
    767 
    +
    768  setdatafolder saveDF
    +
    769 end
    +
    770 
    +
    784 function adh5_load_detector_slabs(fileID, detectorpath, [progress])
    +
    785  variable fileID
    +
    786  string detectorpath
    +
    787  variable progress
    +
    788 
    +
    789  if (ParamIsDefault(progress))
    +
    790  progress = 1
    +
    791  endif
    +
    792  variable result = 0
    +
    793 
    +
    794  // avoid compilation error if HDF5 XOP has not been loaded
    +
    795  #if Exists("HDF5LoadData")
    +
    796  string datasetname
    +
    797  string datawavename
    +
    798 
    +
    799  // detector data
    +
    800  datasetname = detectorpath + "data"
    +
    801  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    802  InitHDF5DataInfo(di)
    +
    803  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    +
    804  if (err != 0)
    +
    805  print "error accessing detector/data"
    +
    806  return -1
    +
    807  endif
    +
    808  if (di.ndims < 2)
    +
    809  print "error: rank of dataset < 2"
    +
    810  return -2
    +
    811  endif
    +
    812 
    +
    813  // nx and nz are the image dimensions
    +
    814  variable idx, idy, idz, idt, izt
    +
    815  idx = di.ndims - 1
    +
    816  idy = di.ndims - 2
    +
    817  idz = -1
    +
    818  idt = -1
    +
    819 
    +
    820  variable nx, ny, nz, nt, nzt
    +
    821  nx = di.dims[idx]
    +
    822  ny = di.dims[idy]
    +
    823  nz = 1
    +
    824  nt = 1
    +
    825 
    +
    826  make /n=(nx,ny,nz,nt) /o data
    +
    827  string dim_labels = "AD_Dim0;AD_Dim1;AD_DimN;AD_DimX;AD_DimY"
    +
    828  string dim_label
    +
    829  dim_label = StringFromList(0, dim_labels, ";")
    +
    830  setdimlabel 0, -1, $dim_label, data
    +
    831  dim_labels = RemoveFromList(dim_label, dim_labels, ";")
    +
    832  dim_label = StringFromList(0, dim_labels, ";")
    +
    833  setdimlabel 1, -1, $dim_label, data
    +
    834  dim_labels = RemoveFromList(dim_label, dim_labels, ";")
    +
    835 
    +
    836  // find additional dimensions, ignore singletons
    +
    837  variable id
    +
    838  for (id = idy - 1; (id >= 0) && (nz == 1); id -= 1)
    +
    839  if (di.dims[id] > 1)
    +
    840  idz = id
    +
    841  nz = di.dims[id]
    +
    842  dim_label = StringFromList(0, dim_labels, ";")
    +
    843  setdimlabel 2, -1, $dim_label, data
    +
    844  endif
    +
    845  dim_labels = RemoveListItem(0, dim_labels, ";")
    +
    846  endfor
    +
    847  for (id = idz - 1; (id >= 0) && (nt == 1); id -= 1)
    +
    848  if (di.dims[id] > 1)
    +
    849  idt = id
    +
    850  nt = di.dims[id]
    +
    851  dim_label = StringFromList(0, dim_labels, ";")
    +
    852  setdimlabel 3, -1, $dim_label, data
    +
    853  endif
    +
    854  dim_labels = RemoveListItem(0, dim_labels, ";")
    +
    855  endfor
    +
    856  redimension /n=(nx,ny,nz,nt) data
    +
    857 
    +
    858  // default values if dimensions are not present in dataset
    +
    859  if (idz < 0)
    +
    860  idz = idx + 1
    +
    861  idt = idz + 1
    +
    862  elseif (idt < 0)
    +
    863  idt = idx + 1
    +
    864  endif
    +
    865 
    +
    866  nzt = nz * nt
    +
    867  izt = 0
    +
    868  if (progress)
    +
    869  display_progress_panel("HDF5 Import", "Loading data...", nzt)
    +
    870  endif
    +
    871 
    +
    872  // load data image by image
    +
    873  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
    +
    874  wave slab
    +
    875  slab[][%Start] = 0
    +
    876  slab[][%Stride] = 1
    +
    877  slab[][%Count] = 1
    +
    878  slab[][%Block] = 1
    +
    879  slab[idx][%Block] = nx
    +
    880  slab[idy][%Block] = ny
    +
    881 
    +
    882  variable iz, it
    +
    883  for (iz = 0; iz < nz; iz += 1)
    +
    884  for (it = 0; it < nt; it += 1)
    +
    885  slab[idz][%Start] = iz
    +
    886  slab[idt][%Start] = it
    +
    887  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
    +
    888  wave slabdata // 2D, 3D, or 4D with singletons
    +
    889  switch (WaveDims(slabdata))
    +
    890  case 2:
    +
    891  data[][][iz][it] = slabdata[q][p]
    +
    892  break
    +
    893  case 3:
    +
    894  data[][][iz][it] = slabdata[0][q][p]
    +
    895  break
    +
    896  case 4:
    +
    897  data[][][iz][it] = slabdata[0][0][q][p]
    +
    898  break
    +
    899  endswitch
    +
    900  // progress window
    +
    901  izt += 1
    +
    902  if (progress)
    +
    903  if (update_progress_panel(izt))
    +
    904  result = -4 // user abort
    +
    905  break
    +
    906  endif
    +
    907  endif
    +
    908  endfor
    +
    909  if (result < 0)
    +
    910  break
    +
    911  endif
    +
    912  endfor
    +
    913 
    +
    914  if (nz == 1)
    +
    915  redimension /n=(nx,ny) data
    +
    916  elseif (nt == 1)
    +
    917  redimension /n=(nx,ny,nz) data
    +
    918  endif
    +
    919 
    +
    920  if (progress)
    + +
    922  endif
    +
    923  #else
    +
    924  Abort "HDF5 XOP not loaded."
    +
    925  #endif
    +
    926 
    +
    927  return result
    +
    928 end
    +
    929 
    +
    949 function adh5_load_detector_image(fileID, detectorpath, dim2start, dim2count, dim3start, dim3count)
    +
    950  variable fileID
    +
    951  string detectorpath
    +
    952  variable dim2start
    +
    953  variable dim2count
    +
    954  variable dim3start
    +
    955  variable dim3count
    +
    956 
    +
    957  // avoid compilation error if HDF5 XOP has not been loaded
    +
    958  #if Exists("HDF5LoadData")
    +
    959  string datasetname
    +
    960  string datawavename
    +
    961 
    +
    962  // detector data
    +
    963  datasetname = detectorpath + "data"
    +
    964  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    965  InitHDF5DataInfo(di)
    +
    966  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    +
    967  if (err != 0)
    +
    968  print "error accessing detector/data"
    +
    969  return -1
    +
    970  endif
    +
    971  if (di.ndims < 1)
    +
    972  print "error: rank of dataset < 1"
    +
    973  return -2
    +
    974  endif
    +
    975 
    +
    976  // nx and nz are the image dimensions
    +
    977  variable idx, idy, idz, idt
    +
    978  idx = di.ndims - 1
    +
    979  idy = di.ndims >= 2 ? di.ndims - 2 : 1
    +
    980  idz = di.ndims >= 3 ? di.ndims - 3 : 2
    +
    981  idt = di.ndims >= 4 ? di.ndims - 4 : 3
    +
    982 
    +
    983  variable nx, ny
    +
    984  nx = di.dims[idx]
    +
    985  ny = di.ndims >= 2 ? di.dims[idy] : 1
    +
    986 
    +
    987  variable dim2end = dim2start + dim2count - 1
    +
    988  variable dim3end = dim3start + dim3count - 1
    +
    989 
    +
    990  // the slab wave is at least 4-dimensional
    +
    991  // it will also load lower-dimensional datasets
    +
    992  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
    +
    993  wave slab
    +
    994  slab[][%Start] = 0
    +
    995  slab[][%Stride] = 1
    +
    996  slab[][%Count] = 1
    +
    997  slab[][%Block] = 1
    +
    998  slab[idx][%Block] = nx
    +
    999  slab[idy][%Block] = ny
    +
    1000 
    +
    1001  make /n=(nx,ny)/o/d data
    +
    1002  data = 0
    +
    1003  variable iz, it
    +
    1004  variable navg = 0
    +
    1005  for (iz = dim2start; iz <= dim2end; iz += 1)
    +
    1006  for (it = dim3start; it <= dim3end; it += 1)
    +
    1007  slab[idz][%Start] = iz
    +
    1008  slab[idt][%Start] = it
    +
    1009  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
    +
    1010  wave slabdata // 2D, 3D, or 4D with singletons
    +
    1011  switch (WaveDims(slabdata))
    +
    1012  case 1:
    +
    1013  data += slabdata[p]
    +
    1014  navg += 1
    +
    1015  break
    +
    1016  case 2:
    +
    1017  data += slabdata[q][p]
    +
    1018  navg += 1
    +
    1019  break
    +
    1020  case 3:
    +
    1021  data += slabdata[0][q][p]
    +
    1022  navg += 1
    +
    1023  break
    +
    1024  case 4:
    +
    1025  data += slabdata[0][0][q][p]
    +
    1026  navg += 1
    +
    1027  break
    +
    1028  endswitch
    +
    1029  endfor
    +
    1030  endfor
    +
    1031  data /= navg
    +
    1032  setdimlabel 0, -1, AD_Dim0, data
    +
    1033  setdimlabel 1, -1, AD_Dim1, data
    +
    1034 
    +
    1035  #else
    +
    1036  Abort "HDF5 XOP not loaded."
    +
    1037  #endif
    +
    1038 end
    +
    1039 
    + +
    1046  string all_funcs = FunctionList("*", ";", "KIND:6,NPARAMS:2,VALTYPE:8")
    +
    1047  string result = ""
    +
    1048 
    +
    1049  variable ii
    +
    1050  variable nn = ItemsInList(all_funcs, ";")
    +
    1051 
    +
    1052  string funcname
    +
    1053  string info
    +
    1054  variable nparams
    +
    1055  variable accept
    +
    1056 
    +
    1057  for (ii = 0; ii < nn; ii += 1)
    +
    1058  funcname = StringFromList(ii, all_funcs, ";")
    +
    1059  info = FunctionInfo(funcname)
    +
    1060  accept = (NumberByKey("RETURNTYPE", info, ":", ";") == 0x4000)
    +
    1061  accept = accept && (cmpstr(StringByKey("THREADSAFE", info, ":", ";"), "yes") == 0)
    +
    1062  accept = accept && (NumberByKey("N_PARAMS", info, ":", ";") == 2)
    +
    1063  accept = accept && (NumberByKey("N_OPT_PARAMS", info, ":", ";") == 0)
    +
    1064  if (accept)
    +
    1065  // one numeric wave and one pass-by-reference string
    +
    1066  accept = accept && (NumberByKey("PARAM_0_TYPE", info, ":", ";") == 0x4002)
    +
    1067  accept = accept && (NumberByKey("PARAM_1_TYPE", info, ":", ";") == 0x3000)
    +
    1068  endif
    +
    1069  if (accept)
    +
    1070  result = AddListItem(funcname, result, ";")
    +
    1071  endif
    +
    1072  endfor
    +
    1073 
    +
    1074  result = SortList(result, ";", 4)
    +
    1075  return result
    +
    1076 end
    +
    1077 
    +
    1115 threadsafe function /wave adh5_default_reduction(source, param)
    +
    1116  wave source
    +
    1117  string &param
    +
    1118 
    +
    1119  // demo code
    +
    1120  // integrate along the dimensions
    +
    1121  make /n=0 /free dest1, dest2
    +
    1122  adh5_setup_profile(source, dest1, 0)
    +
    1123  ad_profile_x_w(source, 0, -1, dest1)
    +
    1124  adh5_setup_profile(source, dest2, 1)
    +
    1125  ad_profile_y_w(source, 0, -1, dest2)
    +
    1126 
    +
    1127  make /n=2 /free /wave results
    +
    1128  results[0] = dest1
    +
    1129  results[1] = dest2
    +
    1130  return results
    +
    1131 end
    +
    1132 
    +
    1138 threadsafe function adh5_setup_profile(image, profile, dim)
    +
    1139  wave image // prototype
    +
    1140  wave profile // destination wave
    +
    1141  variable dim // which dimension to keep: 0 = X, 1 = Y
    +
    1142 
    +
    1143  redimension /n=(dimsize(image, dim)) profile
    +
    1144  setscale /p x dimoffset(image, dim), dimdelta(image, dim), waveunits(image, dim), profile
    +
    1145  setscale d 0, 0, waveunits(image, -1), profile
    +
    1146  setdimlabel 0, -1, $getdimlabel(image, dim, -1), profile
    +
    1147 end
    +
    1148 
    +
    1171 function /s adh5_test_reduction_func(source, reduction_func, reduction_param, result_prefix)
    +
    1172  wave source
    +
    1173  funcref adh5_default_reduction reduction_func
    +
    1174  string reduction_param
    +
    1175  string result_prefix
    +
    1176 
    +
    1177  wave /wave results = reduction_func(source, reduction_param)
    +
    1178  adh5_get_result_waves(results, result_prefix, 1)
    +
    1179 
    +
    1180  return reduction_param
    +
    1181 end
    +
    1182 
    +
    1203 function adh5_reduce_brick(source, reduction_func, reduction_param, result_prefix, [progress, nthreads])
    +
    1204  wave source
    +
    1205  funcref adh5_default_reduction reduction_func
    +
    1206  string reduction_param
    +
    1207  string result_prefix
    +
    1208 
    +
    1209  variable progress
    +
    1210  variable nthreads
    +
    1211 
    +
    1212  if (ParamIsDefault(progress))
    +
    1213  progress = 1
    +
    1214  endif
    +
    1215  if (ParamIsDefault(nthreads))
    +
    1216  nthreads = -1
    +
    1217  endif
    +
    1218 
    +
    1219  dfref base_df = GetDataFolderDFR()
    +
    1220  variable result = 0
    +
    1221  string wavenames = ""
    +
    1222 
    +
    1223  // nx and nz are the image dimensions
    +
    1224  variable nx, ny, nz, nt
    +
    1225  nx = dimsize(source, 0)
    +
    1226  ny = dimsize(source, 1)
    +
    1227  nz = dimsize(source, 2)
    +
    1228  // force 4th dimension to singleton (ad_extract_slab handles 3 dimensions only)
    +
    1229  nt = 1
    +
    1230 
    +
    1231  variable nzt = max(nz, 1) * max(nt, 1)
    +
    1232 
    +
    1233  // set up multi threading
    +
    1234  if (nthreads < 0)
    +
    1235  nthreads = ThreadProcessorCount
    +
    1236  endif
    +
    1237  if (nthreads > 0)
    +
    1238  variable threadGroupID = ThreadGroupCreate(nthreads)
    +
    1239  variable ithread
    +
    1240  for (ithread = 0; ithread < nthreads; ithread += 1)
    +
    1241  ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
    +
    1242  endfor
    +
    1243  else
    +
    1244  make /n=(nzt) /df /free processing_folders
    +
    1245  endif
    +
    1246 
    +
    1247  if (progress)
    +
    1248  display_progress_panel("Reduction", "Processing data...", nzt)
    +
    1249  endif
    +
    1250 
    +
    1251  variable iz, it
    +
    1252  variable n_sent = 0
    +
    1253  variable n_recvd = 0
    +
    1254  variable tmo = 0
    +
    1255  string dfname
    +
    1256  dfref dfr
    +
    1257  variable iw, nw
    +
    1258  string sw
    +
    1259  make /n=0 /free /wave result_waves
    +
    1260 
    +
    1261  iz = 0
    +
    1262  it = 0
    +
    1263 
    +
    1264  do
    +
    1265  // fill the processing queue up to a maximum number of folders
    +
    1266  if (n_sent < max(1, nthreads) * 10 + n_recvd)
    +
    1267  if (iz < nz)
    +
    1268  if (it < nt)
    +
    1269  // load a slab into a temporary folder
    +
    1270  dfname = "processing_" + num2str(n_sent)
    +
    1271  NewDataFolder /s $dfname
    +
    1272  ad_extract_slab(source, nan, nan, nan, nan, iz, iz, "image", pscale=1)
    +
    1273  wave image
    +
    1274  variable /g r_index = iz
    +
    1275  variable /g s_index = it
    +
    1276  string /g func_param = reduction_param
    +
    1277 
    +
    1278  if (nthreads > 0)
    +
    1279  // send to thread group
    +
    1280  WaveClear image
    +
    1281  ThreadGroupPutDF threadGroupID, :
    +
    1282  else
    +
    1283  // process immediately in single-thread mode
    +
    1284  processing_folders[n_sent] = GetDataFolderDFR()
    +
    1285  string param = func_param
    +
    1286  wave /wave reduced_waves = reduction_func(image, param)
    +
    1287  variable /g func_result = numpnts(reduced_waves)
    +
    1288  adh5_get_result_waves(reduced_waves, "redw_", 0)
    +
    1289  WaveClear image, reduced_waves
    +
    1290  setdatafolder ::
    +
    1291  endif
    +
    1292 
    +
    1293  iz += 1
    +
    1294  n_sent += 1
    +
    1295  tmo = 0
    +
    1296  else
    +
    1297  iz += 1
    +
    1298  it = 0
    +
    1299  endif
    +
    1300  endif
    +
    1301  else
    +
    1302  // throttle the loop if processing is slow
    +
    1303  tmo = min(100, tmo + 10)
    +
    1304  endif
    +
    1305 
    +
    1306  // receive a slab from the processing queue
    +
    1307  if (n_recvd < nzt)
    +
    1308  if (nthreads > 0)
    +
    1309  dfr = ThreadGroupGetDFR(threadGroupID, tmo)
    +
    1310  else
    +
    1311  dfr = processing_folders[n_recvd]
    +
    1312  processing_folders[n_recvd] = $""
    +
    1313  endif
    +
    1314 
    +
    1315  if (DatafolderRefStatus(dfr) != 0)
    +
    1316  // access results folder
    +
    1317  nvar rr = dfr:r_index
    +
    1318  nvar ss = dfr:s_index
    +
    1319  nvar func_result = dfr:func_result
    +
    1320 
    +
    1321  if (func_result < 1)
    +
    1322  print "error during data reduction."
    +
    1323  result = -3
    +
    1324  break
    +
    1325  endif
    +
    1326 
    +
    1327  // initialize result waves just once
    +
    1328  if (numpnts(result_waves) == 0)
    +
    1329  redimension /n=(func_result) result_waves
    +
    1330  for (iw = 0; iw < func_result; iw += 1)
    +
    1331  sw = "redw_" + num2str(iw)
    +
    1332  wave profile = dfr:$sw
    +
    1333  sw = "ReducedData" + num2str(iw+1)
    +
    1334  make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
    +
    1335  wave data = $sw
    +
    1336  setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
    +
    1337  setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
    +
    1338  setscale /p y dimoffset(source, 2), dimdelta(source, 2), waveunits(source, 2), data
    +
    1339  setscale /p z dimoffset(source, 3), dimdelta(source, 3), waveunits(source, 3), data
    +
    1340  setscale d 0, 0, waveunits(profile, -1), data
    +
    1341  note data, note(profile)
    +
    1342  result_waves[iw] = data
    +
    1343  endfor
    +
    1344  endif
    +
    1345 
    +
    1346  // copy results
    +
    1347  for (iw = 0; iw < func_result; iw += 1)
    +
    1348  sw = "redw_" + num2str(iw)
    +
    1349  wave profile = dfr:$sw
    +
    1350  wave data = result_waves[iw]
    +
    1351  data[][rr][ss] = profile[p]
    +
    1352  endfor
    +
    1353 
    +
    1354  n_recvd += 1
    +
    1355  KillDataFolder /Z dfr
    +
    1356  endif
    +
    1357  else
    +
    1358  // processing complete
    +
    1359  break
    +
    1360  endif
    +
    1361 
    +
    1362  // update progress window
    +
    1363  if (progress)
    +
    1364  if (update_progress_panel(n_recvd))
    +
    1365  print "user abort"
    +
    1366  result = -4
    +
    1367  break
    +
    1368  endif
    +
    1369  endif
    +
    1370  while ((n_recvd < nzt) && (result == 0))
    +
    1371 
    +
    1372  // clean up
    +
    1373  if (nthreads > 0)
    +
    1374  variable tstatus = ThreadGroupRelease(threadGroupID)
    +
    1375  if (tstatus == -2)
    +
    1376  print "error: thread did not terminate properly."
    +
    1377  result = -5
    +
    1378  endif
    +
    1379  endif
    +
    1380 
    +
    1381  // finalize results
    +
    1382  nw = numpnts(result_waves)
    +
    1383  wavenames = ""
    +
    1384  for (iw = 0; iw < nw; iw += 1)
    +
    1385  wave /z data = result_waves[iw]
    +
    1386  if (WaveExists(data))
    +
    1387  if (nz == 1)
    +
    1388  redimension /n=(-1, 0, 0) data
    +
    1389  elseif (nt == 1)
    +
    1390  redimension /n=(-1, nz, 0) data
    +
    1391  endif
    +
    1392  wavenames += nameofwave(data) + ";"
    +
    1393  endif
    +
    1394  endfor
    +
    1395 
    +
    1396  if (progress)
    + +
    1398  endif
    +
    1399 
    +
    1400  setdatafolder base_df
    +
    1401  return result
    +
    1402 end
    +
    1403 
    +
    1410 threadsafe static function reduce_brick_worker(reduction_func)
    +
    1411  funcref adh5_default_reduction reduction_func
    +
    1412  do
    +
    1413  // wait for job from main thread
    +
    1414  do
    +
    1415  dfref dfr = ThreadGroupGetDFR(0, 1000)
    +
    1416  if (DataFolderRefStatus(dfr) == 0)
    +
    1417  if (GetRTError(2))
    +
    1418  return 0 // no more jobs
    +
    1419  endif
    +
    1420  else
    +
    1421  break
    +
    1422  endif
    +
    1423  while (1)
    +
    1424 
    +
    1425  // get input data
    +
    1426  wave image = dfr:image
    +
    1427  svar func_param = dfr:func_param
    +
    1428  nvar rr = dfr:r_index
    +
    1429  nvar ss = dfr:s_index
    +
    1430 
    +
    1431  // do the work
    +
    1432  newdatafolder /s outDF
    +
    1433  variable /g r_index = rr
    +
    1434  variable /g s_index = ss
    +
    1435  string param = func_param
    +
    1436  wave /wave reduced_waves = reduction_func(image, param)
    +
    1437  variable /g func_result = numpnts(reduced_waves)
    +
    1438 
    +
    1439  // send output to queue and clean up
    +
    1440  adh5_get_result_waves(reduced_waves, "redw_", 0)
    +
    1441  WaveClear image, reduced_waves
    +
    1442  ThreadGroupPutDF 0, :
    +
    1443  KillDataFolder dfr
    +
    1444  while (1)
    +
    1445 
    +
    1446  return 0
    +
    1447 end
    +
    1448 
    +
    1463 threadsafe function adh5_get_result_waves(results, result_prefix, start_index)
    +
    1464  wave /wave results
    +
    1465  string result_prefix
    +
    1466  variable start_index
    +
    1467 
    +
    1468  variable nw = numpnts(results)
    +
    1469  variable iw
    +
    1470  string sw
    +
    1471  for (iw = 0; iw < nw; iw += 1)
    +
    1472  sw = result_prefix + num2str(iw + start_index)
    +
    1473  duplicate /o results[iw], $sw
    +
    1474  endfor
    +
    1475 end
    +
    1476 
    +
    1499 function adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduction_param, [progress, nthreads])
    +
    1500  variable fileID
    +
    1501  string detectorpath
    +
    1502  funcref adh5_default_reduction reduction_func
    +
    1503  string reduction_param
    +
    1504  variable progress
    +
    1505  variable nthreads
    +
    1506 
    +
    1507  if (ParamIsDefault(progress))
    +
    1508  progress = 1
    +
    1509  endif
    +
    1510  if (ParamIsDefault(nthreads))
    +
    1511  nthreads = -1
    +
    1512  endif
    +
    1513  variable result = 0
    +
    1514 
    +
    1515  // avoid compilation error if HDF5 XOP has not been loaded
    +
    1516  #if Exists("HDF5LoadData")
    +
    1517  string datasetname
    +
    1518  string datawavename
    +
    1519 
    +
    1520  // detector data
    +
    1521  datasetname = detectorpath + "data"
    +
    1522  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    1523  InitHDF5DataInfo(di)
    +
    1524  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
    +
    1525  if (err != 0)
    +
    1526  print "error accessing detector/data"
    +
    1527  return -1
    +
    1528  endif
    +
    1529  if (di.ndims < 2)
    +
    1530  print "error: rank of dataset < 2"
    +
    1531  return -2
    +
    1532  endif
    +
    1533 
    +
    1534  // nx and nz are the image dimensions
    +
    1535  variable idx, idy, idz, idt
    +
    1536  idx = di.ndims - 1
    +
    1537  idy = di.ndims - 2
    +
    1538  idz = -1
    +
    1539  idt = -1
    +
    1540 
    +
    1541  variable nx, ny, nz, nt
    +
    1542  nx = di.dims[idx]
    +
    1543  ny = di.dims[idy]
    +
    1544  nz = 1
    +
    1545  nt = 1
    +
    1546 
    +
    1547  // find additional dimensions, ignore singletons
    +
    1548  variable id
    +
    1549  for (id = idy - 1; (id >= 0) && (nz == 1); id -= 1)
    +
    1550  if (di.dims[id] > 1)
    +
    1551  idz = id
    +
    1552  nz = di.dims[id]
    +
    1553  endif
    +
    1554  endfor
    +
    1555  for (id = idz - 1; (id >= 0) && (nt == 1); id -= 1)
    +
    1556  if (di.dims[id] > 1)
    +
    1557  idt = id
    +
    1558  nt = di.dims[id]
    +
    1559  endif
    +
    1560  endfor
    +
    1561  // default values if dimensions are not present in dataset
    +
    1562  if (idz < 0)
    +
    1563  idz = idx + 1
    +
    1564  idt = idz + 1
    +
    1565  elseif (idt < 0)
    +
    1566  idt = idx + 1
    +
    1567  endif
    +
    1568  variable nzt = nz * nt
    +
    1569  variable izt
    +
    1570 
    +
    1571  // load data image by image
    +
    1572  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
    +
    1573  wave slab
    +
    1574  slab[][%Start] = 0
    +
    1575  slab[][%Stride] = 1
    +
    1576  slab[][%Count] = 1
    +
    1577  slab[][%Block] = 1
    +
    1578  slab[idx][%Block] = nx
    +
    1579  slab[idy][%Block] = ny
    +
    1580 
    +
    1581  // set up multi threading
    +
    1582  if (nthreads < 0)
    +
    1583  nthreads = ThreadProcessorCount
    +
    1584  endif
    +
    1585  if (nthreads > 0)
    +
    1586  variable threadGroupID = ThreadGroupCreate(nthreads)
    +
    1587  variable ithread
    +
    1588  for (ithread = 0; ithread < nthreads; ithread += 1)
    +
    1589  ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
    +
    1590  endfor
    +
    1591  else
    +
    1592  make /n=(nzt) /df /free processing_folders
    +
    1593  endif
    +
    1594 
    +
    1595  if (progress)
    +
    1596  display_progress_panel("HDF5 Import", "Loading data (step 1 of 2)...", nzt)
    +
    1597  endif
    +
    1598 
    +
    1599  make /n=(nx,ny)/d image_template
    +
    1600  setdimlabel 0, -1, AD_Dim0, image_template
    +
    1601  setdimlabel 1, -1, AD_Dim1, image_template
    +
    1602  adh5_scale(image_template)
    +
    1603 
    +
    1604  variable iz, it
    +
    1605  string dfname
    +
    1606  variable iw, nw
    +
    1607  string sw
    +
    1608  make /n=0 /free /wave result_waves
    +
    1609 
    +
    1610  izt = 0
    +
    1611  for (iz = 0; iz < nz; iz += 1)
    +
    1612  for (it = 0; it < nt; it += 1)
    +
    1613  // load hyperslab
    +
    1614  slab[idz][%Start] = iz
    +
    1615  slab[idt][%Start] = it
    +
    1616  dfname = "processing_" + num2str(izt)
    +
    1617  newdatafolder /s $dfname
    +
    1618  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
    +
    1619 
    +
    1620  // send to processing queue
    +
    1621  duplicate image_template, image
    +
    1622  variable /g r_index = iz
    +
    1623  variable /g s_index = it
    +
    1624  string /g func_param = reduction_param
    +
    1625 
    +
    1626  if (nthreads > 0)
    +
    1627  WaveClear image
    +
    1628  ThreadGroupPutDF threadGroupID, :
    +
    1629  else
    +
    1630  processing_folders[izt] = GetDataFolderDFR()
    +
    1631  wave slabdata
    +
    1632  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
    +
    1633  variable /g func_result = numpnts(reduced_waves)
    +
    1634  adh5_get_result_waves(reduced_waves, "redw_", 0)
    +
    1635  WaveClear slabdata, image, reduced_waves
    +
    1636  setdatafolder ::
    +
    1637  endif
    +
    1638 
    +
    1639  izt += 1
    +
    1640  // progress window
    +
    1641  if (progress)
    +
    1642  if (update_progress_panel(izt))
    +
    1643  result = -4 // user abort
    +
    1644  break
    +
    1645  endif
    +
    1646  endif
    +
    1647  endfor
    +
    1648  endfor
    +
    1649 
    +
    1650  killwaves /z slab, image_template
    +
    1651  if (progress)
    +
    1652  update_progress_panel(0, message="Processing data (step 2 of 2)...")
    +
    1653  endif
    +
    1654 
    +
    1655  dfref dfr
    +
    1656  for (izt = 0; (izt < nzt) && (result == 0); izt += 1)
    +
    1657  if (nthreads > 0)
    +
    1658  do
    +
    1659  dfr = ThreadGroupGetDFR(threadGroupID, 1000)
    +
    1660  if (DatafolderRefStatus(dfr) != 0)
    +
    1661  break
    +
    1662  endif
    +
    1663  if (progress)
    +
    1664  if (update_progress_panel(izt))
    +
    1665  result = -4 // user abort
    +
    1666  break
    +
    1667  endif
    +
    1668  endif
    +
    1669  while (1)
    +
    1670  else
    +
    1671  dfr = processing_folders[izt]
    +
    1672  if (progress)
    +
    1673  if (update_progress_panel(izt))
    +
    1674  result = -4 // user abort
    +
    1675  break
    +
    1676  endif
    +
    1677  endif
    +
    1678  endif
    +
    1679 
    +
    1680  if (result != 0)
    +
    1681  break
    +
    1682  endif
    +
    1683 
    +
    1684  nvar rr = dfr:r_index
    +
    1685  nvar ss = dfr:s_index
    +
    1686  nvar func_result = dfr:func_result
    +
    1687 
    +
    1688  if (func_result < 1)
    +
    1689  result = -3 // dimension reduction error
    +
    1690  break
    +
    1691  endif
    +
    1692 
    +
    1693  if (numpnts(result_waves) == 0)
    +
    1694  redimension /n=(func_result) result_waves
    +
    1695  for (iw = 0; iw < func_result; iw += 1)
    +
    1696  sw = "redw_" + num2str(iw)
    +
    1697  wave profile = dfr:$sw
    +
    1698  sw = "ReducedData" + num2str(iw+1)
    +
    1699  make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
    +
    1700  wave data = $sw
    +
    1701  setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
    +
    1702  setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
    +
    1703  setscale d 0, 0, waveunits(profile, -1), data
    +
    1704  result_waves[iw] = data
    +
    1705  endfor
    +
    1706  endif
    +
    1707  for (iw = 0; iw < func_result; iw += 1)
    +
    1708  sw = "redw_" + num2str(iw)
    +
    1709  wave profile = dfr:$sw
    +
    1710  wave data = result_waves[iw]
    +
    1711  data[][rr][ss] = profile[p]
    +
    1712  endfor
    +
    1713  endfor
    +
    1714 
    +
    1715  if (nthreads > 0)
    +
    1716  variable tstatus = ThreadGroupRelease(threadGroupID)
    +
    1717  if (tstatus == -2)
    +
    1718  result = -5 // thread did not terminate properly
    +
    1719  endif
    +
    1720  else
    +
    1721  for (izt = 0; izt < nzt; izt += 1)
    +
    1722  KillDataFolder /Z processing_folders[izt]
    +
    1723  endfor
    +
    1724  endif
    +
    1725 
    +
    1726  if (result == 0)
    +
    1727  nw = numpnts(result_waves)
    +
    1728  for (iw = 0; iw < nw; iw += 1)
    +
    1729  wave data = result_waves[iw]
    +
    1730  if (nz == 1)
    +
    1731  redimension /n=(dimsize(data, 0)) data
    +
    1732  elseif (nt == 1)
    +
    1733  redimension /n=(dimsize(data, 0),nz) data
    +
    1734  setdimlabel 1, -1, AD_DimN, data
    +
    1735  else
    +
    1736  setdimlabel 1, -1, AD_DimN, data
    +
    1737  setdimlabel 2, -1, AD_DimX, data
    +
    1738  endif
    +
    1739  endfor
    +
    1740  endif
    +
    1741  if (progress)
    + +
    1743  endif
    +
    1744 
    +
    1745  #else
    +
    1746  Abort "HDF5 XOP not loaded."
    +
    1747  #endif
    +
    1748  return result
    +
    1749 end
    +
    1750 
    +
    1751 threadsafe static function reduce_slab_worker(reduction_func)
    +
    1752  funcref adh5_default_reduction reduction_func
    +
    1753  do
    +
    1754  // wait for job from main thread
    +
    1755  do
    +
    1756  dfref dfr = ThreadGroupGetDFR(0, 1000)
    +
    1757  if (DataFolderRefStatus(dfr) == 0)
    +
    1758  if (GetRTError(2))
    +
    1759  return 0 // no more jobs
    +
    1760  endif
    +
    1761  else
    +
    1762  break
    +
    1763  endif
    +
    1764  while (1)
    +
    1765 
    +
    1766  // get input data
    +
    1767  wave slabdata = dfr:slabdata
    +
    1768  wave image = dfr:image
    +
    1769  svar func_param = dfr:func_param
    +
    1770  nvar rr = dfr:r_index
    +
    1771  nvar ss = dfr:s_index
    +
    1772 
    +
    1773  // do the work
    +
    1774  newdatafolder /s outDF
    +
    1775  variable /g r_index = rr
    +
    1776  variable /g s_index = ss
    +
    1777  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
    +
    1778  variable /g func_result = numpnts(reduced_waves)
    +
    1779 
    +
    1780  // send output to queue and clean up
    +
    1781  adh5_get_result_waves(reduced_waves, "redw_", 0)
    +
    1782  WaveClear slabdata, image, reduced_waves
    +
    1783  ThreadGroupPutDF 0, :
    +
    1784  KillDataFolder dfr
    +
    1785  while (1)
    +
    1786 
    +
    1787  return 0
    +
    1788 end
    +
    1789 
    +
    1790 threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_param)
    +
    1791  wave slabdata
    +
    1792  wave image
    +
    1793  funcref adh5_default_reduction reduction_func
    +
    1794  string reduction_param
    +
    1795 
    +
    1796  switch (WaveDims(slabdata))
    +
    1797  case 2:
    +
    1798  image = slabdata[q][p]
    +
    1799  break
    +
    1800  case 3:
    +
    1801  image = slabdata[0][q][p]
    +
    1802  break
    +
    1803  case 4:
    +
    1804  image = slabdata[0][0][q][p]
    +
    1805  break
    +
    1806  endswitch
    +
    1807 
    +
    1808  return reduction_func(image, reduction_param)
    +
    1809 end
    +
    1810 
    +
    1823 function adh5_loadattr_all(fileID, attributespath)
    +
    1824  variable fileID
    +
    1825  string attributespath
    +
    1826 
    +
    1827  string datasetname
    +
    1828  string datawavename
    +
    1829 
    +
    1830  // avoid compilation error if HDF5 XOP has not been loaded
    +
    1831  #if Exists("HDF5LoadData")
    +
    1832 
    +
    1833  // datasets in NDAttributes group
    +
    1834  HDF5ListGroup /F /TYPE=2 fileID, attributespath
    +
    1835  string h5datasets = S_HDF5ListGroup
    +
    1836  HDF5ListAttributes /TYPE=1 /Z fileID, attributespath
    +
    1837  string h5attributes = S_HDF5ListAttributes
    +
    1838 
    +
    1839  variable nds = ItemsInList(h5datasets, ";")
    +
    1840  variable na = ItemsInList(h5attributes, ";")
    +
    1841  variable ids
    +
    1842  variable idest = 0
    +
    1843  variable n_attr
    +
    1844  string s_attr
    +
    1845  string s_source
    +
    1846 
    +
    1847  make /n=(nds+na) /t /o IN, ID, IV, IU
    +
    1848 
    +
    1849  for (ids = 0; ids < nds; ids += 1)
    +
    1850  datasetname = StringFromList(ids, h5datasets, ";")
    +
    1851  HDF5LoadData /O/Q fileID, datasetname
    +
    1852  if (v_flag == 0)
    +
    1853  datawavename = StringFromList(0, s_wavenames)
    +
    1854  else
    +
    1855  datawavename = ""
    +
    1856  endif
    +
    1857  HDF5LoadData /A="source"/O/Q/TYPE=2 fileID, datasetname
    +
    1858  if (v_flag == 0)
    +
    1859  wave /t source
    +
    1860  s_source = source[0]
    +
    1861  else
    +
    1862  s_source = ""
    +
    1863  endif
    +
    1864  read_attribute_info(datawavename, s_source, idest)
    +
    1865  endfor
    +
    1866 
    +
    1867  // attributes of NDAttributes group
    +
    1868  if (v_flag == 0)
    +
    1869  nds = ItemsInList(h5attributes, ";")
    +
    1870  else
    +
    1871  nds = 0
    +
    1872  endif
    +
    1873  for (ids = 0; ids < nds; ids += 1)
    +
    1874  datasetname = StringFromList(ids, h5attributes, ";")
    +
    1875  HDF5LoadData /A=datasetname/O/Q/TYPE=1 fileID, attributespath
    +
    1876  if (v_flag == 0)
    +
    1877  datawavename = StringFromList(0, s_wavenames)
    +
    1878  read_attribute_info(datawavename, "", idest) // we don't get the source of these attributes
    +
    1879  endif
    +
    1880  endfor
    +
    1881 
    +
    1882  redimension /n=(idest) IN, ID, IV, IU
    +
    1883  sort {IN, ID}, IN, ID, IV, IU
    +
    1884 
    +
    1885  killwaves /z source
    +
    1886  #else
    +
    1887  Abort "HDF5 XOP not loaded."
    +
    1888  #endif
    +
    1889 
    +
    1890 end
    +
    1891 
    +
    1905 static function read_attribute_info(datawavename, source, idest)
    +
    1906  string datawavename // name of the attribute wave in the current folder.
    +
    1907  // can be text or numeric.
    +
    1908  string source
    +
    1909  // source identifier (EPICS name) of the attribute.
    +
    1910  variable &idest
    +
    1911  // destination index in IN, ID, IV, IU where the results are written.
    +
    1912  // the variable is incremented if data was written, otherwise it is left unchanged.
    +
    1913  // make sure IN, ID, IV, IU have at least idest + 1 elements.
    +
    1914 
    +
    1915  wave /t IN
    +
    1916  wave /t ID
    +
    1917  wave /t IV
    +
    1918  wave /t IU
    +
    1919 
    +
    1920  variable n_attr
    +
    1921  string s_attr
    +
    1922 
    +
    1923  if (exists(datawavename) == 1)
    +
    1924  if (strlen(source) > 0)
    +
    1925  Note $datawavename, "PV=" + source
    +
    1926  endif
    +
    1927  switch(WaveType($datawavename, 1))
    +
    1928  case 1: // numeric
    +
    1929  wave w_attr = $datawavename
    +
    1930  n_attr = numpnts(w_attr)
    +
    1931  sprintf s_attr, "%.12g", w_attr[0]
    +
    1932  break
    +
    1933  case 2: // text
    +
    1934  wave /t wt_attr = $datawavename
    +
    1935  n_attr = numpnts(wt_attr)
    +
    1936  s_attr = wt_attr[0]
    +
    1937  break
    +
    1938  default: // unknown
    +
    1939  n_attr = 0
    +
    1940  endswitch
    +
    1941  if (n_attr == 1)
    +
    1942  IN[idest] = source
    +
    1943  ID[idest] = datawavename
    +
    1944  IV[idest] = s_attr
    +
    1945  IU[idest] = "" // we don't get the units
    +
    1946  idest += 1
    +
    1947  endif
    +
    1948  endif
    +
    1949 end
    +
    1950 
    +
    1958 function adh5_scale_scienta(data)
    +
    1959  wave data
    +
    1960 
    +
    1961  dfref saveDF = GetDataFolderDFR()
    +
    1962 
    +
    1963  dfref dataDF = GetWavesDataFolderDFR(data)
    +
    1964  dfref attrDF = GetAttrDataFolderDFR(data)
    +
    1965 
    +
    1966  wave /SDFR=attrDF LensMode
    +
    1967  wave /SDFR=attrDF /Z ChannelBegin, ChannelEnd
    +
    1968  wave /SDFR=attrDF /Z SliceBegin, SliceEnd
    +
    1969 
    +
    1970  variable EDim, ADim
    +
    1971  variable ELow, EHigh, ALow, AHigh
    +
    1972  string EUnit, AUnit
    +
    1973 
    +
    1974  // which dimension is angle and which one is energy?
    +
    1975  strswitch(GetDimLabel(data, 0, -1))
    +
    1976  case "AD_Dim0":
    +
    1977  EDim = 0
    +
    1978  break
    +
    1979  case "AD_Dim1":
    +
    1980  EDim = 1
    +
    1981  break
    +
    1982  default:
    +
    1983  EDim = -1
    +
    1984  endswitch
    +
    1985  strswitch(GetDimLabel(data, 1, -1))
    +
    1986  case "AD_Dim0":
    +
    1987  ADim = 0
    +
    1988  break
    +
    1989  case "AD_Dim1":
    +
    1990  ADim = 1
    +
    1991  break
    +
    1992  default:
    +
    1993  ADim = -1
    +
    1994  endswitch
    +
    1995 
    +
    1996  // defaults (point scaling)
    +
    1997  if (EDim >= 0)
    +
    1998  ELow = dimoffset(data, EDim)
    +
    1999  EHigh = dimoffset(data, EDim) + dimdelta(data, EDim) * (dimsize(data, EDim) - 1)
    +
    2000  EUnit = "eV"
    +
    2001  endif
    +
    2002  if (ADim >= 0)
    +
    2003  ALow = dimoffset(data, ADim)
    +
    2004  AHigh = dimoffset(data, ADim) + dimdelta(data, ADim) * (dimsize(data, ADim) - 1)
    +
    2005  AUnit = "arb."
    +
    2006  endif
    +
    2007 
    +
    2008  // lens mode can give more detail
    +
    2009  if (waveexists(LensMode) && (numpnts(LensMode) >= 1))
    +
    2010  switch(LensMode[0])
    +
    2011  case 1: // Angular45
    +
    2012  ALow = -45/2
    +
    2013  AHigh = +45/2
    +
    2014  AUnit = "°"
    +
    2015  break
    +
    2016  case 2: // Angular60
    +
    2017  ALow = -60/2
    +
    2018  AHigh = +60/2
    +
    2019  AUnit = "°"
    +
    2020  break
    +
    2021  endswitch
    +
    2022  endif
    +
    2023 
    +
    2024  // best option if scales are explicit in separate waves
    +
    2025  if (waveexists(ChannelBegin) && waveexists(ChannelEnd) && (numpnts(ChannelBegin) >= 1) && (numpnts(ChannelEnd) >= 1))
    +
    2026  ELow = ChannelBegin[0]
    +
    2027  EHigh = ChannelEnd[0]
    +
    2028  endif
    +
    2029  if (waveexists(SliceBegin) && waveexists(SliceEnd) && (numpnts(SliceBegin) >= 1) && (numpnts(SliceEnd) >= 1))
    +
    2030  ALow = SliceBegin[0]
    +
    2031  AHigh = SliceEnd[0]
    +
    2032  endif
    +
    2033 
    +
    2034  // apply new scales
    +
    2035  switch(EDim)
    +
    2036  case 0:
    +
    2037  setscale /i x ELow, EHigh, EUnit, data
    +
    2038  break
    +
    2039  case 1:
    +
    2040  setscale /i y ELow, EHigh, EUnit, data
    +
    2041  break
    +
    2042  endswitch
    +
    2043  switch(ADim)
    +
    2044  case 0:
    +
    2045  setscale /i x ALow, AHigh, AUnit, data
    +
    2046  break
    +
    2047  case 1:
    +
    2048  setscale /i y ALow, AHigh, AUnit, data
    +
    2049  break
    +
    2050  endswitch
    +
    2051 
    +
    2052  setscale d 0, 0, "arb.", data
    +
    2053 
    +
    2054  setdatafolder saveDF
    +
    2055 end
    +
    2056 
    +
    2063 function adh5_scale_scan(data)
    +
    2064  wave data
    +
    2065 
    +
    2066  dfref saveDF = GetDataFolderDFR()
    +
    2067 
    +
    2068  dfref dataDF = GetWavesDataFolderDFR(data)
    +
    2069  wave /SDFR=dataDF AcquisitionMode, DetectorMode, EnergyMode
    +
    2070 
    +
    2071  wave /SDFR=dataDF /z Scan1Active, Scan2Active
    +
    2072  wave /SDFR=dataDF /t /z Scan1Positioner1, Scan1Readback1
    +
    2073  wave /SDFR=dataDF /t /z Scan1Positioner2, Scan1Readback2
    +
    2074  wave /SDFR=dataDF /t /z Scan2Positioner1, Scan2Readback1
    +
    2075  wave /SDFR=dataDF /t /z Scan2Positioner2, Scan2Readback2
    +
    2076 
    +
    2077  // TODO : search the data folder for positioner waves,
    +
    2078  // i.e. waves with the PV name corresponding to Scan1Positioner1 in their wave note.
    +
    2079  wave /z zscale
    +
    2080 
    +
    2081  strswitch(GetDimLabel(data, 0, -1))
    +
    2082  case "AD_DimN":
    +
    2083  setscale /i x zscale[0], zscale[numpnts(zscale)-1], "", data
    +
    2084  break
    +
    2085  endswitch
    +
    2086  strswitch(GetDimLabel(data, 1, -1))
    +
    2087  case "AD_DimN":
    +
    2088  setscale /i y zscale[0], zscale[numpnts(zscale)-1], "", data
    +
    2089  break
    +
    2090  endswitch
    +
    2091  strswitch(GetDimLabel(data, 2, -1))
    +
    2092  case "AD_DimN":
    +
    2093  setscale /i z zscale[0], zscale[numpnts(zscale)-1], "", data
    +
    2094  break
    +
    2095  endswitch
    +
    2096 
    +
    2097  setdatafolder saveDF
    +
    2098 end
    +
    string adh5_list_reduction_funcs()
    get a list of functions which can be used as reduction functions.
    +
    static threadsafe variable reduce_slab_worker(funcref reduction_func)
    +
    string adh5_load_preview(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    load a single image from a HDF5 file created by the Area Detector software.
    +
    variable kill_progress_panel()
    +
    string adh5_load_info(string APathName, string AFileName)
    load descriptive info from a HDF5 file created by the Area Detector software.
    +
    variable display_progress_panel(string title, string message, variable progress_max)
    +
    variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
    +
    variable ad_load_dialog(string APathName)
    load area detector data files selected in a file dialog window
    +
    threadsafe variable adh5_get_result_waves(wave results, string result_prefix, variable start_index)
    copy waves from wave reference wave into current data folder
    +
    static variable read_attribute_info(string datawavename, string source, variable *idest)
    sub-function of adh5_loadattr_all.
    +
    threadsafe wave ad_profile_x_w(wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    +
    variable adh5_scale_scienta(wave data)
    set the energy and angle scales of an area detector dataset from the Scienta analyser.
    +
    string adh5_test_reduction_func(wave source, funcref reduction_func, string reduction_param, string result_prefix)
    wrapper function for testing reduction functions from the command line.
    +
    static dfr GetAttrDataFolderDFR(wave data)
    find the attributes data folder of an area detector dataset.
    +
    threadsafe variable adh5_setup_profile(wave image, wave profile, variable dim)
    set up a one-dimensional wave for a line profile based on a 2D original wave.
    +
    variable adh5_loadattr_all(variable fileID, string attributespath)
    load an NDAttributes group from an open HDF5 file into the current data folder.
    +
    variable adh5_scale_scan(wave data)
    scales the extra dimensions of an area detector dataset according to the EPICS scan
    +
    variable adh5_reduce_brick(wave source, funcref reduction_func, string reduction_param, string result_prefix, variable progress=defaultValue, variable nthreads=defaultValue)
    reduce a three-dimensional intensity distribution
    +
    static threadsafe variable reduce_brick_worker(funcref reduction_func)
    thread worker for adh5_reduce_brick
    +
    string ad_suggest_foldername(string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
    generate the name of a data folder based on a file name.
    +
    string adh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    import everything from a HDF5 file created by the Area Detector software.
    +
    threadsafe wave ad_profile_y_w(wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    +
    threadsafe wave adh5_default_reduction(wave source, string *param)
    function prototype for adh5_load_reduced_detector
    +
    threadsafe wave ad_extract_slab(wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable pscale=defaultValue)
    2D cut through 3D dataset, integrate in normal dimension
    +
    variable adh5_redim(wave data)
    redimension a multi-dimensional area detector array loaded from HDF5.
    +
    variable adh5_load_detector_slabs(variable fileID, string detectorpath, variable progress=defaultValue)
    load the detector dataset from the open HDF5 file.
    +
    string adh5_load_reduced(string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable load_data=defaultValue, variable load_attr=defaultValue, variable progress=defaultValue)
    load and reduce a dataset from a HDF5 file created by the Area Detector software.
    +
    variable adh5_load_reduced_detector(variable fileID, string detectorpath, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue)
    load a reduced detector dataset from the open HDF5 file.
    +
    string PearlCleanupName(string name)
    +
    variable adh5_load_detector(variable fileID, string detectorpath)
    load the detector dataset from the open HDF5 file.
    +
    variable adh5_scale(wave data, string source=defaultValue)
    set the dimension scales of an area detector dataset.
    +
    static variable BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind)
    callback function for drag&drop of HDF5 files into Igor.
    +
    static threadsafe wave reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param)
    +
    variable adh5_load_detector_image(variable fileID, string detectorpath, variable dim2start, variable dim2count, variable dim3start, variable dim3count)
    load a single image from the detector dataset of the open HDF5 file
    diff --git a/doc/html/pearl-area-profiles_8ipf.html b/doc/html/pearl-area-profiles_8ipf.html index d1dac1d..b739e90 100644 --- a/doc/html/pearl-area-profiles_8ipf.html +++ b/doc/html/pearl-area-profiles_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-area-profiles.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -103,19 +105,19 @@ Namespaces

    Functions

    threadsafe wave ad_extract_rod (wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable sdev=defaultValue, variable pscale=defaultValue) - 1D cut through 3D dataset, integrate in normal dimensions More...
    + 1D cut through 3D dataset, integrate in normal dimensions More...
      threadsafe wave ad_extract_rod_x (wave dataset, variable q1, variable q2, variable r1, variable r2, string destname, variable noavg=defaultValue, variable sdev=defaultValue) - 1D cut through 3D dataset along X dimension. More...
    + 1D cut through 3D dataset along X dimension. More...
      threadsafe wave ad_extract_rod_y (wave dataset, variable p1, variable p2, variable r1, variable r2, string destname, variable noavg=defaultValue, variable sdev=defaultValue) - 1D cut through 3D dataset along Y dimension. More...
    + 1D cut through 3D dataset along Y dimension. More...
      threadsafe wave ad_extract_rod_z (wave dataset, variable p1, variable p2, variable q1, variable q2, string destname, variable noavg=defaultValue, variable sdev=defaultValue) - 1D cut through 3D dataset along Z dimension. More...
    + 1D cut through 3D dataset along Z dimension. More...
      threadsafe wave ad_extract_slab (wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable pscale=defaultValue) - 2D cut through 3D dataset, integrate in normal dimension More...
    + 2D cut through 3D dataset, integrate in normal dimension More...
      threadsafe wave ad_extract_slab_x (wave dataset, variable p1, variable p2, string destname, variable noavg=defaultValue)   @@ -124,29 +126,29 @@ Functions threadsafe wave ad_extract_slab_z (wave dataset, variable r1, variable r2, string destname, variable noavg=defaultValue)   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. More...
    + 1D cut through 2D dataset along X dimension, new destination wave. More...
      threadsafe wave ad_profile_x_w (wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue) - 1D cut through 2D dataset along X dimension, existing destination wave. More...
    + 1D cut through 2D dataset along X dimension, existing destination wave. More...
      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. More...
    + 1D cut through 2D dataset along Y dimension, new destination wave. More...
      threadsafe wave ad_profile_y_w (wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue) - 1D cut through 2D dataset along X dimension, existing destination wave. More...
    + 1D cut through 2D dataset along X dimension, existing destination wave. More...
      threadsafe variable calc_y_profile_mins (wave image)   variable ad_collect_multiscan_y (wave dataset, wave positions, wave destwave, variable noavg=defaultValue) - collect profiles from a multi-scan. More...
    + collect profiles from a multi-scan. More...
     

    Detailed Description

    profile extraction for multi-dimensional datasets acquired from area detectors.

    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -
    @@ -294,7 +296,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 54 of file pearl-area-profiles.ipf.

    +

    Definition at line 55 of file pearl-area-profiles.ipf.

    @@ -361,9 +363,9 @@ Licensed under the Apache License, Version 2.0 (the "License");

    1D cut through 3D dataset along X dimension.

    -

    see ad_extract_rod() for descriptions of common parameters.

    +

    see ad_extract_rod() for descriptions of common parameters.

    -

    Definition at line 106 of file pearl-area-profiles.ipf.

    +

    Definition at line 107 of file pearl-area-profiles.ipf.

    @@ -430,9 +432,9 @@ Licensed under the Apache License, Version 2.0 (the "License");

    1D cut through 3D dataset along Y dimension.

    -

    see ad_extract_rod() for descriptions of common parameters.

    +

    see ad_extract_rod() for descriptions of common parameters.

    -

    Definition at line 168 of file pearl-area-profiles.ipf.

    +

    Definition at line 169 of file pearl-area-profiles.ipf.

    @@ -499,9 +501,9 @@ Licensed under the Apache License, Version 2.0 (the "License");

    1D cut through 3D dataset along Z dimension.

    -

    see ad_extract_rod() for descriptions of common parameters.

    +

    see ad_extract_rod() for descriptions of common parameters.

    -

    Definition at line 231 of file pearl-area-profiles.ipf.

    +

    Definition at line 232 of file pearl-area-profiles.ipf.

    @@ -596,7 +598,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 313 of file pearl-area-profiles.ipf.

    +

    Definition at line 314 of file pearl-area-profiles.ipf.

    @@ -644,7 +646,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 358 of file pearl-area-profiles.ipf.

    +

    Definition at line 359 of file pearl-area-profiles.ipf.

    @@ -692,7 +694,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 398 of file pearl-area-profiles.ipf.

    +

    Definition at line 399 of file pearl-area-profiles.ipf.

    @@ -740,7 +742,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 438 of file pearl-area-profiles.ipf.

    +

    Definition at line 439 of file pearl-area-profiles.ipf.

    @@ -790,7 +792,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    1D cut through 2D dataset along X dimension, new destination wave.

    -

    Definition at line 480 of file pearl-area-profiles.ipf.

    +

    Definition at line 481 of file pearl-area-profiles.ipf.

    @@ -840,7 +842,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    1D cut through 2D dataset along X dimension, existing destination wave.

    -

    Definition at line 504 of file pearl-area-profiles.ipf.

    +

    Definition at line 505 of file pearl-area-profiles.ipf.

    @@ -890,7 +892,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    1D cut through 2D dataset along Y dimension, new destination wave.

    -

    Definition at line 542 of file pearl-area-profiles.ipf.

    +

    Definition at line 543 of file pearl-area-profiles.ipf.

    @@ -940,7 +942,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    1D cut through 2D dataset along X dimension, existing destination wave.

    -

    Definition at line 567 of file pearl-area-profiles.ipf.

    +

    Definition at line 568 of file pearl-area-profiles.ipf.

    @@ -960,7 +962,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 603 of file pearl-area-profiles.ipf.

    +

    Definition at line 604 of file pearl-area-profiles.ipf.

    @@ -970,9 +972,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
    diff --git a/doc/html/pearl-area-profiles_8ipf_source.html b/doc/html/pearl-area-profiles_8ipf_source.html index 11af8c1..22c9387 100644 --- a/doc/html/pearl-area-profiles_8ipf_source.html +++ b/doc/html/pearl-area-profiles_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-area-profiles.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,29 +87,589 @@ $(document).ready(function(){initNavTree('pearl-area-profiles_8ipf_source.html',
    pearl-area-profiles.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.1
    3 #pragma ModuleName = PearlAreaProfiles
    4 #pragma version = 1.05
    5 
    19 
    25 
    54 threadsafe function /wave ad_extract_rod(dataset, x1, x2, y1, y2, z1, z2, destname, [noavg, sdev, pscale])
    55  wave dataset
    56  variable x1, x2, y1, y2, z1, z2
    57  string destname
    58  variable noavg
    59  variable sdev
    60  variable pscale
    61 
    62  if (wavedims(dataset) != 3)
    63  return $""
    64  endif
    65  if (ParamIsDefault(noavg))
    66  noavg = 0
    67  endif
    68  if (ParamIsDefault(sdev))
    69  sdev = 0
    70  endif
    71  if (ParamIsDefault(pscale))
    72  pscale = 0
    73  endif
    74 
    75  variable p1, p2, q1, q2, r1, r2
    76  if (pscale)
    77  p1 = x1
    78  p2 = x2
    79  q1 = y1
    80  q2 = y2
    81  r1 = z1
    82  r2 = z2
    83  else
    84  p1 = round((x1 - DimOffset(dataset, 0)) / DimDelta(dataset, 0))
    85  p2 = round((x2 - DimOffset(dataset, 0)) / DimDelta(dataset, 0))
    86  q1 = round((y1 - DimOffset(dataset, 1)) / DimDelta(dataset, 1))
    87  q2 = round((y2 - DimOffset(dataset, 1)) / DimDelta(dataset, 1))
    88  r1 = round((z1 - DimOffset(dataset, 2)) / DimDelta(dataset, 2))
    89  r2 = round((z2 - DimOffset(dataset, 2)) / DimDelta(dataset, 2))
    90  endif
    91 
    92  if ((numtype(p1) == 2) || (numtype(p2) == 2))
    93  return ad_extract_rod_x(dataset, min(q1, q2), max(q1, q2), min(r1, r2), max(r1, r2), destname, noavg=noavg, sdev=sdev)
    94  elseif ((numtype(q1) == 2) || (numtype(q2) == 2))
    95  return ad_extract_rod_y(dataset, min(p1, p2), max(p1, p2), min(r1, r2), max(r1, r2), destname, noavg=noavg, sdev=sdev)
    96  elseif ((numtype(r1) == 2) || (numtype(r2) == 2))
    97  return ad_extract_rod_z(dataset, min(p1, p2), max(p1, p2), min(q1, q2), max(q1, q2), destname, noavg=noavg, sdev=sdev)
    98  else
    99  return $""
    100  endif
    101 end
    102 
    106 threadsafe function /wave ad_extract_rod_x(dataset, q1, q2, r1, r2, destname, [noavg, sdev])
    107  wave dataset
    108  variable q1, q2, r1, r2
    109  // -inf < q1 < q2 < +inf, -inf < r1 < r2 < +inf
    110  string destname
    111  variable noavg
    112  variable sdev
    113 
    114  if (ParamIsDefault(noavg))
    115  noavg = 0
    116  endif
    117  if (ParamIsDefault(sdev))
    118  sdev = 0
    119  endif
    120  variable avg = !noavg && !sdev
    121 
    122  q1 = max(q1, 0)
    123  q2 = min(q2, dimsize(dataset, 1) - 1)
    124  r1 = max(r1, 0)
    125  r2 = min(r2, dimsize(dataset, 2) - 1)
    126 
    127  if (strlen(destname) > 0)
    128  duplicate /r=[][q1,q1][r1,r1]/o dataset, $destname
    129  wave w_dest = $destname
    130  else
    131  duplicate /r=[][q1,q1][r1,r1] /free dataset, w_dest
    132  endif
    133  redimension /n=(dimsize(w_dest, 0)) w_dest
    134  setscale /p x dimoffset(dataset, 0), dimdelta(dataset, 0), waveunits(dataset, 0), w_dest
    135 
    136  w_dest = 0
    137  variable qq, rr
    138  variable nn = 0
    139  for (qq = q1; qq <= q2; qq += 1)
    140  for (rr = r1; rr <= r2; rr += 1)
    141  w_dest += dataset[p][qq][rr]
    142  nn += 1
    143  endfor
    144  endfor
    145 
    146  if (sdev)
    147  duplicate /free w_dest, w_squares
    148  w_squares = 0
    149  for (qq = q1; qq <= q2; qq += 1)
    150  for (rr = r1; rr <= r2; rr += 1)
    151  w_squares += dataset[p][qq][rr]^2
    152  endfor
    153  endfor
    154  endif
    155 
    156  if (avg)
    157  w_dest /= nn
    158  elseif (sdev)
    159  w_dest = sqrt( (w_squares - w_dest^2 / nn) / (nn - 1) )
    160  endif
    161 
    162  return w_dest
    163 end
    164 
    168 threadsafe function /wave ad_extract_rod_y(dataset, p1, p2, r1, r2, destname, [noavg, sdev])
    169  wave dataset
    170  variable p1, p2, r1, r2
    171  // 0 <= p1 < p2 < dimsize(0), 0 <= r1 < r2 < dimsize(2)
    172  string destname
    173  variable noavg
    174  variable sdev
    175 
    176  if (ParamIsDefault(noavg))
    177  noavg = 0
    178  endif
    179  if (ParamIsDefault(sdev))
    180  sdev = 0
    181  endif
    182  variable avg = !noavg && !sdev
    183 
    184  p1 = max(p1, 0)
    185  p2 = min(p2, dimsize(dataset, 0) - 1)
    186  r1 = max(r1, 0)
    187  r2 = min(r2, dimsize(dataset, 2) - 1)
    188 
    189  if (strlen(destname) > 0)
    190  duplicate /r=[p1,p1][][r1,r1]/o dataset, $destname
    191  wave w_dest = $destname
    192  else
    193  duplicate /r=[p1,p1][][r1,r1] /free dataset, w_dest
    194  endif
    195  redimension /n=(dimsize(w_dest, 1)) w_dest
    196  setscale /p x dimoffset(dataset, 1), dimdelta(dataset, 1), waveunits(dataset, 1), w_dest
    197 
    198  w_dest = 0
    199  variable pp, rr
    200  variable nn = 0
    201  for (pp = p1; pp <= p2; pp += 1)
    202  for (rr = r1; rr <= r2; rr += 1)
    203  w_dest += dataset[pp][p][rr]
    204  nn += 1
    205  endfor
    206  endfor
    207 
    208  if (sdev)
    209  duplicate /free w_dest, w_squares
    210  w_squares = 0
    211  for (pp = p1; pp <= p2; pp += 1)
    212  for (rr = r1; rr <= r2; rr += 1)
    213  w_squares += dataset[pp][p][rr]^2
    214  nn += 1
    215  endfor
    216  endfor
    217  endif
    218 
    219  if (avg)
    220  w_dest /= nn
    221  elseif (sdev)
    222  w_dest = sqrt( (w_squares - w_dest^2 / nn) / (nn - 1) )
    223  endif
    224 
    225  return w_dest
    226 end
    227 
    231 threadsafe function /wave ad_extract_rod_z(dataset, p1, p2, q1, q2, destname, [noavg, sdev])
    232  wave dataset
    233  variable p1, p2, q1, q2
    234  // 0 <= p1 < p2 < dimsize(0), 0 <= q1 < q2 < dimsize(1)
    235  string destname
    236  variable noavg
    237  variable sdev
    238 
    239  if (ParamIsDefault(noavg))
    240  noavg = 0
    241  endif
    242  if (ParamIsDefault(sdev))
    243  sdev = 0
    244  endif
    245  variable avg = !noavg && !sdev
    246 
    247  p1 = max(p1, 0)
    248  p2 = min(p2, dimsize(dataset, 0) - 1)
    249  q1 = max(q1, 0)
    250  q2 = min(q2, dimsize(dataset, 1) - 1)
    251 
    252  if (strlen(destname) > 0)
    253  duplicate /r=[p1,p1][q1,q1][]/o dataset, $destname
    254  wave w_dest = $destname
    255  else
    256  duplicate /r=[p1,p1][q1,q1][] /free dataset, w_dest
    257  endif
    258  redimension /n=(dimsize(w_dest, 2)) w_dest
    259  setscale /p x dimoffset(dataset, 2), dimdelta(dataset, 2), waveunits(dataset, 2), w_dest
    260 
    261  w_dest = 0
    262  variable pp, qq
    263  variable nn = 0
    264  for (pp = p1; pp <= p2; pp += 1)
    265  for (qq = q1; qq <= q2; qq += 1)
    266  w_dest += dataset[pp][qq][p]
    267  nn += 1
    268  endfor
    269  endfor
    270 
    271  if (sdev)
    272  duplicate /free w_dest, w_squares
    273  w_squares = 0
    274  for (pp = p1; pp <= p2; pp += 1)
    275  for (qq = q1; qq <= q2; qq += 1)
    276  w_squares += dataset[pp][qq][p]^2
    277  nn += 1
    278  endfor
    279  endfor
    280  endif
    281 
    282  if (avg)
    283  w_dest /= nn
    284  elseif (sdev)
    285  w_dest = sqrt( (w_squares - w_dest^2 / nn) / (nn - 1) )
    286  endif
    287 
    288  return w_dest
    289 end
    290 
    313 threadsafe function /wave ad_extract_slab(dataset, x1, x2, y1, y2, z1, z2, destname, [noavg, pscale])
    314  wave dataset
    315  variable x1, x2, y1, y2, z1, z2
    316  string destname
    317  variable noavg
    318  variable pscale
    319 
    320  if (wavedims(dataset) != 3)
    321  return $""
    322  endif
    323  if (ParamIsDefault(noavg))
    324  noavg = 0
    325  endif
    326  if (ParamIsDefault(pscale))
    327  pscale = 0
    328  endif
    329 
    330  variable p1, p2, q1, q2, r1, r2
    331  if (pscale)
    332  p1 = x1
    333  p2 = x2
    334  q1 = y1
    335  q2 = y2
    336  r1 = z1
    337  r2 = z2
    338  else
    339  p1 = round((x1 - DimOffset(dataset, 0)) / DimDelta(dataset, 0))
    340  p2 = round((x2 - DimOffset(dataset, 0)) / DimDelta(dataset, 0))
    341  q1 = round((y1 - DimOffset(dataset, 1)) / DimDelta(dataset, 1))
    342  q2 = round((y2 - DimOffset(dataset, 1)) / DimDelta(dataset, 1))
    343  r1 = round((z1 - DimOffset(dataset, 2)) / DimDelta(dataset, 2))
    344  r2 = round((z2 - DimOffset(dataset, 2)) / DimDelta(dataset, 2))
    345  endif
    346 
    347  if ((numtype(p1) < 2) && (numtype(p2) < 2))
    348  return ad_extract_slab_x(dataset, min(p1, p2), max(p1, p2), destname, noavg=noavg)
    349  elseif ((numtype(q1) < 2) && (numtype(q2) < 2))
    350  return ad_extract_slab_y(dataset, min(q1, q2), max(q1, q2), destname, noavg=noavg)
    351  elseif ((numtype(r1) < 2) && (numtype(r2) < 2))
    352  return ad_extract_slab_z(dataset, min(r1, r2), max(r1, r2), destname, noavg=noavg)
    353  else
    354  return $""
    355  endif
    356 end
    357 
    358 threadsafe function /wave ad_extract_slab_x(dataset, p1, p2, destname, [noavg])
    359  wave dataset
    360  variable p1, p2
    361  // x coordinate range (point scaling) to be integrated
    362  // -inf <= p1 < p2 <= +inf
    363  string destname // name of destination wave. to be created in current data folder. overrides existing.
    364  // if empty, the function returns a free wave
    365  variable noavg // zero or default = average, non-zero = sum
    366 
    367  if (ParamIsDefault(noavg))
    368  noavg = 0
    369  endif
    370  p1 = max(p1, 0)
    371  p2 = min(p2, dimsize(dataset, 0) - 1)
    372 
    373  if (strlen(destname) > 0)
    374  duplicate /r=[p1,p1][][]/o dataset, $destname
    375  wave w_dest = $destname
    376  else
    377  duplicate /r=[p1,p1][][] /free dataset, w_dest
    378  endif
    379  redimension /n=(dimsize(w_dest, 1), dimsize(w_dest, 2)) w_dest
    380  setscale /p x dimoffset(dataset, 1), dimdelta(dataset, 1), waveunits(dataset, 1), w_dest
    381  setscale /p y dimoffset(dataset, 2), dimdelta(dataset, 2), waveunits(dataset, 2), w_dest
    382 
    383  w_dest = 0
    384  variable pp
    385  variable nn = 0
    386  for (pp = p1; pp <= p2; pp += 1)
    387  w_dest += dataset[pp][p][q]
    388  nn += 1
    389  endfor
    390 
    391  if (noavg == 0)
    392  w_dest /= nn
    393  endif
    394 
    395  return w_dest
    396 end
    397 
    398 threadsafe function /wave ad_extract_slab_y(dataset, q1, q2, destname, [noavg])
    399  wave dataset
    400  variable q1, q2
    401  // y coordinate range (point scaling) to be integrated
    402  // -inf <= q1 < q2 <= +inf
    403  string destname // name of destination wave. to be created in current data folder. overrides existing.
    404  // if empty, the function returns a free wave
    405  variable noavg // zero or default = average, non-zero = sum
    406 
    407  if (ParamIsDefault(noavg))
    408  noavg = 0
    409  endif
    410  q1 = max(q1, 0)
    411  q2 = min(q2, dimsize(dataset, 1) - 1)
    412 
    413  if (strlen(destname) > 0)
    414  duplicate /r=[][q1,q1][]/o dataset, $destname
    415  wave w_dest = $destname
    416  else
    417  duplicate /r=[][q1,q1][] /free dataset, w_dest
    418  endif
    419  redimension /n=(dimsize(w_dest, 0), dimsize(w_dest, 2)) w_dest
    420  setscale /p x dimoffset(dataset, 0), dimdelta(dataset, 0), waveunits(dataset, 0), w_dest
    421  setscale /p y dimoffset(dataset, 2), dimdelta(dataset, 2), waveunits(dataset, 2), w_dest
    422 
    423  w_dest = 0
    424  variable qq
    425  variable nn = 0
    426  for (qq = q1; qq <= q2; qq += 1)
    427  w_dest += dataset[p][qq][q]
    428  nn += 1
    429  endfor
    430 
    431  if (noavg == 0)
    432  w_dest /= nn
    433  endif
    434 
    435  return w_dest
    436 end
    437 
    438 threadsafe function /wave ad_extract_slab_z(dataset, r1, r2, destname, [noavg])
    439  wave dataset
    440  variable r1, r2
    441  // z coordinate range (point scaling) to be integrated
    442  // -inf <= r1 < r2 <= +inf
    443  string destname // name of destination wave. to be created in current data folder. overrides existing.
    444  // if empty, the function returns a free wave
    445  variable noavg // zero or default = average, non-zero = sum
    446 
    447  if (ParamIsDefault(noavg))
    448  noavg = 0
    449  endif
    450  r1 = max(r1, 0)
    451  r2 = min(r2, dimsize(dataset, 2) - 1)
    452 
    453  if (strlen(destname) > 0)
    454  duplicate /r=[][][r1,r1]/o dataset, $destname
    455  wave w_dest = $destname
    456  else
    457  duplicate /r=[][][r1,r1] /free dataset, w_dest
    458  endif
    459  redimension /n=(dimsize(w_dest, 0), dimsize(w_dest, 1)) w_dest
    460  setscale /p x dimoffset(dataset, 0), dimdelta(dataset, 0), waveunits(dataset, 0), w_dest
    461  setscale /p y dimoffset(dataset, 1), dimdelta(dataset, 1), waveunits(dataset, 1), w_dest
    462 
    463  w_dest = 0
    464  variable rr
    465  variable nn = 0
    466  for (rr = r1; rr <= r2; rr += 1)
    467  w_dest += dataset[p][q][rr]
    468  nn += 1
    469  endfor
    470 
    471  if (noavg == 0)
    472  w_dest /= nn
    473  endif
    474 
    475  return w_dest
    476 end
    477 
    480 threadsafe function /wave ad_profile_x(dataset, q1, q2, destname, [noavg])
    481  wave dataset
    482  variable q1, q2 // -inf <= q1 < q2 <= +inf
    483  // deprecated: q2 = -1 stands for dimsize(0) - 1
    484  string destname // name of destination wave. to be created in current data folder. overrides existing.
    485  // if empty, the function returns a free wave
    486  variable noavg // zero or default = average, non-zero = sum
    487 
    488  if (ParamIsDefault(noavg))
    489  noavg = 0
    490  endif
    491 
    492  if (strlen(destname) > 0)
    493  duplicate /r=[0,0][] /o dataset, $destname
    494  wave w_dest = $destname
    495  else
    496  duplicate /r=[0,0][] /free dataset, w_dest
    497  endif
    498 
    499  return ad_profile_x_w(dataset, q1, q2, w_dest, noavg=noavg)
    500 end
    501 
    504 threadsafe function /wave ad_profile_x_w(dataset, q1, q2, destwave, [noavg])
    505  wave dataset
    506  variable q1, q2 // -inf <= q1 < q2 <= +inf
    507  // deprecated: q2 = -1 stands for dimsize(0) - 1
    508  wave destwave // existing destination wave
    509  variable noavg // zero or default = average, non-zero = sum
    510 
    511  if (ParamIsDefault(noavg))
    512  noavg = 0
    513  endif
    514 
    515  redimension /n=(dimsize(dataset, 0)) destwave
    516  setscale /p x dimoffset(dataset, 0), dimdelta(dataset, 0), waveunits(dataset, 0), destwave
    517  setscale d 0, 0, waveunits(dataset, -1), destwave
    518 
    519  q1 = max(q1, 0)
    520  if (q2 < 0)
    521  q2 = inf
    522  endif
    523  q2 = min(q2, dimsize(dataset, 1) - 1)
    524 
    525  destwave = 0
    526  variable qq
    527  variable nn = 0
    528  for (qq = q1; qq <= q2; qq += 1)
    529  destwave += dataset[p][qq]
    530  nn += 1
    531  endfor
    532 
    533  if (noavg == 0)
    534  destwave /= nn
    535  endif
    536 
    537  return destwave
    538 end
    539 
    542 threadsafe function /wave ad_profile_y(dataset, p1, p2, destname, [noavg])
    543  wave dataset
    544  variable p1, p2 // -inf <= p1 < p2 < inf
    545  // deprecated: p2 = -1 stands for dimsize(0) - 1
    546  string destname // name of destination wave. to be created in current data folder. overrides existing.
    547  // if empty, the function returns a free wave
    548  variable noavg // zero or default = average, non-zero = sum
    549 
    550  if (ParamIsDefault(noavg))
    551  noavg = 0
    552  endif
    553 
    554  if (strlen(destname) > 0)
    555  duplicate /r=[][0,0] /o dataset, $destname
    556  wave w_dest = $destname
    557  else
    558  duplicate /r=[][0,0] /free dataset, w_dest
    559  endif
    560  MatrixTranspose w_dest
    561 
    562  return ad_profile_y_w(dataset, p1, p2, w_dest, noavg=noavg)
    563 end
    564 
    567 threadsafe function /wave ad_profile_y_w(dataset, p1, p2, destwave, [noavg])
    568  wave dataset
    569  variable p1, p2 // -inf <= p1 < p2 < inf
    570  // deprecated: p2 = -1 stands for dimsize(0) - 1
    571  wave destwave // existing destination wave
    572  variable noavg // zero or default = average, non-zero = sum
    573 
    574  if (ParamIsDefault(noavg))
    575  noavg = 0
    576  endif
    577 
    578  redimension /n=(dimsize(dataset, 1)) destwave
    579  setscale /p x dimoffset(dataset, 1), dimdelta(dataset, 1), waveunits(dataset, 1), destwave
    580  setscale d 0, 0, waveunits(dataset, -1), destwave
    581 
    582  p1 = max(p1, 0)
    583  if (p2 < 0)
    584  p2 = inf
    585  endif
    586  p2 = min(p2, dimsize(dataset, 0) - 1)
    587 
    588  destwave = 0
    589  variable pp
    590  variable nn = 0
    591  for (pp = p1; pp <= p2; pp += 1)
    592  destwave += dataset[pp][p]
    593  nn += 1
    594  endfor
    595 
    596  if (noavg == 0)
    597  destwave /= nn
    598  endif
    599 
    600  return destwave
    601 end
    602 
    603 threadsafe function calc_y_profile_mins(image)
    604  // experimental
    605  wave image
    606 
    607  wave yminlocs = ad_profile_x(image, 0, 0, "ymins", noavg=1)
    608  variable nx = dimsize(image, 0)
    609  variable ix
    610  for (ix = 0; ix < nx; ix += 1)
    611  wave profile = ad_profile_y(image, ix, ix, "", noavg=1)
    612  wavestats /q/m=1 profile
    613  yminlocs[ix] = v_minloc
    614  endfor
    615 end
    616 
    621 function ad_collect_multiscan_y(dataset, positions, destwave, [noavg])
    622  wave dataset
    623  wave positions
    624  wave destwave
    625  variable noavg
    626 
    627  variable tol = (wavemax(positions) - wavemin(positions)) / numpnts(positions) / 100
    628 
    629  duplicate /free positions, positions_sorted
    630  sort positions_sorted, positions_sorted
    631  duplicate /free positions_sorted, positions_diff
    632  differentiate /p /meth=2 positions_sorted /d=positions_diff
    633  positions_diff[0] = 1
    634  extract /free positions_sorted, positions_unique, positions_diff > tol
    635  variable n_unique = numpnts(positions_unique)
    636  redimension /n=(dimsize(dataset, 0), n_unique) destwave
    637 
    638  variable i
    639  variable nx, ny
    640  for (i = 0; i < n_unique; i += 1)
    641  extract /free dataset, data_extract, abs(positions[q] - positions_unique[i]) < tol
    642  nx = dimsize(dataset, 0)
    643  ny = dimsize(data_extract, 0) / nx
    644  redimension /n=(nx, ny) data_extract
    645  wave profile = ad_profile_x(data_extract, -inf, inf, "", noavg=noavg)
    646  destwave[][i] = profile[p]
    647  endfor
    648 end
    threadsafe wave ad_extract_slab_x(wave dataset, variable p1, variable p2, string destname, variable noavg=defaultValue)
    -
    threadsafe wave ad_extract_rod_x(wave dataset, variable q1, variable q2, variable r1, variable r2, string destname, variable noavg=defaultValue, variable sdev=defaultValue)
    1D cut through 3D dataset along X dimension.
    -
    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.
    -
    threadsafe wave ad_profile_x_w(wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    -
    threadsafe wave ad_extract_slab_z(wave dataset, variable r1, variable r2, string destname, variable noavg=defaultValue)
    -
    variable ad_collect_multiscan_y(wave dataset, wave positions, wave destwave, variable noavg=defaultValue)
    collect profiles from a multi-scan.
    -
    threadsafe wave ad_extract_slab_y(wave dataset, variable q1, variable q2, string destname, variable noavg=defaultValue)
    -
    threadsafe wave ad_extract_rod_z(wave dataset, variable p1, variable p2, variable q1, variable q2, string destname, variable noavg=defaultValue, variable sdev=defaultValue)
    1D cut through 3D dataset along Z dimension.
    -
    threadsafe wave ad_profile_y_w(wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    -
    threadsafe wave ad_extract_rod_y(wave dataset, variable p1, variable p2, variable r1, variable r2, string destname, variable noavg=defaultValue, variable sdev=defaultValue)
    1D cut through 3D dataset along Y dimension.
    -
    threadsafe variable calc_y_profile_mins(wave image)
    -
    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.
    -
    threadsafe wave ad_extract_rod(wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable sdev=defaultValue, variable pscale=defaultValue)
    1D cut through 3D dataset, integrate in normal dimensions
    -
    threadsafe wave ad_extract_slab(wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable pscale=defaultValue)
    2D cut through 3D dataset, integrate in normal dimension
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.1
    +
    4 #pragma ModuleName = PearlAreaProfiles
    +
    5 #pragma version = 1.05
    +
    6 
    +
    20 
    +
    26 
    +
    55 threadsafe function /wave ad_extract_rod(dataset, x1, x2, y1, y2, z1, z2, destname, [noavg, sdev, pscale])
    +
    56  wave dataset
    +
    57  variable x1, x2, y1, y2, z1, z2
    +
    58  string destname
    +
    59  variable noavg
    +
    60  variable sdev
    +
    61  variable pscale
    +
    62 
    +
    63  if (wavedims(dataset) != 3)
    +
    64  return $""
    +
    65  endif
    +
    66  if (ParamIsDefault(noavg))
    +
    67  noavg = 0
    +
    68  endif
    +
    69  if (ParamIsDefault(sdev))
    +
    70  sdev = 0
    +
    71  endif
    +
    72  if (ParamIsDefault(pscale))
    +
    73  pscale = 0
    +
    74  endif
    +
    75 
    +
    76  variable p1, p2, q1, q2, r1, r2
    +
    77  if (pscale)
    +
    78  p1 = x1
    +
    79  p2 = x2
    +
    80  q1 = y1
    +
    81  q2 = y2
    +
    82  r1 = z1
    +
    83  r2 = z2
    +
    84  else
    +
    85  p1 = round((x1 - DimOffset(dataset, 0)) / DimDelta(dataset, 0))
    +
    86  p2 = round((x2 - DimOffset(dataset, 0)) / DimDelta(dataset, 0))
    +
    87  q1 = round((y1 - DimOffset(dataset, 1)) / DimDelta(dataset, 1))
    +
    88  q2 = round((y2 - DimOffset(dataset, 1)) / DimDelta(dataset, 1))
    +
    89  r1 = round((z1 - DimOffset(dataset, 2)) / DimDelta(dataset, 2))
    +
    90  r2 = round((z2 - DimOffset(dataset, 2)) / DimDelta(dataset, 2))
    +
    91  endif
    +
    92 
    +
    93  if ((numtype(p1) == 2) || (numtype(p2) == 2))
    +
    94  return ad_extract_rod_x(dataset, min(q1, q2), max(q1, q2), min(r1, r2), max(r1, r2), destname, noavg=noavg, sdev=sdev)
    +
    95  elseif ((numtype(q1) == 2) || (numtype(q2) == 2))
    +
    96  return ad_extract_rod_y(dataset, min(p1, p2), max(p1, p2), min(r1, r2), max(r1, r2), destname, noavg=noavg, sdev=sdev)
    +
    97  elseif ((numtype(r1) == 2) || (numtype(r2) == 2))
    +
    98  return ad_extract_rod_z(dataset, min(p1, p2), max(p1, p2), min(q1, q2), max(q1, q2), destname, noavg=noavg, sdev=sdev)
    +
    99  else
    +
    100  return $""
    +
    101  endif
    +
    102 end
    +
    103 
    +
    107 threadsafe function /wave ad_extract_rod_x(dataset, q1, q2, r1, r2, destname, [noavg, sdev])
    +
    108  wave dataset
    +
    109  variable q1, q2, r1, r2
    +
    110  // -inf < q1 < q2 < +inf, -inf < r1 < r2 < +inf
    +
    111  string destname
    +
    112  variable noavg
    +
    113  variable sdev
    +
    114 
    +
    115  if (ParamIsDefault(noavg))
    +
    116  noavg = 0
    +
    117  endif
    +
    118  if (ParamIsDefault(sdev))
    +
    119  sdev = 0
    +
    120  endif
    +
    121  variable avg = !noavg && !sdev
    +
    122 
    +
    123  q1 = max(q1, 0)
    +
    124  q2 = min(q2, dimsize(dataset, 1) - 1)
    +
    125  r1 = max(r1, 0)
    +
    126  r2 = min(r2, dimsize(dataset, 2) - 1)
    +
    127 
    +
    128  if (strlen(destname) > 0)
    +
    129  duplicate /r=[][q1,q1][r1,r1]/o dataset, $destname
    +
    130  wave w_dest = $destname
    +
    131  else
    +
    132  duplicate /r=[][q1,q1][r1,r1] /free dataset, w_dest
    +
    133  endif
    +
    134  redimension /n=(dimsize(w_dest, 0)) w_dest
    +
    135  setscale /p x dimoffset(dataset, 0), dimdelta(dataset, 0), waveunits(dataset, 0), w_dest
    +
    136 
    +
    137  w_dest = 0
    +
    138  variable qq, rr
    +
    139  variable nn = 0
    +
    140  for (qq = q1; qq <= q2; qq += 1)
    +
    141  for (rr = r1; rr <= r2; rr += 1)
    +
    142  w_dest += dataset[p][qq][rr]
    +
    143  nn += 1
    +
    144  endfor
    +
    145  endfor
    +
    146 
    +
    147  if (sdev)
    +
    148  duplicate /free w_dest, w_squares
    +
    149  w_squares = 0
    +
    150  for (qq = q1; qq <= q2; qq += 1)
    +
    151  for (rr = r1; rr <= r2; rr += 1)
    +
    152  w_squares += dataset[p][qq][rr]^2
    +
    153  endfor
    +
    154  endfor
    +
    155  endif
    +
    156 
    +
    157  if (avg)
    +
    158  w_dest /= nn
    +
    159  elseif (sdev)
    +
    160  w_dest = sqrt( (w_squares - w_dest^2 / nn) / (nn - 1) )
    +
    161  endif
    +
    162 
    +
    163  return w_dest
    +
    164 end
    +
    165 
    +
    169 threadsafe function /wave ad_extract_rod_y(dataset, p1, p2, r1, r2, destname, [noavg, sdev])
    +
    170  wave dataset
    +
    171  variable p1, p2, r1, r2
    +
    172  // 0 <= p1 < p2 < dimsize(0), 0 <= r1 < r2 < dimsize(2)
    +
    173  string destname
    +
    174  variable noavg
    +
    175  variable sdev
    +
    176 
    +
    177  if (ParamIsDefault(noavg))
    +
    178  noavg = 0
    +
    179  endif
    +
    180  if (ParamIsDefault(sdev))
    +
    181  sdev = 0
    +
    182  endif
    +
    183  variable avg = !noavg && !sdev
    +
    184 
    +
    185  p1 = max(p1, 0)
    +
    186  p2 = min(p2, dimsize(dataset, 0) - 1)
    +
    187  r1 = max(r1, 0)
    +
    188  r2 = min(r2, dimsize(dataset, 2) - 1)
    +
    189 
    +
    190  if (strlen(destname) > 0)
    +
    191  duplicate /r=[p1,p1][][r1,r1]/o dataset, $destname
    +
    192  wave w_dest = $destname
    +
    193  else
    +
    194  duplicate /r=[p1,p1][][r1,r1] /free dataset, w_dest
    +
    195  endif
    +
    196  redimension /n=(dimsize(w_dest, 1)) w_dest
    +
    197  setscale /p x dimoffset(dataset, 1), dimdelta(dataset, 1), waveunits(dataset, 1), w_dest
    +
    198 
    +
    199  w_dest = 0
    +
    200  variable pp, rr
    +
    201  variable nn = 0
    +
    202  for (pp = p1; pp <= p2; pp += 1)
    +
    203  for (rr = r1; rr <= r2; rr += 1)
    +
    204  w_dest += dataset[pp][p][rr]
    +
    205  nn += 1
    +
    206  endfor
    +
    207  endfor
    +
    208 
    +
    209  if (sdev)
    +
    210  duplicate /free w_dest, w_squares
    +
    211  w_squares = 0
    +
    212  for (pp = p1; pp <= p2; pp += 1)
    +
    213  for (rr = r1; rr <= r2; rr += 1)
    +
    214  w_squares += dataset[pp][p][rr]^2
    +
    215  nn += 1
    +
    216  endfor
    +
    217  endfor
    +
    218  endif
    +
    219 
    +
    220  if (avg)
    +
    221  w_dest /= nn
    +
    222  elseif (sdev)
    +
    223  w_dest = sqrt( (w_squares - w_dest^2 / nn) / (nn - 1) )
    +
    224  endif
    +
    225 
    +
    226  return w_dest
    +
    227 end
    +
    228 
    +
    232 threadsafe function /wave ad_extract_rod_z(dataset, p1, p2, q1, q2, destname, [noavg, sdev])
    +
    233  wave dataset
    +
    234  variable p1, p2, q1, q2
    +
    235  // 0 <= p1 < p2 < dimsize(0), 0 <= q1 < q2 < dimsize(1)
    +
    236  string destname
    +
    237  variable noavg
    +
    238  variable sdev
    +
    239 
    +
    240  if (ParamIsDefault(noavg))
    +
    241  noavg = 0
    +
    242  endif
    +
    243  if (ParamIsDefault(sdev))
    +
    244  sdev = 0
    +
    245  endif
    +
    246  variable avg = !noavg && !sdev
    +
    247 
    +
    248  p1 = max(p1, 0)
    +
    249  p2 = min(p2, dimsize(dataset, 0) - 1)
    +
    250  q1 = max(q1, 0)
    +
    251  q2 = min(q2, dimsize(dataset, 1) - 1)
    +
    252 
    +
    253  if (strlen(destname) > 0)
    +
    254  duplicate /r=[p1,p1][q1,q1][]/o dataset, $destname
    +
    255  wave w_dest = $destname
    +
    256  else
    +
    257  duplicate /r=[p1,p1][q1,q1][] /free dataset, w_dest
    +
    258  endif
    +
    259  redimension /n=(dimsize(w_dest, 2)) w_dest
    +
    260  setscale /p x dimoffset(dataset, 2), dimdelta(dataset, 2), waveunits(dataset, 2), w_dest
    +
    261 
    +
    262  w_dest = 0
    +
    263  variable pp, qq
    +
    264  variable nn = 0
    +
    265  for (pp = p1; pp <= p2; pp += 1)
    +
    266  for (qq = q1; qq <= q2; qq += 1)
    +
    267  w_dest += dataset[pp][qq][p]
    +
    268  nn += 1
    +
    269  endfor
    +
    270  endfor
    +
    271 
    +
    272  if (sdev)
    +
    273  duplicate /free w_dest, w_squares
    +
    274  w_squares = 0
    +
    275  for (pp = p1; pp <= p2; pp += 1)
    +
    276  for (qq = q1; qq <= q2; qq += 1)
    +
    277  w_squares += dataset[pp][qq][p]^2
    +
    278  nn += 1
    +
    279  endfor
    +
    280  endfor
    +
    281  endif
    +
    282 
    +
    283  if (avg)
    +
    284  w_dest /= nn
    +
    285  elseif (sdev)
    +
    286  w_dest = sqrt( (w_squares - w_dest^2 / nn) / (nn - 1) )
    +
    287  endif
    +
    288 
    +
    289  return w_dest
    +
    290 end
    +
    291 
    +
    314 threadsafe function /wave ad_extract_slab(dataset, x1, x2, y1, y2, z1, z2, destname, [noavg, pscale])
    +
    315  wave dataset
    +
    316  variable x1, x2, y1, y2, z1, z2
    +
    317  string destname
    +
    318  variable noavg
    +
    319  variable pscale
    +
    320 
    +
    321  if (wavedims(dataset) != 3)
    +
    322  return $""
    +
    323  endif
    +
    324  if (ParamIsDefault(noavg))
    +
    325  noavg = 0
    +
    326  endif
    +
    327  if (ParamIsDefault(pscale))
    +
    328  pscale = 0
    +
    329  endif
    +
    330 
    +
    331  variable p1, p2, q1, q2, r1, r2
    +
    332  if (pscale)
    +
    333  p1 = x1
    +
    334  p2 = x2
    +
    335  q1 = y1
    +
    336  q2 = y2
    +
    337  r1 = z1
    +
    338  r2 = z2
    +
    339  else
    +
    340  p1 = round((x1 - DimOffset(dataset, 0)) / DimDelta(dataset, 0))
    +
    341  p2 = round((x2 - DimOffset(dataset, 0)) / DimDelta(dataset, 0))
    +
    342  q1 = round((y1 - DimOffset(dataset, 1)) / DimDelta(dataset, 1))
    +
    343  q2 = round((y2 - DimOffset(dataset, 1)) / DimDelta(dataset, 1))
    +
    344  r1 = round((z1 - DimOffset(dataset, 2)) / DimDelta(dataset, 2))
    +
    345  r2 = round((z2 - DimOffset(dataset, 2)) / DimDelta(dataset, 2))
    +
    346  endif
    +
    347 
    +
    348  if ((numtype(p1) < 2) && (numtype(p2) < 2))
    +
    349  return ad_extract_slab_x(dataset, min(p1, p2), max(p1, p2), destname, noavg=noavg)
    +
    350  elseif ((numtype(q1) < 2) && (numtype(q2) < 2))
    +
    351  return ad_extract_slab_y(dataset, min(q1, q2), max(q1, q2), destname, noavg=noavg)
    +
    352  elseif ((numtype(r1) < 2) && (numtype(r2) < 2))
    +
    353  return ad_extract_slab_z(dataset, min(r1, r2), max(r1, r2), destname, noavg=noavg)
    +
    354  else
    +
    355  return $""
    +
    356  endif
    +
    357 end
    +
    358 
    +
    359 threadsafe function /wave ad_extract_slab_x(dataset, p1, p2, destname, [noavg])
    +
    360  wave dataset
    +
    361  variable p1, p2
    +
    362  // x coordinate range (point scaling) to be integrated
    +
    363  // -inf <= p1 < p2 <= +inf
    +
    364  string destname // name of destination wave. to be created in current data folder. overrides existing.
    +
    365  // if empty, the function returns a free wave
    +
    366  variable noavg // zero or default = average, non-zero = sum
    +
    367 
    +
    368  if (ParamIsDefault(noavg))
    +
    369  noavg = 0
    +
    370  endif
    +
    371  p1 = max(p1, 0)
    +
    372  p2 = min(p2, dimsize(dataset, 0) - 1)
    +
    373 
    +
    374  if (strlen(destname) > 0)
    +
    375  duplicate /r=[p1,p1][][]/o dataset, $destname
    +
    376  wave w_dest = $destname
    +
    377  else
    +
    378  duplicate /r=[p1,p1][][] /free dataset, w_dest
    +
    379  endif
    +
    380  redimension /n=(dimsize(w_dest, 1), dimsize(w_dest, 2)) w_dest
    +
    381  setscale /p x dimoffset(dataset, 1), dimdelta(dataset, 1), waveunits(dataset, 1), w_dest
    +
    382  setscale /p y dimoffset(dataset, 2), dimdelta(dataset, 2), waveunits(dataset, 2), w_dest
    +
    383 
    +
    384  w_dest = 0
    +
    385  variable pp
    +
    386  variable nn = 0
    +
    387  for (pp = p1; pp <= p2; pp += 1)
    +
    388  w_dest += dataset[pp][p][q]
    +
    389  nn += 1
    +
    390  endfor
    +
    391 
    +
    392  if (noavg == 0)
    +
    393  w_dest /= nn
    +
    394  endif
    +
    395 
    +
    396  return w_dest
    +
    397 end
    +
    398 
    +
    399 threadsafe function /wave ad_extract_slab_y(dataset, q1, q2, destname, [noavg])
    +
    400  wave dataset
    +
    401  variable q1, q2
    +
    402  // y coordinate range (point scaling) to be integrated
    +
    403  // -inf <= q1 < q2 <= +inf
    +
    404  string destname // name of destination wave. to be created in current data folder. overrides existing.
    +
    405  // if empty, the function returns a free wave
    +
    406  variable noavg // zero or default = average, non-zero = sum
    +
    407 
    +
    408  if (ParamIsDefault(noavg))
    +
    409  noavg = 0
    +
    410  endif
    +
    411  q1 = max(q1, 0)
    +
    412  q2 = min(q2, dimsize(dataset, 1) - 1)
    +
    413 
    +
    414  if (strlen(destname) > 0)
    +
    415  duplicate /r=[][q1,q1][]/o dataset, $destname
    +
    416  wave w_dest = $destname
    +
    417  else
    +
    418  duplicate /r=[][q1,q1][] /free dataset, w_dest
    +
    419  endif
    +
    420  redimension /n=(dimsize(w_dest, 0), dimsize(w_dest, 2)) w_dest
    +
    421  setscale /p x dimoffset(dataset, 0), dimdelta(dataset, 0), waveunits(dataset, 0), w_dest
    +
    422  setscale /p y dimoffset(dataset, 2), dimdelta(dataset, 2), waveunits(dataset, 2), w_dest
    +
    423 
    +
    424  w_dest = 0
    +
    425  variable qq
    +
    426  variable nn = 0
    +
    427  for (qq = q1; qq <= q2; qq += 1)
    +
    428  w_dest += dataset[p][qq][q]
    +
    429  nn += 1
    +
    430  endfor
    +
    431 
    +
    432  if (noavg == 0)
    +
    433  w_dest /= nn
    +
    434  endif
    +
    435 
    +
    436  return w_dest
    +
    437 end
    +
    438 
    +
    439 threadsafe function /wave ad_extract_slab_z(dataset, r1, r2, destname, [noavg])
    +
    440  wave dataset
    +
    441  variable r1, r2
    +
    442  // z coordinate range (point scaling) to be integrated
    +
    443  // -inf <= r1 < r2 <= +inf
    +
    444  string destname // name of destination wave. to be created in current data folder. overrides existing.
    +
    445  // if empty, the function returns a free wave
    +
    446  variable noavg // zero or default = average, non-zero = sum
    +
    447 
    +
    448  if (ParamIsDefault(noavg))
    +
    449  noavg = 0
    +
    450  endif
    +
    451  r1 = max(r1, 0)
    +
    452  r2 = min(r2, dimsize(dataset, 2) - 1)
    +
    453 
    +
    454  if (strlen(destname) > 0)
    +
    455  duplicate /r=[][][r1,r1]/o dataset, $destname
    +
    456  wave w_dest = $destname
    +
    457  else
    +
    458  duplicate /r=[][][r1,r1] /free dataset, w_dest
    +
    459  endif
    +
    460  redimension /n=(dimsize(w_dest, 0), dimsize(w_dest, 1)) w_dest
    +
    461  setscale /p x dimoffset(dataset, 0), dimdelta(dataset, 0), waveunits(dataset, 0), w_dest
    +
    462  setscale /p y dimoffset(dataset, 1), dimdelta(dataset, 1), waveunits(dataset, 1), w_dest
    +
    463 
    +
    464  w_dest = 0
    +
    465  variable rr
    +
    466  variable nn = 0
    +
    467  for (rr = r1; rr <= r2; rr += 1)
    +
    468  w_dest += dataset[p][q][rr]
    +
    469  nn += 1
    +
    470  endfor
    +
    471 
    +
    472  if (noavg == 0)
    +
    473  w_dest /= nn
    +
    474  endif
    +
    475 
    +
    476  return w_dest
    +
    477 end
    +
    478 
    +
    481 threadsafe function /wave ad_profile_x(dataset, q1, q2, destname, [noavg])
    +
    482  wave dataset
    +
    483  variable q1, q2 // -inf <= q1 < q2 <= +inf
    +
    484  // deprecated: q2 = -1 stands for dimsize(0) - 1
    +
    485  string destname // name of destination wave. to be created in current data folder. overrides existing.
    +
    486  // if empty, the function returns a free wave
    +
    487  variable noavg // zero or default = average, non-zero = sum
    +
    488 
    +
    489  if (ParamIsDefault(noavg))
    +
    490  noavg = 0
    +
    491  endif
    +
    492 
    +
    493  if (strlen(destname) > 0)
    +
    494  duplicate /r=[0,0][] /o dataset, $destname
    +
    495  wave w_dest = $destname
    +
    496  else
    +
    497  duplicate /r=[0,0][] /free dataset, w_dest
    +
    498  endif
    +
    499 
    +
    500  return ad_profile_x_w(dataset, q1, q2, w_dest, noavg=noavg)
    +
    501 end
    +
    502 
    +
    505 threadsafe function /wave ad_profile_x_w(dataset, q1, q2, destwave, [noavg])
    +
    506  wave dataset
    +
    507  variable q1, q2 // -inf <= q1 < q2 <= +inf
    +
    508  // deprecated: q2 = -1 stands for dimsize(0) - 1
    +
    509  wave destwave // existing destination wave
    +
    510  variable noavg // zero or default = average, non-zero = sum
    +
    511 
    +
    512  if (ParamIsDefault(noavg))
    +
    513  noavg = 0
    +
    514  endif
    +
    515 
    +
    516  redimension /n=(dimsize(dataset, 0)) destwave
    +
    517  setscale /p x dimoffset(dataset, 0), dimdelta(dataset, 0), waveunits(dataset, 0), destwave
    +
    518  setscale d 0, 0, waveunits(dataset, -1), destwave
    +
    519 
    +
    520  q1 = max(q1, 0)
    +
    521  if (q2 < 0)
    +
    522  q2 = inf
    +
    523  endif
    +
    524  q2 = min(q2, dimsize(dataset, 1) - 1)
    +
    525 
    +
    526  destwave = 0
    +
    527  variable qq
    +
    528  variable nn = 0
    +
    529  for (qq = q1; qq <= q2; qq += 1)
    +
    530  destwave += dataset[p][qq]
    +
    531  nn += 1
    +
    532  endfor
    +
    533 
    +
    534  if (noavg == 0)
    +
    535  destwave /= nn
    +
    536  endif
    +
    537 
    +
    538  return destwave
    +
    539 end
    +
    540 
    +
    543 threadsafe function /wave ad_profile_y(dataset, p1, p2, destname, [noavg])
    +
    544  wave dataset
    +
    545  variable p1, p2 // -inf <= p1 < p2 < inf
    +
    546  // deprecated: p2 = -1 stands for dimsize(0) - 1
    +
    547  string destname // name of destination wave. to be created in current data folder. overrides existing.
    +
    548  // if empty, the function returns a free wave
    +
    549  variable noavg // zero or default = average, non-zero = sum
    +
    550 
    +
    551  if (ParamIsDefault(noavg))
    +
    552  noavg = 0
    +
    553  endif
    +
    554 
    +
    555  if (strlen(destname) > 0)
    +
    556  duplicate /r=[][0,0] /o dataset, $destname
    +
    557  wave w_dest = $destname
    +
    558  else
    +
    559  duplicate /r=[][0,0] /free dataset, w_dest
    +
    560  endif
    +
    561  MatrixTranspose w_dest
    +
    562 
    +
    563  return ad_profile_y_w(dataset, p1, p2, w_dest, noavg=noavg)
    +
    564 end
    +
    565 
    +
    568 threadsafe function /wave ad_profile_y_w(dataset, p1, p2, destwave, [noavg])
    +
    569  wave dataset
    +
    570  variable p1, p2 // -inf <= p1 < p2 < inf
    +
    571  // deprecated: p2 = -1 stands for dimsize(0) - 1
    +
    572  wave destwave // existing destination wave
    +
    573  variable noavg // zero or default = average, non-zero = sum
    +
    574 
    +
    575  if (ParamIsDefault(noavg))
    +
    576  noavg = 0
    +
    577  endif
    +
    578 
    +
    579  redimension /n=(dimsize(dataset, 1)) destwave
    +
    580  setscale /p x dimoffset(dataset, 1), dimdelta(dataset, 1), waveunits(dataset, 1), destwave
    +
    581  setscale d 0, 0, waveunits(dataset, -1), destwave
    +
    582 
    +
    583  p1 = max(p1, 0)
    +
    584  if (p2 < 0)
    +
    585  p2 = inf
    +
    586  endif
    +
    587  p2 = min(p2, dimsize(dataset, 0) - 1)
    +
    588 
    +
    589  destwave = 0
    +
    590  variable pp
    +
    591  variable nn = 0
    +
    592  for (pp = p1; pp <= p2; pp += 1)
    +
    593  destwave += dataset[pp][p]
    +
    594  nn += 1
    +
    595  endfor
    +
    596 
    +
    597  if (noavg == 0)
    +
    598  destwave /= nn
    +
    599  endif
    +
    600 
    +
    601  return destwave
    +
    602 end
    +
    603 
    +
    604 threadsafe function calc_y_profile_mins(image)
    +
    605  // experimental
    +
    606  wave image
    +
    607 
    +
    608  wave yminlocs = ad_profile_x(image, 0, 0, "ymins", noavg=1)
    +
    609  variable nx = dimsize(image, 0)
    +
    610  variable ix
    +
    611  for (ix = 0; ix < nx; ix += 1)
    +
    612  wave profile = ad_profile_y(image, ix, ix, "", noavg=1)
    +
    613  wavestats /q/m=1 profile
    +
    614  yminlocs[ix] = v_minloc
    +
    615  endfor
    +
    616 end
    +
    617 
    +
    622 function ad_collect_multiscan_y(dataset, positions, destwave, [noavg])
    +
    623  wave dataset
    +
    624  wave positions
    +
    625  wave destwave
    +
    626  variable noavg
    +
    627 
    +
    628  variable tol = (wavemax(positions) - wavemin(positions)) / numpnts(positions) / 100
    +
    629 
    +
    630  duplicate /free positions, positions_sorted
    +
    631  sort positions_sorted, positions_sorted
    +
    632  duplicate /free positions_sorted, positions_diff
    +
    633  differentiate /p /meth=2 positions_sorted /d=positions_diff
    +
    634  positions_diff[0] = 1
    +
    635  extract /free positions_sorted, positions_unique, positions_diff > tol
    +
    636  variable n_unique = numpnts(positions_unique)
    +
    637  redimension /n=(dimsize(dataset, 0), n_unique) destwave
    +
    638 
    +
    639  variable i
    +
    640  variable nx, ny
    +
    641  for (i = 0; i < n_unique; i += 1)
    +
    642  extract /free dataset, data_extract, abs(positions[q] - positions_unique[i]) < tol
    +
    643  nx = dimsize(dataset, 0)
    +
    644  ny = dimsize(data_extract, 0) / nx
    +
    645  redimension /n=(nx, ny) data_extract
    +
    646  wave profile = ad_profile_x(data_extract, -inf, inf, "", noavg=noavg)
    +
    647  destwave[][i] = profile[p]
    +
    648  endfor
    +
    649 end
    +
    threadsafe variable calc_y_profile_mins(wave image)
    +
    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.
    +
    threadsafe wave ad_profile_x_w(wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    +
    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.
    +
    threadsafe wave ad_extract_rod_x(wave dataset, variable q1, variable q2, variable r1, variable r2, string destname, variable noavg=defaultValue, variable sdev=defaultValue)
    1D cut through 3D dataset along X dimension.
    +
    threadsafe wave ad_extract_rod_z(wave dataset, variable p1, variable p2, variable q1, variable q2, string destname, variable noavg=defaultValue, variable sdev=defaultValue)
    1D cut through 3D dataset along Z dimension.
    +
    variable ad_collect_multiscan_y(wave dataset, wave positions, wave destwave, variable noavg=defaultValue)
    collect profiles from a multi-scan.
    +
    threadsafe wave ad_extract_slab_z(wave dataset, variable r1, variable r2, string destname, variable noavg=defaultValue)
    +
    threadsafe wave ad_extract_rod(wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable sdev=defaultValue, variable pscale=defaultValue)
    1D cut through 3D dataset, integrate in normal dimensions
    +
    threadsafe wave ad_profile_y_w(wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    +
    threadsafe wave ad_extract_slab(wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable pscale=defaultValue)
    2D cut through 3D dataset, integrate in normal dimension
    +
    threadsafe wave ad_extract_slab_y(wave dataset, variable q1, variable q2, string destname, variable noavg=defaultValue)
    +
    threadsafe wave ad_extract_slab_x(wave dataset, variable p1, variable p2, string destname, variable noavg=defaultValue)
    +
    threadsafe wave ad_extract_rod_y(wave dataset, variable p1, variable p2, variable r1, variable r2, string destname, variable noavg=defaultValue, variable sdev=defaultValue)
    1D cut through 3D dataset along Y dimension.
    diff --git a/doc/html/pearl-arpes_8ipf.html b/doc/html/pearl-arpes_8ipf.html index 5d1ef8e..ac9935e 100644 --- a/doc/html/pearl-arpes_8ipf.html +++ b/doc/html/pearl-arpes_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-arpes.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -114,7 +116,7 @@ Namespaces

    Functions

    static variable AfterCompiledHook () - initializes package data once when the procedure is first loaded More...
    + initializes package data once when the procedure is first loaded More...
      variable UnloadPearlArpesPackage ()   @@ -128,9 +130,9 @@ Functions
    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -
    @@ -179,7 +181,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 84 of file pearl-arpes.ipf.

    +

    Definition at line 85 of file pearl-arpes.ipf.

    @@ -189,9 +191,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
    diff --git a/doc/html/pearl-arpes_8ipf_source.html b/doc/html/pearl-arpes_8ipf_source.html index 3d7e759..de166a8 100644 --- a/doc/html/pearl-arpes_8ipf_source.html +++ b/doc/html/pearl-arpes_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-arpes.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,17 +87,55 @@ $(document).ready(function(){initNavTree('pearl-arpes_8ipf_source.html','');});
    pearl-arpes.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.1
    3 #pragma ModuleName = PearlArpes
    4 #pragma version = 1.05
    5 #include "pearl-area-display" // 2D and 3D data visualization
    6 #include "pearl-area-profiles" // data processing for multi-dimensional datasets
    7 #include "pearl-area-import" // import data files generated by area detector software
    8 #include "pearl-pshell-import"
    9 #include "pearl-compat" // compatibility with igor 6
    10 #include "pearl-data-explorer" // preview and import panel for PEARL data
    11 #include "pearl-anglescan-process" // angle scan (XPD) processing functions
    12 #include "pearl-anglescan-panel" // panel interface to angle scan processing
    13 #include "pearl-anglescan-tracker" // live preview of hemispherical angle scan
    14 #include "pearl-scienta-preprocess" // pre-processing functions for Scienta detector images
    15 #include "pearl-elog"
    16 #if exists("pvOpen")
    17 #include "pearl-area-live" // live view of area detector
    18 #include "pearl-epics" // EPICS access under Igor
    19 #include "pearl-arpes-scans" // run ARPES scans under Igor
    20 #include "pearl-sample-tracker" // live tracking and adjustment of sample position
    21 #include "pearl-scienta-countrate"
    22 #endif
    23 
    42 
    48 
    75 
    77 static function AfterCompiledHook()
    78 
    79  dfref savefolder = GetDataFolderDFR()
    80 
    81  return 0
    82 end
    83 
    85  execute /p/q/z "DELETEINCLUDE \"pearl-arpes\""
    86  execute /p/q/z "COMPILEPROCEDURES "
    87 end
    variable UnloadPearlArpesPackage()
    Definition: pearl-arpes.ipf:84
    -
    static variable AfterCompiledHook()
    initializes package data once when the procedure is first loaded
    Definition: pearl-arpes.ipf:77
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.1
    +
    4 #pragma ModuleName = PearlArpes
    +
    5 #pragma version = 1.05
    +
    6 #include "pearl-area-display" // 2D and 3D data visualization
    +
    7 #include "pearl-area-profiles" // data processing for multi-dimensional datasets
    +
    8 #include "pearl-area-import" // import data files generated by area detector software
    +
    9 #include "pearl-pshell-import"
    +
    10 #include "pearl-compat" // compatibility with igor 6
    +
    11 #include "pearl-data-explorer" // preview and import panel for PEARL data
    +
    12 #include "pearl-anglescan-process" // angle scan (XPD) processing functions
    +
    13 #include "pearl-anglescan-panel" // panel interface to angle scan processing
    +
    14 #include "pearl-anglescan-tracker" // live preview of hemispherical angle scan
    +
    15 #include "pearl-scienta-preprocess" // pre-processing functions for Scienta detector images
    +
    16 #include "pearl-elog"
    +
    17 #if exists("pvOpen")
    +
    18 #include "pearl-area-live" // live view of area detector
    +
    19 #include "pearl-epics" // EPICS access under Igor
    +
    20 #include "pearl-arpes-scans" // run ARPES scans under Igor
    +
    21 #include "pearl-sample-tracker" // live tracking and adjustment of sample position
    +
    22 #include "pearl-scienta-live"
    +
    23 #endif
    +
    24 
    +
    43 
    +
    49 
    +
    76 
    +
    78 static function AfterCompiledHook()
    +
    79 
    +
    80  dfref savefolder = GetDataFolderDFR()
    +
    81 
    +
    82  return 0
    +
    83 end
    +
    84 
    + +
    86  execute /p/q/z "DELETEINCLUDE \"pearl-arpes\""
    +
    87  execute /p/q/z "COMPILEPROCEDURES "
    +
    88 end
    +
    static variable AfterCompiledHook()
    initializes package data once when the procedure is first loaded
    Definition: pearl-arpes.ipf:78
    +
    variable UnloadPearlArpesPackage()
    Definition: pearl-arpes.ipf:85
    diff --git a/doc/html/pearl-compat_8ipf.html b/doc/html/pearl-compat_8ipf.html index 16034fa..0688377 100644 --- a/doc/html/pearl-compat_8ipf.html +++ b/doc/html/pearl-compat_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-compat.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -131,7 +133,7 @@ Functions
    -

    Definition at line 47 of file pearl-compat.ipf.

    +

    Definition at line 48 of file pearl-compat.ipf.

    @@ -141,9 +143,9 @@ Functions diff --git a/doc/html/pearl-compat_8ipf_source.html b/doc/html/pearl-compat_8ipf_source.html index 2508edc..37e5096 100644 --- a/doc/html/pearl-compat_8ipf_source.html +++ b/doc/html/pearl-compat_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-compat.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,16 +87,58 @@ $(document).ready(function(){initNavTree('pearl-compat_8ipf_source.html','');});
    pearl-compat.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.1
    3 #pragma ModuleName = PearlCompat
    4 #pragma version = 1.01
    5 
    6 // copyright (c) 2019 Paul Scherrer Institut
    7 //
    8 // Licensed under the Apache License, Version 2.0 (the "License");
    9 // you may not use this file except in compliance with the License.
    10 // You may obtain a copy of the License at
    11 // http:///www.apache.org/licenses/LICENSE-2.0
    12 
    25 
    30 
    31 
    32 // Compatible CleanupName function
    33 //
    34 // Igor 8's CleanupName may return long object names (> 31 characters).
    35 // This breaks compatibility with earlier Igor versions.
    36 // Experiments that include waves, folders, windows etc. with long names
    37 // cannot be loaded with an earlier version.
    38 //
    39 // This is a drop-in replacement function for CleanupName.
    40 // In addition to the behaviour of CleanupName,
    41 // this replacement ensures that names are limited to 31 characters.
    42 //
    43 // @param name object name to clean up
    44 //
    45 // @return (str) clean object name
    46 //
    47 function /s PearlCleanupName(name)
    48  string name
    49 
    50 #if IgorVersion() >= 8.00
    51  // note: this function is not threadsafe
    52  return CleanupName(name, 0, 31)
    53 #else
    54  return CleanupName(name, 0)
    55 #endif
    56 
    57 end
    string PearlCleanupName(string name)
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.1
    +
    4 #pragma ModuleName = PearlCompat
    +
    5 #pragma version = 1.01
    +
    6 
    +
    7 // copyright (c) 2019 Paul Scherrer Institut
    +
    8 //
    +
    9 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    10 // you may not use this file except in compliance with the License.
    +
    11 // You may obtain a copy of the License at
    +
    12 // http:///www.apache.org/licenses/LICENSE-2.0
    +
    13 
    +
    26 
    +
    31 
    +
    32 
    +
    33 // Compatible CleanupName function
    +
    34 //
    +
    35 // Igor 8's CleanupName may return long object names (> 31 characters).
    +
    36 // This breaks compatibility with earlier Igor versions.
    +
    37 // Experiments that include waves, folders, windows etc. with long names
    +
    38 // cannot be loaded with an earlier version.
    +
    39 //
    +
    40 // This is a drop-in replacement function for CleanupName.
    +
    41 // In addition to the behaviour of CleanupName,
    +
    42 // this replacement ensures that names are limited to 31 characters.
    +
    43 //
    +
    44 // @param name object name to clean up
    +
    45 //
    +
    46 // @return (str) clean object name
    +
    47 //
    +
    48 function /s PearlCleanupName(name)
    +
    49  string name
    +
    50 
    +
    51 #if IgorVersion() >= 8.00
    +
    52  // note: this function is not threadsafe
    +
    53  return CleanupName(name, 0, 31)
    +
    54 #else
    +
    55  return CleanupName(name, 0)
    +
    56 #endif
    +
    57 
    +
    58 end
    +
    string PearlCleanupName(string name)
    diff --git a/doc/html/pearl-data-explorer_8ipf.html b/doc/html/pearl-data-explorer_8ipf.html index c91517f..3bab478 100644 --- a/doc/html/pearl-data-explorer_8ipf.html +++ b/doc/html/pearl-data-explorer_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-data-explorer.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -82,17 +84,14 @@ $(document).ready(function(){initNavTree('pearl-data-explorer_8ipf.html','');});
    -
    pearl-data-explorer.ipf File Reference
    +
    pearl-data-explorer.ipf File Reference
    - -

    preview and import panel for PEARL data -More...

    -
    #include "pearl-area-import"
    +
    #include <HierarchicalListWidget>
    +#include "pearl-area-import"
    #include "pearl-area-profiles"
    #include "pearl-area-display"
    #include "pearl-compat"
    @@ -100,129 +99,169 @@ $(document).ready(function(){initNavTree('pearl-data-explorer_8ipf.html','');});

    Go to the source code of this file.

    - - - - -

    -Namespaces

     PearlDataExplorer
     preview and import panel for PEARL data
     
    + - - + - + + + + - + - - + + + + + + + + + + + + + + + + + + - + - + - + - - - + - - + - - - - - - - - - - + + + + - - + + + - + - - - - - - - - - + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Functions

    variable pearl_data_explorer ()
     show the pearl data explorer window More...
     
    static variable init_package ()
     initialize the global variables of the data explorer. More...
     
    static variable save_prefs ()
     save persistent package data to the preferences file. More...
     save persistent package data to the preferences file. More...
     
    static variable load_prefs ()
     
    static variable pearl_file_type (string filename)
     check whether a file can be imported by this module. More...
     check whether a file can be imported by this module. More...
     
    static variable update_filepath ()
     update the file path after path change More...
     
    static variable update_filelist ()
     read a list of PEARL files from the file system More...
     read a list of PEARL files from the file system More...
     
    static variable update_datasets ()
     
    static variable get_file_info (string filename)
     load the internal structure of a file More...
     
    static variable attributes_notebook (string filename)
     load attributes More...
     
    static variable extract_attributes (dfref attr_df, dfref dest_df=defaultValue, wave attr_filter=defaultValue, variable include_datawaves=defaultValue, variable include_infowaves=defaultValue)
     extract summary from attribute waves More...
     
    variable test_attributes_notebook ()
     
    static variable create_attributes_notebook (wave attr_names, wave attr_values, string title)
     
    static variable notebook_add_attributes (string notebook_name, wave attr_filter, wave attr_names, wave attr_values)
     
    static variable set_elog_attributes (dfref file_df, string filename=defaultValue, string graphname=defaultValue)
     send general metadata to ELOG panel - if available More...
     
    static variable preview_file (string filename)
     
    static wave preview_pshell_file (string filename)
     load the preview of a PShell HDF5 file. More...
     load the preview of a PShell HDF5 file. More...
     
    static wave preview_hdf_file (string filename)
     load the preview of a PEARL HDF5 file. More...
     load the preview of a PEARL HDF5 file. More...
     
    static wave preview_itx_file (string filename)
     load the preview of a general ITX file. More...
     load the preview of a general ITX file. More...
     
    static wave preview_mtrx_file (string filename)
     load the preview of a Matrix STM file. More...
     
    static variable extract_preview_image (wave data, wave preview)
     extract a preview image from a wave of arbitrary dimension More...
     
    static variable preview_dataset (string datasetname)
     
    static variable preview_datafolder ()
     preview data in the current data folder More...
     
    static variable preview_setscale_x (wave data, wave preview)
     
    static variable preview_attributes (dfref attr_folder, dfref dest_folder=defaultValue, wave attr_filter=defaultValue, variable include_datawaves=defaultValue, variable include_infowaves=defaultValue)
     
    static variable display_dataset (string datasetname)
     
    variable test_attributes_notebook ()
     
    static variable attributes_notebook (wave attr_names, wave attr_values, string title)
     
    static variable notebook_add_attributes (string notebook_name, wave attr_filter, wave attr_names, wave attr_values)
     
    static variable display_dataset (dfref file_df, string dataset)
     displays the graph of a loaded dataset in its own window More...
     
    static string show_preview_graph (wave data, wave xdata=defaultValue)
     
    static string display_preview_trace (wave xtrace, wave ytrace)
     
    static variable load_selected_files (string options=defaultValue)
     load the selected files More...
     
    static variable load_file (string filename, string options=defaultValue)
     
    static variable load_file (string filename, string options=defaultValue, dfref dest_df=defaultValue, variable quiet=defaultValue)
     load one file More...
     
    static variable prompt_hdf_options (string *options)
     
    variable prompt_default_process (string *param)
     prototype for prompting for processing function parameters. More...
     prototype for prompting for processing function parameters. More...
     
    variable prompt_func_params (string func_name, string *func_param)
     
    static dfr load_pshell_file (string filename, string options=defaultValue)
     
    static dfr load_hdf_file (string filename, string options=defaultValue)
     
    static dfr load_itx_file (string filename, string options=defaultValue)
     
    static dfr load_mtrx_file (string filename, string options=defaultValue)
     load a matrix (STM) data file More...
     
    static dfr load_pshell_file (string filename, string options=defaultValue, dfref dest_df=defaultValue, variable quiet=defaultValue)
     load a pshell file More...
     
    static dfr load_hdf_file (string filename, string options=defaultValue, dfref dest_df=defaultValue, variable quiet=defaultValue)
     
    static dfr load_itx_file (string filename, string options=defaultValue, dfref dest_df=defaultValue, variable quiet=defaultValue)
     
    string itx_suggest_foldername (string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
     suggest the name of a data folder based on an igor-text file name More...
     
    void PearlDataExplorer ()
     
    static variable update_controls ()
     update controls state More...
     
    static variable bp_load_prefs (WMButtonAction *ba)
     
    static variable bp_save_prefs (WMButtonAction *ba)
     
    static string shorten_filepath (string long_path, variable max_len)
     shorten a file path for display More...
     
    static variable bp_browse_filepath (WMButtonAction *ba)
     
    static variable bp_update_filelist (WMButtonAction *ba)
     
    static variable bp_load_files (WMButtonAction *ba)
     
    static variable bp_load_files_opt (WMButtonAction *ba)
     
    static string pm_reduction_values ()
     items for data reduction popup More...
     
    static variable pmp_reduction_func (WMPopupAction *pa)
     
    static variable bp_reduction_params (WMButtonAction *ba)
     
    static variable bp_load_options (WMButtonAction *ba)
     
    static variable selected_file (string file, variable do_preview)
     actions after a file has been selected More...
     
    static variable bp_file_next (WMButtonAction *ba)
     
    static variable bp_file_prev (WMButtonAction *ba)
     
    static variable lbp_filelist (WMListboxAction *lba)
     
    static variable bp_update_datasets (WMButtonAction *ba)
     
    static variable bp_dataset_folder (WMButtonAction *ba)
     
    static variable bp_dataset_display (WMButtonAction *ba)
     
    static variable bp_dataset_next (WMButtonAction *ba)
     
    static variable bp_dataset_prev (WMButtonAction *ba)
     
    static variable lbp_datasets (WMListboxAction *lba)
     
    static variable bp_attr_notebook (WMButtonAction *ba)
     
    static variable hlp_setup ()
     
    static variable hl_contents_clear ()
     
    static variable hl_contents_update (dfref file_df)
     populate the contents list box with the internal directory of a HDF5 file More...
     
    static dfr get_pshell_info (string path_name, string file_name, dfref dest_df=defaultValue)
     
    static variable hl_add_objects (string parent_path, string objects)
     populate the contents list box with the given hierarchical paths More...
     
    static variable hl_expand_scans ()
     
    static variable hl_default_selection ()
     
    static variable hlp_contents_open (string HostWindow, string ListControlName, string ContainerPath)
     
    static variable hlp_contents_selection (string HostWindow, string ListControlName, string SelectedItem, variable EventCode)
     
    static variable goto_dataset_folder (string filename, string datapath)
     open data folder corresponding to a file and data path More...
     
    static variable bp_goto_dataset (WMButtonAction *ba)
     "goto DF" button More...
     
    static variable bp_display_dataset (WMButtonAction *ba)
     "display dataset" button More...
     
    static variable send_to_elog ()
     send file metadata to the ELOG panel More...
     
    static variable bp_elog (WMButtonAction *ba)
     
    - - + + @@ -231,22 +270,10 @@ Variables - -

    Variables

    static const string package_name = "pearl_explorer"
     
     version
     
    static const string package_path = "root:packages:pearl_explorer:"
     
    static const string ks_filematch_adh5 = "*.h5"
     
    static const string ks_filematch_itx = "*.itx"
     
    static const string ks_filematch_mtrx = "*_mtrx"
     
    -

    Detailed Description

    -

    preview and import panel for PEARL data

    -

    preview and import panel for PEARL data:

      -
    • area detector (HDF5) files from scienta analyser and prosilica cameras (if HDF5.xop is installed).
    • -
    • igor text files from s-scans and otf-scans.
    • -
    • pshell (HDF5) data files (if HDF5.xop is installed).
    • -
    • matrix STM files (if MatrixFileReader.xop is installed).
    • -
    - -

    Definition in file pearl-data-explorer.ipf.

    -

    Function Documentation

    - -

    ◆ attributes_notebook()

    +

    Function Documentation

    + +

    ◆ attributes_notebook()

    @@ -257,6 +284,377 @@ Variables static variable attributes_notebook ( + string  + filename) + + + + + +static + + +
    + +

    load attributes

    + +

    Definition at line 301 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_attr_notebook()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_attr_notebook (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1914 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_browse_filepath()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_browse_filepath (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1673 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_display_dataset()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_display_dataset (WMButtonAction * ba)
    +
    +static
    +
    + +

    "display dataset" button

    + +

    Definition at line 2263 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_elog()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_elog (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 2351 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_file_next()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_file_next (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1809 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_file_prev()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_file_prev (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1840 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_goto_dataset()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_goto_dataset (WMButtonAction * ba)
    +
    +static
    +
    + +

    "goto DF" button

    +

    the button selects the data folder of the selected file and dataset. an error message is shown if the data folder doesn't exist.

    + +

    Definition at line 2231 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_load_options()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_load_options (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1757 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_load_prefs()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_load_prefs (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1618 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_reduction_params()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_reduction_params (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1735 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_save_prefs()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_save_prefs (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1633 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ bp_update_filelist()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable bp_update_filelist (WMButtonAction * ba)
    +
    +static
    +
    + +

    Definition at line 1696 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ create_attributes_notebook()

    + +
    +
    + + + - - + + + + + + + + + + + +
    + + + + @@ -285,404 +683,12 @@ Variables
    static variable create_attributes_notebook ( wave  attr_names,
    -

    Definition at line 822 of file pearl-data-explorer.ipf.

    +

    Definition at line 480 of file pearl-data-explorer.ipf.

    - -

    ◆ bp_attr_notebook()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_attr_notebook (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1750 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_browse_filepath()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_browse_filepath (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1436 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_dataset_display()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_dataset_display (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1641 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_dataset_folder()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_dataset_folder (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1615 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_dataset_next()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_dataset_next (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1661 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_dataset_prev()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_dataset_prev (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1688 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_file_next()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_file_next (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1502 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_file_prev()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_file_prev (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1534 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_load_files()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_load_files (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1474 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_load_files_opt()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_load_files_opt (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1488 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_load_prefs()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_load_prefs (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1408 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_save_prefs()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_save_prefs (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1422 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_update_datasets()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_update_datasets (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1601 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ bp_update_filelist()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable bp_update_filelist (WMButtonAction * ba)
    -
    -static
    -
    - -

    Definition at line 1460 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ display_dataset()

    + +

    ◆ display_dataset()

    @@ -693,9 +699,19 @@ Variables
    static variable display_dataset (string datasetname)dfref file_df,
    string dataset 
    )
    @@ -705,7 +721,9 @@ Variables
    -

    Definition at line 782 of file pearl-data-explorer.ipf.

    +

    displays the graph of a loaded dataset in its own window

    + +

    Definition at line 897 of file pearl-data-explorer.ipf.

    @@ -743,7 +761,84 @@ Variables
    -

    Definition at line 939 of file pearl-data-explorer.ipf.

    +

    Definition at line 978 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ extract_attributes()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    static variable extract_attributes (dfref attr_df,
    dfref dest_df = defaultValue,
    wave attr_filter = defaultValue,
    variable include_datawaves = defaultValue,
    variable include_infowaves = defaultValue 
    )
    +
    +static
    +
    + +

    extract summary from attribute waves

    +

    by default, all existing attributes are copied. if a text wave attr_filter exists in the pear_explorer folder, only the attributes referenced therein are copied. to set up a filter, duplicate the attr_names wave of a template dataset, and remove unwanted items.

    +
    Parameters
    + + + + + + +
    attr_dfdata folder which contains the original data, e.g. the attr, diags or snaps folder in pshell files.
    dest_dfdestination folder. the output is written to the attr_names and attr_values waves. default = package folder.
    attr_filter(text wave) list of attributes allowed in the output. default = use attr_filter of package folder.
    include_datawaves
      +
    • 1 (default) include data waves (any numeric wave which has a PV=name note).
    • +
    • 0 don't include attributes from data waves.
    • +
    +
    include_infowaves
      +
    • 1 (default) include attributes from info waves (IN, ID, IV, IU).
    • +
    • 0 don't include attributes from info waves.
    • +
    +
    +
    +
    + +

    Definition at line 347 of file pearl-data-explorer.ipf.

    @@ -781,7 +876,412 @@ Variables
    -

    Definition at line 495 of file pearl-data-explorer.ipf.

    +

    extract a preview image from a wave of arbitrary dimension

    + +

    Definition at line 784 of file pearl-data-explorer.ipf.

    + +
    + + +

    ◆ get_file_info()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable get_file_info (string filename)
    +
    +static
    +
    + +

    load the internal structure of a file

    +

    this loads metadata for updating the panels.

    +

    for a pshell file, metadata includes:

      +
    • list of all datasets with types and dimensions
    • +
    • general group
    • +
    +
    Returns
    0 if successful -1 if no data was loaded because the file was not recognized, -2 if no data is found in file
    + +

    Definition at line 273 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ get_pshell_info()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    static dfr get_pshell_info (string path_name,
    string file_name,
    dfref dest_df = defaultValue 
    )
    +
    +static
    +
    + +

    Definition at line 2001 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ goto_dataset_folder()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + +
    static variable goto_dataset_folder (string filename,
    string datapath 
    )
    +
    +static
    +
    + +

    open data folder corresponding to a file and data path

    +

    the function tries to find where a given dataset has been loaded and selects the corresponding data folder. the data folder must exist (after previous import from the file), else an error code is returned and the folder selection will be the closest accessible parent folder of the target.

    +
    Parameters
    + + + +
    filenamefile name (without path). h5 and otf.itx files are supported.
    datapathdataset or group path inside the hdf5 file.
    +
    +
    +
    Returns
    0 if successful, -1 if the file type is unknown -2 if the data path can't be found in the tree.
    + +

    Definition at line 2175 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ hl_add_objects()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + +
    static variable hl_add_objects (string parent_path,
    string objects 
    )
    +
    +static
    +
    + +

    populate the contents list box with the given hierarchical paths

    +
    Returns
    the number of top-level objects
    + +

    Definition at line 2029 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ hl_contents_clear()

    + +
    +
    + + + + + +
    + + + + + + + +
    static variable hl_contents_clear ()
    +
    +static
    +
    + +

    Definition at line 1952 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ hl_contents_update()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable hl_contents_update (dfref file_df)
    +
    +static
    +
    + +

    populate the contents list box with the internal directory of a HDF5 file

    +
    Returns
    the number of top-level objects
    + +

    Definition at line 1966 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ hl_default_selection()

    + +
    +
    + + + + + +
    + + + + + + + +
    static variable hl_default_selection ()
    +
    +static
    +
    + +

    Definition at line 2118 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ hl_expand_scans()

    + +
    +
    + + + + + +
    + + + + + + + +
    static variable hl_expand_scans ()
    +
    +static
    +
    + +

    Definition at line 2089 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ hlp_contents_open()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    static variable hlp_contents_open (string HostWindow,
    string ListControlName,
    string ContainerPath 
    )
    +
    +static
    +
    + +

    Definition at line 2129 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ hlp_contents_selection()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    static variable hlp_contents_selection (string HostWindow,
    string ListControlName,
    string SelectedItem,
    variable EventCode 
    )
    +
    +static
    +
    + +

    Definition at line 2139 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ hlp_setup()

    + +
    +
    + + + + + +
    + + + + + + + +
    static variable hlp_setup ()
    +
    +static
    +
    + +

    Definition at line 1942 of file pearl-data-explorer.ipf.

    @@ -808,10 +1308,7 @@ Variables
    -

    initialize the global variables of the data explorer.

    -

    initializes the global variables and data folder for this procedure file must be called once before the panel is created warning: this function overwrites previous values

    - -

    Definition at line 56 of file pearl-data-explorer.ipf.

    +

    Definition at line 61 of file pearl-data-explorer.ipf.

    @@ -853,35 +1350,20 @@ Variables
    -

    Definition at line 1258 of file pearl-data-explorer.ipf.

    +

    suggest the name of a data folder based on an igor-text file name

    +

    if the file name follows the naming convention source-date-index.extension, the function tries to generate the nick name as source_date_index. otherwise it's just a cleaned up version of the file name.

    +

    igor text is used by the on-the-fly scan tool.

    +
    Parameters
    + + + + + +
    filenamefile name, including extension. can also include a folder path (which is ignored). the extension is currently ignored, but may be used in a later version.
    ignoredateif non-zero, the nick name will not include the date part. defaults to zero
    sourcenamenick name of the data source. the function tries to detect the source from the file name. this option can be used to override auto-detection. allowed values: sscan, otf
    uniqueif non-zero, the resulting name is made a unique data folder name in the current data folder. defaults to zero
    +
    +
    -
    - - -

    ◆ lbp_datasets()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable lbp_datasets (WMListboxAction * lba)
    -
    -static
    -
    - -

    Definition at line 1715 of file pearl-data-explorer.ipf.

    +

    Definition at line 1427 of file pearl-data-explorer.ipf.

    @@ -909,12 +1391,12 @@ Variables
    -

    Definition at line 1566 of file pearl-data-explorer.ipf.

    +

    Definition at line 1871 of file pearl-data-explorer.ipf.

    - -

    ◆ load_file()

    + +

    ◆ load_file()

    @@ -932,7 +1414,19 @@ Variables string  - options = defaultValue  + options = defaultValue, + + + + + dfref  + dest_df = defaultValue, + + + + + variable  + quiet = defaultValue  @@ -947,12 +1441,28 @@ Variables
    -

    Definition at line 996 of file pearl-data-explorer.ipf.

    +

    load one file

    +

    this can be a PShell, HDF5, or ITX file.

    +
    Note
    this function may change the current data folder!
    +
    Parameters
    + + + + +
    optionskey:value; list of load options. the recognized keys are: mode, reduction_func and reduction_params. see main text for a description of possible values. by default (options not specified), options are read from `s_hdf_options. if the option string is empty, the user is prompted for options.
    dest_dfdestination data folder. default: a new folder derived from file name under root.
    quiet
      +
    • 0 (default) print mode and parameters to history.
    • +
    • 1 do not print to history.
    • +
    +
    +
    +
    + +

    Definition at line 1064 of file pearl-data-explorer.ipf.

    - -

    ◆ load_hdf_file()

    + +

    ◆ load_hdf_file()

    @@ -970,7 +1480,19 @@ Variables string  - options = defaultValue  + options = defaultValue, + + + + + dfref  + dest_df = defaultValue, + + + + + variable  + quiet = defaultValue  @@ -985,12 +1507,12 @@ Variables
    -

    Definition at line 1142 of file pearl-data-explorer.ipf.

    +

    Definition at line 1298 of file pearl-data-explorer.ipf.

    - -

    ◆ load_itx_file()

    + +

    ◆ load_itx_file()

    @@ -1008,45 +1530,19 @@ Variables string  - options = defaultValue  - - - - ) - - - - - -static - - -
    - -

    Definition at line 1192 of file pearl-data-explorer.ipf.

    - -
    -
    - -

    ◆ load_mtrx_file()

    - -
    -
    - - -
    - - - - - - + - - + + + + + + + + @@ -1061,9 +1557,7 @@ Variables
    static dfr load_mtrx_file (string filename, options = defaultValue,
    string options = defaultValue dfref dest_df = defaultValue,
    variable quiet = defaultValue 
    -

    load a matrix (STM) data file

    - -

    Definition at line 1235 of file pearl-data-explorer.ipf.

    +

    Definition at line 1358 of file pearl-data-explorer.ipf.

    @@ -1090,12 +1584,12 @@ Variables
    -

    Definition at line 118 of file pearl-data-explorer.ipf.

    +

    Definition at line 155 of file pearl-data-explorer.ipf.

    - -

    ◆ load_pshell_file()

    + +

    ◆ load_pshell_file()

    @@ -1113,7 +1607,19 @@ Variables string  - options = defaultValue  + options = defaultValue, + + + + + dfref  + dest_df = defaultValue, + + + + + variable  + quiet = defaultValue  @@ -1128,7 +1634,37 @@ Variables
    -

    Definition at line 1090 of file pearl-data-explorer.ipf.

    +

    load a pshell file

    +

    if options is not specified, the complete file is loaded. if options is an empty string, the package default options are used.

    +

    data selection is extracted from the datasets list box.

    +

    the file can be loaded in one of the following modes (mode key of the options argument):

    +
      +
    • load_complete load all datasets regardless of selection.
    • +
    • load_scan load default datasets of selected scans.
    • +
    • load_region load default datasets of selected regions.
    • +
    • load_dataset load selected datasets.
    • +
    • load_diags load diagnostic datasets of selected scans.
    • +
    +

    3-dimensional datasets can be loaded with dimension reduction. in this case, the name of the reduction function must be given under the reduction_func key. the reduction parameters are prompted for if a prompt function for the reduction function is found. the default reduction parameters are the most recent parameters s_reduction_params stored in the package data folder.

    +
      +
    • reduction_func:... name of the reduction function.
    • +
    +

    if a reduction function is specified, default reduction parameters are read from s_reduction_params in the package data folder, and the user is prompted to review/update the parameters.

    +
    Parameters
    + + + + +
    optionskey:value; list of load options. the recognized keys are: mode, reduction_func and reduction_params. see main text for a description of possible values. by default (options not specified), options are read from `s_hdf_options. if the option string is empty, the user is prompted for options.
    dest_dfdestination data folder. default: a new folder derived from file name under root.
    quiet
      +
    • 0 (default) print mode and parameters to history.
    • +
    • 1 do not print to history.
    • +
    +
    +
    +
    +
    Returns
    data folder reference of the loaded data. this is the folder which contains the scan sub-folders.
    + +

    Definition at line 1188 of file pearl-data-explorer.ipf.

    @@ -1156,7 +1692,11 @@ Variables
    -

    Definition at line 972 of file pearl-data-explorer.ipf.

    +

    load the selected files

    +

    load the files that are selected in the data explorer panel. the files are loaded using the load_file() function.

    +
    Note
    this function may change the current data folder!
    + +

    Definition at line 1025 of file pearl-data-explorer.ipf.

    @@ -1206,7 +1746,7 @@ Variables
    -

    Definition at line 861 of file pearl-data-explorer.ipf.

    +

    Definition at line 519 of file pearl-data-explorer.ipf.

    @@ -1225,7 +1765,10 @@ Variables
    -

    Definition at line 45 of file pearl-data-explorer.ipf.

    +

    show the pearl data explorer window

    +

    create a pearl data explorer window or bring the existing one to the front. if a new window is created, also initialize all package variables and load package preferences.

    + +

    Definition at line 47 of file pearl-data-explorer.ipf.

    @@ -1260,11 +1803,10 @@ Variables
  • 1 PShell file (HDF5, name starts with psh_)
  • 2 area detector HDF5 file
  • 3 Igor text (itx) file
  • -
  • 4 Matrix STM file (*_mtrx)
  • -

    Definition at line 163 of file pearl-data-explorer.ipf.

    +

    Definition at line 199 of file pearl-data-explorer.ipf.

    @@ -1283,12 +1825,12 @@ Variables
    -

    Definition at line 1317 of file pearl-data-explorer.ipf.

    +

    Definition at line 1478 of file pearl-data-explorer.ipf.

    - -

    ◆ preview_attributes()

    + +

    ◆ pm_reduction_values()

    @@ -1297,39 +1839,10 @@ Variables - + - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - -
    static variable preview_attributes static string pm_reduction_values (dfref attr_folder,
    ) dfref dest_folder = defaultValue,
    wave attr_filter = defaultValue,
    variable include_datawaves = defaultValue,
    variable include_infowaves = defaultValue 
    )
    @@ -1339,7 +1852,37 @@ Variables
    -

    Definition at line 648 of file pearl-data-explorer.ipf.

    +

    items for data reduction popup

    + +

    Definition at line 1712 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ pmp_reduction_func()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static variable pmp_reduction_func (WMPopupAction * pa)
    +
    +static
    +
    + +

    Definition at line 1719 of file pearl-data-explorer.ipf.

    @@ -1366,35 +1909,10 @@ Variables
    -

    Definition at line 577 of file pearl-data-explorer.ipf.

    +

    preview data in the current data folder

    +

    used by preview_itx_file

    -
    - - -

    ◆ preview_dataset()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static variable preview_dataset (string datasetname)
    -
    -static
    -
    - -

    Definition at line 534 of file pearl-data-explorer.ipf.

    +

    Definition at line 826 of file pearl-data-explorer.ipf.

    @@ -1422,7 +1940,7 @@ Variables
    -

    Definition at line 257 of file pearl-data-explorer.ipf.

    +

    Definition at line 629 of file pearl-data-explorer.ipf.

    @@ -1451,7 +1969,7 @@ Variables

    load the preview of a PEARL HDF5 file.

    -

    the preview is an arbitrary detector image extracted from the file, see adh5_load_preview(). the preview is loaded to the preview_image wave in the pear_explorer data folder.

    +

    the preview is an arbitrary detector image extracted from the file, see adh5_load_preview(). the preview is loaded to the preview_image wave in the pear_explorer data folder.

    the s_file_info string is updated with information about the scan dimensions.

    Parameters
    @@ -1461,7 +1979,7 @@ Variables
    Returns
    wave reference of the preview image
    -

    Definition at line 365 of file pearl-data-explorer.ipf.

    +

    Definition at line 717 of file pearl-data-explorer.ipf.

    @@ -1501,47 +2019,7 @@ Variables
    Returns
    wave reference of the preview trace. empty wave reference if the function failed.
    -

    Definition at line 416 of file pearl-data-explorer.ipf.

    - - - - -

    ◆ preview_mtrx_file()

    - -
    -
    -
    - - - - -
    - - - - - - - - -
    static wave preview_mtrx_file (string filename)
    -
    -static
    -
    - -

    load the preview of a Matrix STM file.

    -

    the preview is loaded to the preview_image wave in the pearl_explorer data folder.

    -

    the s_file_info string is updated with information about the scan dimensions.

    -

    this function requires the MatrixFileReader.xop and pearl-matrix-import.ipf to be loaded. otherwise it will return an empty wave reference.

    -
    Parameters
    - - -
    filenamename of a file in the directory specified by the pearl_explorer_filepath path object.
    -
    -
    -
    Returns
    wave reference of the preview image. empty wave reference if the function failed.
    - -

    Definition at line 452 of file pearl-data-explorer.ipf.

    +

    Definition at line 762 of file pearl-data-explorer.ipf.

    @@ -1570,7 +2048,7 @@ Variables

    load the preview of a PShell HDF5 file.

    -

    the preview is an arbitrary detector image extracted from the file, see adh5_load_preview(). the preview is loaded to the preview_image wave in the pear_explorer data folder.

    +

    the preview is an arbitrary detector image extracted from the file, see adh5_load_preview(). the preview is loaded to the preview_image wave in the pear_explorer data folder.

    the s_file_info string is updated with information about the scan dimensions.

    Parameters
    @@ -1580,7 +2058,7 @@ Variables
    Returns
    wave reference of the preview image
    -

    Definition at line 309 of file pearl-data-explorer.ipf.

    +

    Definition at line 671 of file pearl-data-explorer.ipf.

    @@ -1618,7 +2096,7 @@ Variables
    -

    Definition at line 618 of file pearl-data-explorer.ipf.

    +

    Definition at line 866 of file pearl-data-explorer.ipf.

    @@ -1643,7 +2121,7 @@ Variables

    prompt functions must have the same name as the corresponding reduction function with the prefix "prompt_". be aware of the limited length of function names in Igor.

    this function is a prototype. it does nothing but returns OK.

    -

    Definition at line 1070 of file pearl-data-explorer.ipf.

    +

    Definition at line 1130 of file pearl-data-explorer.ipf.

    @@ -1673,7 +2151,7 @@ Variables
    -

    Definition at line 1076 of file pearl-data-explorer.ipf.

    +

    Definition at line 1136 of file pearl-data-explorer.ipf.

    @@ -1701,7 +2179,7 @@ Variables
    -

    Definition at line 1031 of file pearl-data-explorer.ipf.

    +

    Definition at line 1090 of file pearl-data-explorer.ipf.

    @@ -1731,7 +2209,204 @@ Variables

    save persistent package data to the preferences file.

    this function is called when the user clicks the corresponding button. the data saved in the file are: data file path, attributes filter

    -

    Definition at line 102 of file pearl-data-explorer.ipf.

    +

    Definition at line 139 of file pearl-data-explorer.ipf.

    + + + + +

    ◆ selected_file()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + +
    static variable selected_file (string file,
    variable do_preview 
    )
    +
    +static
    +
    + +

    actions after a file has been selected

    +
      +
    • load metadata
    • +
    • load preview if requested
    • +
    +
    Parameters
    + + + +
    filename of selected file
    do_previewenable/disable loading of preview data non-zero: load preview, zero: don't load preview
    +
    +
    + +

    Definition at line 1791 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ send_to_elog()

    + +
    +
    + + + + + +
    + + + + + + + +
    static variable send_to_elog ()
    +
    +static
    +
    + +

    send file metadata to the ELOG panel

    +

    metadate is looked up in the following locations:

      +
    1. data folder if it exists
    2. +
    3. file info folder inside package folder
    4. +
    5. package folder if it contains preview data from the selected file (???)
    6. +
    + +

    Definition at line 2295 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ set_elog_attributes()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    static variable set_elog_attributes (dfref file_df,
    string filename = defaultValue,
    string graphname = defaultValue 
    )
    +
    +static
    +
    + +

    send general metadata to ELOG panel - if available

    +

    the following metatdata are sent. they must be present as strings in the specified data folder:

    + + + + + + + + + + + + + + + +
    ELOG parameter global string function argument
    file s_filepath filename
    graph attachment graphname
    author authors
    p-group pgroup
    project proposal
    sample sample
    +
    Parameters
    + + + + +
    file_dfdata folder that contains the metadata.
    filenameoverride file path read from s_filepath global string variable. if neither is declared, the file name is reset to empty field.
    graphnameselect this graph window for attaching. default: do not change the selection.
    +
    +
    + +

    Definition at line 568 of file pearl-data-explorer.ipf.

    + +
    +
    + +

    ◆ shorten_filepath()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + +
    static string shorten_filepath (string long_path,
    variable max_len 
    )
    +
    +static
    +
    + +

    shorten a file path for display

    +
    Note
    the result is not a valid path any more!
    + +

    Definition at line 1651 of file pearl-data-explorer.ipf.

    @@ -1769,7 +2444,7 @@ Variables
    -

    Definition at line 888 of file pearl-data-explorer.ipf.

    +

    Definition at line 925 of file pearl-data-explorer.ipf.

    @@ -1788,12 +2463,12 @@ Variables
    -

    Definition at line 815 of file pearl-data-explorer.ipf.

    +

    Definition at line 473 of file pearl-data-explorer.ipf.

    - -

    ◆ update_datasets()

    + +

    ◆ update_controls()

    @@ -1802,7 +2477,7 @@ Variables - + @@ -1815,7 +2490,9 @@ Variables
    static variable update_datasets static variable update_controls ( )
    -

    Definition at line 214 of file pearl-data-explorer.ipf.

    +

    update controls state

    + +

    Definition at line 1557 of file pearl-data-explorer.ipf.

    @@ -1843,9 +2520,39 @@ Variables

    read a list of PEARL files from the file system

    -

    wtFiles and wSelectedFiles in the package data folder are updated. only files for which pearl_file_type() returns non-zero are listed.

    +

    wtFiles and wSelectedFiles in the package data folder are updated. only files for which pearl_file_type() returns non-zero are listed.

    -

    Definition at line 186 of file pearl-data-explorer.ipf.

    +

    Definition at line 231 of file pearl-data-explorer.ipf.

    + +
    + + +

    ◆ update_filepath()

    + +
    +
    + + + + + +
    + + + + + + + +
    static variable update_filepath ()
    +
    +static
    +
    + +

    update the file path after path change

    +

    read the path info from pearl_explorer_filepath and update the path control

    + +

    Definition at line 218 of file pearl-data-explorer.ipf.

    @@ -1870,7 +2577,7 @@ Variables
    -

    Definition at line 40 of file pearl-data-explorer.ipf.

    +

    Definition at line 38 of file pearl-data-explorer.ipf.

    @@ -1894,31 +2601,7 @@ Variables
    -

    Definition at line 42 of file pearl-data-explorer.ipf.

    - -
    - - -

    ◆ ks_filematch_mtrx

    - -
    -
    - - - - - -
    - - - - -
    const string ks_filematch_mtrx = "*_mtrx"
    -
    -static
    -
    - -

    Definition at line 43 of file pearl-data-explorer.ipf.

    +

    Definition at line 40 of file pearl-data-explorer.ipf.

    @@ -1942,31 +2625,7 @@ Variables
    -

    Definition at line 41 of file pearl-data-explorer.ipf.

    - -
    - - -

    ◆ package_name

    - -
    -
    - - - - - -
    - - - - -
    const string package_name = "pearl_explorer"
    -
    -static
    -
    - -

    Definition at line 37 of file pearl-data-explorer.ipf.

    +

    Definition at line 39 of file pearl-data-explorer.ipf.

    @@ -1990,19 +2649,55 @@ Variables
    -

    Definition at line 38 of file pearl-data-explorer.ipf.

    +

    Definition at line 36 of file pearl-data-explorer.ipf.

    + +
    + + +

    ◆ version

    + +
    +
    + + + + +
    version
    +
    +Initial value:
    = 1.14
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    static const string package_name = "pearl_explorer"
    +
    +

    Definition at line 6 of file pearl-data-explorer.ipf.

    +
    static const string package_name
    package name is used as data folder name
    diff --git a/doc/html/pearl-data-explorer_8ipf.js b/doc/html/pearl-data-explorer_8ipf.js index 9db751d..3a5e35c 100644 --- a/doc/html/pearl-data-explorer_8ipf.js +++ b/doc/html/pearl-data-explorer_8ipf.js @@ -1,59 +1,71 @@ var pearl_data_explorer_8ipf = [ - [ "attributes_notebook", "pearl-data-explorer_8ipf.html#ad6cfb2c00d5112add84542a25eb68b19", null ], + [ "attributes_notebook", "pearl-data-explorer_8ipf.html#a844467a592e5b26b2324326f22b7da89", null ], [ "bp_attr_notebook", "pearl-data-explorer_8ipf.html#a4ef196f752bb5780ed4f4a588f9ebc81", null ], [ "bp_browse_filepath", "pearl-data-explorer_8ipf.html#a02a64144b7ed2c1bc230e265c55e81a1", null ], - [ "bp_dataset_display", "pearl-data-explorer_8ipf.html#a5660c6f5f78d880b0805bad4eefed1d5", null ], - [ "bp_dataset_folder", "pearl-data-explorer_8ipf.html#a6b642da731bde1029e0fa2ff69d5fb06", null ], - [ "bp_dataset_next", "pearl-data-explorer_8ipf.html#a3bbb332e319ef7ec5f0fe2d16afaf005", null ], - [ "bp_dataset_prev", "pearl-data-explorer_8ipf.html#add62ff5193206c9f207952bcd72dac88", null ], + [ "bp_display_dataset", "pearl-data-explorer_8ipf.html#a0f7473343cf773af9efedee1a18ac5db", null ], + [ "bp_elog", "pearl-data-explorer_8ipf.html#a64bd3e5e68b30c94db00c58fa3be3f0d", null ], [ "bp_file_next", "pearl-data-explorer_8ipf.html#a9cefcdc49b2169e99c743b0a683ed3a6", null ], [ "bp_file_prev", "pearl-data-explorer_8ipf.html#a6aa44ff12b8530adbaaaf7405b1a68ba", null ], - [ "bp_load_files", "pearl-data-explorer_8ipf.html#a742902dfaf2246f10b70f52805c6df1f", null ], - [ "bp_load_files_opt", "pearl-data-explorer_8ipf.html#ad61aa85dcf24dbf7e093dac3d0bf6f19", null ], + [ "bp_goto_dataset", "pearl-data-explorer_8ipf.html#a01e48e67a22dc56851447bd77abecbe1", null ], + [ "bp_load_options", "pearl-data-explorer_8ipf.html#a3fd06ac9aa62de7f00e10ce749ba12c9", null ], [ "bp_load_prefs", "pearl-data-explorer_8ipf.html#a1868754e64cb1448e564c0936e78574d", null ], + [ "bp_reduction_params", "pearl-data-explorer_8ipf.html#a70150946799d759473b409b3371e3ae2", null ], [ "bp_save_prefs", "pearl-data-explorer_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5", null ], - [ "bp_update_datasets", "pearl-data-explorer_8ipf.html#af9f8769ca2989f152f23d976d1467a48", null ], [ "bp_update_filelist", "pearl-data-explorer_8ipf.html#a45be265789a5260e3daa05eca0ec309e", null ], - [ "display_dataset", "pearl-data-explorer_8ipf.html#ae79a57a41c734ce8836f427b81011b5d", null ], + [ "create_attributes_notebook", "pearl-data-explorer_8ipf.html#a77047115739da6d28055f7fd44c9fd2c", null ], + [ "display_dataset", "pearl-data-explorer_8ipf.html#a67cd1a025e5428d443027c1f57eaec09", null ], [ "display_preview_trace", "pearl-data-explorer_8ipf.html#a001074020ad32b290d390a450a389c69", null ], + [ "extract_attributes", "pearl-data-explorer_8ipf.html#af4474f34647ec24f27f900226c6bb3bd", null ], [ "extract_preview_image", "pearl-data-explorer_8ipf.html#a0adc1b370fd3bf230b61b094b3c0accb", null ], + [ "get_file_info", "pearl-data-explorer_8ipf.html#a66043ccbe2e8dda258e639cb7a231537", null ], + [ "get_pshell_info", "pearl-data-explorer_8ipf.html#a28921b185d4e6fbe9a7a689757269f19", null ], + [ "goto_dataset_folder", "pearl-data-explorer_8ipf.html#a896081071fffecdeff09ae4c9d6e84cb", null ], + [ "hl_add_objects", "pearl-data-explorer_8ipf.html#a54be4e40b17906c281cdf649d6ce537e", null ], + [ "hl_contents_clear", "pearl-data-explorer_8ipf.html#ad95697e197428ff73a1a258ea3bb79b2", null ], + [ "hl_contents_update", "pearl-data-explorer_8ipf.html#aba2f8be504e49469194cc4b562be3a9c", null ], + [ "hl_default_selection", "pearl-data-explorer_8ipf.html#a7c36ce6ccfaa77cf7a6b68b9014c1b9b", null ], + [ "hl_expand_scans", "pearl-data-explorer_8ipf.html#a5d0c796365e8a24683c73e2b29571018", null ], + [ "hlp_contents_open", "pearl-data-explorer_8ipf.html#a384a37c2865baf5c21b63cff2488c3b3", null ], + [ "hlp_contents_selection", "pearl-data-explorer_8ipf.html#a36fd730f2d057513179dd59f8fddaf75", null ], + [ "hlp_setup", "pearl-data-explorer_8ipf.html#af616e37167d5753b11e513bd03685ab8", null ], [ "init_package", "pearl-data-explorer_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725", null ], [ "itx_suggest_foldername", "pearl-data-explorer_8ipf.html#a6b5e9729ee6dedbb217c741639a168ed", null ], - [ "lbp_datasets", "pearl-data-explorer_8ipf.html#a8ec37ab6c651003957d7e1ba728de89e", null ], [ "lbp_filelist", "pearl-data-explorer_8ipf.html#a614e89b9c06511144ccb380e61cc7bd6", null ], - [ "load_file", "pearl-data-explorer_8ipf.html#a1bbf3e1592f3344f3628526fa549dfdf", null ], - [ "load_hdf_file", "pearl-data-explorer_8ipf.html#a0c839d5f8f49e6937a6532bba3ef3714", null ], - [ "load_itx_file", "pearl-data-explorer_8ipf.html#a26f2f2bf5efc39dabb2a01abcc559e3e", null ], - [ "load_mtrx_file", "pearl-data-explorer_8ipf.html#a98e327fa65bbcb3cd7c97545f7201afe", null ], + [ "load_file", "pearl-data-explorer_8ipf.html#a435adef620193e09110ff69ca8d106de", null ], + [ "load_hdf_file", "pearl-data-explorer_8ipf.html#a96a3ef643cc29948ba57a3bfa1339c4d", null ], + [ "load_itx_file", "pearl-data-explorer_8ipf.html#ababd5be120b526ca410c53b4a2ba3f8d", null ], [ "load_prefs", "pearl-data-explorer_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3", null ], - [ "load_pshell_file", "pearl-data-explorer_8ipf.html#a74c69e870329c5dd3b08f92bdeb21d87", null ], + [ "load_pshell_file", "pearl-data-explorer_8ipf.html#a0e1e23060294bd4b18980e59229c70ed", null ], [ "load_selected_files", "pearl-data-explorer_8ipf.html#a2178d5acf21fe4372ecc06224bec28ba", null ], [ "notebook_add_attributes", "pearl-data-explorer_8ipf.html#a0c162346b59b0f66d34ee26ce5fe1e52", null ], [ "pearl_data_explorer", "pearl-data-explorer_8ipf.html#ab7e3b3a0a901f7559ee9f5affb9a6fca", null ], [ "pearl_file_type", "pearl-data-explorer_8ipf.html#a8a923d7095071e7e6f99018379807732", null ], [ "PearlDataExplorer", "pearl-data-explorer_8ipf.html#a5b824531904179a94e0eaa3ffa09172e", null ], - [ "preview_attributes", "pearl-data-explorer_8ipf.html#a415e4867be1ee37d84fd609b06f6dcb8", null ], + [ "pm_reduction_values", "pearl-data-explorer_8ipf.html#a638a13044aede37cabe0c2c7a7c0cb06", null ], + [ "pmp_reduction_func", "pearl-data-explorer_8ipf.html#a166273677188a66c25a84616c6f4baa9", null ], [ "preview_datafolder", "pearl-data-explorer_8ipf.html#a6e8eaf8c092f5da60bd425f9bd8bf178", null ], - [ "preview_dataset", "pearl-data-explorer_8ipf.html#a68d38e9464f7d13520ec040cffdf5c3b", null ], [ "preview_file", "pearl-data-explorer_8ipf.html#a3232c51a8c19eaf86b9bc67352967a9f", null ], [ "preview_hdf_file", "pearl-data-explorer_8ipf.html#a1731f8e1507d90e285885723ae32ba13", null ], [ "preview_itx_file", "pearl-data-explorer_8ipf.html#a4633885afab755fbc5d262178b9ddcb8", null ], - [ "preview_mtrx_file", "pearl-data-explorer_8ipf.html#a340f334c6caa966ee1eb891614e57b5b", null ], [ "preview_pshell_file", "pearl-data-explorer_8ipf.html#a457d2257ffd5880ab858fa583a5d1c99", null ], [ "preview_setscale_x", "pearl-data-explorer_8ipf.html#a5a7d3c00360944c00f236900b992694d", null ], [ "prompt_default_process", "pearl-data-explorer_8ipf.html#a505ebda6bdecc4120e01766d7aedaf5d", null ], [ "prompt_func_params", "pearl-data-explorer_8ipf.html#a1d7f4ad59b81ecd84bb63cfabd9f24dc", null ], [ "prompt_hdf_options", "pearl-data-explorer_8ipf.html#a200e7ba052fbce4614fb4254701646ab", null ], [ "save_prefs", "pearl-data-explorer_8ipf.html#ac729557a307bddd2f2ad298199976c01", null ], + [ "selected_file", "pearl-data-explorer_8ipf.html#ac477142f1949dc32d86663f1de4384e5", null ], + [ "send_to_elog", "pearl-data-explorer_8ipf.html#aac8d96d9ccaeddab1cb0f463b01616cb", null ], + [ "set_elog_attributes", "pearl-data-explorer_8ipf.html#a93c61109535e1644f5e53aabb895b48a", null ], + [ "shorten_filepath", "pearl-data-explorer_8ipf.html#a00307dffd6f272f13acfe4dea99a81d4", null ], [ "show_preview_graph", "pearl-data-explorer_8ipf.html#a4db79d04c74beb1af71b72916f8f0362", null ], [ "test_attributes_notebook", "pearl-data-explorer_8ipf.html#a71f9c277d310c3f4e7739be69dad0ab5", null ], - [ "update_datasets", "pearl-data-explorer_8ipf.html#ad50f4c430d8bfe0fb5a1356cd9b84bf4", null ], + [ "update_controls", "pearl-data-explorer_8ipf.html#a57e21bffee4cd64f2ea1efd9cc958bf1", null ], [ "update_filelist", "pearl-data-explorer_8ipf.html#a04cc0b9d5e3a649ba3514fcbf126eefe", null ], + [ "update_filepath", "pearl-data-explorer_8ipf.html#ae02b954d90dc8f43c007cc3fb1a1ee16", null ], [ "ks_filematch_adh5", "pearl-data-explorer_8ipf.html#a181ccce237172811baf3de5a7a06370d", null ], [ "ks_filematch_itx", "pearl-data-explorer_8ipf.html#a53af8689144e3aeb27ca177db5dd0c22", null ], - [ "ks_filematch_mtrx", "pearl-data-explorer_8ipf.html#ad720655ff881ddecae2e1b8afed58fa0", null ], [ "ks_filematch_pshell", "pearl-data-explorer_8ipf.html#a00bf5267a40b2b3d760c64d73e139878", null ], - [ "package_name", "pearl-data-explorer_8ipf.html#aca457d1f4414d20a911254b1de13ebbb", null ], - [ "package_path", "pearl-data-explorer_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b", null ] + [ "package_path", "pearl-data-explorer_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b", null ], + [ "version", "pearl-data-explorer_8ipf.html#a4c7a521b8f1a0769c09bfa4a1fca7dab", null ] ]; \ No newline at end of file diff --git a/doc/html/pearl-data-explorer_8ipf_source.html b/doc/html/pearl-data-explorer_8ipf_source.html index 452ea17..edb1b74 100644 --- a/doc/html/pearl-data-explorer_8ipf_source.html +++ b/doc/html/pearl-data-explorer_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-data-explorer.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,89 +87,2191 @@ $(document).ready(function(){initNavTree('pearl-data-explorer_8ipf_source.html',
    pearl-data-explorer.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.1
    3 #pragma ModuleName = PearlDataExplorer
    4 #pragma version = 1.50
    5 #include "pearl-area-import"
    6 #include "pearl-area-profiles"
    7 #include "pearl-area-display"
    8 #include "pearl-compat"
    9 #include "pearl-pshell-import"
    10 #if exists("MFR_OpenResultFile")
    11 #include "pearl-matrix-import"
    12 #endif
    13 
    14 // copyright (c) 2013-16 Paul Scherrer Institut
    15 //
    16 // Licensed under the Apache License, Version 2.0 (the "License");
    17 // you may not use this file except in compliance with the License.
    18 // You may obtain a copy of the License at
    19 // http:///www.apache.org/licenses/LICENSE-2.0
    20 
    31 
    36 
    37 static strconstant package_name = "pearl_explorer"
    38 static strconstant package_path = "root:packages:pearl_explorer:"
    39 
    40 static strconstant ks_filematch_adh5 = "*.h5"
    41 static strconstant ks_filematch_pshell = "psh*.h5"
    42 static strconstant ks_filematch_itx = "*.itx"
    43 static strconstant ks_filematch_mtrx = "*_mtrx"
    44 
    46  init_package()
    47  load_prefs()
    48  execute /q/z "PearlDataExplorer()"
    49 end
    50 
    56 static function init_package()
    57 
    58  dfref savefolder = GetDataFolderDFR()
    59  SetDataFolder root:
    60  newdatafolder /o/s packages
    61  newdatafolder /o/s $package_name
    62  if (exists("v_InitPanelDone") == 2)
    63  SetDataFolder savefolder
    64  return 0
    65  endif
    66 
    67  make /o/n=0/t wtFiles
    68  make /o/n=0/i wSelectedFiles,wSelectedDatasets
    69  make /o/n=0/t wtDatasets
    70  make /o/n=0/t wtPositioners,wtDetectors
    71  make /o/n=0/i wSelectedPositioners,wSelectedDetectors
    72 
    73  make /o/n=(1,1) preview_image // preview 2D data
    74  make /o/n=0 preview_trace // preview 1D data
    75  make /o/n=0/t attr_names, attr_values, attr_filter, attr_filter_summary
    76 
    77  // persistent strings and variables. persistent = saved in preferences
    78  string /g s_filepath = "" // directory path to be listed
    79  string /g s_hdf_options = "" // recently used HDF5 load options
    80  string /g s_reduction_params = "" // recently used reduction parameters
    81  string /g s_preview_pvs = "" // semicolon-separated list of EPICS PVs to display in preview.
    82  // the list items can contain wildcards for StringMatch
    83  s_preview_pvs = "*OP:CURRENT*;*Stats*Total*;*KEITHLEY*READOUT;*CADC*"
    84 
    85  // non-persistent strings and variables
    86  string /g s_preview_file = "" // file or folder name of the current preview
    87  string /g s_preview_source = "" // data source, e.g. EPICS channel name, of the current preview
    88  string /g s_profiles_graph = "" // window name of the current preview if the data is two-dimensional
    89  string /g s_preview_trace_graph = "" // window name of the current preview if the data is one-dimensional
    90  string /g s_file_info = "" // description of selected file
    91 
    92  variable/g v_InitPanelDone = 1
    93 
    94  SetDataFolder savefolder
    95 end
    96 
    102 static function save_prefs()
    103  dfref saveDF = GetDataFolderDFR()
    104  dfref df = $package_path
    105  if (DataFolderRefStatus(df) == 1)
    106  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    107  fullPath += package_name
    108  NewPath/O/C/Q tempPackagePrefsPath, fullPath
    109  fullPath += ":preferences.pxp"
    110  SetDataFolder df
    111  string objects = "attr_filter;attr_filter_summary;s_filepath;s_hdf_options;s_reduction_params;s_preview_pvs"
    112  SaveData /O /Q /J=objects fullPath
    113  KillPath/Z tempPackagePrefsPath
    114  endif
    115  SetDataFolder saveDF
    116 end
    117 
    118 static function load_prefs()
    119  // loads persistent package data from the preferences file
    120  // the preferences file is an Igor packed experiment file in a special preferences folder
    121  dfref saveDF = GetDataFolderDFR()
    122 
    123  variable result = -1
    124  setdatafolder root:
    125  NewDataFolder /O/S packages
    126  NewDataFolder /O/S $package_name
    127  dfref packageDF = GetDataFolderDFR()
    128  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    129  fullPath += package_name
    130 
    131  GetFileFolderInfo /Q /Z fullPath
    132  if (V_Flag == 0) // Disk directory exists?
    133  fullPath += ":preferences.pxp"
    134  GetFileFolderInfo /Q /Z fullPath
    135  if (V_Flag == 0) // Preference file exist?
    136  LoadData /O /R /Q fullPath
    137  result = 0
    138  endif
    139  endif
    140 
    141  if (result == 0)
    142  svar /sdfr=packageDF filepath = s_filepath
    143  NewPath /O/Z pearl_explorer_filepath, filepath
    146  endif
    147 
    148  SetDataFolder saveDF
    149  return result
    150 end
    151 
    163 static function pearl_file_type(filename)
    164  string filename
    165 
    166  if (StringMatch(filename, ks_filematch_pshell))
    167  return 1
    168  elseif (StringMatch(filename, ks_filematch_adh5))
    169  return 2
    170  elseif (StringMatch(filename, ks_filematch_itx))
    171  return 3
    172 #if exists("MFR_OpenResultFile")
    173  elseif (StringMatch(filename, ks_filematch_mtrx))
    174  return 4
    175 #endif
    176  else
    177  return 0
    178  endif
    179 end
    180 
    186 static function update_filelist()
    187  dfref saveDF = GetDataFolderDFR()
    188 
    189  string all_files
    190  wave /t wtFiles = $(package_path + "wtFiles")
    191  wave wSelectedFiles = $(package_path + "wSelectedFiles")
    192  variable nn
    193 
    194  PathInfo pearl_explorer_filepath
    195  if (v_flag == 1)
    196  all_files = IndexedFile(pearl_explorer_filepath, -1, "????")
    197  nn = ItemsInList(all_files)
    198  else
    199  all_files = ""
    200  nn = 0
    201  endif
    202 
    203  make /n=(nn) /t /free wtAllFiles
    204  wtAllFiles = StringFromList(p, all_files)
    205  Extract /o /t wtAllFiles, wtFiles, pearl_file_type(wtAllFiles[p])
    206  Sort /A /R wtFiles, wtFiles
    207 
    208  redimension /n=(numpnts(wtFiles)) wSelectedFiles
    209  wSelectedFiles = 0
    210 
    211  setdatafolder saveDF
    212 end
    213 
    214 static function update_datasets()
    215  // updates the list of imported datasets.
    216  // a dataset means any top-level data folder
    217  // which includes a string variable named pearl_explorer_import.
    218  dfref saveDF = GetDataFolderDFR()
    219 
    220  setdatafolder root:
    221  dfref rootdf = GetDataFolderDFR()
    222  setdatafolder $package_path
    223  dfref privatedf = GetDataFolderDFR()
    224 
    225  wave /t wtDatasets
    226  wave wSelectedDatasets
    227  variable maxdf = CountObjectsDFR(rootdf, 4)
    228  redimension /n=(maxdf) wtDatasets
    229 
    230  variable idf = 0
    231  variable ndf = 0
    232  string sdf
    233 
    234  do
    235  sdf = GetIndexedObjNameDFR(rootdf, 4, idf)
    236  if (strlen(sdf) >= 1)
    237  setdatafolder rootdf
    238  setdatafolder $sdf
    239  svar /z importer = pearl_explorer_import
    240  if (svar_exists(importer))
    241  wtDatasets[ndf] = sdf
    242  ndf += 1
    243  endif
    244  else
    245  break
    246  endif
    247  idf += 1
    248  while(1)
    249 
    250  redimension /n=(ndf) wtDatasets, wSelectedDatasets
    251  wSelectedDatasets = 0
    252  sort wtDatasets, wtDatasets
    253 
    254  setdatafolder saveDF
    255 end
    256 
    257 static function preview_file(filename)
    258  string filename
    259 
    260  dfref saveDF = GetDataFolderDFR()
    261 
    262  variable ft = pearl_file_type(filename)
    263  switch(ft)
    264  case 1:
    265  wave /z image = preview_pshell_file(filename)
    266  break
    267  case 2:
    268  wave /z image = preview_hdf_file(filename)
    269  break
    270  case 3:
    271  wave /z image = preview_itx_file(filename)
    272  break
    273  case 4:
    274  wave /z image = preview_mtrx_file(filename)
    275  break
    276  default:
    277  wave /z image = $""
    278  endswitch
    279 
    280  if (WaveExists(image))
    281  string graphname = show_preview_graph(image)
    282  // preset ELOG panel - if available
    283  if (exists("PearlElog#set_panel_attributes") == 6)
    284  string cmd
    285  sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"File=%s\")", ParseFilePath(0, filename, ":", 1, 0)
    286  execute /Q/Z cmd
    287  if (strlen(graphname) > 0)
    288  sprintf cmd, "PearlElog#set_panel_graphs(\"\", \"%s\")", graphname
    289  execute /Q/Z cmd
    290  endif
    291  endif
    292  endif
    293 
    294  setdatafolder saveDF
    295  return 0
    296 end
    297 
    309 static function /wave preview_pshell_file(filename)
    310  string filename
    311 
    312  dfref saveDF = GetDataFolderDFR()
    313 
    314  setdatafolder $package_path
    315  dfref previewDF = GetDataFolderDFR()
    316  svar s_preview_file
    317  svar s_preview_source
    318  svar /z s_file_info
    319  if (! svar_exists(s_file_info))
    320  string /g s_file_info
    321  endif
    322 
    323  dfref tempDF = NewFreeDataFolder()
    324  setdatafolder tempDF
    325  string dataname
    326  dataname = psh5_load_preview("pearl_explorer_filepath", filename)
    327 
    328  s_preview_file = filename
    329  s_preview_source = ""
    330 
    331  wave /z data = $dataname
    332  if (waveexists(data))
    333  duplicate /o data, previewDF:preview_image
    334  else
    335  print "no data found in file " + filename
    336  endif
    337 
    338  if (strlen(s_preview_file) > 0)
    339  s_file_info = psh5_load_info("pearl_explorer_filepath", filename)
    340  else
    341  s_file_info = ""
    342  endif
    343 
    344  dfref attrDF = tempDF:attr
    345  if (DataFolderRefStatus(attrDF))
    346  preview_attributes(attrDF)
    347  endif
    348 
    349  setdatafolder saveDF
    350  wave /z /sdfr=previewDF preview_image
    351  return preview_image
    352 end
    353 
    365 static function /wave preview_hdf_file(filename)
    366  string filename
    367 
    368  dfref saveDF = GetDataFolderDFR()
    369  setdatafolder $package_path
    370  svar s_preview_file
    371  svar s_preview_source
    372  adh5_load_preview("preview_image", "pearl_explorer_filepath", filename)
    373  s_preview_file = filename
    374  s_preview_source = ""
    375  wave /z preview_image
    376 
    377  svar /z s_file_info
    378  if (! svar_exists(s_file_info))
    379  string /g s_file_info
    380  endif
    381  if (strlen(s_preview_file) > 0)
    382  s_file_info = adh5_load_info("pearl_explorer_filepath", filename)
    383  else
    384  s_file_info = ""
    385  endif
    386 
    387  if (DataFolderExists("attr"))
    388  setdatafolder attr
    389  preview_attributes(GetDataFolderDFR())
    390  setdatafolder ::
    391  endif
    392 
    393  setdatafolder saveDF
    394  return preview_image
    395 end
    396 
    416 static function /wave preview_itx_file(filename)
    417  string filename
    418 
    419  dfref saveDF = GetDataFolderDFR()
    420  setdatafolder $package_path
    421  svar s_preview_file
    422  svar s_preview_source
    423  wave preview_image
    424 
    425  dfref dataDF = newfreedatafolder()
    426  setdatafolder dataDF
    427  LoadWave /t/p=pearl_explorer_filepath/q filename
    428  s_preview_file = s_filename
    429  s_preview_source = ""
    430 
    432  preview_attributes(dataDF, include_datawaves=0)
    433 
    434  setdatafolder saveDF
    435  return preview_image
    436 end
    437 
    452 static function /wave preview_mtrx_file(filename)
    453  string filename
    454 
    455 #if exists("MFR_OpenResultFile")
    456  dfref saveDF = GetDataFolderDFR()
    457  setdatafolder $package_path
    458  variable /g V_MatrixFileReaderOverwrite = 1
    459  variable /g V_MatrixFileReaderFolder = 0
    460  variable /g V_MatrixFileReaderDouble = 0
    461  svar s_preview_file
    462  svar s_preview_source
    463  string datanames
    464  string dataname
    465  datanames = mtrx_load_preview("preview", "pearl_explorer_filepath", filename)
    466  if (strlen(datanames) > 0)
    467  s_preview_file = filename
    468 
    469  dataname = StringFromList(0, datanames)
    470  wave data = $dataname
    471  duplicate /o $dataname, preview_image
    472  s_preview_source = StringByKey("Dataset", note(data), "=", "\r")
    473 
    474  svar /z s_file_info
    475  if (svar_exists(s_file_info))
    476  s_file_info = ""
    477  endif
    478 
    479  variable i
    480  variable n = ItemsInList(datanames)
    481  string s
    482  for (i = 0; i < n; i += 1)
    483  s = StringFromList(i, datanames)
    484  killwaves /z $s
    485  endfor
    486  endif
    487  wave /z preview_image
    488  setdatafolder saveDF
    489 #else
    490  wave /z preview_image = $""
    491 #endif
    492  return preview_image
    493 end
    494 
    495 static function extract_preview_image(data, preview)
    496  // extracts a preview image from a wave of arbitrary dimension
    497  wave data
    498  wave preview
    499 
    500  variable z1, z2
    501 
    502  // extract image
    503  switch (WaveDims(data))
    504  case 1:
    505  redimension /n=(numpnts(data)) preview
    506  preview = data[p]
    507  break
    508  case 2:
    509  redimension /n=(dimsize(data, 0), dimsize(data, 1)) preview
    510  preview = data
    511  break
    512  case 3:
    513  redimension /n=(dimsize(data, 0), dimsize(data, 1)) preview
    514  z1 = floor(DimSize(data, 2) / 2)
    515  z2 = z1
    516  wave slab = ad_extract_slab(data, nan, nan, nan, nan, z1, z2, "", pscale=1)
    517  preview = slab
    518  break
    519  case 4:
    520  // not implemented
    521  endswitch
    522 
    523  switch (WaveDims(data))
    524  case 4:
    525  case 3:
    526  case 2:
    527  setscale /p y dimoffset(data, 1), dimdelta(data, 1), waveunits(data, 1), preview
    528  case 1:
    529  setscale /p x dimoffset(data, 0), dimdelta(data, 0), waveunits(data, 0), preview
    530  setscale d 0, 0, waveunits(data, -1), preview
    531  endswitch
    532 end
    533 
    534 static function preview_dataset(datasetname)
    535  string datasetname // name of a data folder under root
    536 
    537  dfref saveDF = GetDataFolderDFR()
    538 
    539  if (!DataFolderExists("root:" + datasetname))
    540  return -1
    541  endif
    542  setdatafolder root:
    543  setdatafolder $datasetname
    544  dfref datadf = GetDataFolderDFR()
    545  wave /z data
    546 
    547  setdatafolder $package_path
    548  svar s_preview_file
    549  svar s_preview_source
    550  wave preview_image
    551  if (WaveExists(data))
    552  s_preview_file = datasetname
    553  s_preview_source = ""
    554  extract_preview_image(data, preview_image)
    555  show_preview_graph(preview_image)
    556  else
    557  preview_image = nan
    558  s_preview_file = datasetname
    559  setdatafolder datadf
    561  show_preview_graph(preview_image)
    562  endif
    563 
    564  // attributes
    565  setdatafolder datadf
    566  if (DataFolderExists("attr"))
    567  setdatafolder attr
    568  preview_attributes(GetDataFolderDFR())
    569  else
    570  preview_attributes(GetDataFolderDFR(), include_datawaves=0)
    571  endif
    572 
    573  setdatafolder saveDF
    574  return 0
    575 end
    576 
    577 static function preview_datafolder()
    578  // preview data in the current data folder
    579  dfref saveDF = GetDataFolderDFR()
    580 
    581  setdatafolder $package_path
    582  svar s_preview_file
    583  svar s_preview_source
    584  svar s_preview_pvs
    585  wave preview_image
    586 
    587  setdatafolder saveDF
    588 
    589  // select a wave to display
    590  // consider only double-precision waves, i.e. ignore text and other special waves
    591  // filter by matching PV name to s_preview_pvs
    592  string d_names = WaveList("*", ";", "DP:1")
    593  variable nw = ItemsInList(d_names, ";")
    594  variable npv = ItemsInList(s_preview_pvs, ";")
    595  variable iw, ipv
    596  string wname, wnote, pv_name, pv_match
    597  for (iw = 0; iw < nw; iw += 1)
    598  wname = StringFromList(iw, d_names, ";")
    599  wnote = note($wname)
    600  pv_name = StringByKey("PV", wnote, "=", "\r")
    601  // find matching data wave by PV name
    602  for (ipv = 0; ipv < npv; ipv += 1)
    603  pv_match = StringFromList(ipv, s_preview_pvs)
    604  if (StringMatch(pv_name, pv_match))
    605  wave data = $wname
    606  s_preview_source = pv_name
    607  extract_preview_image(data, preview_image)
    608  preview_setscale_x(data, preview_image)
    609  npv = 0
    610  nw = 0
    611  endif
    612  endfor
    613  endfor
    614 
    615  setdatafolder saveDF
    616 end
    617 
    618 static function preview_setscale_x(data, preview)
    619  // sets the approximate x scale of OTF data.
    620  // requires an Axis1 tag with name of x wave in the wave note.
    621  // if any of these conditions is true, the function does not change the scaling:
    622  // 1) Axis1 tag or referenced wave is missing.
    623  // 2) preview wave is not set to point scaling.
    624  // 3) x wave is not monotonic (90% of the steps in the same direction).
    625  wave data
    626  wave preview
    627 
    628  if ((DimOffset(preview, 0) == 0) && (DimDelta(preview, 0) == 1))
    629  string xname = StringByKey("Axis1", note(data), "=", "\r")
    630  wave /z xwave = $xname
    631  if (WaveExists(xwave))
    632  // check for monotonicity
    633  variable monotonic = 0
    634  duplicate /free xwave, xdiff
    635  differentiate /p xwave /D=xdiff
    636  duplicate /free xdiff, xflag
    637  xflag = xdiff > 0
    638  monotonic = sum(xflag) > numpnts(xwave) * 0.9
    639  xflag = xdiff < 0
    640  monotonic = monotonic || (sum(xflag) > numpnts(xwave) * 0.9)
    641  if (monotonic)
    642  setscale /i x xwave[0], xwave[numpnts(xwave)-1], waveunits(xwave, -1), preview
    643  endif
    644  endif
    645  endif
    646 end
    647 
    648 static function preview_attributes(attr_folder, [dest_folder, attr_filter, include_datawaves, include_infowaves])
    649  // copies the first elements of attributes in the specified folder to the preview waves
    650  // by default, all existing attributes are copied
    651  // if a text wave attr_filter exists in the pear_explorer folder, only the attributes referenced therein are copied
    652  // to set up a filter, duplicate the attr_names wave of a template dataset, and remove unwanted items
    653  dfref attr_folder // data folder which contains the attribute waves
    654  dfref dest_folder // destination folder. the output is written to the attr_names and attr_values waves
    655  // default = package folder
    656  wave /t attr_filter // list of attributes allowed in the output
    657  // default = use attr_filter of package folder
    658  variable include_datawaves // 1 (default) = include data waves (any numeric wave which has a PV=name note)
    659  // 0 = don't include attributes from data waves
    660  variable include_infowaves // 1 (default) = include attributes from info waves (IN, ID, IV, IU)
    661  // 0 = don't include attributes from info waves
    662 
    663  dfref saveDF = GetDataFolderDFR()
    664  setdatafolder $package_path
    665 
    666  if (ParamIsDefault(dest_folder))
    667  dest_folder = GetDataFolderDFR() // package folder
    668  endif
    669  if (ParamIsDefault(attr_filter))
    670  wave /t /z attr_filter
    671  endif
    672  if (ParamIsDefault(include_datawaves))
    673  include_datawaves = 1
    674  endif
    675  if (ParamIsDefault(include_infowaves))
    676  include_infowaves = 1
    677  endif
    678 
    679  setdatafolder dest_folder
    680  wave /t /z attr_names, attr_values
    681  if (!WaveExists(attr_names) || !WaveExists(attr_values))
    682  make /n=(1) /o /t attr_names, attr_values
    683  endif
    684  attr_names = ""
    685  attr_values = ""
    686 
    687  setdatafolder attr_folder
    688  wave /t /z IN
    689  wave /t /z ID
    690  wave /t /z IV
    691  wave /t /z IU
    692 
    693  // compile list of attributes
    694  variable nattr // destination attributes
    695  variable iattr
    696  variable ninfo // info wave elements
    697  variable iinfo
    698  variable nw // attribute waves
    699  variable iw
    700  string sw
    701  string ss
    702 
    703  if (WaveExists(IN) && include_infowaves)
    704  ninfo = numpnts(IN)
    705  else
    706  ninfo = 0
    707  endif
    708  if (include_datawaves)
    709  string waves = WaveList("*", ";", "")
    710  string exceptions = "ID;IN;IU;IV"
    711  waves = RemoveFromList(exceptions, waves)
    712  nw = ItemsInList(waves, ";")
    713  else
    714  nw = 0
    715  endif
    716 
    717  if (WaveExists(attr_filter) && (numpnts(attr_filter) >= 1))
    718  nattr = numpnts(attr_filter)
    719  redimension /n=(nattr) attr_names
    720  attr_names = attr_filter
    721  else
    722  if(ninfo > 0)
    723  redimension /n=(ninfo) attr_names
    724  attr_names = SelectString(strlen(ID[p]) >= 0, IN[p], ID[p]) // use ID unless empty
    725  endif
    726 
    727  nattr = ninfo + nw
    728  iattr = ninfo
    729  redimension /n=(nattr) attr_names
    730  for (iw = 0; iw < nw; iw +=1 )
    731  sw = StringFromList(iw, waves, ";")
    732  ss = StringByKey("PV", note($sw), "=", "\r")
    733  FindValue /text=sw attr_names
    734  if ((v_value < 0) && (strlen(ss) >= 0))
    735  attr_names[iattr] = sw
    736  iattr += 1
    737  endif
    738  endfor
    739  nattr = iattr
    740  endif
    741  redimension /n=(nattr) attr_names, attr_values
    742  sort attr_names, attr_names
    743 
    744  // look up attribute values
    745  for (iattr = 0; iattr < nattr; iattr += 1)
    746  sw = attr_names[iattr]
    747  // try info waves
    748  if (ninfo > 0)
    749  FindValue /text=sw ID
    750  if (v_value >= 0)
    751  attr_values[iattr] = IV[v_value]
    752  endif
    753  FindValue /text=sw IN
    754  if (v_value >= 0)
    755  attr_values[iattr] = IV[v_value]
    756  endif
    757  endif
    758 
    759  // override from attribute wave if existent
    760  if (nw > 0)
    761  switch (WaveType($sw, 1))
    762  case 1: // numeric
    763  wave /z w = $sw
    764  if (WaveExists(w) && (numpnts(w) >= 1))
    765  sprintf ss, "%g", w[0]
    766  attr_values[iattr] = ss
    767  endif
    768  break
    769  case 2: // text
    770  wave /t/z wt = $sw
    771  if (WaveExists(wt) && (numpnts(wt) >= 1))
    772  attr_values[iattr] = wt[0]
    773  endif
    774  break
    775  endswitch
    776  endif
    777  endfor
    778 
    779  setdatafolder saveDF
    780 end
    781 
    782 static function display_dataset(datasetname)
    783  // displays the graph of a loaded dataset in its own window
    784  string datasetname // name of a data folder under root
    785 
    786  dfref saveDF = GetDataFolderDFR()
    787 
    788  if (!DataFolderExists("root:" + datasetname))
    789  return -1
    790  endif
    791  setdatafolder root:
    792  setdatafolder $datasetname
    793  dfref datadf = GetDataFolderDFR()
    794  wave /z data
    795  if (!WaveExists(data))
    796  wave /z data = data1
    797  endif
    798 
    799  if (WaveExists(data))
    800  switch(WaveDims(data))
    801  case 2:
    802  ad_display_profiles(data)
    803  break
    804  case 3:
    805  ad_display_slice(data)
    806  ad_brick_slicer(data)
    807  break
    808  endswitch
    809  endif
    810 
    811  setdatafolder saveDF
    812  return 0
    813 end
    814 
    816  dfref df = GetDataFolderDFR()
    817  wave /t /sdfr=df attr_names
    818  wave /t /sdfr=df attr_values
    819  attributes_notebook(attr_names, attr_values, GetDataFolder(0))
    820 end
    821 
    822 static function attributes_notebook(attr_names, attr_values, title)
    823  wave /t attr_names
    824  wave /t attr_values
    825  string title
    826 
    827  dfref saveDF = GetDataFolderDFR()
    828  setdatafolder $package_path
    829  wave /t/z attr_filter, attr_filter_summary
    830 
    831  string name = PearlCleanupName("nb_" + title[0,27])
    832  if (WinType(name) == 5)
    833  Notebook $name selection={startOfFile, endOfFile}
    834  Notebook $name text=""
    835  else
    836  NewNotebook /F=1 /K=1 /N=$name as title
    837  GetWindow $name wsize
    838  v_right = v_left + 260
    839  v_bottom = v_top + 360
    840  MoveWindow /W=$name v_left, v_top, v_right, v_bottom
    841  Notebook $name tabs={2*72}
    842  endif
    843 
    844  // summary
    845  if (WaveExists(attr_filter_summary) && (numpnts(attr_filter_summary) >= 1))
    846  notebook $name fStyle=1, text="Summary\r\r"
    847  notebook $name fStyle=0
    848  notebook_add_attributes(name, attr_filter_summary, attr_names, attr_values)
    849  notebook $name text="\r"
    850  endif
    851 
    852  // all attributes
    853  notebook $name fStyle=1, text="All Attributes\r\r"
    854  notebook $name fStyle=0
    855  notebook_add_attributes(name, $"", attr_names, attr_values)
    856  notebook $name selection={startOfFile,startOfFile}, findText={"",1}
    857 
    858  setdatafolder saveDF
    859 end
    860 
    861 static function notebook_add_attributes(notebook_name, attr_filter, attr_names, attr_values)
    862  string notebook_name
    863  wave /t /z attr_filter
    864  wave /t attr_names
    865  wave /t attr_values
    866 
    867  variable nw = numpnts(attr_names)
    868  variable iw
    869  string sw
    870  string ss
    871 
    872  variable do_filter = WaveExists(attr_filter)
    873 
    874  for (iw = 0; iw < nw; iw += 1)
    875  if (do_filter)
    876  sw = attr_names[iw]
    877  FindValue /text=sw attr_filter
    878  else
    879  v_value = 0
    880  endif
    881  if (v_value >= 0)
    882  sprintf ss, "%s\t%s\r", attr_names[iw], attr_values[iw]
    883  notebook $notebook_name text=ss
    884  endif
    885  endfor
    886 end
    887 
    888 static function /s show_preview_graph(data, [xdata])
    889  // displays a preview of one- or two-dimensional data
    890  wave data // data to be displayed. must either one-dimensional or two-dimensional
    891  wave xdata // positions on x axis
    892 
    893  dfref saveDF = GetDataFolderDFR()
    894  setdatafolder $package_path
    895 
    896  svar s_profiles_graph
    897  svar s_preview_file
    898  svar s_preview_source
    899  svar s_preview_trace_graph
    900 
    901  if ((strlen(s_profiles_graph) > 0) && (WinType(s_profiles_graph) == 1))
    902  KillWindow $s_profiles_graph
    903  endif
    904  if ((strlen(s_preview_trace_graph) > 0) && (WinType(s_preview_trace_graph) == 1))
    905  KillWindow $s_preview_trace_graph
    906  endif
    907 
    908  string graphname
    909  if (wavedims(data) == 2)
    910  s_profiles_graph = ad_display_profiles(data)
    911  ModifyGraph /w=$s_profiles_graph /z wbRGB=(48640,56832,60160)
    912  graphname = s_profiles_graph
    913  elseif (wavedims(data) == 1)
    914  duplicate /o data, preview_trace
    915  if (!ParamIsDefault(xdata))
    916  duplicate /o xdata, preview_trace_x
    917  else
    918  duplicate /o data, preview_trace_x
    919  preview_trace_x = x
    920  setscale d 0, 0, WaveUnits(data, 0), preview_trace_x
    921  endif
    922  s_preview_trace_graph = display_preview_trace(preview_trace_x, preview_trace)
    923  ModifyGraph /w=$s_preview_trace_graph wbRGB=(48640,56832,60160)
    924  graphname = s_preview_trace_graph
    925  else
    926  return ""
    927  endif
    928 
    929  string title = "Preview " + s_preview_file
    930  if (strlen(s_preview_source) > 0)
    931  title = title + " (" + s_preview_source[0,31] + ")"
    932  endif
    933  dowindow /f/t $graphname, title
    934 
    935  setdatafolder saveDF
    936  return graphname
    937 end
    938 
    939 static function /s display_preview_trace(xtrace, ytrace)
    940  wave xtrace
    941  wave ytrace
    942 
    943  display /n=pearl_explorer_1d /k=1 ytrace vs xtrace as "Preview"
    944  string graphname = s_name
    945  ModifyGraph /w=$graphname rgb[0]=(0,0,0)
    946  ModifyGraph /w=$graphname grid=2
    947  ModifyGraph /w=$graphname mirror=1
    948  ModifyGraph /w=$graphname minor=1
    949  ModifyGraph /w=$graphname axThick=0.5
    950  ModifyGraph /w=$graphname gridRGB=(52224,52224,52224)
    951  ModifyGraph /w=$graphname gridHair=0
    952  ModifyGraph /w=$graphname tick=0
    953  ModifyGraph /w=$graphname btLen=4
    954 
    955  // axis labels
    956  string labels = note(ytrace)
    957  string lab
    958  lab = StringByKey("AxisLabelX", labels, "=", "\r")
    959  if (!strlen(lab))
    960  lab = "X"
    961  endif
    962  Label /w=$graphname bottom lab + " (\\U)"
    963  lab = StringByKey("AxisLabelD", labels, "=", "\r")
    964  if (!strlen(lab))
    965  lab = "value"
    966  endif
    967  Label /w=$graphname left lab + " (\\U)"
    968 
    969  return s_name
    970 end
    971 
    972 static function load_selected_files([options])
    973  string options
    974 
    975  dfref saveDF = GetDataFolderDFR()
    976  setdatafolder $package_path
    977 
    978  wave wSelectedFiles
    979  wave/t wtFiles
    980  variable nn = numpnts(wSelectedFiles)
    981  variable ii
    982  for (ii = 0; ii < nn; ii += 1)
    983  if (wSelectedFiles[ii])
    984  if (ParamIsDefault(options))
    985  load_file(wtFiles[ii])
    986  else
    987  load_file(wtFiles[ii], options=options)
    988  endif
    989  endif
    990  endfor
    991 
    993  setdatafolder saveDF
    994 end
    995 
    996 static function load_file(filename, [options])
    997  string filename
    998  string options
    999 
    1000  dfref saveDF = GetDataFolderDFR()
    1001 
    1002  variable ft = pearl_file_type(filename)
    1003  switch(ft)
    1004  case 1:
    1005  if (ParamIsDefault(options))
    1006  load_pshell_file(filename)
    1007  else
    1008  load_pshell_file(filename, options=options)
    1009  endif
    1010  break
    1011  case 2:
    1012  if (ParamIsDefault(options))
    1013  load_hdf_file(filename)
    1014  else
    1015  load_hdf_file(filename, options=options)
    1016  endif
    1017  break
    1018  case 3:
    1019  load_itx_file(filename)
    1020  break
    1021  case 4:
    1022  load_mtrx_file(filename)
    1023  break
    1024  default:
    1025  break
    1026  endswitch
    1027 
    1028  setdatafolder saveDF
    1029 end
    1030 
    1031 static function prompt_hdf_options(options)
    1032  string &options
    1033 
    1034  string mode = StringByKey("mode", options, ":", ";")
    1035  string reduction_func = StringByKey("reduction_func", options, ":", ";")
    1036 
    1037  string modes = "load_reduced"
    1038  string reduction_functions = adh5_list_reduction_funcs()
    1039 
    1040  if (strlen(mode) == 0)
    1041  mode = StringFromList(0, modes, ";")
    1042  endif
    1043  if (strlen(reduction_func) == 0)
    1044  reduction_func = StringFromList(0, reduction_functions, ";")
    1045  endif
    1046 
    1047  prompt mode, "Mode", popup, modes
    1048  prompt reduction_func, "Reduction Function", popup, reduction_functions
    1049  doprompt "HDF5 Loading Options", mode, reduction_func
    1050 
    1051  if (v_flag == 0)
    1052  options = ReplaceStringByKey("mode", options, mode, ":", ";")
    1053  options = ReplaceStringByKey("reduction_func", options, reduction_func, ":", ";")
    1054  endif
    1055  return v_flag // 0 = OK, 1 = cancel
    1056 end
    1057 
    1070 function prompt_default_process(param)
    1071  string &param
    1072 
    1073  return 0
    1074 end
    1075 
    1076 function prompt_func_params(func_name, func_param)
    1077  string func_name
    1078  string &func_param
    1079 
    1080  string prompt_name = "prompt_" + func_name
    1081  if (exists(prompt_name) == 6)
    1082  funcref prompt_default_process prompt_func = $prompt_name
    1083  return prompt_func(func_param)
    1084  else
    1085  // ignore missing prompt function
    1086  return 0
    1087  endif
    1088 end
    1089 
    1090 static function /df load_pshell_file(filename, [options])
    1091  string filename
    1092  string options
    1093 
    1094  dfref saveDF = GetDataFolderDFR()
    1095  string nickname = ad_suggest_foldername(filename)
    1096  string loaded_filename = ""
    1097 
    1098  if (ParamIsDefault(options))
    1099  loaded_filename = psh5_load_complete(nickname, "pearl_explorer_filepath", filename)
    1100  else
    1101  if (strlen(options) == 0)
    1102  svar pref_options = $(package_path + "s_hdf_options")
    1103  options = pref_options
    1104  if (prompt_hdf_options(options) == 0)
    1105  // OK
    1106  pref_options = options
    1107  else
    1108  // cancel
    1109  options = ""
    1110  endif
    1111  endif
    1112 
    1113  string mode = StringByKey("mode", options, ":", ";")
    1114 
    1115  strswitch(mode)
    1116  case "load_reduced":
    1117  string reduction_func = StringByKey("reduction_func", options, ":", ";")
    1118  svar pref_params = $(package_path + "s_reduction_params")
    1119  string reduction_params = pref_params
    1120  if (prompt_func_params(reduction_func, reduction_params) == 0)
    1121  pref_params = reduction_params
    1122  print reduction_func, reduction_params
    1123  psh5_load_reduced(nickname, "pearl_explorer_filepath", filename, $reduction_func, reduction_params)
    1124  svar s_filepath
    1125  loaded_filename = s_filepath
    1126  endif
    1127  break
    1128  endswitch
    1129  endif
    1130 
    1131  dfref dataDF
    1132  if (strlen(loaded_filename) > 0)
    1133  setdatafolder $("root:" + nickname)
    1134  dataDF = GetDataFolderDFR()
    1135  string /g pearl_explorer_import = "load_pshell_file"
    1136  endif
    1137 
    1138  setdatafolder saveDF
    1139  return dataDF
    1140 end
    1141 
    1142 static function /df load_hdf_file(filename, [options])
    1143  string filename
    1144  string options
    1145 
    1146  dfref saveDF = GetDataFolderDFR()
    1147  string nickname = ad_suggest_foldername(filename)
    1148  string loaded_filename = ""
    1149 
    1150  if (ParamIsDefault(options))
    1151  loaded_filename = adh5_load_complete(nickname, "pearl_explorer_filepath", filename)
    1152  else
    1153  if (strlen(options) == 0)
    1154  svar pref_options = $(package_path + "s_hdf_options")
    1155  options = pref_options
    1156  if (prompt_hdf_options(options) == 0)
    1157  // OK
    1158  pref_options = options
    1159  else
    1160  // cancel
    1161  options = ""
    1162  endif
    1163  endif
    1164 
    1165  string mode = StringByKey("mode", options, ":", ";")
    1166 
    1167  strswitch(mode)
    1168  case "load_reduced":
    1169  string reduction_func = StringByKey("reduction_func", options, ":", ";")
    1170  svar pref_params = $(package_path + "s_reduction_params")
    1171  string reduction_params = pref_params
    1172  if (prompt_func_params(reduction_func, reduction_params) == 0)
    1173  pref_params = reduction_params
    1174  print reduction_func, reduction_params
    1175  loaded_filename = adh5_load_reduced(nickname, "pearl_explorer_filepath", filename, $reduction_func, reduction_params)
    1176  endif
    1177  break
    1178  endswitch
    1179  endif
    1180 
    1181  dfref dataDF
    1182  if (strlen(loaded_filename) > 0)
    1183  setdatafolder $("root:" + nickname)
    1184  dataDF = GetDataFolderDFR()
    1185  string /g pearl_explorer_import = "load_hdf_file"
    1186  endif
    1187 
    1188  setdatafolder saveDF
    1189  return dataDF
    1190 end
    1191 
    1192 static function /df load_itx_file(filename, [options])
    1193  string filename
    1194  string options
    1195 
    1196  dfref saveDF = GetDataFolderDFR()
    1197  string nickname = itx_suggest_foldername(filename)
    1198 
    1199  if (ParamIsDefault(options))
    1200  options = ""
    1201  endif
    1202 
    1203  setdatafolder root:
    1204  newdatafolder /s/o $("root:" + nickname)
    1205  dfref dataDF = GetDataFolderDFR()
    1206 
    1207  // note: some versions of PEARL data files save data to a new data folder,
    1208  // and leave the newly created folder as the current folder.
    1209  // the free data folder is used by those files which don't create their own data folder.
    1210  // this is the new recommended behaviour
    1211 
    1212  LoadWave /t/p=pearl_explorer_filepath/q filename
    1213  svar waves = s_wavenames
    1214  dfref actDF = GetDataFolderDFR()
    1215  if (v_flag > 0)
    1216  string /g pearl_explorer_import = "load_itx_file"
    1217  endif
    1218 
    1219  if (!DataFolderRefsEqual(actDF, dataDF))
    1220  // the file created its own data folder.
    1221  // let's kill the pre-allocated folder
    1222  setdatafolder dataDF
    1223  if (ItemsInList(WaveList("*", ";", ""), ";") == 0)
    1224  killdatafolder /z dataDF
    1225  endif
    1226  endif
    1227 
    1228  setdatafolder saveDF
    1229  return actDF
    1230 end
    1231 
    1235 static function /df load_mtrx_file(filename, [options])
    1236  string filename
    1237  string options
    1238 
    1239  dfref saveDF = GetDataFolderDFR()
    1240  dfref dataDF = $""
    1241 
    1242 #if exists("MFR_OpenResultFile")
    1243  setdatafolder root:
    1244  string datasets = ""
    1245  datasets = mtrx_load_file("pearl_explorer_filepath", filename)
    1246  if (strlen(datasets) > 0)
    1247  string /g pearl_explorer_import = "load_mtrx_file"
    1248  string s1 = StringFromList(0, datasets)
    1249  wave w1 = $s1
    1250  dataDF = GetWavesDataFolderDFR(w1)
    1251  endif
    1252 #endif
    1253 
    1254  setdatafolder saveDF
    1255  return dataDF
    1256 end
    1257 
    1258 function /s itx_suggest_foldername(filename, [ignoredate,sourcename,unique])
    1259  // suggests the name of a data folder based on a file name
    1260  // if the file name follows the naming convention source-date-index.extension,
    1261  // the function tries to generate the nick name as source_date_index.
    1262  // otherwise it's just a cleaned up version of the file name.
    1263  string filename // file name, including extension. can also include a folder path (which is ignored)
    1264  // the extension is currently ignored, but may be used later to select the parent folder
    1265  variable ignoredate // if non-zero, the nick name will not include the date part
    1266  // defaults to zero
    1267  string sourcename // nick name of the data source
    1268  // the function tries to detect the source from the file name
    1269  // this option can be used to override auto-detection
    1270  // allowed values: sscan, otf
    1271  variable unique // if non-zero, the resulting name is made a unique data folder name in the current data folder
    1272  // defaults to zero
    1273 
    1274  if (ParamIsDefault(ignoredate))
    1275  ignoredate = 0
    1276  endif
    1277  if (ParamIsDefault(unique))
    1278  unique = 0
    1279  endif
    1280 
    1281  string basename = ParseFilePath(3, filename, ":", 0, 0)
    1282  string extension = ParseFilePath(4, filename, ":", 0, 0)
    1283  string nickname
    1284 
    1285  string autosource
    1286  if (strsearch(basename, "X03DA_PC", 0, 2) >= 0)
    1287  autosource = "sscan"
    1288  basename = ReplaceString("_", basename, "-")
    1289  ignoredate = 1
    1290  elseif (strsearch(basename, "otf", 0, 2) >= 0)
    1291  autosource = "otf"
    1292  endif
    1293  if (ParamIsDefault(sourcename))
    1294  sourcename = autosource
    1295  endif
    1296 
    1297  variable nparts = ItemsInList(basename, "-")
    1298  if (nparts >= 3)
    1299  string datepart = StringFromList(nparts - 2, basename, "-")
    1300  string indexpart = StringFromList(nparts - 1, basename, "-")
    1301  if (ignoredate)
    1302  sprintf nickname, "%s_%s", sourcename, indexpart
    1303  else
    1304  sprintf nickname, "%s_%s_%s", sourcename, datepart, indexpart
    1305  endif
    1306  else
    1307  nickname = PearlCleanupName(basename)
    1308  endif
    1309 
    1310  if (unique && CheckName(nickname, 11))
    1311  nickname = UniqueName(nickname + "_", 11, 0)
    1312  endif
    1313 
    1314  return nickname
    1315 end
    1316 
    1317 Window PearlDataExplorer() : Panel
    1318  PauseUpdate; Silent 1 // building window...
    1319  NewPanel /K=1 /W=(800,0,1530,444) as "PEARL Data Explorer"
    1320  ModifyPanel cbRGB=(48640,56832,60160)
    1321 
    1322  GroupBox gb_filepath,pos={8,4},size={224,52},title="file system folder"
    1323  TitleBox tb_filepath,pos={20,24},size={174,20},frame=2
    1324  TitleBox tb_filepath,variable=root:packages:pearl_explorer:s_filepath,fixedSize=1
    1325  Button b_browse_filepath,pos={200,24},size={20,20},proc=PearlDataExplorer#bp_browse_filepath,title="..."
    1326  Button b_browse_filepath,fColor=(65280,48896,32768)
    1327 
    1328  GroupBox gb_prefs,pos={240,4},size={58,52},title="prefs",help={"explorer package preferences"}
    1329  Button b_save_prefs,pos={252,20},size={32,17},proc=PearlDataExplorer#bp_save_prefs,title="save"
    1330  Button b_save_prefs,help={"save preferences of the data explorer package (data file path, attributes filter)"}
    1331  Button b_save_prefs,fColor=(65280,48896,32768)
    1332  Button b_load_prefs,pos={252,36},size={32,17},proc=PearlDataExplorer#bp_load_prefs,title="load"
    1333  Button b_load_prefs,help={"load preferences of the data explorer package"}
    1334  Button b_load_prefs,fColor=(65280,48896,32768)
    1335 
    1336  GroupBox gb_filelist,pos={8,64},size={224,372},title="data files"
    1337  ListBox lb_files,pos={20,84},size={200,212},proc=PearlDataExplorer#lbp_filelist
    1338  ListBox lb_files,listWave=root:packages:pearl_explorer:wtFiles
    1339  ListBox lb_files,selWave=root:packages:pearl_explorer:wSelectedFiles,row= 11,mode= 4
    1340  TitleBox tb_file_info,pos={20,300},size={198,78},frame=2,fixedSize=1
    1341  TitleBox tb_file_info,variable= root:packages:pearl_explorer:s_file_info
    1342 
    1343  Button b_update_filelist,pos={20,386},size={60,20},proc=PearlDataExplorer#bp_update_filelist,title="update list"
    1344  Button b_update_filelist,fColor=(65280,48896,32768)
    1345  CheckBox cb_file_preview,pos={84,390},size={60,20},title="preview"
    1346  CheckBox cb_file_preview,help={"enable/disable automatic preview window when selecting a data file"}
    1347  CheckBox cb_file_preview,value=1
    1348  Button b_file_prev,pos={176,386},size={20,20},proc=PearlDataExplorer#bp_file_prev,title="\\W646"
    1349  Button b_file_prev,help={"previous file"}
    1350  Button b_file_prev,fColor=(65280,48896,32768)
    1351  Button b_file_next,pos={200,386},size={20,20},proc=PearlDataExplorer#bp_file_next,title="\\W649"
    1352  Button b_file_next,help={"next file"}
    1353  Button b_file_next,fColor=(65280,48896,32768)
    1354 
    1355  Button b_load_files,pos={20,410},size={76,20},proc=PearlDataExplorer#bp_load_files,title="load complete"
    1356  Button b_load_files,help={"load the complete contents from the selected files"}
    1357  Button b_load_files,fColor=(65280,48896,32768)
    1358  Button b_load_files_opt,pos={100,410},size={76,20},proc=PearlDataExplorer#bp_load_files_opt,title="load reduced"
    1359  Button b_load_files_opt,help={"load data from the selected files with options (reduced dimensions)"}
    1360  Button b_load_files_opt,fColor=(65280,48896,32768)
    1361 
    1362  // datasets group
    1363  GroupBox gb_datasets,pos={240,64},size={224,372},title="datasets"
    1364  ListBox lb_datasets,pos={252,84},size={200,300},proc=PearlDataExplorer#lbp_datasets,help={"list of loaded datasets"}
    1365  ListBox lb_datasets,listWave=root:packages:pearl_explorer:wtDatasets
    1366  ListBox lb_datasets,selWave=root:packages:pearl_explorer:wSelectedDatasets,mode= 1
    1367  ListBox lb_datasets,selRow= -1
    1368 
    1369  Button b_update_datasets,pos={252,386},size={60,20},proc=PearlDataExplorer#bp_update_datasets,title="update list"
    1370  Button b_update_datasets,help={"update the list of datasets"}
    1371  Button b_update_datasets,fColor=(65280,48896,32768)
    1372  CheckBox cb_dataset_preview,pos={316,390},size={60,20},title="preview"
    1373  CheckBox cb_dataset_preview,help={"enable/disable automatic preview window when selecting a dataset"}
    1374  CheckBox cb_dataset_preview,value=0
    1375  Button b_dataset_prev,pos={408,386},size={20,20},proc=PearlDataExplorer#bp_dataset_prev,title="\\W646"
    1376  Button b_dataset_prev,help={"goto previous dataset"}
    1377  Button b_dataset_prev,fColor=(65280,48896,32768)
    1378  Button b_dataset_next,pos={432,386},size={20,20},proc=PearlDataExplorer#bp_dataset_next,title="\\W649"
    1379  Button b_dataset_next,help={"goto next dataset"}
    1380  Button b_dataset_next,fColor=(65280,48896,32768)
    1381 
    1382  Button b_dataset_folder,pos={252,410},size={50,20},proc=PearlDataExplorer#bp_dataset_folder,title="goto DF"
    1383  Button b_dataset_folder,help={"set the current data folder of the selected dataset"}
    1384  Button b_dataset_folder,fColor=(65280,48896,32768)
    1385  Button b_dataset_display,pos={306,410},size={50,20},proc=PearlDataExplorer#bp_dataset_display,title="display"
    1386  Button b_dataset_display,help={"display the selected dataset in its own window"}
    1387  Button b_dataset_display,fColor=(65280,48896,32768)
    1388 
    1389  GroupBox gb_preview,pos={472,4},size={250,52},title="preview"
    1390  TitleBox tb_preview_file,pos={484,24},size={226,20},frame=2
    1391  TitleBox tb_preview_file,variable=root:packages:pearl_explorer:s_preview_file,fixedSize=1
    1392 
    1393  GroupBox gb_attributes,pos={472,64},size={250,372},title="attributes"
    1394  Button b_attr_notebook,pos={484,386},size={60,20},proc=PearlDataExplorer#bp_attr_notebook,title="notebook"
    1395  Button b_attr_notebook,help={"show attribute list in a notebook"}
    1396  Button b_attr_notebook,fColor=(65280,48896,32768)
    1397 
    1398  String fldrSav0= GetDataFolder(1)
    1399  SetDataFolder root:packages:pearl_explorer:
    1400  Edit/W=(484,84,710,384)/HOST=# attr_names,attr_values
    1401  ModifyTable format(Point)=1,width(Point)=0,width(attr_names)=103,width(attr_values)=103
    1402  ModifyTable statsArea=85
    1403  SetDataFolder fldrSav0
    1404  RenameWindow #,T0
    1405  SetActiveSubwindow ##
    1406 EndMacro
    1407 
    1408 static function bp_load_prefs(ba) : ButtonControl
    1409  STRUCT WMButtonAction &ba
    1410 
    1411  switch( ba.eventCode )
    1412  case 2: // mouse up
    1413  load_prefs()
    1414  break
    1415  case -1: // control being killed
    1416  break
    1417  endswitch
    1418 
    1419  return 0
    1420 End
    1421 
    1422 static function bp_save_prefs(ba) : ButtonControl
    1423  STRUCT WMButtonAction &ba
    1424 
    1425  switch( ba.eventCode )
    1426  case 2: // mouse up
    1427  save_prefs()
    1428  break
    1429  case -1: // control being killed
    1430  break
    1431  endswitch
    1432 
    1433  return 0
    1434 End
    1435 
    1436 static function bp_browse_filepath(ba) : ButtonControl
    1437  STRUCT WMButtonAction &ba
    1438 
    1439  dfref saveDF = GetDataFolderDFR()
    1440 
    1441  switch( ba.eventCode )
    1442  case 2: // mouse up
    1443  PathInfo /S pearl_explorer_filepath
    1444  NewPath /M="select data file folder" /O/Z pearl_explorer_filepath
    1445  if (v_flag == 0)
    1446  PathInfo /S pearl_explorer_filepath
    1447  svar filepath = $(package_path + "s_filepath")
    1448  filepath = s_path
    1449  update_filelist()
    1450  endif
    1451  break
    1452  case -1: // control being killed
    1453  break
    1454  endswitch
    1455 
    1456  setdatafolder saveDF
    1457  return 0
    1458 End
    1459 
    1460 static function bp_update_filelist(ba) : ButtonControl
    1461  STRUCT WMButtonAction &ba
    1462 
    1463  switch( ba.eventCode )
    1464  case 2: // mouse up
    1465  update_filelist()
    1466  break
    1467  case -1: // control being killed
    1468  break
    1469  endswitch
    1470 
    1471  return 0
    1472 End
    1473 
    1474 static function bp_load_files(ba) : ButtonControl
    1475  STRUCT WMButtonAction &ba
    1476 
    1477  switch( ba.eventCode )
    1478  case 2: // mouse up
    1480  break
    1481  case -1: // control being killed
    1482  break
    1483  endswitch
    1484 
    1485  return 0
    1486 End
    1487 
    1488 static function bp_load_files_opt(ba) : ButtonControl
    1489  STRUCT WMButtonAction &ba
    1490 
    1491  switch( ba.eventCode )
    1492  case 2: // mouse up
    1493  load_selected_files(options="")
    1494  break
    1495  case -1: // control being killed
    1496  break
    1497  endswitch
    1498 
    1499  return 0
    1500 End
    1501 
    1502 static function bp_file_next(ba) : ButtonControl
    1503  STRUCT WMButtonAction &ba
    1504 
    1505  dfref saveDF = GetDataFolderDFR()
    1506 
    1507  switch( ba.eventCode )
    1508  case 2: // mouse up
    1509  setdatafolder $package_path
    1510  wave /t wtFiles
    1511  wave wSelectedFiles
    1512  FindValue /i=1 wSelectedFiles
    1513  v_value += 1
    1514  if (v_value >= numpnts(wtFiles))
    1515  v_value = min(numpnts(wtFiles) - 1, 0)
    1516  endif
    1517  wSelectedFiles = p == v_value
    1518  if (v_value >= 0)
    1519  variable ifile = v_value
    1520  ControlInfo /W=PearlDataExplorer cb_file_preview
    1521  if (v_value)
    1522  preview_file(wtFiles[ifile])
    1523  endif
    1524  endif
    1525  break
    1526  case -1: // control being killed
    1527  break
    1528  endswitch
    1529 
    1530  setdatafolder saveDF
    1531  return 0
    1532 End
    1533 
    1534 static function bp_file_prev(ba) : ButtonControl
    1535  STRUCT WMButtonAction &ba
    1536 
    1537  dfref saveDF = GetDataFolderDFR()
    1538 
    1539  switch( ba.eventCode )
    1540  case 2: // mouse up
    1541  setdatafolder $package_path
    1542  wave /t wtFiles
    1543  wave wSelectedFiles
    1544  FindValue /i=1 wSelectedFiles
    1545  v_value -= 1
    1546  if (v_value < 0)
    1547  v_value = numpnts(wtFiles) - 1
    1548  endif
    1549  wSelectedFiles = p == v_value
    1550  if (v_value >= 0)
    1551  variable ifile = v_value
    1552  ControlInfo /W=PearlDataExplorer cb_file_preview
    1553  if (v_value)
    1554  preview_file(wtFiles[ifile])
    1555  endif
    1556  endif
    1557  break
    1558  case -1: // control being killed
    1559  break
    1560  endswitch
    1561 
    1562  setdatafolder saveDF
    1563  return 0
    1564 End
    1565 
    1566 static function lbp_filelist(lba) : ListBoxControl
    1567  STRUCT WMListboxAction &lba
    1568 
    1569  Variable row = lba.row
    1570  Variable col = lba.col
    1571  WAVE/T/Z listWave = lba.listWave
    1572  WAVE/Z selWave = lba.selWave
    1573 
    1574  switch( lba.eventCode )
    1575  case -1: // control being killed
    1576  break
    1577  case 1: // mouse down
    1578  if (selWave[row])
    1579  ControlInfo /W=PearlDataExplorer cb_file_preview
    1580  if (v_value)
    1581  preview_file(listWave[row])
    1582  endif
    1583  endif
    1584  break
    1585  case 3: // double click
    1586  break
    1587  case 4: // cell selection
    1588  case 5: // cell selection plus shift key
    1589  break
    1590  case 6: // begin edit
    1591  break
    1592  case 7: // finish edit
    1593  break
    1594  case 13: // checkbox clicked (Igor 6.2 or later)
    1595  break
    1596  endswitch
    1597 
    1598  return 0
    1599 End
    1600 
    1601 static function bp_update_datasets(ba) : ButtonControl
    1602  STRUCT WMButtonAction &ba
    1603 
    1604  switch( ba.eventCode )
    1605  case 2: // mouse up
    1606  update_datasets()
    1607  break
    1608  case -1: // control being killed
    1609  break
    1610  endswitch
    1611 
    1612  return 0
    1613 End
    1614 
    1615 static function bp_dataset_folder(ba) : ButtonControl
    1616  STRUCT WMButtonAction &ba
    1617 
    1618  switch( ba.eventCode )
    1619  case 2: // mouse up
    1620  ControlInfo /W=PearlDataExplorer lb_datasets
    1621  if (v_value >= 0)
    1622  setdatafolder $package_path
    1623  wave /t wtDatasets
    1624  string dataset = wtDatasets[v_value]
    1625  string cmd
    1626  sprintf cmd, "setdatafolder root:%s", PossiblyQuoteName(dataset)
    1627  execute /q /z cmd
    1628  cmd = "setdatafolder :scan1"
    1629  execute /q /z cmd
    1630  sprintf cmd, "setdatafolder %s", GetDataFolder(1)
    1631  print cmd
    1632  endif
    1633  break
    1634  case -1: // control being killed
    1635  break
    1636  endswitch
    1637 
    1638  return 0
    1639 End
    1640 
    1641 static function bp_dataset_display(ba) : ButtonControl
    1642  STRUCT WMButtonAction &ba
    1643 
    1644  switch( ba.eventCode )
    1645  case 2: // mouse up
    1646  ControlInfo /W=PearlDataExplorer lb_datasets
    1647  if (v_value >= 0)
    1648  setdatafolder $package_path
    1649  wave /t wtDatasets
    1650  string dataset = wtDatasets[v_value]
    1651  display_dataset(dataset)
    1652  endif
    1653  break
    1654  case -1: // control being killed
    1655  break
    1656  endswitch
    1657 
    1658  return 0
    1659 End
    1660 
    1661 static function bp_dataset_next(ba) : ButtonControl
    1662  STRUCT WMButtonAction &ba
    1663 
    1664  switch( ba.eventCode )
    1665  case 2: // mouse up
    1666  ControlInfo /W=PearlDataExplorer lb_datasets
    1667  wave /t wtDatasets = $(s_datafolder + s_value)
    1668  v_value += 1
    1669  if (v_value >= numpnts(wtDatasets))
    1670  v_value = min(0, numpnts(wtDatasets) - 1)
    1671  endif
    1672  ListBox lb_datasets win=PearlDataExplorer, selRow=v_value
    1673  if (v_value >= 0)
    1674  variable ids = v_value
    1675  ControlInfo /W=PearlDataExplorer cb_dataset_preview
    1676  if (v_value)
    1677  preview_dataset(wtDatasets[ids])
    1678  endif
    1679  endif
    1680  break
    1681  case -1: // control being killed
    1682  break
    1683  endswitch
    1684 
    1685  return 0
    1686 End
    1687 
    1688 static function bp_dataset_prev(ba) : ButtonControl
    1689  STRUCT WMButtonAction &ba
    1690 
    1691  switch( ba.eventCode )
    1692  case 2: // mouse up
    1693  ControlInfo /W=PearlDataExplorer lb_datasets
    1694  wave /t wtDatasets = $(s_datafolder + s_value)
    1695  v_value -= 1
    1696  if (v_value < 0)
    1697  v_value = max(-1, numpnts(wtDatasets) - 1)
    1698  endif
    1699  ListBox lb_datasets win=PearlDataExplorer, selRow=v_value
    1700  if (v_value >= 0)
    1701  variable ids = v_value
    1702  ControlInfo /W=PearlDataExplorer cb_dataset_preview
    1703  if (v_value)
    1704  preview_dataset(wtDatasets[ids])
    1705  endif
    1706  endif
    1707  break
    1708  case -1: // control being killed
    1709  break
    1710  endswitch
    1711 
    1712  return 0
    1713 End
    1714 
    1715 static function lbp_datasets(lba) : ListBoxControl
    1716  STRUCT WMListboxAction &lba
    1717 
    1718  Variable row = lba.row
    1719  Variable col = lba.col
    1720  WAVE/T/Z listWave = lba.listWave
    1721  WAVE/Z selWave = lba.selWave
    1722 
    1723  switch( lba.eventCode )
    1724  case -1: // control being killed
    1725  break
    1726  case 1: // mouse down
    1727  if (row >= 0)
    1728  ControlInfo /W=PearlDataExplorer cb_dataset_preview
    1729  if (v_value)
    1730  preview_dataset(listWave[row])
    1731  endif
    1732  endif
    1733  break
    1734  case 3: // double click
    1735  break
    1736  case 4: // cell selection
    1737  case 5: // cell selection plus shift key
    1738  break
    1739  case 6: // begin edit
    1740  break
    1741  case 7: // finish edit
    1742  break
    1743  case 13: // checkbox clicked (Igor 6.2 or later)
    1744  break
    1745  endswitch
    1746 
    1747  return 0
    1748 End
    1749 
    1750 static function bp_attr_notebook(ba) : ButtonControl
    1751  STRUCT WMButtonAction &ba
    1752 
    1753  dfref saveDF = GetDataFolderDFR()
    1754 
    1755  switch( ba.eventCode )
    1756  case 2: // mouse up
    1757  setdatafolder $package_path
    1758  svar s_preview_file
    1759  wave /t /z attr_names
    1760  wave /t /z attr_values
    1761  if (WaveExists(attr_names))
    1762  attributes_notebook(attr_names, attr_values, s_preview_file)
    1763  endif
    1764  break
    1765  case -1: // control being killed
    1766  break
    1767  endswitch
    1768 
    1769  setdatafolder saveDF
    1770  return 0
    1771 End
    static dfr load_mtrx_file(string filename, string options=defaultValue)
    load a matrix (STM) data file
    -
    static const string package_path
    -
    string adh5_load_preview(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    load a single image from a HDF5 file created by the Area Detector software.
    -
    static variable update_datasets()
    -
    string psh5_load_reduced(string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue)
    load and reduce the ScientaImage dataset of the first scan of a PShell data file. ...
    -
    static variable bp_browse_filepath(WMButtonAction *ba)
    -
    static variable preview_file(string filename)
    -
    variable prompt_default_process(string *param)
    prototype for prompting for processing function parameters.
    -
    string adh5_load_info(string APathName, string AFileName)
    load descriptive info from a HDF5 file created by the Area Detector software.
    -
    static variable bp_dataset_prev(WMButtonAction *ba)
    -
    static string display_preview_trace(wave xtrace, wave ytrace)
    -
    static variable bp_file_prev(WMButtonAction *ba)
    -
    variable ad_brick_slicer(wave data)
    open a slicer panel for 3D data.
    -
    interface for writing ELOG entries with Igor graphs as attachment.
    -
    static variable lbp_datasets(WMListboxAction *lba)
    -
    static variable bp_load_files_opt(WMButtonAction *ba)
    -
    static variable load_selected_files(string options=defaultValue)
    -
    string PearlCleanupName(string name)
    -
    static variable bp_load_files(WMButtonAction *ba)
    -
    static variable preview_datafolder()
    -
    static variable bp_file_next(WMButtonAction *ba)
    -
    static variable lbp_filelist(WMListboxAction *lba)
    -
    static variable prompt_hdf_options(string *options)
    -
    static variable bp_update_datasets(WMButtonAction *ba)
    -
    static const string ks_filematch_pshell
    -
    static const string ks_filematch_adh5
    -
    static wave preview_mtrx_file(string filename)
    load the preview of a Matrix STM file.
    -
    static variable init_package()
    initialize the global variables of the data explorer.
    -
    static wave preview_pshell_file(string filename)
    load the preview of a PShell HDF5 file.
    -
    static variable bp_dataset_folder(WMButtonAction *ba)
    -
    static variable preview_dataset(string datasetname)
    -
    static const string package_name
    -
    static variable update_filelist()
    read a list of PEARL files from the file system
    -
    static dfr load_itx_file(string filename, string options=defaultValue)
    -
    string psh5_load_preview(string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue, string pref_scans=defaultValue, string pref_datasets=defaultValue)
    load a preview image from a PShell data file.
    -
    static variable bp_attr_notebook(WMButtonAction *ba)
    -
    static variable load_file(string filename, string options=defaultValue)
    -
    preview and import panel for PEARL data
    -
    static variable bp_load_prefs(WMButtonAction *ba)
    -
    static variable preview_setscale_x(wave data, wave preview)
    -
    static variable bp_save_prefs(WMButtonAction *ba)
    -
    static dfr load_hdf_file(string filename, string options=defaultValue)
    -
    string ad_suggest_foldername(string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
    generate the name of a data folder based on a file name.
    -
    static wave preview_hdf_file(string filename)
    load the preview of a PEARL HDF5 file.
    -
    static variable pearl_file_type(string filename)
    check whether a file can be imported by this module.
    -
    static variable bp_dataset_display(WMButtonAction *ba)
    -
    static const string ks_filematch_itx
    -
    string adh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    import everything from a HDF5 file created by the Area Detector software.
    -
    static variable bp_dataset_next(WMButtonAction *ba)
    -
    static variable extract_preview_image(wave data, wave preview)
    -
    string psh5_load_info(string APathName, string AFileName)
    load descriptive info from a PShell data file.
    -
    string adh5_load_reduced(string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable load_data=defaultValue, variable load_attr=defaultValue, variable progress=defaultValue)
    load and reduce a dataset from a HDF5 file created by the Area Detector software. ...
    -
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    -
    static variable bp_update_filelist(WMButtonAction *ba)
    -
    variable pearl_data_explorer()
    -
    string itx_suggest_foldername(string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
    -
    string psh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    load everything from a PShell data file.
    -
    static variable load_prefs()
    -
    variable prompt_func_params(string func_name, string *func_param)
    -
    static wave preview_itx_file(string filename)
    load the preview of a general ITX file.
    -
    static variable display_dataset(string datasetname)
    -
    static dfr load_pshell_file(string filename, string options=defaultValue)
    -
    static variable save_prefs()
    save persistent package data to the preferences file.
    -
    variable test_attributes_notebook()
    -
    static string show_preview_graph(wave data, wave xdata=defaultValue)
    -
    string mtrx_load_preview(string destName, string pathName, string fileName, string traces=defaultValue)
    load a preview image from a Matrix data file.
    -
    string ad_display_slice(wave data)
    display three-dimensional data by 2D slice.
    -
    static const string ks_filematch_mtrx
    -
    static variable attributes_notebook(wave attr_names, wave attr_values, string title)
    -
    string mtrx_load_file(string pathName, string fileName, string traces=defaultValue)
    load all data from a Matrix data file.
    -
    static variable preview_attributes(dfref attr_folder, dfref dest_folder=defaultValue, wave attr_filter=defaultValue, variable include_datawaves=defaultValue, variable include_infowaves=defaultValue)
    -
    string adh5_list_reduction_funcs()
    get a list of functions which can be used as reduction functions.
    -
    static variable notebook_add_attributes(string notebook_name, wave attr_filter, wave attr_names, wave attr_values)
    -
    threadsafe wave ad_extract_slab(wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable pscale=defaultValue)
    2D cut through 3D dataset, integrate in normal dimension
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.36
    +
    4 #pragma ModuleName = PearlDataExplorer
    +
    5 #pragma version = 2.1
    +
    6 #include <HierarchicalListWidget>, version >= 1.14
    +
    7 #include "pearl-area-import"
    +
    8 #include "pearl-area-profiles"
    +
    9 #include "pearl-area-display"
    +
    10 #include "pearl-compat"
    +
    11 #include "pearl-pshell-import"
    +
    12 
    +
    13 // copyright (c) 2013-22 Paul Scherrer Institut
    +
    14 //
    +
    15 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    16 // you may not use this file except in compliance with the License.
    +
    17 // You may obtain a copy of the License at
    +
    18 // http:///www.apache.org/licenses/LICENSE-2.0
    +
    19 
    +
    29 
    +
    34 
    +
    35 static strconstant package_name = "pearl_explorer"
    +
    36 static strconstant package_path = "root:packages:pearl_explorer:"
    +
    37 
    +
    38 static strconstant ks_filematch_adh5 = "*.h5"
    +
    39 static strconstant ks_filematch_pshell = "psh*.h5"
    +
    40 static strconstant ks_filematch_itx = "*.itx"
    +
    41 
    + +
    48  DoWindow /HIDE=0 /F PearlDataExplorer
    +
    49  if (v_flag == 0)
    +
    50  init_package()
    +
    51  load_prefs()
    +
    52  execute /q/z "PearlDataExplorer()"
    +
    53  MakeListIntoHierarchicalList("PearlDataExplorer", "lb_contents", "PearlDataExplorer#hlp_contents_open", selectionMode=WMHL_SelectionNonContinguous, pathSeparator="/")
    +
    54  WMHL_AddColumns("PearlDataExplorer", "lb_contents", 1)
    +
    55  WMHL_SetNotificationProc("PearlDataExplorer", "lb_contents", "PearlDataExplorer#hlp_contents_selection", WMHL_SetSelectNotificationProc)
    +
    56  ListBox lb_contents win=PearlDataExplorer, widths={6,60,20}
    + +
    58  endif
    +
    59 end
    +
    60 
    +
    61 static function init_package()
    +
    62  dfref save_df = GetDataFolderDFR()
    +
    63  SetDataFolder root:
    +
    64  newdatafolder /o/s packages
    +
    65  newdatafolder /o/s $package_name
    +
    66  if (exists("v_InitPanelDone") == 2)
    +
    67  SetDataFolder save_df
    +
    68  return 0
    +
    69  endif
    +
    70 
    +
    71  make /o/n=0/t wtFiles
    +
    72  make /o/n=0/i wSelectedFiles,wSelectedDatasets
    +
    73  make /o/n=0/t wtDatasets
    +
    74  make /o/n=0/t wtPositioners,wtDetectors
    +
    75  make /o/n=0/i wSelectedPositioners,wSelectedDetectors
    +
    76 
    +
    77  make /o/n=(1,1) preview_image // preview 2D data
    +
    78  make /o/n=0 preview_trace // preview 1D data
    +
    79  make /o/n=0/t attr_names, attr_values, attr_filter, attr_filter_summary
    +
    80 
    +
    81  // persistent strings and variables. persistent = saved in preferences
    +
    82  string /g s_filepath = "" // directory path to be listed
    +
    83  string /g s_hdf_options = "" // recently used HDF5 load options
    +
    84  string /g s_reduction_params = "" // recently used reduction parameters
    +
    85  string /g s_preview_pvs = "" // semicolon-separated list of EPICS PVs to display in preview.
    +
    86  // the list items can contain wildcards for StringMatch
    +
    87  s_preview_pvs = "*OP:CURRENT*;*Stats*Total*;*KEITHLEY*READOUT;*CADC*"
    +
    88 
    +
    89  redimension /n=26 attr_filter_summary
    +
    90  attr_filter_summary[0] = "MonoEnergy"
    +
    91  attr_filter_summary[1] = "MonoGrating"
    +
    92  attr_filter_summary[2] = "ExitSlit"
    +
    93  attr_filter_summary[3] = "FrontendHSize"
    +
    94  attr_filter_summary[4] = "FrontendVSize"
    +
    95  attr_filter_summary[5] = "ManipulatorPhi"
    +
    96  attr_filter_summary[6] = "ManipulatorTheta"
    +
    97  attr_filter_summary[7] = "ManipulatorTilt"
    +
    98  attr_filter_summary[8] = "ManipulatorX"
    +
    99  attr_filter_summary[9] = "ManipulatorY"
    +
    100  attr_filter_summary[10] = "ManipulatorZ"
    +
    101  attr_filter_summary[11] = "PassEnergy"
    +
    102  attr_filter_summary[12] = "LensMode"
    +
    103  attr_filter_summary[13] = "ScientaDwellTime"
    +
    104  attr_filter_summary[14] = "ScientaCenterEnergy"
    +
    105  attr_filter_summary[15] = "ScientaChannelBegin"
    +
    106  attr_filter_summary[16] = "ScientaChannelEnd"
    +
    107  attr_filter_summary[17] = "ScientaSliceBegin"
    +
    108  attr_filter_summary[18] = "ScientaSliceEnd"
    +
    109  attr_filter_summary[19] = "ScientaNumChannels"
    +
    110  attr_filter_summary[20] = "StepSize"
    +
    111  attr_filter_summary[21] = "ScientaNumSlices"
    +
    112  attr_filter_summary[22] = "ManipulatorTempA"
    +
    113  attr_filter_summary[23] = "ManipulatorTempB"
    +
    114  attr_filter_summary[24] = "RefCurrent"
    +
    115  attr_filter_summary[25] = "SampleCurrent"
    +
    116 
    +
    117  // non-persistent strings and variables
    +
    118  string /g s_short_filepath = "" // abbreviated directory path
    +
    119  string /g s_selected_file = ""
    +
    120  string /g s_selected_dataset = ""
    +
    121  string /g s_preview_file = "" // file or folder name of the current preview
    +
    122  string /g s_preview_source = "" // data source, e.g. EPICS channel name, of the current preview
    +
    123  string /g s_profiles_graph = "" // window name of the current preview if the data is two-dimensional
    +
    124  string /g s_preview_trace_graph = "" // window name of the current preview if the data is one-dimensional
    +
    125  string /g s_preview_graph = "" // window name of the most recent preview graph
    +
    126  string /g s_file_info = "" // description of selected file
    +
    127  string /g s_result = "" // result of last operation
    +
    128 
    +
    129  variable/g v_InitPanelDone = 1
    +
    130 
    +
    131  SetDataFolder save_df
    +
    132 end
    +
    133 
    +
    139 static function save_prefs()
    +
    140  dfref save_df = GetDataFolderDFR()
    +
    141  dfref df = $package_path
    +
    142  if (DataFolderRefStatus(df) == 1)
    +
    143  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    +
    144  fullPath += package_name
    +
    145  NewPath/O/C/Q tempPackagePrefsPath, fullPath
    +
    146  fullPath += ":preferences.pxp"
    +
    147  SetDataFolder df
    +
    148  string objects = "attr_filter;attr_filter_summary;s_filepath;s_hdf_options;s_reduction_params;s_preview_pvs"
    +
    149  SaveData /O /Q /J=objects fullPath
    +
    150  KillPath/Z tempPackagePrefsPath
    +
    151  endif
    +
    152  SetDataFolder save_df
    +
    153 end
    +
    154 
    +
    155 static function load_prefs()
    +
    156  // loads persistent package data from the preferences file
    +
    157  // the preferences file is an Igor packed experiment file in a special preferences folder
    +
    158  dfref save_df = GetDataFolderDFR()
    +
    159 
    +
    160  variable result = -1
    +
    161  setdatafolder root:
    +
    162  NewDataFolder /O/S packages
    +
    163  NewDataFolder /O/S $package_name
    +
    164  dfref package_df = GetDataFolderDFR()
    +
    165  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    +
    166  fullPath += package_name
    +
    167 
    +
    168  GetFileFolderInfo /Q /Z fullPath
    +
    169  if (V_Flag == 0) // Disk directory exists?
    +
    170  fullPath += ":preferences.pxp"
    +
    171  GetFileFolderInfo /Q /Z fullPath
    +
    172  if (V_Flag == 0) // Preference file exist?
    +
    173  LoadData /O /R /Q fullPath
    +
    174  result = 0
    +
    175  endif
    +
    176  endif
    +
    177 
    +
    178  if (result == 0)
    +
    179  svar /sdfr=package_df filepath = s_filepath
    +
    180  NewPath /O/Z pearl_explorer_filepath, filepath
    + + +
    183  endif
    +
    184 
    +
    185  SetDataFolder save_df
    +
    186  return result
    +
    187 end
    +
    188 
    +
    199 static function pearl_file_type(filename)
    +
    200  string filename
    +
    201 
    +
    202  if (StringMatch(filename, ks_filematch_pshell))
    +
    203  return 1
    +
    204  elseif (StringMatch(filename, ks_filematch_adh5))
    +
    205  return 2
    +
    206  elseif (StringMatch(filename, ks_filematch_itx))
    +
    207  return 3
    +
    208  else
    +
    209  return 0
    +
    210  endif
    +
    211 end
    +
    212 
    +
    218 static function update_filepath()
    +
    219  PathInfo /S pearl_explorer_filepath
    +
    220  svar filepath = $(package_path + "s_filepath")
    +
    221  svar shortpath = $(package_path + "s_short_filepath")
    +
    222  filepath = s_path
    +
    223  shortpath = shorten_filepath(filepath, 40)
    +
    224 end
    +
    225 
    +
    231 static function update_filelist()
    +
    232  dfref save_df = GetDataFolderDFR()
    +
    233 
    +
    234  string all_files
    +
    235  wave /t wtFiles = $(package_path + "wtFiles")
    +
    236  wave wSelectedFiles = $(package_path + "wSelectedFiles")
    +
    237  variable nn
    +
    238 
    +
    239  PathInfo pearl_explorer_filepath
    +
    240  if (v_flag == 1)
    +
    241  all_files = IndexedFile(pearl_explorer_filepath, -1, "????")
    +
    242  nn = ItemsInList(all_files)
    +
    243  else
    +
    244  all_files = ""
    +
    245  nn = 0
    +
    246  endif
    +
    247 
    +
    248  make /n=(nn) /t /free wtAllFiles
    +
    249  wtAllFiles = StringFromList(p, all_files)
    +
    250  Extract /o /t wtAllFiles, wtFiles, pearl_file_type(wtAllFiles[p])
    +
    251  Sort /A /R wtFiles, wtFiles
    +
    252 
    +
    253  redimension /n=(numpnts(wtFiles)) wSelectedFiles
    +
    254  wSelectedFiles = 0
    +
    255 
    +
    256  setdatafolder save_df
    +
    257 end
    +
    258 
    +
    259 // ====== metadata ======
    +
    260 
    +
    273 static function get_file_info(filename)
    +
    274  string filename
    +
    275 
    +
    276  dfref save_df = GetDataFolderDFR()
    +
    277  dfref package_df = $package_path
    +
    278 
    +
    279  variable ft = pearl_file_type(filename)
    +
    280  variable result = 0
    +
    281 
    +
    282  switch(ft)
    +
    283  case 1:
    +
    284  case 2:
    +
    285  dfref file_df = get_pshell_info("pearl_explorer_filepath", filename)
    +
    286  result = hl_contents_update(file_df)
    +
    287  result = result >= 3 ? 0 : -2
    +
    288  break
    +
    289  default:
    + +
    291  dfref file_df = package_df:file_info
    +
    292  KillDataFolder /z file_df
    +
    293  result = -1
    +
    294  endswitch
    +
    295 
    +
    296  setdatafolder save_df
    +
    297  return result
    +
    298 end
    +
    299 
    +
    301 static function attributes_notebook(filename)
    +
    302  string filename
    +
    303 
    +
    304  dfref save_df = GetDataFolderDFR()
    +
    305  dfref temp_df = NewFreeDataFolder()
    +
    306 
    +
    307  load_file(filename, options="mode:load_diags", dest_df=temp_df, quiet=1)
    +
    308  svar /sdfr=temp_df /z s_loaded_datasets
    +
    309  string scan
    +
    310  dfref scan_df
    +
    311  if (SVAR_Exists(s_loaded_datasets) && (strlen(s_loaded_datasets) >= 4))
    +
    312  scan = StringFromList(0, psh5_extract_scan_paths(s_loaded_datasets), ";")
    +
    313  scan_df = psh5_dataset_to_folder(temp_df, scan)
    +
    314  else
    +
    315  scan_df = temp_df
    +
    316  endif
    +
    317 
    +
    318  dfref attr_df = ps_find_attr_folder(scan_df)
    +
    319  if (DataFolderRefStatus(attr_df))
    +
    320  extract_attributes(attr_df, dest_df=temp_df)
    +
    321  wave /t /sdfr=temp_df /z attr_names
    +
    322  wave /t /sdfr=temp_df /z attr_values
    +
    323  if (WaveExists(attr_names) && WaveExists(attr_values))
    +
    324  create_attributes_notebook(attr_names, attr_values, filename)
    +
    325  endif
    +
    326  endif
    +
    327 
    +
    328  setdatafolder save_df
    +
    329 end
    +
    330 
    +
    347 static function extract_attributes(attr_df, [dest_df, attr_filter, include_datawaves, include_infowaves])
    +
    348  dfref attr_df
    +
    349  dfref dest_df
    +
    350  wave /t attr_filter
    +
    351  variable include_datawaves
    +
    352  variable include_infowaves
    +
    353 
    +
    354  dfref save_df = GetDataFolderDFR()
    +
    355  dfref package_df = $package_path
    +
    356 
    +
    357  if (ParamIsDefault(dest_df))
    +
    358  dest_df = GetDataFolderDFR()
    +
    359  endif
    +
    360  if (ParamIsDefault(attr_filter) || !WaveExists(attr_filter))
    +
    361  wave /t /sdfr=package_df /z attr_filter
    +
    362  endif
    +
    363  if (ParamIsDefault(include_datawaves))
    +
    364  include_datawaves = 1
    +
    365  endif
    +
    366  if (ParamIsDefault(include_infowaves))
    +
    367  include_infowaves = 1
    +
    368  endif
    +
    369 
    +
    370  setdatafolder dest_df
    +
    371  wave /t /z attr_names, attr_values
    +
    372  if (!WaveExists(attr_names) || !WaveExists(attr_values))
    +
    373  make /n=(1) /o /t attr_names, attr_values
    +
    374  endif
    +
    375  attr_names = ""
    +
    376  attr_values = ""
    +
    377 
    +
    378  setdatafolder attr_df
    +
    379  wave /t /z IN
    +
    380  wave /t /z ID
    +
    381  wave /t /z IV
    +
    382  wave /t /z IU
    +
    383 
    +
    384  // compile list of attributes
    +
    385  variable nattr // destination attributes
    +
    386  variable iattr
    +
    387  variable ninfo // info wave elements
    +
    388  variable iinfo
    +
    389  variable nw // attribute waves
    +
    390  variable iw
    +
    391  string sw
    +
    392  string ss
    +
    393 
    +
    394  if (WaveExists(IN) && include_infowaves)
    +
    395  ninfo = numpnts(IN)
    +
    396  else
    +
    397  ninfo = 0
    +
    398  endif
    +
    399  if (include_datawaves)
    +
    400  string waves = WaveList("*", ";", "")
    +
    401  string exceptions = "ID;IN;IU;IV"
    +
    402  waves = RemoveFromList(exceptions, waves)
    +
    403  nw = ItemsInList(waves, ";")
    +
    404  else
    +
    405  nw = 0
    +
    406  endif
    +
    407 
    +
    408  if (WaveExists(attr_filter) && (numpnts(attr_filter) >= 1))
    +
    409  nattr = numpnts(attr_filter)
    +
    410  redimension /n=(nattr) attr_names
    +
    411  attr_names = attr_filter
    +
    412  else
    +
    413  if(ninfo > 0)
    +
    414  redimension /n=(ninfo) attr_names
    +
    415  attr_names = SelectString(strlen(ID[p]) >= 0, IN[p], ID[p]) // use ID unless empty
    +
    416  endif
    +
    417 
    +
    418  nattr = ninfo + nw
    +
    419  iattr = ninfo
    +
    420  redimension /n=(nattr) attr_names
    +
    421  for (iw = 0; iw < nw; iw +=1 )
    +
    422  sw = StringFromList(iw, waves, ";")
    +
    423  ss = StringByKey("PV", note($sw), "=", "\r")
    +
    424  FindValue /text=sw attr_names
    +
    425  if ((v_value < 0) && (strlen(ss) >= 0))
    +
    426  attr_names[iattr] = sw
    +
    427  iattr += 1
    +
    428  endif
    +
    429  endfor
    +
    430  nattr = iattr
    +
    431  endif
    +
    432  redimension /n=(nattr) attr_names, attr_values
    +
    433  sort attr_names, attr_names
    +
    434 
    +
    435  // look up attribute values
    +
    436  for (iattr = 0; iattr < nattr; iattr += 1)
    +
    437  sw = attr_names[iattr]
    +
    438  // try info waves
    +
    439  if (ninfo > 0)
    +
    440  FindValue /text=sw ID
    +
    441  if (v_value >= 0)
    +
    442  attr_values[iattr] = IV[v_value]
    +
    443  endif
    +
    444  FindValue /text=sw IN
    +
    445  if (v_value >= 0)
    +
    446  attr_values[iattr] = IV[v_value]
    +
    447  endif
    +
    448  endif
    +
    449 
    +
    450  // override from attribute wave if existent
    +
    451  if (nw > 0)
    +
    452  switch (WaveType($sw, 1))
    +
    453  case 1: // numeric
    +
    454  wave /z w = $sw
    +
    455  if (WaveExists(w) && (numpnts(w) >= 1))
    +
    456  sprintf ss, "%g", w[0]
    +
    457  attr_values[iattr] = ss
    +
    458  endif
    +
    459  break
    +
    460  case 2: // text
    +
    461  wave /t/z wt = $sw
    +
    462  if (WaveExists(wt) && (numpnts(wt) >= 1))
    +
    463  attr_values[iattr] = wt[0]
    +
    464  endif
    +
    465  break
    +
    466  endswitch
    +
    467  endif
    +
    468  endfor
    +
    469 
    +
    470  setdatafolder save_df
    +
    471 end
    +
    472 
    + +
    474  dfref df = GetDataFolderDFR()
    +
    475  wave /t /sdfr=df attr_names
    +
    476  wave /t /sdfr=df attr_values
    +
    477  create_attributes_notebook(attr_names, attr_values, GetDataFolder(0))
    +
    478 end
    +
    479 
    +
    480 static function create_attributes_notebook(attr_names, attr_values, title)
    +
    481  wave /t attr_names
    +
    482  wave /t attr_values
    +
    483  string title
    +
    484 
    +
    485  dfref save_df = GetDataFolderDFR()
    +
    486  setdatafolder $package_path
    +
    487  wave /t/z attr_filter, attr_filter_summary
    +
    488 
    +
    489  string name = PearlCleanupName("nb_" + title[0,27])
    +
    490  if (WinType(name) == 5)
    +
    491  Notebook $name selection={startOfFile, endOfFile}
    +
    492  Notebook $name text=""
    +
    493  else
    +
    494  NewNotebook /F=1 /K=1 /N=$name as title
    +
    495  GetWindow $name wsize
    +
    496  v_right = v_left + 260
    +
    497  v_bottom = v_top + 360
    +
    498  MoveWindow /W=$name v_left, v_top, v_right, v_bottom
    +
    499  Notebook $name tabs={2*72}
    +
    500  endif
    +
    501 
    +
    502  // summary
    +
    503  if (WaveExists(attr_filter_summary) && (numpnts(attr_filter_summary) >= 1))
    +
    504  notebook $name fStyle=1, text="Summary\r\r"
    +
    505  notebook $name fStyle=0
    +
    506  notebook_add_attributes(name, attr_filter_summary, attr_names, attr_values)
    +
    507  notebook $name text="\r"
    +
    508  endif
    +
    509 
    +
    510  // all attributes
    +
    511  notebook $name fStyle=1, text="All Attributes\r\r"
    +
    512  notebook $name fStyle=0
    +
    513  notebook_add_attributes(name, $"", attr_names, attr_values)
    +
    514  notebook $name selection={startOfFile,startOfFile}, findText={"",1}
    +
    515 
    +
    516  setdatafolder save_df
    +
    517 end
    +
    518 
    +
    519 static function notebook_add_attributes(notebook_name, attr_filter, attr_names, attr_values)
    +
    520  string notebook_name
    +
    521  wave /t /z attr_filter
    +
    522  wave /t attr_names
    +
    523  wave /t attr_values
    +
    524 
    +
    525  variable nw = numpnts(attr_names)
    +
    526  variable iw
    +
    527  string sw
    +
    528  string ss
    +
    529 
    +
    530  variable do_filter = WaveExists(attr_filter)
    +
    531 
    +
    532  for (iw = 0; iw < nw; iw += 1)
    +
    533  if (do_filter)
    +
    534  sw = attr_names[iw]
    +
    535  FindValue /text=sw attr_filter
    +
    536  else
    +
    537  v_value = 0
    +
    538  endif
    +
    539  if (v_value >= 0)
    +
    540  sprintf ss, "%s\t%s\r", attr_names[iw], attr_values[iw]
    +
    541  notebook $notebook_name text=ss
    +
    542  endif
    +
    543  endfor
    +
    544 end
    +
    545 
    +
    568 static function set_elog_attributes(file_df, [filename, graphname])
    +
    569  dfref file_df
    +
    570  string filename
    +
    571  string graphname
    +
    572 
    +
    573  if (ParamIsDefault(filename))
    +
    574  svar /sdfr=file_df /z loaded_file=s_filepath
    +
    575  if (svar_Exists(loaded_file))
    +
    576  filename = loaded_file
    +
    577  else
    +
    578  filename = ""
    +
    579  endif
    +
    580  endif
    +
    581 
    +
    582  if (ParamIsDefault(graphname))
    +
    583  graphname = ""
    +
    584  endif
    +
    585 
    +
    586  string cmd
    +
    587 
    +
    588  if (exists("PearlElog#set_panel_attributes") == 6)
    +
    589  sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"File=%s\")", ParseFilePath(0, filename, ":", 1, 0)
    +
    590  execute /Q/Z cmd
    +
    591  if ((strlen(graphname) > 0) && (WinType(graphname) == 1))
    +
    592  sprintf cmd, "PearlElog#set_panel_graphs(\"\", \"%s\")", graphname
    +
    593  execute /Q/Z cmd
    +
    594  endif
    +
    595  svar /sdfr=file_df /z authors
    +
    596  if (svar_Exists(authors))
    +
    597  if (strlen(authors)>=1)
    +
    598  sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"author=%s\")", authors
    +
    599  execute /Q/Z cmd
    +
    600  endif
    +
    601  endif
    +
    602  svar /sdfr=file_df /z pgroup
    +
    603  if (svar_Exists(pgroup))
    +
    604  if (strlen(pgroup)>=1)
    +
    605  sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"p-group=%s\")", pgroup
    +
    606  execute /Q/Z cmd
    +
    607  endif
    +
    608  endif
    +
    609  svar /sdfr=file_df /z proposal
    +
    610  if (svar_Exists(proposal))
    +
    611  if (strlen(proposal)>=1)
    +
    612  sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"project=%s\")", proposal
    +
    613  execute /Q/Z cmd
    +
    614  endif
    +
    615  endif
    +
    616  svar /sdfr=file_df /z proposer
    +
    617  svar /sdfr=file_df /z sample
    +
    618  if (svar_Exists(sample))
    +
    619  if (strlen(sample)>=1)
    +
    620  sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"sample=%s\")", sample
    +
    621  execute /Q/Z cmd
    +
    622  endif
    +
    623  endif
    +
    624  endif
    +
    625 end
    +
    626 
    +
    627 // ====== preview ======
    +
    628 
    +
    629 static function preview_file(filename)
    +
    630  string filename
    +
    631 
    +
    632  dfref save_df = GetDataFolderDFR()
    +
    633  dfref preview_df = $package_path
    +
    634 
    +
    635  killStrings /z authors, pgroup, proposal, proposer, sample
    +
    636 
    +
    637  variable ft = pearl_file_type(filename)
    +
    638  switch(ft)
    +
    639  case 1:
    +
    640  wave /z image = preview_pshell_file(filename)
    +
    641  break
    +
    642  case 2:
    +
    643  wave /z image = preview_hdf_file(filename)
    +
    644  break
    +
    645  case 3:
    +
    646  wave /z image = preview_itx_file(filename)
    +
    647  break
    +
    648  default:
    +
    649  wave /z image = $""
    +
    650  endswitch
    +
    651 
    +
    652  if (WaveExists(image))
    +
    653  show_preview_graph(image)
    +
    654  endif
    +
    655 
    +
    656  setdatafolder save_df
    +
    657  return 0
    +
    658 end
    +
    659 
    +
    671 static function /wave preview_pshell_file(filename)
    +
    672  string filename
    +
    673 
    +
    674  dfref save_df = GetDataFolderDFR()
    +
    675 
    +
    676  setdatafolder $package_path
    +
    677  dfref preview_df = GetDataFolderDFR()
    +
    678  svar s_preview_file
    +
    679  svar s_preview_source
    +
    680  svar /z s_file_info
    +
    681  if (! svar_exists(s_file_info))
    +
    682  string /g s_file_info
    +
    683  endif
    +
    684 
    +
    685  dfref temp_df = NewFreeDataFolder()
    +
    686  dfref file_df = psh5_preview("pearl_explorer_filepath", filename, dest_df=temp_df)
    +
    687  svar /z /sdfr=temp_df dataname=s_preview_wave
    +
    688 
    +
    689  s_preview_file = filename
    +
    690  s_preview_source = ""
    +
    691 
    +
    692  wave /z /sdfr=temp_df data = $dataname
    +
    693  if (waveexists(data))
    +
    694  duplicate /o data, preview_df:preview_image
    +
    695  else
    +
    696  print "no data found in file " + filename
    +
    697  endif
    +
    698 
    +
    699  s_file_info = ""
    +
    700 
    +
    701  setdatafolder save_df
    +
    702  wave /z /sdfr=preview_df preview_image
    +
    703  return preview_image
    +
    704 end
    +
    705 
    +
    717 static function /wave preview_hdf_file(filename)
    +
    718  string filename
    +
    719 
    +
    720  dfref save_df = GetDataFolderDFR()
    +
    721  setdatafolder $package_path
    +
    722  svar s_preview_file
    +
    723  svar s_preview_source
    +
    724  adh5_load_preview("preview_image", "pearl_explorer_filepath", filename)
    +
    725  s_preview_file = filename
    +
    726  s_preview_source = ""
    +
    727  wave /z preview_image
    +
    728 
    +
    729  svar /z s_file_info
    +
    730  if (! svar_exists(s_file_info))
    +
    731  string /g s_file_info
    +
    732  endif
    +
    733  if (strlen(s_preview_file) > 0)
    +
    734  s_file_info = adh5_load_info("pearl_explorer_filepath", filename)
    +
    735  else
    +
    736  s_file_info = ""
    +
    737  endif
    +
    738 
    +
    739  setdatafolder save_df
    +
    740  return preview_image
    +
    741 end
    +
    742 
    +
    762 static function /wave preview_itx_file(filename)
    +
    763  string filename
    +
    764 
    +
    765  dfref save_df = GetDataFolderDFR()
    +
    766  setdatafolder $package_path
    +
    767  svar s_preview_file
    +
    768  svar s_preview_source
    +
    769  wave preview_image
    +
    770 
    +
    771  dfref data_df = newfreedatafolder()
    +
    772  setdatafolder data_df
    +
    773  LoadWave /t/p=pearl_explorer_filepath/q filename
    +
    774  s_preview_file = s_filename
    +
    775  s_preview_source = ""
    +
    776 
    + +
    778 
    +
    779  setdatafolder save_df
    +
    780  return preview_image
    +
    781 end
    +
    782 
    +
    784 static function extract_preview_image(data, preview)
    +
    785  wave data
    +
    786  wave preview
    +
    787 
    +
    788  variable z1, z2
    +
    789 
    +
    790  // extract image
    +
    791  switch (WaveDims(data))
    +
    792  case 1:
    +
    793  redimension /n=(numpnts(data)) preview
    +
    794  preview = data[p]
    +
    795  break
    +
    796  case 2:
    +
    797  redimension /n=(dimsize(data, 0), dimsize(data, 1)) preview
    +
    798  preview = data
    +
    799  break
    +
    800  case 3:
    +
    801  redimension /n=(dimsize(data, 0), dimsize(data, 1)) preview
    +
    802  z1 = floor(DimSize(data, 2) / 2)
    +
    803  z2 = z1
    +
    804  wave slab = ad_extract_slab(data, nan, nan, nan, nan, z1, z2, "", pscale=1)
    +
    805  preview = slab
    +
    806  break
    +
    807  case 4:
    +
    808  // not implemented
    +
    809  endswitch
    +
    810 
    +
    811  switch (WaveDims(data))
    +
    812  case 4:
    +
    813  case 3:
    +
    814  case 2:
    +
    815  setscale /p y dimoffset(data, 1), dimdelta(data, 1), waveunits(data, 1), preview
    +
    816  case 1:
    +
    817  setscale /p x dimoffset(data, 0), dimdelta(data, 0), waveunits(data, 0), preview
    +
    818  setscale d 0, 0, waveunits(data, -1), preview
    +
    819  endswitch
    +
    820 end
    +
    821 
    +
    826 static function preview_datafolder()
    +
    827  dfref save_df = GetDataFolderDFR()
    +
    828 
    +
    829  setdatafolder $package_path
    +
    830  svar s_preview_file
    +
    831  svar s_preview_source
    +
    832  svar s_preview_pvs
    +
    833  wave preview_image
    +
    834 
    +
    835  setdatafolder save_df
    +
    836 
    +
    837  // select a wave to display
    +
    838  // consider only double-precision waves, i.e. ignore text and other special waves
    +
    839  // filter by matching PV name to s_preview_pvs
    +
    840  string d_names = WaveList("*", ";", "DP:1")
    +
    841  variable nw = ItemsInList(d_names, ";")
    +
    842  variable npv = ItemsInList(s_preview_pvs, ";")
    +
    843  variable iw, ipv
    +
    844  string wname, wnote, pv_name, pv_match
    +
    845  for (iw = 0; iw < nw; iw += 1)
    +
    846  wname = StringFromList(iw, d_names, ";")
    +
    847  wnote = note($wname)
    +
    848  pv_name = StringByKey("PV", wnote, "=", "\r")
    +
    849  // find matching data wave by PV name
    +
    850  for (ipv = 0; ipv < npv; ipv += 1)
    +
    851  pv_match = StringFromList(ipv, s_preview_pvs)
    +
    852  if (StringMatch(pv_name, pv_match))
    +
    853  wave data = $wname
    +
    854  s_preview_source = pv_name
    +
    855  extract_preview_image(data, preview_image)
    +
    856  preview_setscale_x(data, preview_image)
    +
    857  npv = 0
    +
    858  nw = 0
    +
    859  endif
    +
    860  endfor
    +
    861  endfor
    +
    862 
    +
    863  setdatafolder save_df
    +
    864 end
    +
    865 
    +
    866 static function preview_setscale_x(data, preview)
    +
    867  // sets the approximate x scale of OTF data.
    +
    868  // requires an Axis1 tag with name of x wave in the wave note.
    +
    869  // if any of these conditions is true, the function does not change the scaling:
    +
    870  // 1) Axis1 tag or referenced wave is missing.
    +
    871  // 2) preview wave is not set to point scaling.
    +
    872  // 3) x wave is not monotonic (90% of the steps in the same direction).
    +
    873  wave data
    +
    874  wave preview
    +
    875 
    +
    876  if ((DimOffset(preview, 0) == 0) && (DimDelta(preview, 0) == 1))
    +
    877  string xname = StringByKey("Axis1", note(data), "=", "\r")
    +
    878  wave /z xwave = $xname
    +
    879  if (WaveExists(xwave))
    +
    880  // check for monotonicity
    +
    881  variable monotonic = 0
    +
    882  duplicate /free xwave, xdiff
    +
    883  differentiate /p xwave /D=xdiff
    +
    884  duplicate /free xdiff, xflag
    +
    885  xflag = xdiff > 0
    +
    886  monotonic = sum(xflag) > numpnts(xwave) * 0.9
    +
    887  xflag = xdiff < 0
    +
    888  monotonic = monotonic || (sum(xflag) > numpnts(xwave) * 0.9)
    +
    889  if (monotonic)
    +
    890  setscale /i x xwave[0], xwave[numpnts(xwave)-1], waveunits(xwave, -1), preview
    +
    891  endif
    +
    892  endif
    +
    893  endif
    +
    894 end
    +
    895 
    +
    897 static function display_dataset(file_df, dataset)
    +
    898  dfref file_df // top data folder of file
    +
    899  string dataset // dataset path inside data folder
    +
    900 
    +
    901  dfref save_df = GetDataFolderDFR()
    +
    902 
    +
    903  dfref data_df = psh5_dataset_to_folder(file_df, dataset)
    +
    904  SetDataFolder data_df
    +
    905  string data_name = StringFromList(ItemsInList(dataset, "/") - 1, dataset, "/")
    +
    906  wave /z data=$data_name
    +
    907 
    +
    908  if (WaveExists(data))
    +
    909  switch(WaveDims(data))
    +
    910  case 1:
    +
    911  case 2:
    +
    912  show_preview_graph(data)
    +
    913  break
    +
    914  case 3:
    +
    915  ad_display_slice(data)
    +
    916  ad_brick_slicer(data)
    +
    917  break
    +
    918  endswitch
    +
    919  endif
    +
    920 
    +
    921  setdatafolder save_df
    +
    922  return 0
    +
    923 end
    +
    924 
    +
    925 static function /s show_preview_graph(data, [xdata])
    +
    926  // displays a preview of one- or two-dimensional data
    +
    927  wave data // data to be displayed. must either one-dimensional or two-dimensional
    +
    928  wave xdata // positions on x axis
    +
    929 
    +
    930  dfref save_df = GetDataFolderDFR()
    +
    931  setdatafolder $package_path
    +
    932 
    +
    933  svar s_profiles_graph
    +
    934  svar s_preview_file
    +
    935  svar s_preview_source
    +
    936  svar s_preview_trace_graph
    +
    937  svar s_preview_graph
    +
    938 
    +
    939  if ((strlen(s_profiles_graph) > 0) && (WinType(s_profiles_graph) == 1))
    +
    940  KillWindow $s_profiles_graph
    +
    941  endif
    +
    942  if ((strlen(s_preview_trace_graph) > 0) && (WinType(s_preview_trace_graph) == 1))
    +
    943  KillWindow $s_preview_trace_graph
    +
    944  endif
    +
    945 
    +
    946  string graphname
    +
    947  if (wavedims(data) == 2)
    +
    948  s_profiles_graph = ad_display_profiles(data)
    +
    949  ModifyGraph /w=$s_profiles_graph /z wbRGB=(48640,56832,60160)
    +
    950  graphname = s_profiles_graph
    +
    951  elseif (wavedims(data) == 1)
    +
    952  duplicate /o data, preview_trace
    +
    953  if (!ParamIsDefault(xdata))
    +
    954  duplicate /o xdata, preview_trace_x
    +
    955  else
    +
    956  duplicate /o data, preview_trace_x
    +
    957  preview_trace_x = x
    +
    958  setscale d 0, 0, WaveUnits(data, 0), preview_trace_x
    +
    959  endif
    +
    960  s_preview_trace_graph = display_preview_trace(preview_trace_x, preview_trace)
    +
    961  ModifyGraph /w=$s_preview_trace_graph wbRGB=(48640,56832,60160)
    +
    962  graphname = s_preview_trace_graph
    +
    963  else
    +
    964  return ""
    +
    965  endif
    +
    966 
    +
    967  string title = "Preview " + s_preview_file
    +
    968  if (strlen(s_preview_source) > 0)
    +
    969  title = title + " (" + s_preview_source[0,31] + ")"
    +
    970  endif
    +
    971  dowindow /f/t $graphname, title
    +
    972  s_preview_graph = graphname
    +
    973 
    +
    974  setdatafolder save_df
    +
    975  return graphname
    +
    976 end
    +
    977 
    +
    978 static function /s display_preview_trace(xtrace, ytrace)
    +
    979  wave /z xtrace
    +
    980  wave ytrace
    +
    981 
    +
    982  if (WaveExists(xtrace))
    +
    983  display /n=pearl_explorer_1d /k=1 ytrace vs xtrace as "Preview"
    +
    984  else
    +
    985  display /n=pearl_explorer_1d /k=1 ytrace as "Preview"
    +
    986  endif
    +
    987 
    +
    988  string graphname = s_name
    +
    989  ModifyGraph /w=$graphname rgb[0]=(0,0,0)
    +
    990  ModifyGraph /w=$graphname grid=2
    +
    991  ModifyGraph /w=$graphname mirror=1
    +
    992  ModifyGraph /w=$graphname minor=1
    +
    993  ModifyGraph /w=$graphname axThick=0.5
    +
    994  ModifyGraph /w=$graphname gridRGB=(52224,52224,52224)
    +
    995  ModifyGraph /w=$graphname gridHair=0
    +
    996  ModifyGraph /w=$graphname tick=0
    +
    997  ModifyGraph /w=$graphname btLen=4
    +
    998 
    +
    999  // axis labels
    +
    1000  string labels = note(ytrace)
    +
    1001  string lab
    +
    1002  lab = StringByKey("AxisLabelX", labels, "=", "\r")
    +
    1003  if (!strlen(lab))
    +
    1004  lab = "X"
    +
    1005  endif
    +
    1006  Label /w=$graphname bottom lab + " (\\U)"
    +
    1007  lab = StringByKey("Dataset", labels, "=", "\r")
    +
    1008  if (!strlen(lab))
    +
    1009  lab = "value"
    +
    1010  endif
    +
    1011  Label /w=$graphname left lab + " (\\U)"
    +
    1012 
    +
    1013  return s_name
    +
    1014 end
    +
    1015 
    +
    1016 // ====== file loading ======
    +
    1017 
    +
    1025 static function load_selected_files([options])
    +
    1026  string options
    +
    1027 
    +
    1028  dfref save_df = GetDataFolderDFR()
    +
    1029  setdatafolder $package_path
    +
    1030 
    +
    1031  wave wSelectedFiles
    +
    1032  wave/t wtFiles
    +
    1033  variable nn = numpnts(wSelectedFiles)
    +
    1034  variable ii
    +
    1035  for (ii = 0; ii < nn; ii += 1)
    +
    1036  if (wSelectedFiles[ii])
    +
    1037  setdatafolder save_df
    +
    1038  if (ParamIsDefault(options))
    +
    1039  load_file(wtFiles[ii])
    +
    1040  else
    +
    1041  load_file(wtFiles[ii], options=options)
    +
    1042  endif
    +
    1043  endif
    +
    1044  endfor
    +
    1045 end
    +
    1046 
    +
    1064 static function load_file(filename, [options, dest_df, quiet])
    +
    1065  string filename
    +
    1066  string options
    +
    1067  dfref dest_df
    +
    1068  variable quiet
    +
    1069 
    +
    1070  if (ParamIsDefault(options))
    +
    1071  options = ""
    +
    1072  endif
    +
    1073 
    +
    1074  variable ft = pearl_file_type(filename)
    +
    1075  switch(ft)
    +
    1076  case 1:
    +
    1077  load_pshell_file(filename, options=options, dest_df=dest_df, quiet=quiet)
    +
    1078  break
    +
    1079  case 2:
    +
    1080  load_hdf_file(filename, options=options, dest_df=dest_df, quiet=quiet)
    +
    1081  break
    +
    1082  case 3:
    +
    1083  load_itx_file(filename, dest_df=dest_df, quiet=quiet)
    +
    1084  break
    +
    1085  default:
    +
    1086  break
    +
    1087  endswitch
    +
    1088 end
    +
    1089 
    +
    1090 static function prompt_hdf_options(options)
    +
    1091  string &options
    +
    1092 
    +
    1093  string mode = StringByKey("mode", options, ":", ";")
    +
    1094  string reduction_func = StringByKey("reduction_func", options, ":", ";")
    +
    1095 
    +
    1096  string modes = "load_scan;load_region;load_dataset;load_diags;load_complete;"
    +
    1097  string reduction_funcs = adh5_list_reduction_funcs()
    +
    1098  reduction_funcs = RemoveFromList("adh5_default_reduction", reduction_funcs, ";")
    +
    1099 
    +
    1100  if (strlen(mode) == 0)
    +
    1101  mode = StringFromList(0, modes, ";")
    +
    1102  endif
    +
    1103  if (strlen(reduction_func) == 0)
    +
    1104  reduction_func = StringFromList(0, reduction_funcs, ";")
    +
    1105  endif
    +
    1106 
    +
    1107  prompt mode, "Mode", popup, modes
    +
    1108  prompt reduction_func, "Reduction Function", popup, reduction_funcs
    +
    1109  doprompt "HDF5 Loading Options", mode, reduction_func
    +
    1110 
    +
    1111  if (v_flag == 0)
    +
    1112  options = ReplaceStringByKey("mode", options, mode, ":", ";")
    +
    1113  options = ReplaceStringByKey("reduction_func", options, reduction_func, ":", ";")
    +
    1114  endif
    +
    1115  return v_flag // 0 = OK, 1 = cancel
    +
    1116 end
    +
    1117 
    +
    1130 function prompt_default_process(param)
    +
    1131  string &param
    +
    1132 
    +
    1133  return 0
    +
    1134 end
    +
    1135 
    +
    1136 function prompt_func_params(func_name, func_param)
    +
    1137  string func_name
    +
    1138  string &func_param
    +
    1139 
    +
    1140  string prompt_name = "prompt_" + func_name
    +
    1141  if (exists(prompt_name) == 6)
    +
    1142  funcref prompt_default_process prompt_func = $prompt_name
    +
    1143  return prompt_func(func_param)
    +
    1144  else
    +
    1145  // ignore missing prompt function
    +
    1146  return 0
    +
    1147  endif
    +
    1148 end
    +
    1149 
    +
    1188 static function /df load_pshell_file(filename, [options, dest_df, quiet])
    +
    1189  string filename
    +
    1190  string options
    +
    1191  dfref dest_df
    +
    1192  variable quiet
    +
    1193 
    +
    1194  dfref save_df = GetDataFolderDFR()
    +
    1195 
    +
    1196  svar pref_options = $(package_path + "s_hdf_options")
    +
    1197  svar pref_params = $(package_path + "s_reduction_params")
    +
    1198  string path = "pearl_explorer_filepath"
    +
    1199 
    +
    1200  if (ParamIsDefault(options))
    +
    1201  options = pref_options
    +
    1202  endif
    +
    1203 
    +
    1204  if (strlen(options) == 0)
    +
    1205  if (prompt_hdf_options(options) == 0)
    +
    1206  pref_options = options
    +
    1207  else
    +
    1208  return $""
    +
    1209  endif
    +
    1210  endif
    +
    1211 
    +
    1212  string reduction_func = StringByKey("reduction_func", options, ":", ";")
    +
    1213  string reduction_params = pref_params
    +
    1214  variable max_rank = 2
    +
    1215 
    +
    1216  if (exists(reduction_func) == 6)
    +
    1217  max_rank = 3
    +
    1218  if (prompt_func_params(reduction_func, reduction_params) == 0)
    +
    1219  pref_params = reduction_params
    +
    1220  else
    +
    1221  return $""
    +
    1222  endif
    +
    1223  endif
    +
    1224 
    +
    1225  string mode = StringByKey("mode", options, ":", ";")
    +
    1226  string selected_datasets = WMHL_SelectedObjectsList("PearlDataExplorer", "lb_contents")
    +
    1227  string selected_scans = psh5_extract_scan_paths(selected_datasets)
    +
    1228  string selected_regions = psh5_extract_region_paths(selected_datasets)
    +
    1229  variable dsc
    +
    1230 
    +
    1231  if (!quiet)
    +
    1232  print mode, filename
    +
    1233  if (strlen(reduction_func))
    +
    1234  print reduction_func, reduction_params
    +
    1235  endif
    +
    1236  endif
    +
    1237 
    +
    1238  strswitch(mode)
    +
    1239  case "load_complete":
    +
    1240  dsc = kDSCAll
    +
    1241  dfref file_df = psh5_load(path, filename, "", "", "*", classes=dsc, reduction_func=reduction_func, reduction_params=reduction_params, dest_df=dest_df)
    +
    1242  break
    +
    1243  case "load_diags":
    +
    1244  if (ItemsInList(selected_scans, ";") == 0)
    +
    1245  if (!quiet)
    +
    1246  print "no scan selected - defaulting to scan 1."
    +
    1247  endif
    +
    1248  selected_scans = "/scan1;"
    +
    1249  endif
    + +
    1251  dfref file_df = psh5_load(path, filename, selected_scans, "", "", classes=dsc, dest_df=dest_df)
    +
    1252  break
    +
    1253  case "load_scan":
    +
    1254  if (ItemsInList(selected_scans, ";") == 0)
    +
    1255  if (!quiet)
    +
    1256  print "no scan selected - defaulting to scan 1."
    +
    1257  endif
    +
    1258  selected_scans = "/scan1;"
    +
    1259  endif
    + +
    1261  dfref file_df = psh5_load(path, filename, selected_scans, "", "", classes=dsc, max_rank=max_rank, reduction_func=reduction_func, reduction_params=reduction_params, dest_df=dest_df)
    +
    1262  break
    +
    1263  case "load_region":
    +
    1264  if (ItemsInList(selected_regions, ";") == 0)
    +
    1265  if (!quiet)
    +
    1266  print "no region selected - defaulting to scan 1/region 1."
    +
    1267  endif
    +
    1268  selected_regions = "/scan1/region1;"
    +
    1269  endif
    + +
    1271  dfref file_df = psh5_load(path, filename, "", selected_regions, "", classes=dsc, max_rank=max_rank, reduction_func=reduction_func, reduction_params=reduction_params, dest_df=dest_df)
    +
    1272  break
    +
    1273  case "load_dataset":
    +
    1274  if (ItemsInList(selected_datasets, ";") > 0)
    +
    1275  dsc = kDSCAll
    +
    1276  dfref file_df = psh5_load(path, filename, "", "", selected_datasets, classes=dsc, reduction_func=reduction_func, reduction_params=reduction_params, dest_df=dest_df)
    +
    1277  else
    +
    1278  if (!quiet)
    +
    1279  DoAlert /T="PShell Import" 0, "Please select the datasets to load."
    +
    1280  endif
    +
    1281  endif
    +
    1282  break
    +
    1283  endswitch
    +
    1284 
    +
    1285  if (DataFolderRefStatus(file_df))
    +
    1286  setdatafolder file_df
    +
    1287  string /g pearl_explorer_import = "load_pshell_file"
    +
    1288  if (!quiet)
    +
    1289  print "data loaded to", GetDataFolder(1)
    +
    1290  endif
    +
    1291  else
    +
    1292  setdatafolder save_df
    +
    1293  endif
    +
    1294 
    +
    1295  return file_df
    +
    1296 end
    +
    1297 
    +
    1298 static function /df load_hdf_file(filename, [options, dest_df, quiet])
    +
    1299  string filename
    +
    1300  string options
    +
    1301  dfref dest_df
    +
    1302  variable quiet
    +
    1303 
    +
    1304  dfref save_df = GetDataFolderDFR()
    +
    1305  string nickname = ad_suggest_foldername(filename)
    +
    1306  string loaded_filename = ""
    +
    1307 
    +
    1308  if (ParamIsDefault(dest_df) || !DataFolderRefStatus(dest_df))
    +
    1309  //
    +
    1310  else
    +
    1311  DoAlert /T="load_hdf_file" 0, "optional argument dest_df not supported."
    +
    1312  return $""
    +
    1313  endif
    +
    1314 
    +
    1315  if (ParamIsDefault(options))
    +
    1316  loaded_filename = adh5_load_complete(nickname, "pearl_explorer_filepath", filename)
    +
    1317  else
    +
    1318  if (strlen(options) == 0)
    +
    1319  svar pref_options = $(package_path + "s_hdf_options")
    +
    1320  options = pref_options
    +
    1321  if (prompt_hdf_options(options) == 0)
    +
    1322  // OK
    +
    1323  pref_options = options
    +
    1324  else
    +
    1325  // cancel
    +
    1326  options = ""
    +
    1327  endif
    +
    1328  endif
    +
    1329 
    +
    1330  string mode = StringByKey("mode", options, ":", ";")
    +
    1331 
    +
    1332  strswitch(mode)
    +
    1333  case "load_reduced":
    +
    1334  string reduction_func = StringByKey("reduction_func", options, ":", ";")
    +
    1335  svar pref_params = $(package_path + "s_reduction_params")
    +
    1336  string reduction_params = pref_params
    +
    1337  if (prompt_func_params(reduction_func, reduction_params) == 0)
    +
    1338  pref_params = reduction_params
    +
    1339  print reduction_func, reduction_params
    +
    1340  loaded_filename = adh5_load_reduced(nickname, "pearl_explorer_filepath", filename, $reduction_func, reduction_params)
    +
    1341  endif
    +
    1342  break
    +
    1343  endswitch
    +
    1344  endif
    +
    1345 
    +
    1346  dfref data_df
    +
    1347  if (strlen(loaded_filename) > 0)
    +
    1348  setdatafolder $("root:" + nickname)
    +
    1349  data_df = GetDataFolderDFR()
    +
    1350  string /g pearl_explorer_import = "load_hdf_file"
    +
    1351  else
    +
    1352  setdatafolder save_df
    +
    1353  endif
    +
    1354 
    +
    1355  return data_df
    +
    1356 end
    +
    1357 
    +
    1358 static function /df load_itx_file(filename, [options, dest_df, quiet])
    +
    1359  string filename
    +
    1360  string options
    +
    1361  dfref dest_df
    +
    1362  variable quiet
    +
    1363 
    +
    1364  dfref save_df = GetDataFolderDFR()
    +
    1365  string nickname = itx_suggest_foldername(filename)
    +
    1366 
    +
    1367  if (ParamIsDefault(options))
    +
    1368  options = ""
    +
    1369  endif
    +
    1370 
    +
    1371  variable own_data_df = 0
    +
    1372  if (ParamIsDefault(dest_df) || !DataFolderRefStatus(dest_df))
    +
    1373  setdatafolder root:
    +
    1374  newdatafolder /s/o $("root:" + nickname)
    +
    1375  own_data_df = 1
    +
    1376  else
    +
    1377  setdatafolder dest_df
    +
    1378  endif
    +
    1379  dfref data_df = GetDataFolderDFR()
    +
    1380 
    +
    1381  // note: some versions of PEARL data files save data to a new data folder,
    +
    1382  // and leave the newly created folder as the current folder.
    +
    1383  // the free data folder is used by those files which don't create their own data folder.
    +
    1384  // this is the new recommended behaviour
    +
    1385 
    +
    1386  LoadWave /t/p=pearl_explorer_filepath/q filename
    +
    1387  svar waves = s_wavenames
    +
    1388  dfref act_df = GetDataFolderDFR()
    +
    1389  if (v_flag > 0)
    +
    1390  string /g pearl_explorer_import = "load_itx_file"
    +
    1391  endif
    +
    1392 
    +
    1393  if (!DataFolderRefsEqual(act_df, data_df) && own_data_df)
    +
    1394  // the file created its own data folder.
    +
    1395  // let's kill the pre-allocated folder
    +
    1396  setdatafolder data_df
    +
    1397  if (ItemsInList(WaveList("*", ";", ""), ";") == 0)
    +
    1398  killdatafolder /z data_df
    +
    1399  endif
    +
    1400  endif
    +
    1401 
    +
    1402  setdatafolder save_df
    +
    1403  return act_df
    +
    1404 end
    +
    1405 
    +
    1427 function /s itx_suggest_foldername(filename, [ignoredate,sourcename,unique])
    +
    1428  string filename
    +
    1429  variable ignoredate
    +
    1430  string sourcename
    +
    1431  variable unique
    +
    1432 
    +
    1433  if (ParamIsDefault(ignoredate))
    +
    1434  ignoredate = 0
    +
    1435  endif
    +
    1436  if (ParamIsDefault(unique))
    +
    1437  unique = 0
    +
    1438  endif
    +
    1439 
    +
    1440  string basename = ParseFilePath(3, filename, ":", 0, 0)
    +
    1441  string extension = ParseFilePath(4, filename, ":", 0, 0)
    +
    1442  string nickname
    +
    1443 
    +
    1444  string autosource
    +
    1445  if (strsearch(basename, "X03DA_PC", 0, 2) >= 0)
    +
    1446  autosource = "sscan"
    +
    1447  basename = ReplaceString("_", basename, "-")
    +
    1448  ignoredate = 1
    +
    1449  elseif (strsearch(basename, "otf", 0, 2) >= 0)
    +
    1450  autosource = "otf"
    +
    1451  endif
    +
    1452  if (ParamIsDefault(sourcename))
    +
    1453  sourcename = autosource
    +
    1454  endif
    +
    1455 
    +
    1456  variable nparts = ItemsInList(basename, "-")
    +
    1457  if (nparts >= 3)
    +
    1458  string datepart = StringFromList(nparts - 2, basename, "-")
    +
    1459  string indexpart = StringFromList(nparts - 1, basename, "-")
    +
    1460  if (ignoredate)
    +
    1461  sprintf nickname, "%s_%s", sourcename, indexpart
    +
    1462  else
    +
    1463  sprintf nickname, "%s_%s_%s", sourcename, datepart, indexpart
    +
    1464  endif
    +
    1465  else
    +
    1466  nickname = PearlCleanupName(basename)
    +
    1467  endif
    +
    1468 
    +
    1469  if (unique && CheckName(nickname, 11))
    +
    1470  nickname = UniqueName(nickname + "_", 11, 0)
    +
    1471  endif
    +
    1472 
    +
    1473  return nickname
    +
    1474 end
    +
    1475 
    +
    1476 // ====== panel ======
    +
    1477 
    +
    1478 Window PearlDataExplorer() : Panel
    +
    1479  PauseUpdate; Silent 1 // building window...
    +
    1480  NewPanel /K=1 /W=(510,45,1190,539) as "PEARL Data Explorer"
    +
    1481  ModifyPanel cbRGB=(48640,56832,60160)
    +
    1482  GroupBox g_data_reduction,pos={355.00,370.00},size={306.00,49.00},title="data reduction"
    +
    1483  GroupBox g_data_reduction,help={"data reduction of 3D ScientaImage"}
    +
    1484  GroupBox gb_filepath,pos={8.00,4.00},size={328.00,48.00},title="file system folder"
    +
    1485  TitleBox tb_filepath,pos={20.00,28.00},size={279.00,21.00},frame=0
    +
    1486  TitleBox tb_filepath,variable= root:packages:pearl_explorer:s_short_filepath,fixedSize=1
    +
    1487  Button b_browse_filepath,pos={303.00,24.00},size={20.00,20.00},proc=PearlDataExplorer#bp_browse_filepath,title="..."
    +
    1488  Button b_browse_filepath,fColor=(65280,48896,32768)
    +
    1489  GroupBox gb_prefs,pos={8.00,351.00},size={65.00,131.00},title="prefs"
    +
    1490  GroupBox gb_prefs,help={"explorer package preferences"}
    +
    1491  Button b_save_prefs,pos={21.00,394.00},size={38.00,17.00},proc=PearlDataExplorer#bp_save_prefs,title="save"
    +
    1492  Button b_save_prefs,help={"save preferences of the data explorer package (data file path, attributes filter)"}
    +
    1493  Button b_save_prefs,fColor=(65280,48896,32768)
    +
    1494  Button b_load_prefs,pos={21.00,374.00},size={38.00,17.00},proc=PearlDataExplorer#bp_load_prefs,title="load"
    +
    1495  Button b_load_prefs,help={"load preferences of the data explorer package"}
    +
    1496  Button b_load_prefs,fColor=(65280,48896,32768)
    +
    1497  GroupBox gb_filelist,pos={8.00,55.00},size={328.00,293.00},title="data files"
    +
    1498  ListBox lb_files,pos={20.00,83.00},size={303.00,222.00},proc=PearlDataExplorer#lbp_filelist
    +
    1499  ListBox lb_files,listWave=root:packages:pearl_explorer:wtFiles
    +
    1500  ListBox lb_files,selWave=root:packages:pearl_explorer:wSelectedFiles,mode= 4
    +
    1501  Button b_update_filelist,pos={246.00,315.00},size={76.00,22.00},proc=PearlDataExplorer#bp_update_filelist,title="update list"
    +
    1502  Button b_update_filelist,fColor=(65280,48896,32768)
    +
    1503  CheckBox cb_file_preview,pos={78.00,318.00},size={59.00,14.00},title="preview"
    +
    1504  CheckBox cb_file_preview,help={"enable/disable automatic preview window when selecting a data file"}
    +
    1505  CheckBox cb_file_preview,value= 0
    +
    1506  Button b_file_prev,pos={20.00,314.00},size={22.00,22.00},proc=PearlDataExplorer#bp_file_prev,title="\\W646"
    +
    1507  Button b_file_prev,help={"previous file"},fColor=(65280,48896,32768)
    +
    1508  Button b_file_next,pos={44.00,314.00},size={22.00,22.00},proc=PearlDataExplorer#bp_file_next,title="\\W649"
    +
    1509  Button b_file_next,help={"next file"},fColor=(65280,48896,32768)
    +
    1510  Button b_goto_dataset,pos={355.00,315.00},size={64.00,22.00},disable=2,proc=PearlDataExplorer#bp_goto_dataset,title="goto DF"
    +
    1511  Button b_goto_dataset,help={"change the current data folder ot where the selected dataset could be located"}
    +
    1512  Button b_goto_dataset,fColor=(65280,48896,32768)
    +
    1513  Button b_display_dataset,pos={423.00,315.00},size={64.00,22.00},disable=2,proc=PearlDataExplorer#bp_display_dataset,title="display"
    +
    1514  Button b_display_dataset,help={"display the selected dataset in its own window"}
    +
    1515  Button b_display_dataset,fColor=(65280,48896,32768)
    +
    1516  Button b_load_complete,pos={355.00,451.00},size={92.00,22.00},disable=2,proc=PearlDataExplorer#bp_load_options,title="all data"
    +
    1517  Button b_load_complete,help={"load all datasets of the selected file."}
    +
    1518  Button b_load_complete,userdata= "mode:load_complete;"
    +
    1519  Button b_load_complete,fColor=(65280,48896,32768)
    +
    1520  TitleBox tb_selected_file,pos={360.00,28.00},size={309.00,22.00},frame=0
    +
    1521  TitleBox tb_selected_file,variable= root:packages:pearl_explorer:s_selected_file,fixedSize=1
    +
    1522  GroupBox gb_contents,pos={346.00,55.00},size={327.00,294.00},title="datasets"
    +
    1523  Button b_attr_notebook,pos={97.00,375.00},size={64.00,22.00},disable=2,proc=PearlDataExplorer#bp_attr_notebook,title="notebook"
    +
    1524  Button b_attr_notebook,help={"show a summary of attributes in a notebook window"}
    +
    1525  Button b_attr_notebook,fColor=(65280,48896,32768)
    +
    1526  ListBox lb_contents,pos={355.00,84.00},size={305.00,222.00}
    +
    1527  ListBox lb_contents,keySelectCol= 1
    +
    1528  GroupBox gb_selected_file,pos={346.00,4.00},size={328.00,48.00},title="selected file"
    +
    1529  Button b_load_region,pos={355.00,426.00},size={92.00,22.00},disable=2,proc=PearlDataExplorer#bp_load_options,title="region"
    +
    1530  Button b_load_region,help={"load the selected region"}
    +
    1531  Button b_load_region,userdata= "mode:load_region;",fColor=(65280,48896,32768)
    +
    1532  PopupMenu popup_reduction,pos={366.00,391.00},size={200.00,17.00},bodyWidth=200,proc=PearlDataExplorer#pmp_reduction_func
    +
    1533  PopupMenu popup_reduction,help={"data reduction of 3d ScientaImage. note: the list may contain unsuitable functions. check the code or documentation!"}
    +
    1534  PopupMenu popup_reduction,mode=1,popvalue="None",value= #"PearlDataExplorer#pm_reduction_values()"
    +
    1535  GroupBox group_import,pos={346.00,351.00},size={326.00,131.00},title="import"
    +
    1536  Button b_load_scan,pos={450.00,426.00},size={94.00,22.00},disable=2,proc=PearlDataExplorer#bp_load_options,title="scan"
    +
    1537  Button b_load_scan,help={"load the selected scan"},userdata= "mode:load_scan;"
    +
    1538  Button b_load_scan,fColor=(65280,48896,32768)
    +
    1539  Button b_load_diags,pos={450.00,451.00},size={94.00,22.00},disable=2,proc=PearlDataExplorer#bp_load_options,title="diagnostics"
    +
    1540  Button b_load_diags,help={"load diagnostics of selected scans"},userdata= "mode:load_diags;"
    +
    1541  Button b_load_diags,fColor=(65280,48896,32768)
    +
    1542  Button b_load_dataset,pos={547.00,426.00},size={101.00,22.00},disable=2,proc=PearlDataExplorer#bp_load_options,title="dataset"
    +
    1543  Button b_load_dataset,help={"load the selected datasets"}
    +
    1544  Button b_load_dataset,userdata= "mode:load_dataset;",fColor=(65280,48896,32768)
    +
    1545  Button b_reduction_params,pos={571.00,390.00},size={71.00,19.00},disable=2,proc=PearlDataExplorer#bp_reduction_params,title="set params"
    +
    1546  Button b_reduction_params,help={"set data reduction parameters"}
    +
    1547  Button b_reduction_params,fColor=(65280,48896,32768)
    +
    1548  GroupBox g_fileinfo,pos={85.00,351.00},size={251.00,131.00},title="file info"
    +
    1549  Button b_elog,pos={97.00,401.00},size={64.00,22.00},disable=2,proc=PearlDataExplorer#bp_elog,title="ELOG"
    +
    1550  Button b_elog,help={"send file metadata to ELOG panel (does not submit to ELOG)"}
    +
    1551  Button b_elog,fColor=(65280,48896,32768)
    +
    1552  ToolsGrid grid=(0,28.35,5)
    +
    1553 EndMacro
    +
    1554 
    +
    1557 static function update_controls()
    +
    1558  dfref package_df = $package_path
    +
    1559  svar /z /sdfr=package_df hl_contents_datasets
    +
    1560  wave /z /sdfr=package_df wSelectedFiles
    +
    1561 
    +
    1562  variable file_selected = 0
    +
    1563  if (WaveExists(wSelectedFiles))
    +
    1564  file_selected = sum(wSelectedFiles)
    +
    1565  endif
    +
    1566 
    +
    1567  string selected_datasets = WMHL_SelectedObjectsList("PearlDataExplorer", "lb_contents")
    +
    1568  variable scan_selected = strsearch(selected_datasets, "scan", 0, 2) == 0
    +
    1569  variable region_selected = strsearch(selected_datasets, "region", 0, 2) >= 0
    +
    1570 
    +
    1571  variable dataset_selected = 0
    +
    1572  variable nds = ItemsInList(selected_datasets, ";")
    +
    1573  variable ids
    +
    1574  string ds
    +
    1575  if (svar_exists(hl_contents_datasets))
    +
    1576  for (ids = 0; ids < nds; ids += 1)
    +
    1577  ds = "/" + StringFromList(ids, selected_datasets, ";")
    +
    1578  if (NumType(NumberByKey(ds, hl_contents_datasets, ":", ";")) == 0)
    +
    1579  dataset_selected = 1
    +
    1580  break
    +
    1581  endif
    +
    1582  endfor
    +
    1583  else
    +
    1584  nds = 0
    +
    1585  endif
    +
    1586 
    +
    1587  variable dis
    +
    1588  dis = file_selected ? 0 : 2
    +
    1589  Button b_load_complete win=PearlDataExplorer,disable=dis
    +
    1590  Button b_load_diags win=PearlDataExplorer,disable=dis
    +
    1591  dis = file_selected && scan_selected ? 0 : 2
    +
    1592  Button b_attr_notebook win=PearlDataExplorer,disable=dis
    +
    1593 
    +
    1594  dis = file_selected && (strlen(WinList("*ElogPanel*", ";", "WIN:64")) > 1) ? 0 : 2
    +
    1595  Button b_elog win=PearlDataExplorer,disable=dis
    +
    1596  dis = scan_selected ? 0 : 2
    +
    1597  Button b_load_scan win=PearlDataExplorer,disable=dis
    +
    1598  dis = region_selected ? 0 : 2
    +
    1599  Button b_load_region win=PearlDataExplorer,disable=dis
    +
    1600  dis = dataset_selected ? 0 : 2
    +
    1601  Button b_load_dataset win=PearlDataExplorer,disable=dis
    +
    1602  Button b_display_dataset win=PearlDataExplorer,disable=dis
    +
    1603  dis = file_selected && (nds > 0) ? 0 : 2
    +
    1604  Button b_goto_dataset win=PearlDataExplorer,disable=dis
    +
    1605 
    +
    1606  ControlInfo /W=PearlDataExplorer popup_reduction
    +
    1607  if ((cmpstr(S_Value, "None") != 0) && (exists(S_Value) == 6))
    +
    1608  GroupBox g_data_reduction win=PearlDataExplorer,labelBack=(65535,49151,49151)
    +
    1609  Button b_reduction_params win=PearlDataExplorer,disable=0
    +
    1610  else
    +
    1611  GroupBox g_data_reduction win=PearlDataExplorer,labelBack=0
    +
    1612  Button b_reduction_params win=PearlDataExplorer,disable=2
    +
    1613  endif
    +
    1614 
    +
    1615  return 0
    +
    1616 end
    +
    1617 
    +
    1618 static function bp_load_prefs(ba) : ButtonControl
    +
    1619  STRUCT WMButtonAction &ba
    +
    1620 
    +
    1621  switch( ba.eventCode )
    +
    1622  case 2: // mouse up
    +
    1623  load_prefs()
    +
    1624  update_controls()
    +
    1625  break
    +
    1626  case -1: // control being killed
    +
    1627  break
    +
    1628  endswitch
    +
    1629 
    +
    1630  return 0
    +
    1631 End
    +
    1632 
    +
    1633 static function bp_save_prefs(ba) : ButtonControl
    +
    1634  STRUCT WMButtonAction &ba
    +
    1635 
    +
    1636  switch( ba.eventCode )
    +
    1637  case 2: // mouse up
    +
    1638  save_prefs()
    +
    1639  break
    +
    1640  case -1: // control being killed
    +
    1641  break
    +
    1642  endswitch
    +
    1643 
    +
    1644  return 0
    +
    1645 End
    +
    1646 
    +
    1651 static function /s shorten_filepath(long_path, max_len)
    +
    1652  string long_path
    +
    1653  variable max_len
    +
    1654 
    +
    1655  string path = long_path
    +
    1656  variable ellipsis = 0
    +
    1657  do
    +
    1658  if (strlen(path) > max_len)
    +
    1659  path = RemoveListItem(1, path, ":")
    +
    1660  ellipsis += 1
    +
    1661  else
    +
    1662  break
    +
    1663  endif
    +
    1664  while (1)
    +
    1665 
    +
    1666  if (ellipsis >= 1)
    +
    1667  path = AddListItem("
", path, ":", 1)
    +
    1668  endif
    +
    1669 
    +
    1670  return path
    +
    1671 end
    +
    1672 
    +
    1673 static function bp_browse_filepath(ba) : ButtonControl
    +
    1674  STRUCT WMButtonAction &ba
    +
    1675 
    +
    1676  dfref save_df = GetDataFolderDFR()
    +
    1677 
    +
    1678  switch( ba.eventCode )
    +
    1679  case 2: // mouse up
    +
    1680  PathInfo /S pearl_explorer_filepath
    +
    1681  NewPath /M="select data file folder" /O/Z pearl_explorer_filepath
    +
    1682  if (v_flag == 0)
    +
    1683  update_filepath()
    +
    1684  update_filelist()
    +
    1685  update_controls()
    +
    1686  endif
    +
    1687  break
    +
    1688  case -1: // control being killed
    +
    1689  break
    +
    1690  endswitch
    +
    1691 
    +
    1692  setdatafolder save_df
    +
    1693  return 0
    +
    1694 End
    +
    1695 
    +
    1696 static function bp_update_filelist(ba) : ButtonControl
    +
    1697  STRUCT WMButtonAction &ba
    +
    1698 
    +
    1699  switch( ba.eventCode )
    +
    1700  case 2: // mouse up
    +
    1701  update_filelist()
    +
    1702  update_controls()
    +
    1703  break
    +
    1704  case -1: // control being killed
    +
    1705  break
    +
    1706  endswitch
    +
    1707 
    +
    1708  return 0
    +
    1709 End
    +
    1710 
    +
    1712 static function /s pm_reduction_values()
    +
    1713  string reduction_funcs = adh5_list_reduction_funcs()
    +
    1714  reduction_funcs = RemoveFromList("adh5_default_reduction", reduction_funcs, ";")
    +
    1715  reduction_funcs = AddListItem("None", reduction_funcs, ";", 0)
    +
    1716  return reduction_funcs
    +
    1717 end
    +
    1718 
    +
    1719 static function pmp_reduction_func(pa) : PopupMenuControl
    +
    1720  STRUCT WMPopupAction &pa
    +
    1721 
    +
    1722  switch( pa.eventCode )
    +
    1723  case 2: // mouse up
    +
    1724  Variable popNum = pa.popNum
    +
    1725  String popStr = pa.popStr
    +
    1726  update_controls()
    +
    1727  break
    +
    1728  case -1: // control being killed
    +
    1729  break
    +
    1730  endswitch
    +
    1731 
    +
    1732  return 0
    +
    1733 End
    +
    1734 
    +
    1735 static function bp_reduction_params(ba) : ButtonControl
    +
    1736  STRUCT WMButtonAction &ba
    +
    1737 
    +
    1738  switch( ba.eventCode )
    +
    1739  case 2: // mouse up
    +
    1740  ControlInfo /W=PearlDataExplorer popup_reduction
    +
    1741  if ((cmpstr(S_Value, "None") != 0) && (exists(S_Value) == 6))
    +
    1742  svar pref_params = $(package_path + "s_reduction_params")
    +
    1743  string reduction_func = S_Value
    +
    1744  string reduction_params = pref_params
    +
    1745  if (prompt_func_params(reduction_func, reduction_params) == 0)
    +
    1746  pref_params = reduction_params
    +
    1747  endif
    +
    1748  endif
    +
    1749  break
    +
    1750  case -1: // control being killed
    +
    1751  break
    +
    1752  endswitch
    +
    1753 
    +
    1754  return 0
    +
    1755 End
    +
    1756 
    +
    1757 static function bp_load_options(ba) : ButtonControl
    +
    1758  STRUCT WMButtonAction &ba
    +
    1759 
    +
    1760  switch( ba.eventCode )
    +
    1761  case 2: // mouse up
    +
    1762  // options must be in the button's unnamed user data in the form: "mode:load_complete".
    +
    1763  // see load_pshell_file for recognized values.
    +
    1764  string options=ba.userData
    +
    1765 
    +
    1766  // data reduction popup
    +
    1767  ControlInfo /W=PearlDataExplorer popup_reduction
    +
    1768  if ((cmpstr(S_Value, "None") != 0) && (exists(S_Value) == 6))
    +
    1769  options = ReplaceStringByKey("reduction_func", options, S_Value, ":", ";")
    +
    1770  endif
    +
    1771 
    +
    1772  load_selected_files(options=options)
    +
    1773  break
    +
    1774  case -1: // control being killed
    +
    1775  break
    +
    1776  endswitch
    +
    1777 
    +
    1778  return 0
    +
    1779 End
    +
    1780 
    +
    1791 static function selected_file(file, do_preview)
    +
    1792  string file
    +
    1793  variable do_preview
    +
    1794 
    +
    1795  dfref save_df = GetDataFolderDFR()
    +
    1796  setdatafolder $package_path
    +
    1797  svar s_selected_file
    +
    1798  s_selected_file = file
    +
    1799  get_file_info(file)
    +
    1800  if (do_preview)
    +
    1801  preview_file(file)
    +
    1802  endif
    +
    1803  update_controls()
    +
    1804 
    +
    1805  setdatafolder save_df
    +
    1806  return 0
    +
    1807 end
    +
    1808 
    +
    1809 static function bp_file_next(ba) : ButtonControl
    +
    1810  STRUCT WMButtonAction &ba
    +
    1811 
    +
    1812  dfref save_df = GetDataFolderDFR()
    +
    1813 
    +
    1814  switch( ba.eventCode )
    +
    1815  case 2: // mouse up
    +
    1816  setdatafolder $package_path
    +
    1817  wave /t wtFiles
    +
    1818  wave wSelectedFiles
    +
    1819  FindValue /i=1 wSelectedFiles
    +
    1820  v_value += 1
    +
    1821  if (v_value >= numpnts(wtFiles))
    +
    1822  v_value = min(numpnts(wtFiles) - 1, 0)
    +
    1823  endif
    +
    1824  wSelectedFiles = p == v_value
    +
    1825  if (v_value >= 0)
    +
    1826  variable ifile = v_value
    +
    1827  ControlInfo /W=PearlDataExplorer cb_file_preview
    +
    1828  selected_file(wtFiles[ifile], v_value)
    +
    1829  endif
    +
    1830  update_controls()
    +
    1831  break
    +
    1832  case -1: // control being killed
    +
    1833  break
    +
    1834  endswitch
    +
    1835 
    +
    1836  setdatafolder save_df
    +
    1837  return 0
    +
    1838 End
    +
    1839 
    +
    1840 static function bp_file_prev(ba) : ButtonControl
    +
    1841  STRUCT WMButtonAction &ba
    +
    1842 
    +
    1843  dfref save_df = GetDataFolderDFR()
    +
    1844 
    +
    1845  switch( ba.eventCode )
    +
    1846  case 2: // mouse up
    +
    1847  setdatafolder $package_path
    +
    1848  wave /t wtFiles
    +
    1849  wave wSelectedFiles
    +
    1850  FindValue /i=1 wSelectedFiles
    +
    1851  v_value -= 1
    +
    1852  if (v_value < 0)
    +
    1853  v_value = numpnts(wtFiles) - 1
    +
    1854  endif
    +
    1855  wSelectedFiles = p == v_value
    +
    1856  if (v_value >= 0)
    +
    1857  variable ifile = v_value
    +
    1858  ControlInfo /W=PearlDataExplorer cb_file_preview
    +
    1859  selected_file(wtFiles[ifile], v_value)
    +
    1860  endif
    +
    1861  update_controls()
    +
    1862  break
    +
    1863  case -1: // control being killed
    +
    1864  break
    +
    1865  endswitch
    +
    1866 
    +
    1867  setdatafolder save_df
    +
    1868  return 0
    +
    1869 End
    +
    1870 
    +
    1871 static function lbp_filelist(lba) : ListBoxControl
    +
    1872  STRUCT WMListboxAction &lba
    +
    1873 
    +
    1874  dfref save_df = GetDataFolderDFR()
    +
    1875 
    +
    1876  Variable row = lba.row
    +
    1877  Variable col = lba.col
    +
    1878  WAVE/T/Z listWave = lba.listWave
    +
    1879  WAVE/Z selWave = lba.selWave
    +
    1880 
    +
    1881  switch( lba.eventCode )
    +
    1882  case -1: // control being killed
    +
    1883  break
    +
    1884  case 1: // mouse down
    +
    1885  setdatafolder $package_path
    +
    1886  wave wSelectedFiles
    +
    1887  if (selWave[row])
    +
    1888  if (sum(wSelectedFiles) == 1)
    +
    1889  ControlInfo /W=PearlDataExplorer cb_file_preview
    +
    1890  selected_file(listWave[row], v_value)
    +
    1891  else
    +
    1892  selected_file(listWave[row], 0)
    +
    1893  endif
    +
    1894  endif
    +
    1895  update_controls()
    +
    1896  break
    +
    1897  case 3: // double click
    +
    1898  break
    +
    1899  case 4: // cell selection
    +
    1900  case 5: // cell selection plus shift key
    +
    1901  break
    +
    1902  case 6: // begin edit
    +
    1903  break
    +
    1904  case 7: // finish edit
    +
    1905  break
    +
    1906  case 13: // checkbox clicked (Igor 6.2 or later)
    +
    1907  break
    +
    1908  endswitch
    +
    1909 
    +
    1910  setdatafolder save_df
    +
    1911  return 0
    +
    1912 End
    +
    1913 
    +
    1914 static function bp_attr_notebook(ba) : ButtonControl
    +
    1915  STRUCT WMButtonAction &ba
    +
    1916 
    +
    1917  dfref save_df = GetDataFolderDFR()
    +
    1918 
    +
    1919  switch( ba.eventCode )
    +
    1920  case 2: // mouse up
    +
    1921  setdatafolder $package_path
    +
    1922  wave wSelectedFiles
    +
    1923  wave/t wtFiles
    +
    1924  variable nn = numpnts(wSelectedFiles)
    +
    1925  variable ii
    +
    1926  for (ii = 0; ii < nn; ii += 1)
    +
    1927  if (wSelectedFiles[ii])
    +
    1928  attributes_notebook(wtFiles[ii])
    +
    1929  break
    +
    1930  endif
    +
    1931  endfor
    +
    1932  break
    +
    1933  case -1: // control being killed
    +
    1934  break
    +
    1935  endswitch
    +
    1936 
    +
    1937  setdatafolder save_df
    +
    1938  return 0
    +
    1939 End
    +
    1940 
    +
    1941 
    +
    1942 static function hlp_setup()
    +
    1943  dfref save_df = GetDataFolderDFR()
    +
    1944  setdatafolder $package_path
    +
    1945 
    +
    1946  MakeListIntoHierarchicalList("PearlDataExplorer", "lb_contents", "hlp_contents_open", selectionMode=WMHL_SelectionSingle, pathSeparator="/")
    +
    1947 
    +
    1948  setdatafolder save_df
    +
    1949  return 0
    +
    1950 end
    +
    1951 
    +
    1952 static function hl_contents_clear()
    +
    1953  do
    +
    1954  if (cmpstr(WMHL_GetItemForRowNumber("PearlDataExplorer", "lb_contents", 0), "<uninitialized>") != 0)
    +
    1955  WMHL_DeleteRowAndChildren("PearlDataExplorer", "lb_contents", 0)
    +
    1956  else
    +
    1957  break
    +
    1958  endif
    +
    1959  while (1)
    +
    1960 end
    +
    1961 
    +
    1966 static function hl_contents_update(file_df)
    +
    1967  dfref file_df
    +
    1968 
    +
    1969  dfref save_df = GetDataFolderDFR()
    +
    1970  setdatafolder $package_path
    + +
    1972 
    +
    1973  variable nds
    +
    1974  variable ids
    +
    1975  string ds
    +
    1976  string extra
    +
    1977  string /g hl_contents_datasets = ""
    +
    1978 
    +
    1979  if (DataFolderRefStatus(file_df))
    +
    1980  svar /sdfr=file_df datasets = s_datasets
    +
    1981  svar /sdfr=file_df datatypes = s_datasets_datatypes
    +
    1982  svar /sdfr=file_df ranks = s_datasets_ranks
    +
    1983  svar /sdfr=file_df dimensions = s_datasets_dimensions
    +
    1984 
    +
    1985  nds = ItemsInList(datasets, ";")
    +
    1986  for (ids = 0; ids < nds; ids += 1)
    +
    1987  ds = StringFromList(ids, datasets, ";")
    +
    1988  extra = StringFromList(ids, dimensions, ";")
    +
    1989  hl_contents_datasets = ReplaceStringByKey(ds, hl_contents_datasets, extra, ":", ";")
    +
    1990  endfor
    +
    1991  endif
    +
    1992 
    +
    1993  variable nobj = hl_add_objects("", hl_contents_datasets)
    +
    1994  hl_expand_scans()
    + +
    1996  setdatafolder save_df
    +
    1997 
    +
    1998  return nobj
    +
    1999 end
    +
    2000 
    +
    2001 static function /df get_pshell_info(path_name, file_name, [dest_df])
    +
    2002  string path_name
    +
    2003  string file_name
    +
    2004  dfref dest_df
    +
    2005 
    +
    2006  dfref save_df = GetDataFolderDFR()
    +
    2007 
    +
    2008  if (!ParamIsDefault(dest_df))
    +
    2009  setdatafolder dest_df
    +
    2010  else
    +
    2011  setdatafolder $package_path
    +
    2012  NewDataFolder /o /s file_info
    +
    2013  endif
    +
    2014 
    +
    2015  dfref file_df = psh5_open_file(path_name, file_name, dest_df=GetDataFolderDFR())
    +
    2016  if (DataFolderRefStatus(file_df))
    +
    2017  psh5_load_general_group(file_df)
    +
    2018  psh5_close_file(file_df)
    +
    2019  endif
    +
    2020 
    +
    2021  setdatafolder save_df
    +
    2022  return file_df
    +
    2023 end
    +
    2024 
    +
    2029 static function hl_add_objects(parent_path, objects)
    +
    2030  string parent_path // e.g. "/a/b"
    +
    2031  string objects // all objects that might appear in the list. e.g. "/a/b/c:col0|col1;/a/b/d:col0|col1;/d/e/f:col0|col1;"
    +
    2032 
    +
    2033  if (cmpstr(parent_path[0], "/") != 0)
    +
    2034  parent_path = "/" + parent_path
    +
    2035  endif
    +
    2036 
    +
    2037  variable nobj = ItemsInList(objects, ";")
    +
    2038  variable iobj
    +
    2039  string obj
    +
    2040  string extra
    +
    2041  variable nel
    +
    2042 
    +
    2043  string child_path = ""
    +
    2044  string child_name = ""
    +
    2045  string child_names = "" // e.g., "child1:1;child3:2;"
    +
    2046  string extra_data = "" // e.g., "child1:col0|col1;child2:col0|col1;"
    +
    2047 
    +
    2048  // filter children of parent
    +
    2049  for (iobj = 0; iobj < nobj; iobj += 1)
    +
    2050  obj = StringFromList(iobj, objects, ";")
    +
    2051 
    +
    2052  if (cmpstr(obj[0, strlen(parent_path)-1], parent_path) == 0)
    +
    2053  child_path = StringFromList(0, obj, ":")
    +
    2054  child_path = child_path[strlen(parent_path), strlen(child_path)-1]
    +
    2055  if (cmpstr(child_path[0], "/") == 0)
    +
    2056  child_path = child_path[1, strlen(child_path)-1]
    +
    2057  endif
    +
    2058  child_name = StringFromList(0, child_path, "/")
    +
    2059  nel = ItemsInList(child_path, "/")
    +
    2060  child_names = ReplaceNumberByKey(child_name, child_names, nel)
    +
    2061  if (nel == 1)
    +
    2062  extra = RemoveListItem(0, obj, ":")
    +
    2063  extra_data = ReplaceStringByKey(child_name, extra_data, extra)
    +
    2064  endif
    +
    2065  endif
    +
    2066  endfor
    +
    2067 
    +
    2068  // add rows
    +
    2069  variable row
    +
    2070  variable children
    +
    2071  nobj = ItemsInList(child_names)
    +
    2072  for (iobj = 0; iobj < nobj; iobj += 1)
    +
    2073  obj = StringFromList(iobj, child_names)
    +
    2074  child_name = StringFromList(0, obj, ":")
    +
    2075  nel = NumberByKey(child_name, child_names)
    +
    2076  WMHL_AddObject("PearlDataExplorer", "lb_contents", parent_path[1, strlen(parent_path)], child_name, nel > 1)
    +
    2077  if (nel == 1)
    +
    2078  extra = StringByKey(child_name, extra_data)
    +
    2079  row = WMHL_GetRowNumberForItem("PearlDataExplorer", "lb_contents", parent_path[1, strlen(parent_path)] + "/" + child_name)
    +
    2080  if (row >= 0)
    +
    2081  WMHL_ExtraColumnData("PearlDataExplorer", "lb_contents", 0, row, StringFromList(0, extra, "|"), 0)
    +
    2082  endif
    +
    2083  endif
    +
    2084  endfor
    +
    2085 
    +
    2086  return nobj
    +
    2087 end
    +
    2088 
    +
    2089 static function hl_expand_scans()
    +
    2090  dfref save_df = GetDataFolderDFR()
    +
    2091  setdatafolder $package_path
    +
    2092 
    +
    2093  svar hl_contents_datasets
    +
    2094  variable nds = ItemsInList(hl_contents_datasets, ";")
    +
    2095  variable ids
    +
    2096  string sds
    +
    2097  string scan
    +
    2098  string scans = ""
    +
    2099  for (ids = 0; ids < nds; ids += 1)
    +
    2100  sds = StringFromList(ids, hl_contents_datasets, ";")
    +
    2101  if (cmpstr(sds[0,4], "/scan", 0) == 0)
    +
    2102  scan = StringFromList(1, sds, "/")
    +
    2103  scans = ReplaceNumberByKey(scan, scans, 1)
    +
    2104  endif
    +
    2105  endfor
    +
    2106 
    +
    2107  variable nscans = ItemsInList(scans)
    +
    2108  variable iscan
    +
    2109  for (iscan = 0; iscan < nscans; iscan += 1)
    +
    2110  scan = StringFromList(iscan, scans)
    +
    2111  scan = StringFromList(0, scan, ":")
    +
    2112  WMHL_OpenAContainer("PearlDataExplorer", "lb_contents", scan)
    +
    2113  endfor
    +
    2114 
    +
    2115  setdatafolder save_df
    +
    2116 end
    +
    2117 
    +
    2118 static function hl_default_selection()
    +
    2119  variable row
    +
    2120  row = WMHL_GetRowNumberForItem("PearlDataExplorer", "lb_contents", "scan 1")
    +
    2121  if (row < 0)
    +
    2122  row = WMHL_GetRowNumberForItem("PearlDataExplorer", "lb_contents", "scan1")
    +
    2123  endif
    +
    2124  if (row >= 0)
    +
    2125  WMHL_SelectARow("PearlDataExplorer", "lb_contents", row, 1)
    +
    2126  endif
    +
    2127 end
    +
    2128 
    +
    2129 static function hlp_contents_open(HostWindow, ListControlName, ContainerPath)
    +
    2130  String HostWindow, ListControlName, ContainerPath
    +
    2131 
    +
    2132  dfref save_df = GetDataFolderDFR()
    +
    2133  setdatafolder $package_path
    +
    2134  svar hl_contents_datasets
    +
    2135  hl_add_objects(ContainerPath, hl_contents_datasets)
    +
    2136  setdatafolder save_df
    +
    2137 end
    +
    2138 
    +
    2139 static function hlp_contents_selection(HostWindow, ListControlName, SelectedItem, EventCode)
    +
    2140  String HostWindow, ListControlName
    +
    2141  String SelectedItem
    +
    2142  Variable EventCode
    +
    2143 
    +
    2144  dfref save_df = GetDataFolderDFR()
    +
    2145  setdatafolder $package_path
    +
    2146 
    +
    2147  switch (eventCode)
    +
    2148  case 3: // double click
    +
    2149  // todo: load dataset?
    +
    2150  break
    +
    2151  case 4: // cell selection
    +
    2152  case 5: // cell selection plus shift key
    +
    2153  update_controls()
    +
    2154  break
    +
    2155  endswitch
    +
    2156 
    +
    2157  setdatafolder save_df
    +
    2158  return 0
    +
    2159 end
    +
    2160 
    +
    2175 static function goto_dataset_folder(filename, datapath)
    +
    2176  string filename
    +
    2177  string datapath
    +
    2178 
    +
    2179  dfref save_df = GetDataFolderDFR()
    +
    2180  setdatafolder $package_path
    +
    2181 
    +
    2182  variable ft = pearl_file_type(filename)
    +
    2183  string parent_folder
    +
    2184  string folder
    +
    2185  string path
    +
    2186 
    +
    2187  switch(ft)
    +
    2188  case 1:
    +
    2189  case 2:
    +
    2190  parent_folder = ad_suggest_foldername(filename)
    +
    2191  path = "root:" + parent_folder
    +
    2192  if (DataFolderExists(path))
    +
    2193  setdatafolder $path
    +
    2194  else
    +
    2195  return -2
    +
    2196  endif
    +
    2197 
    +
    2198  variable nparts = ItemsInList(datapath, "/")
    +
    2199  variable ipart
    +
    2200  for (ipart = 0; ipart < nparts; ipart += 1)
    +
    2201  folder = StringFromList(ipart, datapath, "/")
    +
    2202  path = ":" + ps_fix_folder_name(folder)
    +
    2203  if (DataFolderExists(path))
    +
    2204  setdatafolder $path
    +
    2205  endif
    +
    2206  endfor
    +
    2207  break
    +
    2208 
    +
    2209  case 3:
    +
    2210  parent_folder = "root:" + itx_suggest_foldername(filename)
    +
    2211  if (DataFolderExists(parent_folder))
    +
    2212  setdatafolder $parent_folder
    +
    2213  else
    +
    2214  return -2
    +
    2215  endif
    +
    2216  break
    +
    2217 
    +
    2218  default:
    +
    2219  // unsupported file type
    +
    2220  return -1
    +
    2221  endswitch
    +
    2222 
    +
    2223  return 0
    +
    2224 end
    +
    2225 
    +
    2231 static function bp_goto_dataset(ba) : ButtonControl
    +
    2232  STRUCT WMButtonAction &ba
    +
    2233 
    +
    2234  switch( ba.eventCode )
    +
    2235  case 2: // mouse up
    +
    2236  dfref save_df = GetDataFolderDFR()
    +
    2237  setdatafolder $package_path
    +
    2238  svar s_selected_file
    +
    2239  svar hl_contents_datasets
    +
    2240  string datapath = StringFromList(0, WMHL_SelectedObjectsList("PearlDataExplorer", "lb_contents"))
    +
    2241  if (strsearch(hl_contents_datasets, datapath, 0) != 0)
    +
    2242  datapath = datapath + "/"
    +
    2243  endif
    +
    2244  variable result = goto_dataset_folder(s_selected_file, datapath)
    +
    2245  if (result != 0)
    +
    2246  setdatafolder save_df
    +
    2247  string msg
    +
    2248  msg = "Can't find data folder. Has the file been loaded?"
    +
    2249  DoAlert /T="Goto DF" 0, msg
    +
    2250  endif
    +
    2251 
    +
    2252  break
    +
    2253  case -1: // control being killed
    +
    2254  break
    +
    2255  endswitch
    +
    2256 
    +
    2257  return 0
    +
    2258 End
    +
    2259 
    +
    2263 static function bp_display_dataset(ba) : ButtonControl
    +
    2264  STRUCT WMButtonAction &ba
    +
    2265 
    +
    2266  switch( ba.eventCode )
    +
    2267  case 2: // mouse up
    +
    2268  dfref save_df = GetDataFolderDFR()
    +
    2269  setdatafolder $package_path
    +
    2270  svar s_selected_file
    +
    2271  svar hl_contents_datasets
    +
    2272  string datapath = StringFromList(0, WMHL_SelectedObjectsList("PearlDataExplorer", "lb_contents"))
    +
    2273  if (strsearch(hl_contents_datasets, datapath, 0) < 0)
    +
    2274  // path leads to folder
    +
    2275  return 0
    +
    2276  endif
    +
    2277  goto_dataset_folder(s_selected_file, "")
    +
    2278  display_dataset(GetDataFolderDFR(), datapath)
    +
    2279  setdatafolder save_df
    +
    2280  break
    +
    2281  case -1: // control being killed
    +
    2282  break
    +
    2283  endswitch
    +
    2284 
    +
    2285  return 0
    +
    2286 End
    +
    2287 
    +
    2295 static function send_to_elog()
    +
    2296  dfref save_df = GetDataFolderDFR()
    +
    2297 
    +
    2298  dfref preview_df = $package_path
    +
    2299  svar /z /sdfr=preview_df s_selected_file
    +
    2300  svar /z /sdfr=preview_df s_preview_file
    +
    2301  svar /z /sdfr=preview_df s_preview_graph
    +
    2302 
    +
    2303  if (!SVAR_Exists(s_selected_file) || (strlen(s_selected_file) < 1))
    +
    2304  return 0
    +
    2305  endif
    +
    2306 
    +
    2307  // check data folder
    +
    2308  variable result = -1
    +
    2309  result = goto_dataset_folder(s_selected_file, "")
    +
    2310  if (result == 0)
    +
    2311  dfref data_df = GetDataFolderDFR()
    +
    2312  svar /sdfr=data_df /z authors
    +
    2313  if (!svar_Exists(authors))
    +
    2314  result = -1
    +
    2315  endif
    +
    2316  endif
    +
    2317 
    +
    2318  // file info folder
    +
    2319  dfref infoDF = preview_df:file_info
    +
    2320  if ((result != 0) && (DataFolderRefStatus(infoDF)))
    +
    2321  svar /z /sdfr=infoDF s_filepath
    +
    2322  if (SVAR_Exists(s_filepath) && (strsearch(s_filepath, s_selected_file, inf, 1) >= 0))
    +
    2323  dfref data_df = infoDF
    +
    2324  result = 0
    +
    2325  endif
    +
    2326  endif
    +
    2327 
    +
    2328  // check preview (package) folder
    +
    2329  if ((result != 0) && (SVAR_Exists(s_preview_file) && (cmpstr(s_preview_file, s_selected_file) == 0)))
    +
    2330  dfref data_df = preview_df
    +
    2331  result = 0
    +
    2332  endif
    +
    2333 
    +
    2334  string graphname
    +
    2335  if (SVAR_Exists(s_preview_graph) && (WinType(s_preview_graph) == 1))
    +
    2336  graphname = s_preview_graph
    +
    2337  else
    +
    2338  graphname = ""
    +
    2339  endif
    +
    2340 
    +
    2341  if (result == 0)
    +
    2342  set_elog_attributes(data_df, filename=s_selected_file, graphname=graphname)
    +
    2343  string windowname
    +
    2344  windowname = StringFromList(0, WinList("*ElogPanel*", ";", "WIN:64"), ";")
    +
    2345  DoWindow /F $windowname
    +
    2346  endif
    +
    2347 
    +
    2348  setdatafolder save_df
    +
    2349 end
    +
    2350 
    +
    2351 static function bp_elog(ba) : ButtonControl
    +
    2352  STRUCT WMButtonAction &ba
    +
    2353 
    +
    2354  switch( ba.eventCode )
    +
    2355  case 2: // mouse up
    +
    2356  send_to_elog()
    +
    2357  break
    +
    2358  case -1: // control being killed
    +
    2359  break
    +
    2360  endswitch
    +
    2361 
    +
    2362  return 0
    +
    2363 End
    +
    2364 
    +
    variable pearl_data_explorer()
    show the pearl data explorer window
    +
    static variable save_prefs()
    save persistent package data to the preferences file.
    +
    static variable bp_goto_dataset(WMButtonAction *ba)
    "goto DF" button
    +
    string ps_fix_folder_name(string group_name)
    convert HDF5 group name to data folder name and fix compatibility issues
    +
    static variable hlp_contents_selection(string HostWindow, string ListControlName, string SelectedItem, variable EventCode)
    +
    string adh5_list_reduction_funcs()
    get a list of functions which can be used as reduction functions.
    +
    static string show_preview_graph(wave data, wave xdata=defaultValue)
    +
    string ad_display_slice(wave data)
    display three-dimensional data by 2D slice.
    +
    static variable preview_datafolder()
    preview data in the current data folder
    +
    const variable kDSCEssentialDiags
    +
    static variable update_controls()
    update controls state
    +
    static const string ks_filematch_pshell
    +
    variable prompt_default_process(string *param)
    prototype for prompting for processing function parameters.
    +
    static dfr get_pshell_info(string path_name, string file_name, dfref dest_df=defaultValue)
    +
    string adh5_load_preview(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    load a single image from a HDF5 file created by the Area Detector software.
    +
    static variable load_selected_files(string options=defaultValue)
    load the selected files
    +
    string psh5_load_general_group(dfref file_df)
    load organizational metadata from the general group.
    +
    static variable bp_elog(WMButtonAction *ba)
    +
    static variable update_filelist()
    read a list of PEARL files from the file system
    +
    static variable create_attributes_notebook(wave attr_names, wave attr_values, string title)
    +
    static variable hl_default_selection()
    +
    string adh5_load_info(string APathName, string AFileName)
    load descriptive info from a HDF5 file created by the Area Detector software.
    +
    static variable notebook_add_attributes(string notebook_name, wave attr_filter, wave attr_names, wave attr_values)
    +
    const variable kDSCMonitors
    +
    static variable pmp_reduction_func(WMPopupAction *pa)
    +
    static variable prompt_hdf_options(string *options)
    +
    static variable load_file(string filename, string options=defaultValue, dfref dest_df=defaultValue, variable quiet=defaultValue)
    load one file
    +
    static variable hl_contents_clear()
    +
    const variable kDSCPositioners
    +
    static const string ks_filematch_adh5
    +
    static variable bp_attr_notebook(WMButtonAction *ba)
    +
    void PearlDataExplorer()
    +
    static wave preview_pshell_file(string filename)
    load the preview of a PShell HDF5 file.
    +
    static variable bp_load_prefs(WMButtonAction *ba)
    +
    static const string ks_filematch_itx
    +
    const variable kDSCScientaScaling
    +
    static variable bp_save_prefs(WMButtonAction *ba)
    +
    interface for writing ELOG entries with Igor graphs as attachment.
    +
    string psh5_extract_region_paths(string datasets)
    trim dataset paths to the scan/region part
    +
    static variable selected_file(string file, variable do_preview)
    actions after a file has been selected
    +
    static variable display_dataset(dfref file_df, string dataset)
    displays the graph of a loaded dataset in its own window
    +
    static variable init_package()
    +
    static variable preview_setscale_x(wave data, wave preview)
    +
    static string shorten_filepath(string long_path, variable max_len)
    shorten a file path for display
    +
    static variable bp_browse_filepath(WMButtonAction *ba)
    +
    static variable set_elog_attributes(dfref file_df, string filename=defaultValue, string graphname=defaultValue)
    send general metadata to ELOG panel - if available
    +
    static variable lbp_filelist(WMListboxAction *lba)
    +
    static variable bp_display_dataset(WMButtonAction *ba)
    "display dataset" button
    +
    static variable extract_attributes(dfref attr_df, dfref dest_df=defaultValue, wave attr_filter=defaultValue, variable include_datawaves=defaultValue, variable include_infowaves=defaultValue)
    extract summary from attribute waves
    +
    const variable kDSCSnaps
    +
    static variable attributes_notebook(string filename)
    load attributes
    +
    dfr psh5_dataset_to_folder(dfref parent_df, string datasetpath)
    map dataset path to datafolder path
    +
    string ad_suggest_foldername(string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
    generate the name of a data folder based on a file name.
    +
    const variable kDSCMeta
    +
    static dfr load_itx_file(string filename, string options=defaultValue, dfref dest_df=defaultValue, variable quiet=defaultValue)
    +
    const variable kDSCDiags
    +
    static variable goto_dataset_folder(string filename, string datapath)
    open data folder corresponding to a file and data path
    +
    static variable get_file_info(string filename)
    load the internal structure of a file
    +
    static dfr load_pshell_file(string filename, string options=defaultValue, dfref dest_df=defaultValue, variable quiet=defaultValue)
    load a pshell file
    +
    string adh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    import everything from a HDF5 file created by the Area Detector software.
    +
    dfr ps_find_attr_folder(dfref scan_df)
    find the attributes data folder
    +
    static variable hl_contents_update(dfref file_df)
    populate the contents list box with the internal directory of a HDF5 file
    +
    string itx_suggest_foldername(string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
    suggest the name of a data folder based on an igor-text file name
    +
    const variable kDSCAttrs
    +
    static variable bp_reduction_params(WMButtonAction *ba)
    +
    static variable send_to_elog()
    send file metadata to the ELOG panel
    +
    static variable bp_file_next(WMButtonAction *ba)
    +
    static variable hlp_setup()
    +
    threadsafe wave adh5_default_reduction(wave source, string *param)
    function prototype for adh5_load_reduced_detector
    +
    threadsafe wave ad_extract_slab(wave dataset, variable x1, variable x2, variable y1, variable y2, variable z1, variable z2, string destname, variable noavg=defaultValue, variable pscale=defaultValue)
    2D cut through 3D dataset, integrate in normal dimension
    +
    static wave preview_itx_file(string filename)
    load the preview of a general ITX file.
    +
    static variable update_filepath()
    update the file path after path change
    +
    const variable kDSCDetectors
    +
    dfr psh5_preview(string path_name, string file_name, dfref dest_df=defaultValue, string preview_datasets=defaultValue)
    load preview
    +
    variable test_attributes_notebook()
    +
    static variable pearl_file_type(string filename)
    check whether a file can be imported by this module.
    +
    variable psh5_close_file(dfref file_df)
    close a HDF5 file opened by psh5_open_file.
    + +
    string adh5_load_reduced(string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable load_data=defaultValue, variable load_attr=defaultValue, variable progress=defaultValue)
    load and reduce a dataset from a HDF5 file created by the Area Detector software.
    +
    static string pm_reduction_values()
    items for data reduction popup
    +
    string PearlCleanupName(string name)
    +
    static variable load_prefs()
    +
    variable prompt_func_params(string func_name, string *func_param)
    +
    dfr psh5_load(string path_name, string file_name, string scans, string regions, string datasets, variable classes=defaultValue, variable max_rank=defaultValue, string reduction_func=defaultValue, string reduction_params=defaultValue, dfref dest_df=defaultValue)
    main data loading function
    +
    static dfr load_hdf_file(string filename, string options=defaultValue, dfref dest_df=defaultValue, variable quiet=defaultValue)
    +
    static variable hlp_contents_open(string HostWindow, string ListControlName, string ContainerPath)
    +
    static variable bp_update_filelist(WMButtonAction *ba)
    +
    static variable extract_preview_image(wave data, wave preview)
    extract a preview image from a wave of arbitrary dimension
    +
    static variable bp_file_prev(WMButtonAction *ba)
    +
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    +
    variable ad_brick_slicer(wave data)
    open a slicer panel for 3D data.
    +
    static variable preview_file(string filename)
    +
    string psh5_extract_scan_paths(string datasets)
    trim dataset paths to the scan part
    +
    dfr psh5_open_file(string path_name, string file_name, dfref dest_df=defaultValue)
    open a HDF5 file created by the PShell data acquisition program and prepare the data folder.
    +
    static const string package_name
    package name is used as data folder name
    +
    static string display_preview_trace(wave xtrace, wave ytrace)
    +
    static variable hl_expand_scans()
    +
    static variable bp_load_options(WMButtonAction *ba)
    +
    static variable hl_add_objects(string parent_path, string objects)
    populate the contents list box with the given hierarchical paths
    +
    static const string package_path
    +
    const variable kDSCAll
    +
    static wave preview_hdf_file(string filename)
    load the preview of a PEARL HDF5 file.
    diff --git a/doc/html/pearl-elog_8ipf.html b/doc/html/pearl-elog_8ipf.html index 7877fc8..a01cbb0 100644 --- a/doc/html/pearl-elog_8ipf.html +++ b/doc/html/pearl-elog_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-elog.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -104,115 +106,115 @@ Namespaces

    Functions

    variable pearl_elog (string logbook) - main function to initialize ELOG and to open an ELOG panel. More...
    + main function to initialize ELOG and to open an ELOG panel. More...
      static variable IgorBeforeNewHook (string igorApplicationNameStr) - save preferences and recent values before Igor opens a new experiment. More...
    + save preferences and recent values before Igor opens a new experiment. More...
      static variable IgorQuitHook (string igorApplicationNameStr) - save preferences and recent values before Igor quits. More...
    + save preferences and recent values before Igor quits. More...
      static variable AfterFileOpenHook (variable refNum, string file, string pathName, string type, string creator, variable kind) - initialize the package and reload preferences after an experiment is loaded. More...
    + initialize the package and reload preferences after an experiment is loaded. More...
      static dfr get_elog_df (string name, variable category) - get the package, logbook, or template datafolder. More...
    + get the package, logbook, or template datafolder. More...
      static variable init_package (variable clean=defaultValue) - initialize the package data folder. More...
    + initialize the package data folder. More...
      variable elog_init_pearl_templates () - setup PEARL template logbooks. More...
    + setup PEARL template logbooks. More...
      static variable init_volatile_vars () - initialize volatile variables. More...
    + initialize volatile variables. More...
      variable elog_create_logbook (string name, string template=defaultValue) - create a new logbook. More...
    + create a new logbook. More...
      variable elog_config (string elog_path=defaultValue, string hostname=defaultValue, variable port=defaultValue, string subdir=defaultValue) - set global module configuration parameters More...
    + set global module configuration parameters More...
      variable elog_login (string logbook, string username, string password) - set username and password for login to a logbook More...
    + set username and password for login to a logbook More...
      variable elog_logout (string logbook) - clear username and password of a logbook or all logbooks. More...
    + clear username and password of a logbook or all logbooks. More...
      static variable save_prefs () - save persistent package data to the preferences file. More...
    + save persistent package data to the preferences file. More...
      static variable load_prefs () - load persistent package data from the preferences file. More...
    + load persistent package data from the preferences file. More...
      static string list_logbooks (variable templates=defaultValue) - get a list of configured logbooks or templates. More...
    + get a list of configured logbooks or templates. More...
      variable elog_validate_attributes (string logbook, string attributes) - validate attributes More...
    + validate attributes More...
      variable elog_create_entry (string logbook, string attributes, string message, variable encoding=defaultValue, string graphs=defaultValue, variable replyto=defaultValue) - create a new entry in ELOG More...
    + create a new entry in ELOG More...
      variable elog_add_attachment (string logbook, variable id, string graphs) - add one or more graphs to an existing ELOG entry More...
    + add one or more graphs to an existing ELOG entry More...
      static string prepare_command_line (string logbook) - format the ELOG command and essential address arguments. More...
    + format the ELOG command and essential address arguments. More...
      static string format_url (string logbook) - format the URL for display to the user More...
    + format the URL for display to the user More...
      static string prepare_graph_attachments (string graphs) - prepare screenshots of graph windows for attachments More...
    + prepare screenshots of graph windows for attachments More...
      static string get_timestamp (string sep)   static string create_message_file (string message) - save the message to a temporary text file More...
    + save the message to a temporary text file More...
      static string create_graph_file (string graphname, variable fileindex) - save a graph to a temporary graphics file More...
    + save a graph to a temporary graphics file More...
      static string create_cmd_file (string cmd) - write the command line to a file. More...
    + write the command line to a file. More...
      static string get_log_path ()   static variable cleanup_temp_files () - delete temporary files created by the ELOG module. More...
    + delete temporary files created by the ELOG module. More...
      static variable parse_result () - parse the result file from an elog invokation. More...
    + parse the result file from an elog invokation. More...
      string elog_prompt_logbook () - prompt to open or create a logbook More...
    + prompt to open or create a logbook More...
      variable elog_prompt_login (string logbook) - prompt the user for login to a logbook More...
    + prompt the user for login to a logbook More...
      string PearlElogPanel (string logbook) - open a new panel for submitting data to ELOG. More...
    + open a new panel for submitting data to ELOG. More...
      static variable elog_panel_hook (WMWinHookStruct *s)   static variable update_attach_items (string logbook) - update the list of attachments More...
    + update the list of attachments More...
      static variable move_attach_item (string logbook, variable item, variable distance) - move an attachment item in the list of attachments More...
    + move an attachment item in the list of attachments More...
      static variable bp_attach_updown (WMButtonAction *ba) - button procedure for the attachment up and down buttons More...
    + button procedure for the attachment up and down buttons More...
      static variable bp_submit (WMButtonAction *ba) - button procedure for the Submit and Reply buttons More...
    + button procedure for the Submit and Reply buttons More...
      static variable bp_attach_top (WMButtonAction *ba) - select top graph window for attachment More...
    + select top graph window for attachment More...
      static variable bp_attach_allnone (WMButtonAction *ba) - select/deselect all graph windows for attachment More...
    + select/deselect all graph windows for attachment More...
      static variable bp_attach (WMButtonAction *ba)   @@ -227,22 +229,22 @@ Functions static string get_default_panel_name ()   static string get_panel_attributes (string windowname) - get a list of attributes from the fields of the ELOG panel. More...
    + get a list of attributes from the fields of the ELOG panel. More...
      static string set_panel_attributes (string windowname, string attributes, variable clear=defaultValue) - set the fields of the ELOG panel More...
    + set the fields of the ELOG panel More...
      static string get_panel_message (string windowname) - get the message field of the ELOG panel More...
    + get the message field of the ELOG panel More...
      static string set_panel_message (string windowname, string message) - set the message field of the ELOG panel More...
    + set the message field of the ELOG panel More...
      static string get_panel_graphs (string windowname) - get the names of the graphs selected for attachment More...
    + get the names of the graphs selected for attachment More...
      static string set_panel_graphs (string windowname, string graphs) - update selection of graphs for attachment More...
    + update selection of graphs for attachment More...
     
  • attach any Igor graph to ELOG.
  • configurable logbook templates for logbooks that share the same configuration.
  • common server configurations available on the ELOG command line (hostname, port, SSL, username, password, sub-directory).
  • -
  • not specific to the configuration at PEARL. PEARL code is concentrated in the elog_init_pearl_templates() function.
  • +
  • not specific to the configuration at PEARL. PEARL code is concentrated in the elog_init_pearl_templates() function.
  • the configuration of the ELOG server and logbooks as well as the most recently used attributes are persisted in the preference file.
  • usage:

      @@ -309,9 +311,9 @@ Variables * [-n 0|1|2] Encoding: 0:ELcode,1:plain,2:HTML * -m <textfile>] | <text> *
      Author
      matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
      -

    @@ -278,7 +280,7 @@ Variables

    -

    Definition at line 1635 of file pearl-elog.ipf.

    +

    Definition at line 1636 of file pearl-elog.ipf.

    @@ -434,7 +436,7 @@ Variables

    select/deselect all graph windows for attachment

    -

    Definition at line 1614 of file pearl-elog.ipf.

    +

    Definition at line 1615 of file pearl-elog.ipf.

    @@ -464,7 +466,7 @@ Variables

    select top graph window for attachment

    -

    Definition at line 1598 of file pearl-elog.ipf.

    +

    Definition at line 1599 of file pearl-elog.ipf.

    @@ -494,7 +496,7 @@ Variables

    button procedure for the attachment up and down buttons

    -

    Definition at line 1519 of file pearl-elog.ipf.

    +

    Definition at line 1520 of file pearl-elog.ipf.

    @@ -522,7 +524,7 @@ Variables
    -

    Definition at line 1696 of file pearl-elog.ipf.

    +

    Definition at line 1697 of file pearl-elog.ipf.

    @@ -550,7 +552,7 @@ Variables
    -

    Definition at line 1712 of file pearl-elog.ipf.

    +

    Definition at line 1713 of file pearl-elog.ipf.

    @@ -578,7 +580,7 @@ Variables
    -

    Definition at line 1730 of file pearl-elog.ipf.

    +

    Definition at line 1731 of file pearl-elog.ipf.

    @@ -606,7 +608,7 @@ Variables
    -

    Definition at line 1668 of file pearl-elog.ipf.

    +

    Definition at line 1669 of file pearl-elog.ipf.

    @@ -636,7 +638,7 @@ Variables

    button procedure for the Submit and Reply buttons

    -

    Definition at line 1551 of file pearl-elog.ipf.

    +

    Definition at line 1552 of file pearl-elog.ipf.

    @@ -664,10 +666,10 @@ Variables

    delete temporary files created by the ELOG module.

    -

    this deletes all temporary graph files that are referenced by the volatile temp_graph_files list. temp_graph_files is a semicolon-delimited string. items are added by create_graph_file().

    +

    this deletes all temporary graph files that are referenced by the volatile temp_graph_files list. temp_graph_files is a semicolon-delimited string. items are added by create_graph_file().

    this function should be called before a new experiment is loaded or igor quits.

    -

    Definition at line 1115 of file pearl-elog.ipf.

    +

    Definition at line 1116 of file pearl-elog.ipf.

    @@ -699,7 +701,7 @@ Variables

    the command script changes the working directory to the Temporary directory. it also deletes a previous elog.log file.

    Note
    somewhere the command line (even inside command files) is limited to 1024 bytes. for this reason all files should now be in the Temporary directory assigned by igor.
    -

    Definition at line 1059 of file pearl-elog.ipf.

    +

    Definition at line 1060 of file pearl-elog.ipf.

    @@ -750,7 +752,7 @@ Variables
    Returns
    (string) name of the created file. empty string if unsuccessful.
    Version
    1.41 the return value has changed from full path to file name only due to the limited length of the command line (1024 bytes).
    -

    Definition at line 1023 of file pearl-elog.ipf.

    +

    Definition at line 1024 of file pearl-elog.ipf.

    @@ -790,7 +792,7 @@ Variables
    Returns
    (string) name of the created file. empty string if unsuccessful.
    Version
    1.41 the return value has changed from full path to file name only due to the limited length of the command line (1024 bytes).
    -

    Definition at line 982 of file pearl-elog.ipf.

    +

    Definition at line 983 of file pearl-elog.ipf.

    @@ -837,7 +839,7 @@ Variables
    Warning
    this will delete all existing attachments of the entry!
    -

    Definition at line 792 of file pearl-elog.ipf.

    +

    Definition at line 793 of file pearl-elog.ipf.

    @@ -881,7 +883,7 @@ Variables

    set global module configuration parameters

    -

    Definition at line 473 of file pearl-elog.ipf.

    +

    Definition at line 474 of file pearl-elog.ipf.

    @@ -956,7 +958,7 @@ Variables -

    Definition at line 685 of file pearl-elog.ipf.

    +

    Definition at line 686 of file pearl-elog.ipf.

    @@ -996,7 +998,7 @@ Variables -

    Definition at line 414 of file pearl-elog.ipf.

    +

    Definition at line 415 of file pearl-elog.ipf.

    @@ -1019,7 +1021,7 @@ Variables

    template logbooks for PEARL.

    Remarks
    this function is specific to the setup at PEARL.
    -

    Definition at line 262 of file pearl-elog.ipf.

    +

    Definition at line 263 of file pearl-elog.ipf.

    @@ -1057,7 +1059,7 @@ Variables

    set username and password for login to a logbook

    the username and password are stored (in plain text) in global strings under the selected logbook folder. this is necessary for sending data to the ELOG server.

    -

    call elog_logout() to clear the password variables and to avoid unintended use of your credentials.

    +

    call elog_logout() to clear the password variables and to avoid unintended use of your credentials.

    Warning
    igor does not have a built-in mechanism to protect passwords. user names and passwords are stored in plain text in the data folder tree. as such they are saved to experiment files and preferences.
    Parameters
    @@ -1066,7 +1068,7 @@ Variables -

    Definition at line 513 of file pearl-elog.ipf.

    +

    Definition at line 514 of file pearl-elog.ipf.

    @@ -1095,7 +1097,7 @@ Variables -

    Definition at line 533 of file pearl-elog.ipf.

    +

    Definition at line 534 of file pearl-elog.ipf.

    @@ -1123,7 +1125,7 @@ Variables
    -

    Definition at line 1395 of file pearl-elog.ipf.

    +

    Definition at line 1396 of file pearl-elog.ipf.

    @@ -1144,7 +1146,7 @@ Variables

    prompt to open or create a logbook

    -

    Definition at line 1184 of file pearl-elog.ipf.

    +

    Definition at line 1185 of file pearl-elog.ipf.

    @@ -1166,7 +1168,7 @@ Variables

    prompt the user for login to a logbook

    -

    Definition at line 1214 of file pearl-elog.ipf.

    +

    Definition at line 1215 of file pearl-elog.ipf.

    @@ -1200,7 +1202,7 @@ Variables
    Returns
    0 if all required attributes are present and enumerated items are correct. non-zero if a violation is detected.
    Todo:
    function currently not implemented, always returns 0
    -

    Definition at line 653 of file pearl-elog.ipf.

    +

    Definition at line 654 of file pearl-elog.ipf.

    @@ -1236,7 +1238,7 @@ Variables
    -

    Definition at line 902 of file pearl-elog.ipf.

    +

    Definition at line 903 of file pearl-elog.ipf.

    @@ -1263,7 +1265,7 @@ Variables
    -

    Definition at line 1747 of file pearl-elog.ipf.

    +

    Definition at line 1748 of file pearl-elog.ipf.

    @@ -1317,7 +1319,7 @@ Variables
    Returns
    data folder reference
    -

    Definition at line 170 of file pearl-elog.ipf.

    +

    Definition at line 171 of file pearl-elog.ipf.

    @@ -1344,7 +1346,7 @@ Variables
    -

    Definition at line 1095 of file pearl-elog.ipf.

    +

    Definition at line 1096 of file pearl-elog.ipf.

    @@ -1381,7 +1383,7 @@ Variables
    Returns
    list of attributes to in the format "key1=value1;key2=value2".
    -

    Definition at line 1760 of file pearl-elog.ipf.

    +

    Definition at line 1761 of file pearl-elog.ipf.

    @@ -1418,7 +1420,7 @@ Variables
    Returns
    a semicolon-separated list, or the empty string if the selection is not valid.
    -

    Definition at line 1926 of file pearl-elog.ipf.

    +

    Definition at line 1927 of file pearl-elog.ipf.

    @@ -1455,7 +1457,7 @@ Variables
    Returns
    message text
    -

    Definition at line 1880 of file pearl-elog.ipf.

    +

    Definition at line 1881 of file pearl-elog.ipf.

    @@ -1483,7 +1485,7 @@ Variables
    -

    Definition at line 958 of file pearl-elog.ipf.

    +

    Definition at line 959 of file pearl-elog.ipf.

    @@ -1513,7 +1515,7 @@ Variables

    save preferences and recent values before Igor opens a new experiment.

    -

    Definition at line 127 of file pearl-elog.ipf.

    +

    Definition at line 128 of file pearl-elog.ipf.

    @@ -1543,7 +1545,7 @@ Variables

    save preferences and recent values before Igor quits.

    -

    Definition at line 135 of file pearl-elog.ipf.

    +

    Definition at line 136 of file pearl-elog.ipf.

    @@ -1584,7 +1586,7 @@ Variables -

    Definition at line 217 of file pearl-elog.ipf.

    +

    Definition at line 218 of file pearl-elog.ipf.

    @@ -1613,9 +1615,9 @@ Variables

    initialize volatile variables.

    create and initialize all volatile variables for the configured notebooks. values of existing variables are not changed.

    -

    this function must be called after new logbooks have been configured, specifically by elog_create_logbook() and load_prefs().

    +

    this function must be called after new logbooks have been configured, specifically by elog_create_logbook() and load_prefs().

    -

    Definition at line 340 of file pearl-elog.ipf.

    +

    Definition at line 341 of file pearl-elog.ipf.

    @@ -1653,7 +1655,7 @@ Variables
    Returns
    semicolon-separated list of logbooks
    -

    Definition at line 618 of file pearl-elog.ipf.

    +

    Definition at line 619 of file pearl-elog.ipf.

    @@ -1683,7 +1685,7 @@ Variables

    load persistent package data from the preferences file.

    the preferences file is an Igor packed experiment file in a special preferences folder

    -

    Definition at line 584 of file pearl-elog.ipf.

    +

    Definition at line 585 of file pearl-elog.ipf.

    @@ -1729,7 +1731,7 @@ Variables

    move an attachment item in the list of attachments

    -

    Definition at line 1495 of file pearl-elog.ipf.

    +

    Definition at line 1496 of file pearl-elog.ipf.

    @@ -1759,7 +1761,7 @@ Variables

    parse the result file from an elog invokation.

    Returns
    the ID of the generated message, or a value <= 0 if an error occurred.
    -

    Definition at line 1141 of file pearl-elog.ipf.

    +

    Definition at line 1142 of file pearl-elog.ipf.

    @@ -1783,12 +1785,12 @@ Variables

    this function takes care of all necessary initialization, configuration, and preferences. if a panel exists, it will be moved to the front.

    Parameters
    - +
    logbookname of the logbook if empty, the user is prompted to select or create a logbook by elog_prompt_logbook().
    logbookname of the logbook if empty, the user is prompted to select or create a logbook by elog_prompt_logbook().
    -

    Definition at line 97 of file pearl-elog.ipf.

    +

    Definition at line 98 of file pearl-elog.ipf.

    @@ -1809,7 +1811,7 @@ Variables

    open a new panel for submitting data to ELOG.

    -

    this function creates only the panel but not the necessary data folders. call init_package() and load_prefs() once before creating panels.

    +

    this function creates only the panel but not the necessary data folders. call init_package() and load_prefs() once before creating panels.

    Parameters
    @@ -1817,7 +1819,7 @@ Variables -

    Definition at line 1241 of file pearl-elog.ipf.

    +

    Definition at line 1242 of file pearl-elog.ipf.

    @@ -1854,7 +1856,7 @@ Variables -

    Definition at line 853 of file pearl-elog.ipf.

    +

    Definition at line 854 of file pearl-elog.ipf.

    @@ -1891,7 +1893,7 @@ Variables -

    Definition at line 939 of file pearl-elog.ipf.

    +

    Definition at line 940 of file pearl-elog.ipf.

    @@ -1921,7 +1923,7 @@ Variables

    save persistent package data to the preferences file.

    saves everything under the persistent folder of the package.

    -

    Definition at line 564 of file pearl-elog.ipf.

    +

    Definition at line 565 of file pearl-elog.ipf.

    @@ -1979,7 +1981,7 @@ Variables -

    Definition at line 1807 of file pearl-elog.ipf.

    +

    Definition at line 1808 of file pearl-elog.ipf.

    @@ -2026,7 +2028,7 @@ Variables -

    Definition at line 1966 of file pearl-elog.ipf.

    +

    Definition at line 1967 of file pearl-elog.ipf.

    @@ -2074,7 +2076,7 @@ Variables
    Returns
    original message (unchanged)
    -

    Definition at line 1906 of file pearl-elog.ipf.

    +

    Definition at line 1907 of file pearl-elog.ipf.

    @@ -2104,7 +2106,7 @@ Variables

    update the list of attachments

    -

    Definition at line 1434 of file pearl-elog.ipf.

    +

    Definition at line 1435 of file pearl-elog.ipf.

    @@ -2129,7 +2131,7 @@ Variables
    logbookname of the target logbook
    -

    Definition at line 1134 of file pearl-elog.ipf.

    +

    Definition at line 1135 of file pearl-elog.ipf.

    @@ -2153,7 +2155,7 @@ Variables
    -

    Definition at line 1133 of file pearl-elog.ipf.

    +

    Definition at line 1134 of file pearl-elog.ipf.

    @@ -2177,7 +2179,7 @@ Variables
    -

    Definition at line 1431 of file pearl-elog.ipf.

    +

    Definition at line 1432 of file pearl-elog.ipf.

    @@ -2201,7 +2203,7 @@ Variables
    -

    Definition at line 1429 of file pearl-elog.ipf.

    +

    Definition at line 1430 of file pearl-elog.ipf.

    @@ -2225,7 +2227,7 @@ Variables
    -

    Definition at line 1430 of file pearl-elog.ipf.

    +

    Definition at line 1431 of file pearl-elog.ipf.

    @@ -2249,7 +2251,7 @@ Variables
    -

    Definition at line 155 of file pearl-elog.ipf.

    +

    Definition at line 156 of file pearl-elog.ipf.

    @@ -2273,7 +2275,7 @@ Variables
    -

    Definition at line 153 of file pearl-elog.ipf.

    +

    Definition at line 154 of file pearl-elog.ipf.

    @@ -2297,7 +2299,7 @@ Variables
    -

    Definition at line 156 of file pearl-elog.ipf.

    +

    Definition at line 157 of file pearl-elog.ipf.

    @@ -2321,7 +2323,7 @@ Variables
    -

    Definition at line 154 of file pearl-elog.ipf.

    +

    Definition at line 155 of file pearl-elog.ipf.

    @@ -2345,7 +2347,7 @@ Variables
    -

    Definition at line 85 of file pearl-elog.ipf.

    +

    Definition at line 86 of file pearl-elog.ipf.

    @@ -2369,7 +2371,7 @@ Variables
    -

    Definition at line 86 of file pearl-elog.ipf.

    +

    Definition at line 87 of file pearl-elog.ipf.

    @@ -2379,9 +2381,9 @@ Variables diff --git a/doc/html/pearl-elog_8ipf_source.html b/doc/html/pearl-elog_8ipf_source.html index 595137f..21d3993 100644 --- a/doc/html/pearl-elog_8ipf_source.html +++ b/doc/html/pearl-elog_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-elog.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,77 +87,1714 @@ $(document).ready(function(){initNavTree('pearl-elog_8ipf_source.html','');});
    pearl-elog.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.41
    3 #pragma IgorVersion = 6.2
    4 #pragma ModuleName = PearlElog
    5 
    6 // author: matthias.muntwiler@psi.ch
    7 // Copyright (c) 2013-17 Paul Scherrer Institut
    8 
    9 // Licensed under the Apache License, Version 2.0 (the "License");
    10 // you may not use this file except in compliance with the License.
    11 // You may obtain a copy of the License at
    12 // http://www.apache.org/licenses/LICENSE-2.0
    13 
    79 
    84 
    85 static strconstant package_name = "pearl_elog"
    86 static strconstant package_path = "root:packages:pearl_elog:"
    87 
    97 function pearl_elog(logbook)
    98  string logbook
    99 
    100  if (init_package() == 0)
    101  load_prefs()
    102  string templates = list_logbooks(templates=1)
    103  if (ItemsInList(templates) < 1)
    105  endif
    106  endif
    107 
    108  if (strlen(logbook) == 0)
    109  logbook = elog_prompt_logbook()
    110  endif
    111 
    112  string win_name = logbook + "ElogPanel"
    113  if (strlen(logbook) > 0)
    114  if (strlen(WinList(win_name, ";", "")) > 0)
    115  DoWindow /F $win_name
    116  else
    117  win_name = PearlElogPanel(logbook)
    118  STRUCT WMWinHookStruct s
    119  s.eventCode = 0
    120  s.winName = win_name
    121  elog_panel_hook(s)
    122  endif
    123  endif
    124 end
    125 
    127 static function IgorBeforeNewHook(igorApplicationNameStr)
    128  string igorApplicationNameStr
    129  save_prefs()
    131  return 0
    132 end
    133 
    135 static function IgorQuitHook(igorApplicationNameStr)
    136  string igorApplicationNameStr
    137  save_prefs()
    139  return 0
    140 end
    141 
    143 static function AfterFileOpenHook(refNum,file,pathName,type,creator,kind)
    144  Variable refNum,kind
    145  String file,pathName,type,creator
    146  if( (kind >= 1) && (kind <= 2))
    147  init_package(clean=1)
    148  load_prefs()
    149  endif
    150  return 0
    151 end
    152 
    153 static constant kdfRoot = 0
    154 static constant kdfVolatile = 1
    155 static constant kdfPersistent = 2
    156 static constant kdfTemplates = 3
    157 
    170 static function /df get_elog_df(name, category)
    171  string name
    172  variable category
    173 
    174  dfref df_package = $package_path
    175  dfref df_persistent = df_package:persistent
    176  dfref df_volatile = df_package:volatile
    177 
    178  switch(category)
    179  case kdfRoot:
    180  dfref df_parent = df_package
    181  break
    182  case kdfPersistent:
    183  dfref df_parent = df_persistent
    184  break
    185  case kdfTemplates:
    186  dfref df_parent = df_persistent:templates
    187  break
    188  case kdfVolatile:
    189  dfref df_parent = df_volatile
    190  break
    191  default:
    192  Abort "get_elog_df: undefined data folder category."
    193  endswitch
    194 
    195  if ((strlen(name) > 0) && (category >= 1))
    196  if (category == kdfTemplates)
    197  dfref df_logbooks = df_parent
    198  else
    199  dfref df_logbooks = df_parent:logbooks
    200  endif
    201  dfref df_logbook = df_logbooks:$name
    202  return df_logbook
    203  else
    204  return df_parent
    205  endif
    206 end
    207 
    217 static function init_package([clean])
    218  variable clean
    219 
    220  if (ParamIsDefault(clean))
    221  clean = 0
    222  endif
    223 
    224  dfref savedf = getdatafolderdfr()
    225  dfref df_root = get_elog_df("", kdfRoot)
    226  if ((clean == 0) && (DataFolderRefStatus(df_root) == 1))
    227  return 1
    228  endif
    229 
    230  setdatafolder root:
    231  newdatafolder /o/s packages
    232  newdatafolder /o/s $package_name
    233  dfref df_package_root = getdatafolderdfr()
    234  newdatafolder /o/s volatile
    235  dfref df_volatile = getdatafolderdfr()
    236  newdatafolder /o logbooks
    237  setdatafolder df_package_root
    238  newdatafolder /o/s persistent
    239  dfref df_persistent = getdatafolderdfr()
    240  newdatafolder /o logbooks
    241  newdatafolder /o templates
    242 
    243  // common configuration
    244  setdatafolder df_persistent
    245  string /g elog_path = "c:\\program files (x86)\\ELOG\\elog.exe"
    246  string /g hostname = "localhost"
    247  variable /g port = 0 // 0 = unspecified (default)
    248  variable /g ssl = 0 // 0 = plain text (incl. passwords), 1 = secure connection
    249  string /g subdir = ""
    250  variable /g loglevel = 4
    251 
    252  setdatafolder savedf
    253  return 0
    254 end
    255 
    263  dfref savedf = getdatafolderdfr()
    264 
    265  dfref df_root = get_elog_df("", kdfRoot)
    266  dfref df_persistent = get_elog_df("", kdfPersistent)
    267  dfref df_templates = get_elog_df("", kdfTemplates)
    268 
    269  // Experiments template
    270  setdatafolder df_templates
    271  newdatafolder /o/s Experiments
    272 
    273  // attributes (persistent)
    274  // available attributes
    275  string /g attributes = "author;project;p-group;sample;source;task;technique;file;valid;"
    276  // controls corresponding to attributes
    277  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
    278  string /g controls = "sv_author;sv_project;sv_pgroup;sv_sample;pm_source;pm_task;pm_technique;sv_file;cb_valid;"
    279  // attributes with fixed options, value item declares the options string
    280  string /g options = "source=sources;task=tasks;technique=techniques"
    281  // attributes which must be defined
    282  string /g required_attributes = "author;project;p-group;sample;source;task;technique;valid"
    283 
    284  // option lists
    285  string /g sources = "Manual Entry;PShell;Scienta Data;SScan Data;Prosilica Data;OTF Data;Beamline Status;LEED Data;QMS Data;Matrix Data;Igor Pro;Other"
    286  string /g tasks = "Measurement;Optimization;Analysis;Sample Preparation;Sample Storage;Comment;Development;Maintenance;Test;Other"
    287  string /g techniques = "XPS;UPS;XPD;XAS;XMCD;PhD;ARUPS;STM;STS;LEED;AES;QMS;MBE;Sputter/Anneal;Test;Other"
    288 
    289  // Calculations template
    290  setdatafolder df_templates
    291  newdatafolder /o/s Calculations
    292 
    293  // attributes (persistent)
    294  // available attributes
    295  string /g attributes = "author;project;p-group;sample;program;revision;machine;job;experiment;source path;result path;valid"
    296  // controls corresponding to attributes
    297  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
    298  string /g controls = "sv_author;sv_project;sv_pgroup;sv_sample;pm_program;sv_revision;pm_machine;sv_job;sv_experiment;sv_sourcepath;sv_resultpath;cb_valid"
    299  // attributes with fixed options, value item declares the options string
    300  string /g options = "program=programs;machine=machines"
    301  // attributes which must be defined
    302  string /g required_attributes = "author;project;sample"
    303 
    304  // option lists
    305  string /g programs = "PMSCO;EDAC;MSC;SSC;MUFPOT;DMSUP;Other"
    306  string /g machines = "PC;VM;Ra;Merlin;llcx;Other"
    307 
    308  // System template
    309  setdatafolder df_templates
    310  newdatafolder /o/s System
    311 
    312  // attributes (persistent)
    313  // available attributes
    314  string /g attributes = "author;type;system;source;file"
    315  // controls corresponding to attributes
    316  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
    317  string /g controls = "sv_author;pm_type;pm_system;pm_source;sv_file"
    318  // attributes with fixed options, value item declares the options string
    319  string /g options = "type=types;system=systems;source=sources"
    320  // attributes which must be defined
    321  string /g required_attributes = "author;type;system"
    322 
    323  // option lists
    324  string /g types = "Installation;Repair;Maintenance;Test;Commissioning;Bakeout;Incident;Cool-down;Warm-up;Storage;Other"
    325  string /g systems = "Vacuum;Control System;BL;XA;XP;SA;SP;T;LL;Monochromator;Carving;Scienta;STM;PC-Scienta;PC-Matrix;PC-Console;PC-Console-Win;PC-XP;EPS;LAC;Desiccator;Other"
    326  string /g sources = "Manual Entry;PShell;Scienta Data;SScan Data;Prosilica Data;OTF Data;Beamline Status;LEED Data;QMS Data;Matrix Data;Igor Pro;Other"
    327 
    328  setdatafolder savedf
    329  return 0
    330 end
    331 
    340 static function init_volatile_vars()
    341  dfref savedf = GetDataFolderDFR()
    342 
    343  dfref df_volatile_root = get_elog_df("", kdfVolatile)
    344  dfref df_volatile_parent = df_volatile_root:logbooks
    345 
    346  string logbooks = list_logbooks()
    347  string logbook
    348  variable nlb = ItemsInList(logbooks)
    349  variable ilb
    350 
    351  SetDataFolder df_volatile_root
    352  if (exists("temp_graph_files") != 2)
    353  string /g temp_graph_files = ""
    354  endif
    355 
    356  for (ilb = 0; ilb < nlb; ilb += 1)
    357  logbook = StringFromList(ilb, logbooks)
    358 
    359  SetDataFolder df_volatile_parent
    360  if (DataFolderExists(logbook))
    361  SetDataFolder $logbook
    362  else
    363  NewDataFolder /o/s $logbook
    364  endif
    365 
    366  if (exists("username") != 2)
    367  string /g username = ""
    368  endif
    369  if (exists("password") != 2)
    370  string /g password = ""
    371  endif
    372  if (exists("msg_id") != 2)
    373  variable /g msg_id = 0
    374  endif
    375  if (exists("att_list") != 1)
    376  make /n=(0,3) /t /o attach_list
    377  make /n=(0,3) /i /o attach_sel
    378  endif
    379  if (exists("url") != 2)
    380  string /g url = ""
    381  endif
    382  endfor
    383 
    384  SetDataFolder savedf
    385  return 0
    386 end
    387 
    401 
    414 function elog_create_logbook(name, [template])
    415  string name
    416  string template
    417 
    418  if (ParamIsDefault(template))
    419  template = ""
    420  endif
    421 
    422  dfref savedf = getdatafolderdfr()
    423  dfref df_root = get_elog_df("", kdfRoot)
    424  dfref df_persistent_root = get_elog_df("", kdfPersistent)
    425  dfref df_persistent_parent = df_persistent_root:logbooks
    426  dfref df_volatile_root = get_elog_df("", kdfVolatile)
    427  dfref df_volatile_parent = df_volatile_root:logbooks
    428 
    429  setdatafolder df_persistent_parent
    430  if (CheckName(name, 11) != 0)
    431  setdatafolder savedf
    432  Abort "invalid logbook name"
    433  return -1
    434  endif
    435 
    436  if (strlen(template) > 0)
    437  dfref df_template = get_elog_df(template, kdfTemplates)
    438  dfref df_existing = get_elog_df(name, kdfPersistent)
    439  if (DataFolderRefStatus(df_existing))
    440  KillDataFolder /Z df_existing
    441  endif
    442  DuplicateDataFolder df_template, df_persistent_parent:$name
    443  else
    444  NewDataFolder /o/s df_persistent_parent:$name
    445 
    446  // ELOG logbook name
    447  string /g logbook = name
    448  // attributes (persistent)
    449  // available attributes
    450  string /g attributes = ""
    451  // controls corresponding to attributes
    452  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
    453  string /g controls = ""
    454  // attributes with fixed options, value item declares the options string
    455  string /g options = ""
    456  // attributes which must be defined
    457  string /g required_attributes = ""
    458  endif
    459 
    460  // usage data (persistent)
    461  setdatafolder get_elog_df(name, kdfPersistent)
    462  string /g recent = ""
    463  string /g recent_message = ""
    464 
    466 
    467  setdatafolder savedf
    468  return 0
    469 end
    470 
    473 function elog_config([elog_path, hostname, port, subdir])
    474  string elog_path
    475  string hostname
    476  variable port
    477  string subdir
    478 
    479  dfref df = get_elog_df("", kdfPersistent)
    480 
    481  if (!ParamIsDefault(elog_path))
    482  svar /sdfr=df g_elog_path = elog_path
    483  g_elog_path = elog_path
    484  endif
    485  if (!ParamIsDefault(hostname))
    486  svar /sdfr=df g_hostname = hostname
    487  g_hostname = hostname
    488  endif
    489  if (!ParamIsDefault(port))
    490  nvar /sdfr=df g_port = port
    491  g_port = port
    492  endif
    493  if (!ParamIsDefault(subdir))
    494  svar /sdfr=df g_subdir = subdir
    495  g_subdir = subdir
    496  endif
    497 end
    498 
    513 function elog_login(logbook, username, password)
    514  string logbook
    515  string username
    516  string password
    517 
    518  dfref df = get_elog_df(logbook, kdfVolatile)
    519  svar /sdfr=df g_username=username
    520  svar /sdfr=df g_password=password
    521  g_username = username
    522  g_password = password
    523 end
    524 
    533 function elog_logout(logbook)
    534  string logbook
    535 
    536  dfref df = get_elog_df(logbook, kdfVolatile)
    537  if (strlen(logbook) > 0)
    538  svar /z /sdfr=df g_username=username
    539  svar /z /sdfr=df g_password=password
    540  if (svar_exists(g_username))
    541  g_username = ""
    542  endif
    543  if (svar_exists(g_password))
    544  g_password = ""
    545  endif
    546  else
    547  dfref df2 = df:logbooks
    548  variable nlb = CountObjectsDFR(df2, 4)
    549  variable ilb
    550  string slb
    551  for (ilb = 0; ilb < nlb; ilb += 1)
    552  slb = GetIndexedObjNameDFR(df2, 4, ilb)
    553  if (strlen(slb) > 0)
    554  elog_logout(slb)
    555  endif
    556  endfor
    557  endif
    558 end
    559 
    564 static function save_prefs()
    565  dfref saveDF = GetDataFolderDFR()
    566 
    567  dfref df = get_elog_df("", kdfPersistent)
    568  if (DataFolderRefStatus(df) == 1)
    569  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    570  fullPath += package_name
    571  NewPath/O/C/Q tempPackagePrefsPath, fullPath
    572  fullPath += ":preferences.pxp"
    573  SetDataFolder df
    574  SaveData /O /Q /R fullPath
    575  KillPath/Z tempPackagePrefsPath
    576  endif
    577 
    578  SetDataFolder saveDF
    579 end
    580 
    584 static function load_prefs()
    585  dfref saveDF = GetDataFolderDFR()
    586 
    587  variable result = -1
    588  init_package()
    589  setdatafolder get_elog_df("", kdfPersistent)
    590 
    591  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    592  fullPath += package_name
    593 
    594  GetFileFolderInfo /Q /Z fullPath
    595  if (V_Flag == 0) // Disk directory exists?
    596  fullPath += ":preferences.pxp"
    597  GetFileFolderInfo /Q /Z fullPath
    598  if (V_Flag == 0) // Preference file exist?
    599  LoadData /O /R /Q fullPath
    601  result = 0
    602  endif
    603  endif
    604 
    605  SetDataFolder saveDF
    606  return result
    607 end
    608 
    618 static function /s list_logbooks([templates])
    619  variable templates
    620 
    621  if (ParamIsDefault(templates))
    622  templates = 0
    623  endif
    624 
    625  dfref df_persistent = get_elog_df("", kdfPersistent)
    626  if (templates)
    627  dfref df_logbooks = df_persistent:templates
    628  else
    629  dfref df_logbooks = df_persistent:logbooks
    630  endif
    631  string logbooks = ""
    632 
    633  variable nlb = CountObjectsDFR(df_logbooks, 4)
    634  variable ilb
    635  string slb
    636  for (ilb = 0; ilb < nlb; ilb += 1)
    637  slb = GetIndexedObjNameDFR(df_logbooks, 4, ilb)
    638  if (strlen(slb) > 0)
    639  logbooks = AddListItem(slb, logbooks)
    640  endif
    641  endfor
    642 
    643  return SortList(logbooks, ";", 16)
    644 end
    645 
    653 function elog_validate_attributes(logbook, attributes)
    654 
    655  string logbook // name of the logbook (as in igor folder name)
    656  string attributes // key=value list of attributes, semicolon separated
    657 
    658  variable result = 0
    659  return result
    660 end
    661 
    685 function elog_create_entry(logbook, attributes, message, [encoding, graphs, replyto])
    686  string logbook
    687  string attributes
    688  string message
    689  variable encoding
    690  string graphs
    691  variable replyto
    692 
    693  if (ParamIsDefault(encoding))
    694  encoding = 1
    695  endif
    696  if (ParamIsDefault(graphs))
    697  graphs = ""
    698  endif
    699  if (ParamIsDefault(replyto))
    700  replyto = 0
    701  endif
    702 
    703  dfref savedf = getdatafolderdfr()
    704  dfref df_general = get_elog_df("", kdfPersistent)
    705  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    706 
    707  variable result = 0
    708  nvar /sdfr=df_volatile msg_id
    709  nvar /sdfr=df_general loglevel
    710 
    711  if (elog_validate_attributes(logbook,attributes) != 0)
    712  if (loglevel >= 2)
    713  print "ELOG: failed to validate attributes."
    714  endif
    715  result = -3
    716  endif
    717 
    718  string cmd = prepare_command_line(logbook)
    719  if (strlen(cmd) == 0)
    720  if (loglevel >= 2)
    721  print "ELOG: failed to prepare command line."
    722  endif
    723  result = -2
    724  endif
    725 
    726  if (replyto >= 1)
    727  cmd += " -r " + num2str(replyto)
    728  endif
    729  cmd += " -n " + num2str(encoding)
    730 
    731  variable nattr = ItemsInList(attributes, ";")
    732  variable iattr
    733  string sattr
    734  for (iattr = 0; (iattr < nattr) && (result == 0); iattr += 1)
    735  sattr = StringFromList(iattr, attributes, ";")
    736  if (strlen(StringFromList(1, sattr, "=")) > 0)
    737  sattr = ReplaceString("%", sattr, "")
    738  cmd += " -a \"" + sattr + "\""
    739  endif
    740  endfor
    741 
    742  if (result == 0)
    743  string cmd_graphs = prepare_graph_attachments(graphs)
    744  cmd += " " + cmd_graphs
    745  endif
    746 
    747  if ((result == 0) && (strlen(message) > 0))
    748  string messagefile = create_message_file(message)
    749  if (strlen(messagefile) > 0)
    750  cmd += " -m \"" + messagefile + "\""
    751  cmd += " > elog.log"
    752  if (loglevel >= 5)
    753  print cmd
    754  endif
    755  string cmd_file_path = create_cmd_file(cmd)
    756  if (strlen(cmd_file_path) > 0)
    757  ExecuteScriptText cmd_file_path
    758  variable id = parse_result()
    759  if (id > 0)
    760  msg_id = id
    761  if (loglevel >= 4)
    762  print "ELOG: sent message " + num2str(id)
    763  endif
    764  else
    765  if (loglevel >= 2)
    766  print "ELOG: sending message failed."
    767  endif
    768  result = -4
    769  endif
    770  else
    771  result = -2
    772  endif
    773  else
    774  if (loglevel >= 2)
    775  print "ELOG: failed to create temporary message file."
    776  endif
    777  result = -1
    778  endif
    779  endif
    780 
    781  setdatafolder savedf
    782  return result
    783 end
    784 
    792 function elog_add_attachment(logbook, id, graphs)
    793  string logbook
    794  variable id // existing entry ID
    795  string graphs // names of graph windows to be added as attachments, semicolon separated
    796 
    797  dfref savedf = getdatafolderdfr()
    798  dfref df_general = get_elog_df("", kdfPersistent)
    799  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    800 
    801  variable result = 0
    802  nvar /sdfr=df_volatile msg_id
    803  nvar /sdfr=df_general loglevel
    804 
    805  string cmd = prepare_command_line(logbook)
    806  if (strlen(cmd) == 0)
    807  result = -2 // error: invalid/missing command line
    808  endif
    809 
    810  cmd += " -e " + num2str(id)
    811 
    812  if (result == 0)
    813  string cmd_graphs = prepare_graph_attachments(graphs)
    814  if (strlen(cmd_graphs) == 0)
    815  result = -3 // error: invalid/missing graphs
    816  endif
    817  endif
    818 
    819  if (result == 0)
    820  cmd += " " + cmd_graphs
    821  cmd += " > elog.log"
    822  string cmd_file_path = create_cmd_file(cmd)
    823  if (strlen(cmd_file_path) > 0)
    824  ExecuteScriptText cmd_file_path
    825  id = parse_result()
    826  if (id > 0)
    827  msg_id = id
    828  if (loglevel >= 4)
    829  print "ELOG: attached graphs to message " + num2str(id)
    830  endif
    831  else
    832  if (loglevel >= 2)
    833  print "ELOG: failed to attach graphs."
    834  endif
    835  result = -4 // error: elog returned error
    836  endif
    837  else
    838  result = -2 // error: invalid command line
    839  endif
    840  endif
    841 
    842  setdatafolder savedf
    843  return result
    844 end
    845 
    853 static function /s prepare_command_line(logbook)
    854  string logbook
    855 
    856  dfref df_general = get_elog_df("", kdfPersistent)
    857  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
    858  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    859 
    860  svar /sdfr=df_general elog_path
    861  svar /sdfr=df_general hostname
    862  nvar /sdfr=df_general port
    863  nvar /sdfr=df_general ssl
    864  svar /sdfr=df_general subdir
    865  nvar /sdfr=df_general loglevel
    866  svar /sdfr=df_volatile username
    867  svar /sdfr=df_volatile password
    868 
    869  string cmd
    870  cmd = "\"" + elog_path + "\""
    871  if (loglevel >= 5)
    872  cmd += " -v"
    873  endif
    874  cmd += " -h " + hostname
    875  if ((nvar_exists(port)) && (port > 0))
    876  cmd += " -p " + num2str(port)
    877  endif
    878  if ((svar_exists(subdir)) && (strlen(subdir) > 0))
    879  cmd += " -d " + subdir
    880  endif
    881  cmd += " -l \"" + logbook + "\""
    882  if ((nvar_exists(ssl)) && (ssl != 0))
    883  cmd += " -s"
    884  endif
    885  //cmd += " -w " + password
    886  if (svar_exists(username) && svar_exists(password) && (strlen(username) > 0) && (strlen(password) > 0))
    887  cmd += " -u " + username + " " + password
    888  endif
    889 
    890  if (loglevel >= 5)
    891  print cmd
    892  endif
    893 
    894  return cmd
    895 end
    896 
    902 static function /s format_url(logbook)
    903  string logbook
    904 
    905  dfref df_general = get_elog_df("", kdfPersistent)
    906 
    907  svar /sdfr=df_general hostname
    908  nvar /sdfr=df_general port
    909  nvar /sdfr=df_general ssl
    910  svar /sdfr=df_general subdir
    911 
    912  string cmd = ""
    913  if ((nvar_exists(ssl)) && (ssl != 0))
    914  cmd += "https://"
    915  else
    916  cmd += "http://"
    917  endif
    918  cmd += hostname
    919  if ((nvar_exists(port)) && (port > 0))
    920  cmd += ":" + num2str(port)
    921  endif
    922  if ((svar_exists(subdir)) && (strlen(subdir) > 0))
    923  cmd += "/" + subdir
    924  endif
    925  cmd += "/" + logbook
    926 
    927  return cmd
    928 end
    929 
    939 static function /s prepare_graph_attachments(graphs)
    940  string graphs // names of graph windows to be added as attachments, semicolon separated
    941 
    942  string cmd = ""
    943  variable ngraphs = ItemsInList(graphs, ";")
    944  variable igraph
    945  string sgraph
    946  string graph_path
    947  for (igraph = 0; igraph < ngraphs; igraph += 1)
    948  sgraph = StringFromList(igraph, graphs, ";")
    949  graph_path = create_graph_file(sgraph, igraph)
    950  if (strlen(graph_path) > 0)
    951  cmd += " -f \"" + graph_path + "\""
    952  endif
    953  endfor
    954 
    955  return cmd
    956 end
    957 
    958 static function /s get_timestamp(sep)
    959  string sep
    960  Variable now = DateTime
    961  string dat = ReplaceString("-", Secs2Date(DateTime, -2), "")
    962  string tim = ReplaceString(":", Secs2Time(DateTime, 3), "")
    963  return dat + sep + tim
    964 end
    965 
    982 static function /s create_message_file(message)
    983  string message
    984 
    985  message = ReplaceString("%", message, "")
    986  string path = SpecialDirPath("Temporary", 0, 1, 0)
    987  variable len = strlen(path)
    988  string filename
    989 
    990  if (numtype(len) == 0)
    991  filename = "elog_temp_message.txt"
    992  path += filename
    993  variable f1
    994  Open f1 as path
    995  fprintf f1, message
    996  Close f1
    997  else
    998  filename = ""
    999  endif
    1000 
    1001  return filename
    1002 end
    1003 
    1023 static function /s create_graph_file(graphname, fileindex)
    1024  string graphname
    1025  variable fileindex
    1026 
    1027  dfref df_volatile_root = get_elog_df("", kdfVolatile)
    1028  svar /sdfr=df_volatile_root temp_graph_files
    1029 
    1030  string path = SpecialDirPath("Temporary", 0, 1, 0)
    1031  string ts = get_timestamp("_")
    1032  variable len = strlen(path)
    1033  string filename
    1034 
    1035  if (numtype(len) == 0)
    1036  filename = "elog_" + ts + "_" + num2str(fileindex) + ".png"
    1037  path += filename
    1038  SavePICT /B=72 /E=-5 /M /O /W=(0,0,8,6) /WIN=$graphname /Z as path
    1039  if (v_flag == 0)
    1040  temp_graph_files = AddListItem(path, temp_graph_files, ";", inf)
    1041  else
    1042  filename = ""
    1043  endif
    1044  else
    1045  filename = ""
    1046  endif
    1047 
    1048  return filename
    1049 end
    1050 
    1059 static function /s create_cmd_file(cmd)
    1060  string cmd
    1061 
    1062  dfref df_general = get_elog_df("", kdfPersistent)
    1063  nvar /sdfr=df_general loglevel
    1064 
    1065  if (strlen(cmd) >= 1024)
    1066  if (loglevel >= 2)
    1067  print "ELOG: command line too long (add fewer attachments)."
    1068  endif
    1069  return ""
    1070  endif
    1071 
    1072  string work_path = SpecialDirPath("Temporary", 0, 1, 0)
    1073  variable len = strlen(work_path)
    1074  if (numtype(len) == 0)
    1075  string cmdx
    1076  string cmd_path = work_path + "elog_temp_cmd.bat"
    1077 
    1078  variable f1
    1079  Open f1 as cmd_path
    1080  cmdx = "c:\r\n"
    1081  fprintf f1, cmdx
    1082  cmdx = "cd \"" + work_path + "\"\r\n"
    1083  fprintf f1, cmdx
    1084  cmdx = "del elog.log"
    1085  fprintf f1, cmdx + "\r\n"
    1086  fprintf f1, cmd
    1087  Close f1
    1088  else
    1089  cmd_path = ""
    1090  endif
    1091 
    1092  return cmd_path
    1093 end
    1094 
    1095 static function /s get_log_path()
    1096  string path = SpecialDirPath("Temporary", 0, 1, 0)
    1097  variable len = strlen(path)
    1098  if (numtype(len) == 0)
    1099  path += "elog.log"
    1100  else
    1101  path = ""
    1102  endif
    1103 
    1104  return path
    1105 end
    1106 
    1115 static function cleanup_temp_files()
    1116  dfref df_volatile_root = get_elog_df("", kdfVolatile)
    1117  if (DataFolderRefStatus(df_volatile_root))
    1118  svar /sdfr=df_volatile_root /z temp_graph_files
    1119  if (SVAR_Exists(temp_graph_files))
    1120  variable nfi = ItemsInList(temp_graph_files)
    1121  variable ifi
    1122  string sfi
    1123  for (ifi = 0; ifi < nfi; ifi += 1)
    1124  sfi = StringFromList(ifi, temp_graph_files)
    1125  DeleteFile /Z sfi
    1126  endfor
    1127  temp_graph_files = ""
    1128  endif
    1129  endif
    1130  return 0
    1131 end
    1132 
    1133 static strconstant elog_success_msg = "Message successfully transmitted"
    1134 static strconstant elog_parse_id = "ID=%u"
    1135 
    1141 static function parse_result()
    1142  dfref df_general = get_elog_df("", kdfPersistent)
    1143  nvar /sdfr=df_general loglevel
    1144 
    1145  string path = get_log_path()
    1146  string line = ""
    1147  string output = ""
    1148  variable success = 0
    1149  variable id = -1
    1150  string part1 = ""
    1151  string part2 = ""
    1152 
    1153  variable len = strlen(path)
    1154  if (numtype(len) == 0)
    1155  variable f1
    1156  Open /R/Z f1 as path
    1157  if (v_flag == 0)
    1158  do
    1159  FReadLine f1, line
    1160  if (strlen(line) > 0)
    1161  part1 = StringFromList(0, line, ",")
    1162  part2 = ReplaceString(" ", StringFromList(1, line, ","), "")
    1163  success = cmpstr(part1, elog_success_msg) == 0
    1164  if (success)
    1165  sscanf part2, elog_parse_id, id
    1166  endif
    1167  else
    1168  break
    1169  endif
    1170  output += line
    1171  while(!success)
    1172  Close f1
    1173  endif
    1174  endif
    1175  if (loglevel >= 5)
    1176  print output
    1177  endif
    1178 
    1179  return id
    1180 end
    1181 
    1184 function /s elog_prompt_logbook()
    1185  string logbooks = list_logbooks(templates=0)
    1186  logbooks = AddListItem("(new)", logbooks)
    1187  string templates = list_logbooks(templates=1)
    1188  templates = AddListItem("(none)", templates)
    1189 
    1190  string logbook = StringFromList(0, logbooks)
    1191  string template = StringFromList(0, logbooks)
    1192  string name = ""
    1193  string username = ""
    1194  string password = ""
    1195 
    1196  prompt logbook, "logbook", popup logbooks
    1197  prompt template, "template", popup templates
    1198  prompt name, "new logbook name"
    1199 
    1200  doprompt "select logbook", logbook, template, name
    1201  if (!v_flag)
    1202  if (cmpstr(logbook, "(new)") == 0)
    1203  elog_create_logbook(name, template=template)
    1204  logbook = name
    1205  endif
    1206  else
    1207  logbook = ""
    1208  endif
    1209  return logbook
    1210 end
    1211 
    1214 function elog_prompt_login(logbook)
    1215  string logbook
    1216 
    1217  string logbooks = list_logbooks(templates=0)
    1218 
    1219  string username = ""
    1220  string password = ""
    1221 
    1222  prompt logbook, "logbook", popup logbooks
    1223  prompt username, "user name"
    1224  prompt password, "password (blank to log out)"
    1225 
    1226  doprompt "log in to logbook", logbook, username, password
    1227  if (!v_flag)
    1228  elog_login(logbook, username, password)
    1229  endif
    1230 
    1231  return v_flag
    1232 end
    1233 
    1241 function /s PearlElogPanel(logbook)
    1242  string logbook
    1243 
    1244  dfref savedf = getdatafolderdfr()
    1245  dfref df_general = get_elog_df("", kdfPersistent)
    1246  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
    1247  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    1248 
    1249  string win_name = logbook + "ElogPanel"
    1250  string win_title = "ELOG " + logbook
    1251 
    1252  NewPanel /K=1 /N=$win_name /W=(600,200,1200,700) as win_title
    1253  win_name = s_name
    1254  ModifyPanel /w=$win_name cbRGB=(52224,52224,65280)
    1255 
    1256  svar /sdfr=df_persistent attributes
    1257  svar /sdfr=df_persistent controls
    1258  svar /sdfr=df_persistent options
    1259  wave /t /sdfr=df_volatile attach_list
    1260  wave /sdfr=df_volatile attach_sel
    1261  svar /sdfr=df_volatile url
    1262 
    1263  variable iattr
    1264  variable nattr = ItemsInList(attributes, ";")
    1265  string s_attr
    1266  string s_control
    1267  string s_option
    1268  string persistent_path = GetDataFolder(1, df_persistent)
    1269  string volatile_path = GetDataFolder(1, df_volatile)
    1270  string options_path
    1271  string variable_path
    1272  variable ypos = 2
    1273  variable height = 0
    1274 
    1275  for (iattr = 0; iattr < nattr; iattr += 1)
    1276  s_attr = StringFromList(iattr, attributes, ";")
    1277  s_control = StringFromList(iattr, controls, ";")
    1278  strswitch(s_control[0,1])
    1279  case "sv":
    1280  SetVariable $s_control, win=$win_name, pos={0,ypos}, size={300,16}, bodyWidth=230
    1281  SetVariable $s_control, win=$win_name, title=s_attr, value= _STR:""
    1282  SetVariable $s_control, win=$win_name, userdata(attribute)=s_attr
    1283  ypos += 18
    1284  break
    1285  case "pm":
    1286  options_path = persistent_path + StringByKey(s_attr, options, "=", ";")
    1287  PopupMenu $s_control, win=$win_name, pos={0,ypos}, size={300,21}, bodyWidth=230
    1288  PopupMenu $s_control, win=$win_name, title=s_attr
    1289  PopupMenu $s_control, win=$win_name, mode=1, popvalue="Test", value= #options_path
    1290  PopupMenu $s_control, win=$win_name, userdata(attribute)=s_attr
    1291  ypos += 23
    1292  break
    1293  case "cb":
    1294  CheckBox $s_control, win=$win_name, pos={70,ypos}, size={300,14}
    1295  CheckBox $s_control, win=$win_name, title=s_attr, value= 1
    1296  CheckBox $s_control, win=$win_name, userdata(attribute)=s_attr
    1297  ypos += 17
    1298  break
    1299  endswitch
    1300  endfor
    1301  ypos = max(ypos, 80)
    1302 
    1303  TitleBox t_attach, win=$win_name, pos={308,5}, size={70,14}, title="Attachments", frame=0
    1304  height = ypos - 21 - 4
    1305  ListBox lb_attach, win=$win_name, pos={308,21}, size={264,height}
    1306  ListBox lb_attach, win=$win_name, listWave=attach_list
    1307  ListBox lb_attach, win=$win_name, mode=1, selWave=attach_sel, selRow=-1
    1308  ListBox lb_attach, win=$win_name, widths={20,160,80}
    1309  ListBox lb_attach, win=$win_name, help={"Choose graphs to attach to the message."}
    1310 
    1311  Button b_attach_top, win=$win_name, pos={420,2}, size={40,18}, title="top"
    1312  Button b_attach_top, win=$win_name, fcolor=(56576,60928,47872)
    1313  Button b_attach_top, win=$win_name, proc=PearlElog#bp_attach_top
    1314  Button b_attach_top, win=$win_name, help={"Select top graph for attachment."}
    1315  Button b_attach_all, win=$win_name, pos={460,2}, size={40,18}, title="all"
    1316  Button b_attach_all, win=$win_name, fcolor=(56576,60928,47872)
    1317  Button b_attach_all, win=$win_name, proc=PearlElog#bp_attach_allnone
    1318  Button b_attach_all, win=$win_name, help={"Select all graphs for attachment."}
    1319  Button b_attach_none, win=$win_name, pos={500,2}, size={40,18}, title="none"
    1320  Button b_attach_none, win=$win_name, fcolor=(56576,60928,47872)
    1321  Button b_attach_none, win=$win_name, proc=PearlElog#bp_attach_allnone
    1322  Button b_attach_none, win=$win_name, help={"Deselect all attachments."}
    1323  Button b_save_graphs, win=$win_name, pos={540,2}, size={40,18}, title="save"
    1324  Button b_save_graphs, win=$win_name, fcolor=(56576,60928,47872)
    1325  Button b_save_graphs, win=$win_name, proc=PearlElog#bp_save_graphs
    1326  Button b_save_graphs, win=$win_name, help={"Save selected graphs as PNG bitmap files."}
    1327  Button b_attach_up, win=$win_name, pos={576,20}, size={20,20}, title="\\W517"
    1328  Button b_attach_up, win=$win_name, fcolor=(56576,60928,47872)
    1329  Button b_attach_up, win=$win_name, proc=PearlElog#bp_attach_updown
    1330  Button b_attach_up, win=$win_name, help={"Move selected graph up."}
    1331  Button b_attach_dw, win=$win_name, pos={576,40}, size={20,20}, title="\\W523"
    1332  Button b_attach_dw, win=$win_name, fcolor=(56576,60928,47872)
    1333  Button b_attach_dw, win=$win_name, proc=PearlElog#bp_attach_updown
    1334  Button b_attach_dw, win=$win_name, help={"Move selected graph down."}
    1335 
    1336  ypos += 246-160
    1337  Button b_submit,win=$win_name, pos={70,ypos},size={46,20},proc=PearlElog#bp_submit,title="Submit"
    1338  Button b_submit,win=$win_name, help={"Submit form data to ELOG (new entry)."}
    1339  Button b_submit,win=$win_name, fcolor=(56576,60928,47872)
    1340  Button b_clear,win=$win_name, pos={120,ypos},size={46,20},proc=PearlElog#bp_clear,title="Clear"
    1341  Button b_clear,win=$win_name, help={"Clear the form fields"}
    1342  Button b_clear,win=$win_name, fcolor=(56576,60928,47872)
    1343 
    1344  ypos += 272-246
    1345  variable_path = volatile_path + "msg_id"
    1346  SetVariable sv_id,win=$win_name, pos={51,ypos},size={119,16},bodyWidth=77
    1347  SetVariable sv_id,win=$win_name, title="ID",value=$variable_path
    1348  SetVariable sv_id,win=$win_name, help={"ID of last submitted message, or message to attach or reply to."}
    1349 
    1350  TitleBox t_host, win=$win_name, pos={170,ypos+4}, size={112.00,14.00}, frame=0
    1351  TitleBox t_host, win=$win_name, variable=url
    1352 
    1353  ypos += 270-272
    1354  Button b_attach,win=$win_name, pos={170,ypos},size={48,20},proc=PearlElog#bp_attach,title="Attach"
    1355  Button b_attach,win=$win_name, help={"Attach the selected graph to an existing ELOG entry (correct ID required)."}
    1356  Button b_attach,win=$win_name, fcolor=(56576,60928,47872)
    1357  Button b_reply,win=$win_name, pos={220,ypos},size={48,20},proc=PearlElog#bp_submit,title="Reply"
    1358  Button b_reply,win=$win_name, help={"Submit form data to ELOG as a reply to an existing message (correct ID required)."}
    1359  Button b_reply,win=$win_name, fcolor=(56576,60928,47872)
    1360  Button b_login,win=$win_name, pos={550,ypos},size={46,20},proc=PearlElog#bp_login,title="Login"
    1361  Button b_login,win=$win_name, help={"Enter user name and password."}
    1362  Button b_login,win=$win_name, fcolor=(56576,60928,47872)
    1363  Button b_logout,win=$win_name, pos={550,ypos},size={46,20},proc=PearlElog#bp_logout,title="Logout"
    1364  Button b_logout,win=$win_name, help={"Clear user name and password."}
    1365  Button b_logout,win=$win_name, fcolor=(56576,60928,47872), disable=3
    1366 
    1367  SetWindow $win_name, hook(elogPanelHook)=PearlElog#elog_panel_hook
    1368  SetWindow $win_name, userdata(logbook)=logbook
    1369 
    1370  ypos += 160-270
    1371  TitleBox t_message,win=$win_name, pos={10,ypos},size={58,16},fixedSize=1,frame=0,anchor=RT,title="Message"
    1372  DefineGuide UGH0={FT,ypos},UGV0={FL,70},UGH1={FB,-52},UGV1={FR,-2}
    1373  NewNotebook /F=0 /N=Message /OPTS=3 /W=(115,404,345,341)/FG=(UGV0,UGH0,UGV1,UGH1) /HOST=#
    1374  Notebook kwTopWin, defaultTab=20, statusWidth=0, autoSave=0
    1375  Notebook kwTopWin fSize=10, fStyle=0, textRGB=(0,0,0)
    1376  RenameWindow #,Message
    1377  string nb_name = win_name + "#Message"
    1378  SetActiveSubwindow ##
    1379 
    1380  // restore recently used attributes and message
    1381  svar /z /sdfr=df_persistent recent
    1382  if (svar_exists(recent) && (strlen(recent) > 0))
    1383  set_panel_attributes(win_name, recent)
    1384  endif
    1385  svar /z /sdfr=df_persistent recent_message
    1386  if (svar_exists(recent_message) && (strlen(recent_message) > 0))
    1387  set_panel_message(win_name, recent_message)
    1388  endif
    1389  Notebook $nb_name selection={startOfFile,startOfFile}, findText={"",1}
    1390 
    1391  setdatafolder savedf
    1392  return win_name
    1393 end
    1394 
    1395 static function elog_panel_hook(s)
    1396  STRUCT WMWinHookStruct &s
    1397 
    1398  Variable hookResult = 0
    1399 
    1400  switch(s.eventCode)
    1401  case 0: // activate
    1402  string logbook = GetUserData(s.winName, "", "logbook")
    1403  if (strlen(logbook) > 0)
    1404  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    1405  svar /sdfr=df_volatile url
    1406  url = format_url(logbook)
    1407  update_attach_items(logbook)
    1408  endif
    1409  break
    1410  case 6: // resize
    1411  // move bottom-aligned controls when the window is resized
    1412  variable b_top = s.winRect.bottom + 4
    1413  Button b_submit,pos={70,b_top}
    1414  Button b_clear,pos={120,b_top}
    1415  TitleBox t_host, pos={170,b_top+4}
    1416  b_top += 24
    1417  Button b_attach,pos={170,b_top}
    1418  Button b_reply,pos={220,b_top}
    1419  Button b_login, pos={550,b_top}
    1420  Button b_logout, pos={550,b_top}
    1421  b_top += 2
    1422  SetVariable sv_id,pos={51,b_top}
    1423  break
    1424  endswitch
    1425 
    1426  return hookResult // 0 if nothing done, else 1
    1427 end
    1428 
    1429 static constant kAttachColSel = 0
    1430 static constant kAttachColTitle = 1
    1431 static constant kAttachColName = 2
    1432 
    1434 static function update_attach_items(logbook)
    1435  string logbook
    1436 
    1437  dfref savedf = getdatafolderdfr()
    1438  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    1439  wave /t /sdfr=df_volatile attach_list
    1440  wave /sdfr=df_volatile attach_sel
    1441 
    1442  if (!waveexists(attach_list))
    1443  return -1
    1444  endif
    1445  string names = WinList("*", ";", "WIN:1;VISIBLE:1")
    1446  names = SortList(names, ";", 16)
    1447 
    1448  // remove closed graphs
    1449  variable i
    1450  variable k
    1451  variable n = DimSize(attach_list, 0)
    1452  string s
    1453  for (i = n-1; i >= 0; i -= 1)
    1454  s = attach_list[i][kAttachColName]
    1455  if (WhichListItem(s, names) < 0)
    1456  DeletePoints /M=0 i, 1, attach_list, attach_sel
    1457  endif
    1458  endfor
    1459 
    1460  // add new graphs
    1461  n = ItemsInList(names)
    1462  for (i = 0; i < n; i += 1)
    1463  s = StringFromList(i, names)
    1464  FindValue /text=s /txop=4 /z attach_list
    1465  if (v_value < 0)
    1466  k = DimSize(attach_list, 0)
    1467  Redimension /n=(k+1,3) attach_list, attach_sel
    1468  //InsertPoints /M=0 k, 1, attach_list, attach_sel
    1469  attach_list[k][kAttachColSel] = ""
    1470  attach_list[k][kAttachColTitle] = ""
    1471  attach_list[k][kAttachColName] = s
    1472  attach_sel[k][kAttachColSel] = 32
    1473  attach_sel[k][kAttachColTitle] = 0
    1474  attach_sel[k][kAttachColName] = 0
    1475  endif
    1476  endfor
    1477 
    1478  // update titles
    1479  n = DimSize(attach_list, 0)
    1480  for (i = n-1; i >= 0; i -= 1)
    1481  s = attach_list[i][kAttachColName]
    1482  getwindow /z $s, wtitle
    1483  if (v_flag == 0)
    1484  attach_list[i][kAttachColTitle] = s_value
    1485  else
    1486  attach_list[i][kAttachColTitle] = s
    1487  endif
    1488  endfor
    1489 
    1490  setdatafolder savedf
    1491  return 0
    1492 end
    1493 
    1495 static function move_attach_item(logbook, item, distance)
    1496  string logbook
    1497  variable item
    1498  variable distance
    1499 
    1500  dfref savedf = getdatafolderdfr()
    1501  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    1502  wave /t /sdfr=df_volatile attach_list
    1503  wave /sdfr=df_volatile attach_sel
    1504  variable n = DimSize(attach_list, 0)
    1505  variable dest = item + distance
    1506 
    1507  if ((item >= 0) && (item < n) && (dest >= 0) && (dest < n))
    1508  string name = attach_list[item][kAttachColName]
    1509  variable sel = attach_sel[item][kAttachColSel]
    1510  DeletePoints /M=0 item, 1, attach_list, attach_sel
    1511  InsertPoints /M=0 dest, 1, attach_list, attach_sel
    1512  attach_list[dest][kAttachColName] = name
    1513  update_attach_items(logbook)
    1514  attach_sel[dest][kAttachColSel] = sel
    1515  endif
    1516 end
    1517 
    1519 static function bp_attach_updown(ba) : ButtonControl
    1520  STRUCT WMButtonAction &ba
    1521 
    1522  switch( ba.eventCode )
    1523  case 2: // mouse up
    1524  string logbook = GetUserData(ba.win, "", "logbook")
    1525  ControlInfo /w=$ba.win lb_attach
    1526  variable row = v_value
    1527  dfref df = $s_datafolder
    1528  wave /t /sdfr=df attach_list = $s_value
    1529  if (cmpstr(ba.ctrlName, "b_attach_up") == 0)
    1530  // up button
    1531  if (row >= 1)
    1532  move_attach_item(logbook, row, -1)
    1533  ListBox lb_attach, win=$ba.win, selRow=(row-1)
    1534  endif
    1535  else
    1536  // down button
    1537  if (row < DimSize(attach_list, 0) - 1)
    1538  move_attach_item(logbook, row, +1)
    1539  ListBox lb_attach, win=$ba.win, selRow=(row+1)
    1540  endif
    1541  endif
    1542  break
    1543  case -1: // control being killed
    1544  break
    1545  endswitch
    1546 
    1547  return 0
    1548 end
    1549 
    1551 static function bp_submit(ba) : ButtonControl
    1552  STRUCT WMButtonAction &ba
    1553 
    1554  switch( ba.eventCode )
    1555  case 2: // mouse up
    1556  string logbook = GetUserData(ba.win, "", "logbook")
    1557  string attributes
    1558  string message
    1559  string graphs
    1560  attributes = get_panel_attributes(ba.win)
    1561  message = get_panel_message(ba.win)
    1562  graphs = get_panel_graphs(ba.win)
    1563 
    1564  variable id
    1565  if (cmpstr(ba.ctrlName, "b_reply") == 0)
    1566  // Reply button
    1567  ControlInfo /w=$ba.win sv_id
    1568  id = v_value
    1569  else
    1570  // Submit button
    1571  id = 0
    1572  endif
    1573 
    1574  if ((elog_validate_attributes(logbook, attributes) == 0) && (strlen(message) > 0))
    1575  variable result
    1576  result = elog_create_entry(logbook, attributes, message, graphs=graphs, replyto=id)
    1577  if (result == 0)
    1578  dfref df = get_elog_df(logbook, kdfPersistent)
    1579  svar /sdfr=df recent
    1580  recent = attributes
    1581  svar /sdfr=df recent_message
    1582  recent_message = message
    1583  else
    1584  abort "Submission failed. Error code " + num2str(result) + "."
    1585  endif
    1586  else
    1587  abort "Submission failed due to missing/invalid attribute."
    1588  endif
    1589  break
    1590  case -1: // control being killed
    1591  break
    1592  endswitch
    1593 
    1594  return 0
    1595 end
    1596 
    1598 static function bp_attach_top(ba) : ButtonControl
    1599  STRUCT WMButtonAction &ba
    1600 
    1601  switch( ba.eventCode )
    1602  case 2: // mouse up
    1603  string graphs = WinName(0, 1, 1)
    1604  set_panel_graphs(ba.win, graphs)
    1605  break
    1606  case -1: // control being killed
    1607  break
    1608  endswitch
    1609 
    1610  return 0
    1611 end
    1612 
    1614 static function bp_attach_allnone(ba) : ButtonControl
    1615  STRUCT WMButtonAction &ba
    1616 
    1617  switch( ba.eventCode )
    1618  case 2: // mouse up
    1619  string logbook = GetUserData(ba.win, "", "logbook")
    1620  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    1621  wave /sdfr=df_volatile attach_sel
    1622  if (cmpstr(ba.ctrlName, "b_attach_all") == 0)
    1623  attach_sel[][kAttachColSel] = attach_sel[p][kAttachColSel] | 16
    1624  else
    1625  attach_sel[][kAttachColSel] = attach_sel[p][kAttachColSel] & ~16
    1626  endif
    1627  break
    1628  case -1: // control being killed
    1629  break
    1630  endswitch
    1631 
    1632  return 0
    1633 end
    1634 
    1635 static function bp_attach(ba) : ButtonControl
    1636  STRUCT WMButtonAction &ba
    1637 
    1638  switch( ba.eventCode )
    1639  case 2: // mouse up
    1640  string logbook = GetUserData(ba.win, "", "logbook")
    1641  string graphs
    1642  graphs = get_panel_graphs(ba.win)
    1643 
    1644  variable id
    1645  ControlInfo /w=$ba.win sv_id
    1646  id = v_value
    1647 
    1648  // TODO : is there a way around this restriction?
    1649  DoAlert /T="ELOG" 1, "This operation will replace all existing attachments. Do you want to continue?"
    1650 
    1651  if ((id > 0) && (v_flag == 1))
    1652  variable result
    1653  result = elog_add_attachment(logbook, id, graphs)
    1654  if (result != 0)
    1655  abort "Submission failed. Error code " + num2str(result) + "."
    1656  endif
    1657  else
    1658  abort "Submission failed due to missing/invalid attribute."
    1659  endif
    1660  break
    1661  case -1: // control being killed
    1662  break
    1663  endswitch
    1664 
    1665  return 0
    1666 end
    1667 
    1668 static function bp_save_graphs(ba) : ButtonControl
    1669  STRUCT WMButtonAction &ba
    1670 
    1671  switch( ba.eventCode )
    1672  case 2: // mouse up
    1673  string logbook = GetUserData(ba.win, "", "logbook")
    1674  string graphs = get_panel_graphs(ba.win)
    1675  variable ngraphs = ItemsInList(graphs, ";")
    1676 
    1677  variable igraph
    1678  string sgraph
    1679  string graph_path
    1680  for (igraph = 0; igraph < ngraphs; igraph += 1)
    1681  sgraph = StringFromList(igraph, graphs, ";")
    1682  graph_path = create_graph_file(sgraph, igraph)
    1683  if (strlen(graph_path) > 0)
    1684  print graph_path
    1685  endif
    1686  endfor
    1687 
    1688  break
    1689  case -1: // control being killed
    1690  break
    1691  endswitch
    1692 
    1693  return 0
    1694 end
    1695 
    1696 static function bp_clear(ba) : ButtonControl
    1697  STRUCT WMButtonAction &ba
    1698 
    1699  switch( ba.eventCode )
    1700  case 2: // mouse up
    1701  set_panel_attributes(ba.win, "", clear=1)
    1702  set_panel_message(ba.win, "")
    1703  set_panel_graphs(ba.win, "")
    1704  break
    1705  case -1: // control being killed
    1706  break
    1707  endswitch
    1708 
    1709  return 0
    1710 end
    1711 
    1712 static function bp_login(ba) : ButtonControl
    1713  STRUCT WMButtonAction &ba
    1714 
    1715  switch( ba.eventCode )
    1716  case 2: // mouse up
    1717  string logbook = GetUserData(ba.win, "", "logbook")
    1718  if (elog_prompt_login(logbook) == 0)
    1719  Button b_login, win=$ba.win, disable=3
    1720  Button b_logout, win=$ba.win, disable=0
    1721  endif
    1722  break
    1723  case -1: // control being killed
    1724  break
    1725  endswitch
    1726 
    1727  return 0
    1728 end
    1729 
    1730 static function bp_logout(ba) : ButtonControl
    1731  STRUCT WMButtonAction &ba
    1732 
    1733  switch( ba.eventCode )
    1734  case 2: // mouse up
    1735  string logbook = GetUserData(ba.win, "", "logbook")
    1736  elog_logout(logbook)
    1737  Button b_login, win=$ba.win, disable=0
    1738  Button b_logout, win=$ba.win, disable=3
    1739  break
    1740  case -1: // control being killed
    1741  break
    1742  endswitch
    1743 
    1744  return 0
    1745 end
    1746 
    1747 static function /s get_default_panel_name()
    1748  string windowname
    1749  windowname = StringFromList(0, WinList("*ElogPanel*", ";", "WIN:64"), ";")
    1750  return windowname
    1751 end
    1752 
    1760 static function /s get_panel_attributes(windowname)
    1761  string windowname
    1762 
    1763  if (strlen(windowname) == 0)
    1764  windowname = get_default_panel_name()
    1765  endif
    1766  if (strlen(windowname) == 0)
    1767  return ""
    1768  endif
    1769 
    1770  string controls = ControlNameList(windowname, ";")
    1771  string attributes = ""
    1772  string control
    1773  string attribute
    1774  variable ico
    1775  variable nco = ItemsInList(controls, ";")
    1776  for (ico = 0; ico < nco; ico += 1)
    1777  control = StringFromList(ico, controls, ";")
    1778  attribute = GetUserData(windowname, control, "attribute")
    1779  if (strlen(attribute) > 0)
    1780  ControlInfo /w=$windowname $control
    1781  switch(v_flag)
    1782  case 2: // checkbox
    1783  attributes = ReplaceNumberByKey(attribute, attributes, v_value, "=", ";")
    1784  break
    1785  case 3: // popupmenu
    1786  case 5: // setvariable
    1787  attributes = ReplaceStringByKey(attribute, attributes, s_value, "=", ";")
    1788  break
    1789  endswitch
    1790  endif
    1791  endfor
    1792 
    1793  return attributes
    1794 end
    1795 
    1807 static function /s set_panel_attributes(windowname, attributes, [clear])
    1808  string windowname
    1809  string attributes
    1810  variable clear
    1811 
    1812  if (strlen(windowname) == 0)
    1813  windowname = get_default_panel_name()
    1814  endif
    1815  if (strlen(windowname) == 0)
    1816  return ""
    1817  endif
    1818  if (ParamIsDefault(clear))
    1819  clear = 0
    1820  endif
    1821 
    1822  string path
    1823 
    1824  string logbook = GetUserData(windowname, "", "logbook")
    1825  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
    1826  string persistent_path = GetDataFolder(1, df_persistent)
    1827  svar /sdfr=df_persistent options
    1828  string options_path
    1829 
    1830  string controls = ControlNameList(windowname, ";")
    1831  string control
    1832  string attribute
    1833  string value
    1834  variable numval
    1835  variable ico
    1836  variable nco = ItemsInList(controls, ";")
    1837  for (ico = 0; ico < nco; ico += 1)
    1838  control = StringFromList(ico, controls, ";")
    1839  attribute = GetUserData(windowname, control, "attribute")
    1840  if (strlen(attribute))
    1841  value = StringByKey(attribute, attributes, "=", ";")
    1842  if (strlen(value) || clear)
    1843  ControlInfo /w=$windowname $control
    1844  switch(v_flag)
    1845  case 2: // checkbox
    1846  numval = NumberByKey(attribute, attributes, "=", ";")
    1847  if ((numtype(numval) != 0) && clear)
    1848  numval = 0
    1849  endif
    1850  if (numtype(numval) == 0)
    1851  CheckBox $control, value=numval, win=$windowname
    1852  endif
    1853  break
    1854  case 3: // popupmenu
    1855  options_path = persistent_path + StringByKey(attribute, options, "=", ";")
    1856  svar values = $options_path
    1857  numval = WhichListItem(value, values, ";") + 1
    1858  if (numval >= 1)
    1859  PopupMenu $control, mode=numval, win=$windowname
    1860  endif
    1861  break
    1862  case 5: // setvariable
    1863  SetVariable /z $control, value= _STR:value, win=$windowname
    1864  break
    1865  endswitch
    1866  endif
    1867  endif
    1868  endfor
    1869 
    1870  return attributes
    1871 end
    1872 
    1880 static function /s get_panel_message(windowname)
    1881  string windowname
    1882 
    1883  if (strlen(windowname) == 0)
    1884  windowname = get_default_panel_name()
    1885  endif
    1886  if (strlen(windowname) == 0)
    1887  return ""
    1888  endif
    1889 
    1890  string nb = windowname + "#Message"
    1891  notebook $nb selection={startOfFile, endOfFile}
    1892  getselection notebook, $nb, 2
    1893 
    1894  return s_selection
    1895 end
    1896 
    1906 static function /s set_panel_message(windowname, message)
    1907  string windowname
    1908  string message
    1909 
    1910  if (strlen(windowname) == 0)
    1911  windowname = get_default_panel_name()
    1912  endif
    1913 
    1914  string nb = windowname + "#Message"
    1915  notebook $nb selection={startOfFile, endOfFile},text=message
    1916 
    1917  return message
    1918 end
    1919 
    1926 static function /s get_panel_graphs(windowname)
    1927  string windowname // panel window name
    1928 
    1929  dfref savedf = getdatafolderdfr()
    1930  if (strlen(windowname) == 0)
    1931  windowname = get_default_panel_name()
    1932  endif
    1933  if (strlen(windowname) == 0)
    1934  return ""
    1935  endif
    1936 
    1937  string logbook = GetUserData(windowname, "", "logbook")
    1938  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    1939  wave /t /sdfr=df_volatile attach_list
    1940  wave /sdfr=df_volatile attach_sel
    1941  string graphs = ""
    1942  string windows = ""
    1943  string graphname
    1944 
    1945  variable n = DimSize(attach_sel, 0)
    1946  variable i
    1947  for (i = 0; i < n; i += 1)
    1948  if (attach_sel[i][kAttachColSel] & 16)
    1949  graphname = attach_list[i][kAttachColName]
    1950  windows = WinList(graphname, ";", "WIN:1")
    1951  if (ItemsInList(windows) == 1)
    1952  graphs = AddListItem(graphname, graphs, ";", inf)
    1953  endif
    1954  endif
    1955  endfor
    1956 
    1957  return graphs
    1958 end
    1959 
    1966 static function /s set_panel_graphs(windowname, graphs)
    1967  string windowname
    1968  string graphs
    1969 
    1970  if (strlen(windowname) == 0)
    1971  windowname = get_default_panel_name()
    1972  endif
    1973  if (strlen(windowname) == 0)
    1974  return ""
    1975  endif
    1976 
    1977  string logbook = GetUserData(windowname, "", "logbook")
    1978  update_attach_items(logbook)
    1979  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    1980  wave /t /sdfr=df_volatile attach_list
    1981  wave /sdfr=df_volatile attach_sel
    1982 
    1983  variable n = DimSize(attach_sel, 0)
    1984  variable i
    1985  string graphname
    1986  for (i = 0; i < n; i += 1)
    1987  graphname = attach_list[i][kAttachColName]
    1988  if (WhichListItem(graphname, graphs)>= 0)
    1989  attach_sel[i][kAttachColSel] = 48
    1990  else
    1991  attach_sel[i][kAttachColSel] = 32
    1992  endif
    1993  endfor
    1994 end
    variable elog_create_entry(string logbook, string attributes, string message, variable encoding=defaultValue, string graphs=defaultValue, variable replyto=defaultValue)
    create a new entry in ELOG
    Definition: pearl-elog.ipf:685
    -
    static variable AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind)
    initialize the package and reload preferences after an experiment is loaded.
    Definition: pearl-elog.ipf:143
    -
    variable elog_add_attachment(string logbook, variable id, string graphs)
    add one or more graphs to an existing ELOG entry
    Definition: pearl-elog.ipf:792
    -
    static const string package_path
    Definition: pearl-elog.ipf:86
    -
    static string get_panel_graphs(string windowname)
    get the names of the graphs selected for attachment
    -
    static variable bp_attach_updown(WMButtonAction *ba)
    button procedure for the attachment up and down buttons
    -
    static string create_message_file(string message)
    save the message to a temporary text file
    Definition: pearl-elog.ipf:982
    -
    static variable parse_result()
    parse the result file from an elog invokation.
    -
    variable elog_create_logbook(string name, string template=defaultValue)
    create a new logbook.
    Definition: pearl-elog.ipf:414
    -
    static string set_panel_attributes(string windowname, string attributes, variable clear=defaultValue)
    set the fields of the ELOG panel
    -
    static variable bp_logout(WMButtonAction *ba)
    -
    static string get_default_panel_name()
    -
    static variable elog_panel_hook(WMWinHookStruct *s)
    -
    variable elog_config(string elog_path=defaultValue, string hostname=defaultValue, variable port=defaultValue, string subdir=defaultValue)
    set global module configuration parameters
    Definition: pearl-elog.ipf:473
    -
    interface for writing ELOG entries with Igor graphs as attachment.
    -
    static variable IgorBeforeNewHook(string igorApplicationNameStr)
    save preferences and recent values before Igor opens a new experiment.
    Definition: pearl-elog.ipf:127
    -
    static string set_panel_graphs(string windowname, string graphs)
    update selection of graphs for attachment
    -
    variable elog_init_pearl_templates()
    setup PEARL template logbooks.
    Definition: pearl-elog.ipf:262
    -
    static string create_graph_file(string graphname, variable fileindex)
    save a graph to a temporary graphics file
    -
    static const variable kAttachColName
    -
    static variable bp_clear(WMButtonAction *ba)
    -
    variable elog_login(string logbook, string username, string password)
    set username and password for login to a logbook
    Definition: pearl-elog.ipf:513
    -
    static variable bp_attach_top(WMButtonAction *ba)
    select top graph window for attachment
    -
    static const variable kAttachColSel
    -
    string PearlElogPanel(string logbook)
    open a new panel for submitting data to ELOG.
    -
    variable elog_validate_attributes(string logbook, string attributes)
    validate attributes
    Definition: pearl-elog.ipf:653
    -
    static string prepare_graph_attachments(string graphs)
    prepare screenshots of graph windows for attachments
    Definition: pearl-elog.ipf:939
    -
    static string list_logbooks(variable templates=defaultValue)
    get a list of configured logbooks or templates.
    Definition: pearl-elog.ipf:618
    -
    static variable bp_attach(WMButtonAction *ba)
    -
    static variable move_attach_item(string logbook, variable item, variable distance)
    move an attachment item in the list of attachments
    -
    static dfr get_elog_df(string name, variable category)
    get the package, logbook, or template datafolder.
    Definition: pearl-elog.ipf:170
    -
    string elog_prompt_logbook()
    prompt to open or create a logbook
    -
    static variable bp_save_graphs(WMButtonAction *ba)
    -
    static variable update_attach_items(string logbook)
    update the list of attachments
    -
    static variable bp_login(WMButtonAction *ba)
    -
    static const variable kdfVolatile
    Definition: pearl-elog.ipf:154
    -
    static const variable kdfTemplates
    Definition: pearl-elog.ipf:156
    -
    static string prepare_command_line(string logbook)
    format the ELOG command and essential address arguments.
    Definition: pearl-elog.ipf:853
    -
    static variable cleanup_temp_files()
    delete temporary files created by the ELOG module.
    -
    static string get_log_path()
    -
    static const variable kAttachColTitle
    -
    static const string elog_parse_id
    -
    static string get_panel_message(string windowname)
    get the message field of the ELOG panel
    -
    static string create_cmd_file(string cmd)
    write the command line to a file.
    -
    static variable init_volatile_vars()
    initialize volatile variables.
    Definition: pearl-elog.ipf:340
    -
    static variable load_prefs()
    load persistent package data from the preferences file.
    Definition: pearl-elog.ipf:584
    -
    static const variable kdfPersistent
    Definition: pearl-elog.ipf:155
    -
    static variable init_package(variable clean=defaultValue)
    initialize the package data folder.
    Definition: pearl-elog.ipf:217
    -
    static variable save_prefs()
    save persistent package data to the preferences file.
    Definition: pearl-elog.ipf:564
    -
    static const variable kdfRoot
    Definition: pearl-elog.ipf:153
    -
    variable elog_prompt_login(string logbook)
    prompt the user for login to a logbook
    -
    static string set_panel_message(string windowname, string message)
    set the message field of the ELOG panel
    -
    static variable IgorQuitHook(string igorApplicationNameStr)
    save preferences and recent values before Igor quits.
    Definition: pearl-elog.ipf:135
    -
    static variable bp_submit(WMButtonAction *ba)
    button procedure for the Submit and Reply buttons
    -
    static variable bp_attach_allnone(WMButtonAction *ba)
    select/deselect all graph windows for attachment
    -
    static string get_panel_attributes(string windowname)
    get a list of attributes from the fields of the ELOG panel.
    -
    static const string elog_success_msg
    -
    static string get_timestamp(string sep)
    Definition: pearl-elog.ipf:958
    -
    variable elog_logout(string logbook)
    clear username and password of a logbook or all logbooks.
    Definition: pearl-elog.ipf:533
    -
    variable pearl_elog(string logbook)
    main function to initialize ELOG and to open an ELOG panel.
    Definition: pearl-elog.ipf:97
    -
    static string format_url(string logbook)
    format the URL for display to the user
    Definition: pearl-elog.ipf:902
    -
    static const string package_name
    Definition: pearl-elog.ipf:85
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma version = 1.50
    +
    4 #pragma IgorVersion = 6.36
    +
    5 #pragma ModuleName = PearlElog
    +
    6 
    +
    7 // author: matthias.muntwiler@psi.ch
    +
    8 // Copyright (c) 2013-20 Paul Scherrer Institut
    +
    9 
    +
    10 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    11 // you may not use this file except in compliance with the License.
    +
    12 // You may obtain a copy of the License at
    +
    13 // http://www.apache.org/licenses/LICENSE-2.0
    +
    14 
    +
    80 
    +
    85 
    +
    86 static strconstant package_name = "pearl_elog"
    +
    87 static strconstant package_path = "root:packages:pearl_elog:"
    +
    88 
    +
    98 function pearl_elog(logbook)
    +
    99  string logbook
    +
    100 
    +
    101  if (init_package() == 0)
    +
    102  load_prefs()
    +
    103  string templates = list_logbooks(templates=1)
    +
    104  if (ItemsInList(templates) < 1)
    + +
    106  endif
    +
    107  endif
    +
    108 
    +
    109  if (strlen(logbook) == 0)
    +
    110  logbook = elog_prompt_logbook()
    +
    111  endif
    +
    112 
    +
    113  string win_name = logbook + "ElogPanel"
    +
    114  if (strlen(logbook) > 0)
    +
    115  if (strlen(WinList(win_name, ";", "")) > 0)
    +
    116  DoWindow /F $win_name
    +
    117  else
    +
    118  win_name = PearlElogPanel(logbook)
    +
    119  STRUCT WMWinHookStruct s
    +
    120  s.eventCode = 0
    +
    121  s.winName = win_name
    +
    122  elog_panel_hook(s)
    +
    123  endif
    +
    124  endif
    +
    125 end
    +
    126 
    +
    128 static function IgorBeforeNewHook(igorApplicationNameStr)
    +
    129  string igorApplicationNameStr
    +
    130  save_prefs()
    + +
    132  return 0
    +
    133 end
    +
    134 
    +
    136 static function IgorQuitHook(igorApplicationNameStr)
    +
    137  string igorApplicationNameStr
    +
    138  save_prefs()
    + +
    140  return 0
    +
    141 end
    +
    142 
    +
    144 static function AfterFileOpenHook(refNum,file,pathName,type,creator,kind)
    +
    145  Variable refNum,kind
    +
    146  String file,pathName,type,creator
    +
    147  if( (kind >= 1) && (kind <= 2))
    +
    148  init_package(clean=1)
    +
    149  load_prefs()
    +
    150  endif
    +
    151  return 0
    +
    152 end
    +
    153 
    +
    154 static constant kdfRoot = 0
    +
    155 static constant kdfVolatile = 1
    +
    156 static constant kdfPersistent = 2
    +
    157 static constant kdfTemplates = 3
    +
    158 
    +
    171 static function /df get_elog_df(name, category)
    +
    172  string name
    +
    173  variable category
    +
    174 
    +
    175  dfref df_package = $package_path
    +
    176  dfref df_persistent = df_package:persistent
    +
    177  dfref df_volatile = df_package:volatile
    +
    178 
    +
    179  switch(category)
    +
    180  case kdfRoot:
    +
    181  dfref df_parent = df_package
    +
    182  break
    +
    183  case kdfPersistent:
    +
    184  dfref df_parent = df_persistent
    +
    185  break
    +
    186  case kdfTemplates:
    +
    187  dfref df_parent = df_persistent:templates
    +
    188  break
    +
    189  case kdfVolatile:
    +
    190  dfref df_parent = df_volatile
    +
    191  break
    +
    192  default:
    +
    193  Abort "get_elog_df: undefined data folder category."
    +
    194  endswitch
    +
    195 
    +
    196  if ((strlen(name) > 0) && (category >= 1))
    +
    197  if (category == kdfTemplates)
    +
    198  dfref df_logbooks = df_parent
    +
    199  else
    +
    200  dfref df_logbooks = df_parent:logbooks
    +
    201  endif
    +
    202  dfref df_logbook = df_logbooks:$name
    +
    203  return df_logbook
    +
    204  else
    +
    205  return df_parent
    +
    206  endif
    +
    207 end
    +
    208 
    +
    218 static function init_package([clean])
    +
    219  variable clean
    +
    220 
    +
    221  if (ParamIsDefault(clean))
    +
    222  clean = 0
    +
    223  endif
    +
    224 
    +
    225  dfref savedf = getdatafolderdfr()
    +
    226  dfref df_root = get_elog_df("", kdfRoot)
    +
    227  if ((clean == 0) && (DataFolderRefStatus(df_root) == 1))
    +
    228  return 1
    +
    229  endif
    +
    230 
    +
    231  setdatafolder root:
    +
    232  newdatafolder /o/s packages
    +
    233  newdatafolder /o/s $package_name
    +
    234  dfref df_package_root = getdatafolderdfr()
    +
    235  newdatafolder /o/s volatile
    +
    236  dfref df_volatile = getdatafolderdfr()
    +
    237  newdatafolder /o logbooks
    +
    238  setdatafolder df_package_root
    +
    239  newdatafolder /o/s persistent
    +
    240  dfref df_persistent = getdatafolderdfr()
    +
    241  newdatafolder /o logbooks
    +
    242  newdatafolder /o templates
    +
    243 
    +
    244  // common configuration
    +
    245  setdatafolder df_persistent
    +
    246  string /g elog_path = "c:\\program files (x86)\\ELOG\\elog.exe"
    +
    247  string /g hostname = "localhost"
    +
    248  variable /g port = 0 // 0 = unspecified (default)
    +
    249  variable /g ssl = 0 // 0 = plain text (incl. passwords), 1 = secure connection
    +
    250  string /g subdir = ""
    +
    251  variable /g loglevel = 4
    +
    252 
    +
    253  setdatafolder savedf
    +
    254  return 0
    +
    255 end
    +
    256 
    + +
    264  dfref savedf = getdatafolderdfr()
    +
    265 
    +
    266  dfref df_root = get_elog_df("", kdfRoot)
    +
    267  dfref df_persistent = get_elog_df("", kdfPersistent)
    +
    268  dfref df_templates = get_elog_df("", kdfTemplates)
    +
    269 
    +
    270  // Experiments template
    +
    271  setdatafolder df_templates
    +
    272  newdatafolder /o/s Experiments
    +
    273 
    +
    274  // attributes (persistent)
    +
    275  // available attributes
    +
    276  string /g attributes = "author;project;p-group;sample;source;task;technique;file;valid;"
    +
    277  // controls corresponding to attributes
    +
    278  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
    +
    279  string /g controls = "sv_author;sv_project;sv_pgroup;sv_sample;pm_source;pm_task;pm_technique;sv_file;cb_valid;"
    +
    280  // attributes with fixed options, value item declares the options string
    +
    281  string /g options = "source=sources;task=tasks;technique=techniques"
    +
    282  // attributes which must be defined
    +
    283  string /g required_attributes = "author;project;sample;source;task;technique;valid"
    +
    284 
    +
    285  // option lists
    +
    286  string /g sources = "Manual Entry;PShell;Scienta Data;SScan Data;Prosilica Data;OTF Data;Beamline Status;LEED Data;QMS Data;Matrix Data;Igor Pro;Other"
    +
    287  string /g tasks = "Measurement;Optimization;Analysis;Sample Preparation;Sample Storage;Comment;Development;Maintenance;Test;Other"
    +
    288  string /g techniques = "XPS;UPS;XPD;XAS;XMCD;PhD;ARUPS;STM;STS;LEED;AES;QMS;MBE;Sputter/Anneal;Test;Other"
    +
    289 
    +
    290  // Calculations template
    +
    291  setdatafolder df_templates
    +
    292  newdatafolder /o/s Calculations
    +
    293 
    +
    294  // attributes (persistent)
    +
    295  // available attributes
    +
    296  string /g attributes = "author;project;p-group;sample;program;revision;machine;job;experiment;source path;result path;valid"
    +
    297  // controls corresponding to attributes
    +
    298  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
    +
    299  string /g controls = "sv_author;sv_project;sv_pgroup;sv_sample;pm_program;sv_revision;pm_machine;sv_job;sv_experiment;sv_sourcepath;sv_resultpath;cb_valid"
    +
    300  // attributes with fixed options, value item declares the options string
    +
    301  string /g options = "program=programs;machine=machines"
    +
    302  // attributes which must be defined
    +
    303  string /g required_attributes = "author;project;sample"
    +
    304 
    +
    305  // option lists
    +
    306  string /g programs = "PMSCO;EDAC;MSC;SSC;MUFPOT;DMSUP;Other"
    +
    307  string /g machines = "PC;VM;Ra;Merlin;llcx;Other"
    +
    308 
    +
    309  // System template
    +
    310  setdatafolder df_templates
    +
    311  newdatafolder /o/s System
    +
    312 
    +
    313  // attributes (persistent)
    +
    314  // available attributes
    +
    315  string /g attributes = "author;type;system;source;file"
    +
    316  // controls corresponding to attributes
    +
    317  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
    +
    318  string /g controls = "sv_author;pm_type;pm_system;pm_source;sv_file"
    +
    319  // attributes with fixed options, value item declares the options string
    +
    320  string /g options = "type=types;system=systems;source=sources"
    +
    321  // attributes which must be defined
    +
    322  string /g required_attributes = "author;type;system"
    +
    323 
    +
    324  // option lists
    +
    325  string /g types = "Installation;Repair;Maintenance;Test;Commissioning;Bakeout;Incident;Cool-down;Warm-up;Storage;Other"
    +
    326  string /g systems = "Vacuum;Control System;BL;XA;XP;SA;SP;T;LL;Monochromator;Carving;Scienta;STM;PC-Scienta;PC-Matrix;PC-Console;PC-Console-Win;PC-XP;EPS;LAC;Desiccator;Other"
    +
    327  string /g sources = "Manual Entry;PShell;Scienta Data;SScan Data;Prosilica Data;OTF Data;Beamline Status;LEED Data;QMS Data;Matrix Data;Igor Pro;Other"
    +
    328 
    +
    329  setdatafolder savedf
    +
    330  return 0
    +
    331 end
    +
    332 
    +
    341 static function init_volatile_vars()
    +
    342  dfref savedf = GetDataFolderDFR()
    +
    343 
    +
    344  dfref df_volatile_root = get_elog_df("", kdfVolatile)
    +
    345  dfref df_volatile_parent = df_volatile_root:logbooks
    +
    346 
    +
    347  string logbooks = list_logbooks()
    +
    348  string logbook
    +
    349  variable nlb = ItemsInList(logbooks)
    +
    350  variable ilb
    +
    351 
    +
    352  SetDataFolder df_volatile_root
    +
    353  if (exists("temp_graph_files") != 2)
    +
    354  string /g temp_graph_files = ""
    +
    355  endif
    +
    356 
    +
    357  for (ilb = 0; ilb < nlb; ilb += 1)
    +
    358  logbook = StringFromList(ilb, logbooks)
    +
    359 
    +
    360  SetDataFolder df_volatile_parent
    +
    361  if (DataFolderExists(logbook))
    +
    362  SetDataFolder $logbook
    +
    363  else
    +
    364  NewDataFolder /o/s $logbook
    +
    365  endif
    +
    366 
    +
    367  if (exists("username") != 2)
    +
    368  string /g username = ""
    +
    369  endif
    +
    370  if (exists("password") != 2)
    +
    371  string /g password = ""
    +
    372  endif
    +
    373  if (exists("msg_id") != 2)
    +
    374  variable /g msg_id = 0
    +
    375  endif
    +
    376  if (exists("att_list") != 1)
    +
    377  make /n=(0,3) /t /o attach_list
    +
    378  make /n=(0,3) /i /o attach_sel
    +
    379  endif
    +
    380  if (exists("url") != 2)
    +
    381  string /g url = ""
    +
    382  endif
    +
    383  endfor
    +
    384 
    +
    385  SetDataFolder savedf
    +
    386  return 0
    +
    387 end
    +
    388 
    +
    402 
    +
    415 function elog_create_logbook(name, [template])
    +
    416  string name
    +
    417  string template
    +
    418 
    +
    419  if (ParamIsDefault(template))
    +
    420  template = ""
    +
    421  endif
    +
    422 
    +
    423  dfref savedf = getdatafolderdfr()
    +
    424  dfref df_root = get_elog_df("", kdfRoot)
    +
    425  dfref df_persistent_root = get_elog_df("", kdfPersistent)
    +
    426  dfref df_persistent_parent = df_persistent_root:logbooks
    +
    427  dfref df_volatile_root = get_elog_df("", kdfVolatile)
    +
    428  dfref df_volatile_parent = df_volatile_root:logbooks
    +
    429 
    +
    430  setdatafolder df_persistent_parent
    +
    431  if (CheckName(name, 11) != 0)
    +
    432  setdatafolder savedf
    +
    433  Abort "invalid logbook name"
    +
    434  return -1
    +
    435  endif
    +
    436 
    +
    437  if (strlen(template) > 0)
    +
    438  dfref df_template = get_elog_df(template, kdfTemplates)
    +
    439  dfref df_existing = get_elog_df(name, kdfPersistent)
    +
    440  if (DataFolderRefStatus(df_existing))
    +
    441  KillDataFolder /Z df_existing
    +
    442  endif
    +
    443  DuplicateDataFolder df_template, df_persistent_parent:$name
    +
    444  else
    +
    445  NewDataFolder /o/s df_persistent_parent:$name
    +
    446 
    +
    447  // ELOG logbook name
    +
    448  string /g logbook = name
    +
    449  // attributes (persistent)
    +
    450  // available attributes
    +
    451  string /g attributes = ""
    +
    452  // controls corresponding to attributes
    +
    453  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
    +
    454  string /g controls = ""
    +
    455  // attributes with fixed options, value item declares the options string
    +
    456  string /g options = ""
    +
    457  // attributes which must be defined
    +
    458  string /g required_attributes = ""
    +
    459  endif
    +
    460 
    +
    461  // usage data (persistent)
    +
    462  setdatafolder get_elog_df(name, kdfPersistent)
    +
    463  string /g recent = ""
    +
    464  string /g recent_message = ""
    +
    465 
    + +
    467 
    +
    468  setdatafolder savedf
    +
    469  return 0
    +
    470 end
    +
    471 
    +
    474 function elog_config([elog_path, hostname, port, subdir])
    +
    475  string elog_path
    +
    476  string hostname
    +
    477  variable port
    +
    478  string subdir
    +
    479 
    +
    480  dfref df = get_elog_df("", kdfPersistent)
    +
    481 
    +
    482  if (!ParamIsDefault(elog_path))
    +
    483  svar /sdfr=df g_elog_path = elog_path
    +
    484  g_elog_path = elog_path
    +
    485  endif
    +
    486  if (!ParamIsDefault(hostname))
    +
    487  svar /sdfr=df g_hostname = hostname
    +
    488  g_hostname = hostname
    +
    489  endif
    +
    490  if (!ParamIsDefault(port))
    +
    491  nvar /sdfr=df g_port = port
    +
    492  g_port = port
    +
    493  endif
    +
    494  if (!ParamIsDefault(subdir))
    +
    495  svar /sdfr=df g_subdir = subdir
    +
    496  g_subdir = subdir
    +
    497  endif
    +
    498 end
    +
    499 
    +
    514 function elog_login(logbook, username, password)
    +
    515  string logbook
    +
    516  string username
    +
    517  string password
    +
    518 
    +
    519  dfref df = get_elog_df(logbook, kdfVolatile)
    +
    520  svar /sdfr=df g_username=username
    +
    521  svar /sdfr=df g_password=password
    +
    522  g_username = username
    +
    523  g_password = password
    +
    524 end
    +
    525 
    +
    534 function elog_logout(logbook)
    +
    535  string logbook
    +
    536 
    +
    537  dfref df = get_elog_df(logbook, kdfVolatile)
    +
    538  if (strlen(logbook) > 0)
    +
    539  svar /z /sdfr=df g_username=username
    +
    540  svar /z /sdfr=df g_password=password
    +
    541  if (svar_exists(g_username))
    +
    542  g_username = ""
    +
    543  endif
    +
    544  if (svar_exists(g_password))
    +
    545  g_password = ""
    +
    546  endif
    +
    547  else
    +
    548  dfref df2 = df:logbooks
    +
    549  variable nlb = CountObjectsDFR(df2, 4)
    +
    550  variable ilb
    +
    551  string slb
    +
    552  for (ilb = 0; ilb < nlb; ilb += 1)
    +
    553  slb = GetIndexedObjNameDFR(df2, 4, ilb)
    +
    554  if (strlen(slb) > 0)
    +
    555  elog_logout(slb)
    +
    556  endif
    +
    557  endfor
    +
    558  endif
    +
    559 end
    +
    560 
    +
    565 static function save_prefs()
    +
    566  dfref saveDF = GetDataFolderDFR()
    +
    567 
    +
    568  dfref df = get_elog_df("", kdfPersistent)
    +
    569  if (DataFolderRefStatus(df) == 1)
    +
    570  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    +
    571  fullPath += package_name
    +
    572  NewPath/O/C/Q tempPackagePrefsPath, fullPath
    +
    573  fullPath += ":preferences.pxp"
    +
    574  SetDataFolder df
    +
    575  SaveData /O /Q /R fullPath
    +
    576  KillPath/Z tempPackagePrefsPath
    +
    577  endif
    +
    578 
    +
    579  SetDataFolder saveDF
    +
    580 end
    +
    581 
    +
    585 static function load_prefs()
    +
    586  dfref saveDF = GetDataFolderDFR()
    +
    587 
    +
    588  variable result = -1
    +
    589  init_package()
    +
    590  setdatafolder get_elog_df("", kdfPersistent)
    +
    591 
    +
    592  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
    +
    593  fullPath += package_name
    +
    594 
    +
    595  GetFileFolderInfo /Q /Z fullPath
    +
    596  if (V_Flag == 0) // Disk directory exists?
    +
    597  fullPath += ":preferences.pxp"
    +
    598  GetFileFolderInfo /Q /Z fullPath
    +
    599  if (V_Flag == 0) // Preference file exist?
    +
    600  LoadData /O /R /Q fullPath
    + +
    602  result = 0
    +
    603  endif
    +
    604  endif
    +
    605 
    +
    606  SetDataFolder saveDF
    +
    607  return result
    +
    608 end
    +
    609 
    +
    619 static function /s list_logbooks([templates])
    +
    620  variable templates
    +
    621 
    +
    622  if (ParamIsDefault(templates))
    +
    623  templates = 0
    +
    624  endif
    +
    625 
    +
    626  dfref df_persistent = get_elog_df("", kdfPersistent)
    +
    627  if (templates)
    +
    628  dfref df_logbooks = df_persistent:templates
    +
    629  else
    +
    630  dfref df_logbooks = df_persistent:logbooks
    +
    631  endif
    +
    632  string logbooks = ""
    +
    633 
    +
    634  variable nlb = CountObjectsDFR(df_logbooks, 4)
    +
    635  variable ilb
    +
    636  string slb
    +
    637  for (ilb = 0; ilb < nlb; ilb += 1)
    +
    638  slb = GetIndexedObjNameDFR(df_logbooks, 4, ilb)
    +
    639  if (strlen(slb) > 0)
    +
    640  logbooks = AddListItem(slb, logbooks)
    +
    641  endif
    +
    642  endfor
    +
    643 
    +
    644  return SortList(logbooks, ";", 16)
    +
    645 end
    +
    646 
    +
    654 function elog_validate_attributes(logbook, attributes)
    +
    655 
    +
    656  string logbook // name of the logbook (as in igor folder name)
    +
    657  string attributes // key=value list of attributes, semicolon separated
    +
    658 
    +
    659  variable result = 0
    +
    660  return result
    +
    661 end
    +
    662 
    +
    686 function elog_create_entry(logbook, attributes, message, [encoding, graphs, replyto])
    +
    687  string logbook
    +
    688  string attributes
    +
    689  string message
    +
    690  variable encoding
    +
    691  string graphs
    +
    692  variable replyto
    +
    693 
    +
    694  if (ParamIsDefault(encoding))
    +
    695  encoding = 1
    +
    696  endif
    +
    697  if (ParamIsDefault(graphs))
    +
    698  graphs = ""
    +
    699  endif
    +
    700  if (ParamIsDefault(replyto))
    +
    701  replyto = 0
    +
    702  endif
    +
    703 
    +
    704  dfref savedf = getdatafolderdfr()
    +
    705  dfref df_general = get_elog_df("", kdfPersistent)
    +
    706  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    707 
    +
    708  variable result = 0
    +
    709  nvar /sdfr=df_volatile msg_id
    +
    710  nvar /sdfr=df_general loglevel
    +
    711 
    +
    712  if (elog_validate_attributes(logbook,attributes) != 0)
    +
    713  if (loglevel >= 2)
    +
    714  print "ELOG: failed to validate attributes."
    +
    715  endif
    +
    716  result = -3
    +
    717  endif
    +
    718 
    +
    719  string cmd = prepare_command_line(logbook)
    +
    720  if (strlen(cmd) == 0)
    +
    721  if (loglevel >= 2)
    +
    722  print "ELOG: failed to prepare command line."
    +
    723  endif
    +
    724  result = -2
    +
    725  endif
    +
    726 
    +
    727  if (replyto >= 1)
    +
    728  cmd += " -r " + num2str(replyto)
    +
    729  endif
    +
    730  cmd += " -n " + num2str(encoding)
    +
    731 
    +
    732  variable nattr = ItemsInList(attributes, ";")
    +
    733  variable iattr
    +
    734  string sattr
    +
    735  for (iattr = 0; (iattr < nattr) && (result == 0); iattr += 1)
    +
    736  sattr = StringFromList(iattr, attributes, ";")
    +
    737  if (strlen(StringFromList(1, sattr, "=")) > 0)
    +
    738  sattr = ReplaceString("%", sattr, "")
    +
    739  cmd += " -a \"" + sattr + "\""
    +
    740  endif
    +
    741  endfor
    +
    742 
    +
    743  if (result == 0)
    +
    744  string cmd_graphs = prepare_graph_attachments(graphs)
    +
    745  cmd += " " + cmd_graphs
    +
    746  endif
    +
    747 
    +
    748  if ((result == 0) && (strlen(message) > 0))
    +
    749  string messagefile = create_message_file(message)
    +
    750  if (strlen(messagefile) > 0)
    +
    751  cmd += " -m \"" + messagefile + "\""
    +
    752  cmd += " > elog.log"
    +
    753  if (loglevel >= 5)
    +
    754  print cmd
    +
    755  endif
    +
    756  string cmd_file_path = create_cmd_file(cmd)
    +
    757  if (strlen(cmd_file_path) > 0)
    +
    758  ExecuteScriptText cmd_file_path
    +
    759  variable id = parse_result()
    +
    760  if (id > 0)
    +
    761  msg_id = id
    +
    762  if (loglevel >= 4)
    +
    763  print "ELOG: sent message " + num2str(id)
    +
    764  endif
    +
    765  else
    +
    766  if (loglevel >= 2)
    +
    767  print "ELOG: sending message failed."
    +
    768  endif
    +
    769  result = -4
    +
    770  endif
    +
    771  else
    +
    772  result = -2
    +
    773  endif
    +
    774  else
    +
    775  if (loglevel >= 2)
    +
    776  print "ELOG: failed to create temporary message file."
    +
    777  endif
    +
    778  result = -1
    +
    779  endif
    +
    780  endif
    +
    781 
    +
    782  setdatafolder savedf
    +
    783  return result
    +
    784 end
    +
    785 
    +
    793 function elog_add_attachment(logbook, id, graphs)
    +
    794  string logbook
    +
    795  variable id // existing entry ID
    +
    796  string graphs // names of graph windows to be added as attachments, semicolon separated
    +
    797 
    +
    798  dfref savedf = getdatafolderdfr()
    +
    799  dfref df_general = get_elog_df("", kdfPersistent)
    +
    800  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    801 
    +
    802  variable result = 0
    +
    803  nvar /sdfr=df_volatile msg_id
    +
    804  nvar /sdfr=df_general loglevel
    +
    805 
    +
    806  string cmd = prepare_command_line(logbook)
    +
    807  if (strlen(cmd) == 0)
    +
    808  result = -2 // error: invalid/missing command line
    +
    809  endif
    +
    810 
    +
    811  cmd += " -e " + num2str(id)
    +
    812 
    +
    813  if (result == 0)
    +
    814  string cmd_graphs = prepare_graph_attachments(graphs)
    +
    815  if (strlen(cmd_graphs) == 0)
    +
    816  result = -3 // error: invalid/missing graphs
    +
    817  endif
    +
    818  endif
    +
    819 
    +
    820  if (result == 0)
    +
    821  cmd += " " + cmd_graphs
    +
    822  cmd += " > elog.log"
    +
    823  string cmd_file_path = create_cmd_file(cmd)
    +
    824  if (strlen(cmd_file_path) > 0)
    +
    825  ExecuteScriptText cmd_file_path
    +
    826  id = parse_result()
    +
    827  if (id > 0)
    +
    828  msg_id = id
    +
    829  if (loglevel >= 4)
    +
    830  print "ELOG: attached graphs to message " + num2str(id)
    +
    831  endif
    +
    832  else
    +
    833  if (loglevel >= 2)
    +
    834  print "ELOG: failed to attach graphs."
    +
    835  endif
    +
    836  result = -4 // error: elog returned error
    +
    837  endif
    +
    838  else
    +
    839  result = -2 // error: invalid command line
    +
    840  endif
    +
    841  endif
    +
    842 
    +
    843  setdatafolder savedf
    +
    844  return result
    +
    845 end
    +
    846 
    +
    854 static function /s prepare_command_line(logbook)
    +
    855  string logbook
    +
    856 
    +
    857  dfref df_general = get_elog_df("", kdfPersistent)
    +
    858  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
    +
    859  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    860 
    +
    861  svar /sdfr=df_general elog_path
    +
    862  svar /sdfr=df_general hostname
    +
    863  nvar /sdfr=df_general port
    +
    864  nvar /sdfr=df_general ssl
    +
    865  svar /sdfr=df_general subdir
    +
    866  nvar /sdfr=df_general loglevel
    +
    867  svar /sdfr=df_volatile username
    +
    868  svar /sdfr=df_volatile password
    +
    869 
    +
    870  string cmd
    +
    871  cmd = "\"" + elog_path + "\""
    +
    872  if (loglevel >= 5)
    +
    873  cmd += " -v"
    +
    874  endif
    +
    875  cmd += " -h " + hostname
    +
    876  if ((nvar_exists(port)) && (port > 0))
    +
    877  cmd += " -p " + num2str(port)
    +
    878  endif
    +
    879  if ((svar_exists(subdir)) && (strlen(subdir) > 0))
    +
    880  cmd += " -d " + subdir
    +
    881  endif
    +
    882  cmd += " -l \"" + logbook + "\""
    +
    883  if ((nvar_exists(ssl)) && (ssl != 0))
    +
    884  cmd += " -s"
    +
    885  endif
    +
    886  //cmd += " -w " + password
    +
    887  if (svar_exists(username) && svar_exists(password) && (strlen(username) > 0) && (strlen(password) > 0))
    +
    888  cmd += " -u " + username + " " + password
    +
    889  endif
    +
    890 
    +
    891  if (loglevel >= 5)
    +
    892  print cmd
    +
    893  endif
    +
    894 
    +
    895  return cmd
    +
    896 end
    +
    897 
    +
    903 static function /s format_url(logbook)
    +
    904  string logbook
    +
    905 
    +
    906  dfref df_general = get_elog_df("", kdfPersistent)
    +
    907 
    +
    908  svar /sdfr=df_general hostname
    +
    909  nvar /sdfr=df_general port
    +
    910  nvar /sdfr=df_general ssl
    +
    911  svar /sdfr=df_general subdir
    +
    912 
    +
    913  string cmd = ""
    +
    914  if ((nvar_exists(ssl)) && (ssl != 0))
    +
    915  cmd += "https://"
    +
    916  else
    +
    917  cmd += "http://"
    +
    918  endif
    +
    919  cmd += hostname
    +
    920  if ((nvar_exists(port)) && (port > 0))
    +
    921  cmd += ":" + num2str(port)
    +
    922  endif
    +
    923  if ((svar_exists(subdir)) && (strlen(subdir) > 0))
    +
    924  cmd += "/" + subdir
    +
    925  endif
    +
    926  cmd += "/" + logbook
    +
    927 
    +
    928  return cmd
    +
    929 end
    +
    930 
    +
    940 static function /s prepare_graph_attachments(graphs)
    +
    941  string graphs // names of graph windows to be added as attachments, semicolon separated
    +
    942 
    +
    943  string cmd = ""
    +
    944  variable ngraphs = ItemsInList(graphs, ";")
    +
    945  variable igraph
    +
    946  string sgraph
    +
    947  string graph_path
    +
    948  for (igraph = 0; igraph < ngraphs; igraph += 1)
    +
    949  sgraph = StringFromList(igraph, graphs, ";")
    +
    950  graph_path = create_graph_file(sgraph, igraph)
    +
    951  if (strlen(graph_path) > 0)
    +
    952  cmd += " -f \"" + graph_path + "\""
    +
    953  endif
    +
    954  endfor
    +
    955 
    +
    956  return cmd
    +
    957 end
    +
    958 
    +
    959 static function /s get_timestamp(sep)
    +
    960  string sep
    +
    961  Variable now = DateTime
    +
    962  string dat = ReplaceString("-", Secs2Date(DateTime, -2), "")
    +
    963  string tim = ReplaceString(":", Secs2Time(DateTime, 3), "")
    +
    964  return dat + sep + tim
    +
    965 end
    +
    966 
    +
    983 static function /s create_message_file(message)
    +
    984  string message
    +
    985 
    +
    986  message = ReplaceString("%", message, "")
    +
    987  string path = SpecialDirPath("Temporary", 0, 1, 0)
    +
    988  variable len = strlen(path)
    +
    989  string filename
    +
    990 
    +
    991  if (numtype(len) == 0)
    +
    992  filename = "elog_temp_message.txt"
    +
    993  path += filename
    +
    994  variable f1
    +
    995  Open f1 as path
    +
    996  fprintf f1, message
    +
    997  Close f1
    +
    998  else
    +
    999  filename = ""
    +
    1000  endif
    +
    1001 
    +
    1002  return filename
    +
    1003 end
    +
    1004 
    +
    1024 static function /s create_graph_file(graphname, fileindex)
    +
    1025  string graphname
    +
    1026  variable fileindex
    +
    1027 
    +
    1028  dfref df_volatile_root = get_elog_df("", kdfVolatile)
    +
    1029  svar /sdfr=df_volatile_root temp_graph_files
    +
    1030 
    +
    1031  string path = SpecialDirPath("Temporary", 0, 1, 0)
    +
    1032  string ts = get_timestamp("_")
    +
    1033  variable len = strlen(path)
    +
    1034  string filename
    +
    1035 
    +
    1036  if (numtype(len) == 0)
    +
    1037  filename = "elog_" + ts + "_" + num2str(fileindex) + ".png"
    +
    1038  path += filename
    +
    1039  SavePICT /B=72 /E=-5 /M /O /W=(0,0,8,6) /WIN=$graphname /Z as path
    +
    1040  if (v_flag == 0)
    +
    1041  temp_graph_files = AddListItem(path, temp_graph_files, ";", inf)
    +
    1042  else
    +
    1043  filename = ""
    +
    1044  endif
    +
    1045  else
    +
    1046  filename = ""
    +
    1047  endif
    +
    1048 
    +
    1049  return filename
    +
    1050 end
    +
    1051 
    +
    1060 static function /s create_cmd_file(cmd)
    +
    1061  string cmd
    +
    1062 
    +
    1063  dfref df_general = get_elog_df("", kdfPersistent)
    +
    1064  nvar /sdfr=df_general loglevel
    +
    1065 
    +
    1066  if (strlen(cmd) >= 1024)
    +
    1067  if (loglevel >= 2)
    +
    1068  print "ELOG: command line too long (add fewer attachments)."
    +
    1069  endif
    +
    1070  return ""
    +
    1071  endif
    +
    1072 
    +
    1073  string work_path = SpecialDirPath("Temporary", 0, 1, 0)
    +
    1074  variable len = strlen(work_path)
    +
    1075  if (numtype(len) == 0)
    +
    1076  string cmdx
    +
    1077  string cmd_path = work_path + "elog_temp_cmd.bat"
    +
    1078 
    +
    1079  variable f1
    +
    1080  Open f1 as cmd_path
    +
    1081  cmdx = "c:\r\n"
    +
    1082  fprintf f1, cmdx
    +
    1083  cmdx = "cd \"" + work_path + "\"\r\n"
    +
    1084  fprintf f1, cmdx
    +
    1085  cmdx = "del elog.log"
    +
    1086  fprintf f1, cmdx + "\r\n"
    +
    1087  fprintf f1, cmd
    +
    1088  Close f1
    +
    1089  else
    +
    1090  cmd_path = ""
    +
    1091  endif
    +
    1092 
    +
    1093  return cmd_path
    +
    1094 end
    +
    1095 
    +
    1096 static function /s get_log_path()
    +
    1097  string path = SpecialDirPath("Temporary", 0, 1, 0)
    +
    1098  variable len = strlen(path)
    +
    1099  if (numtype(len) == 0)
    +
    1100  path += "elog.log"
    +
    1101  else
    +
    1102  path = ""
    +
    1103  endif
    +
    1104 
    +
    1105  return path
    +
    1106 end
    +
    1107 
    +
    1116 static function cleanup_temp_files()
    +
    1117  dfref df_volatile_root = get_elog_df("", kdfVolatile)
    +
    1118  if (DataFolderRefStatus(df_volatile_root))
    +
    1119  svar /sdfr=df_volatile_root /z temp_graph_files
    +
    1120  if (SVAR_Exists(temp_graph_files))
    +
    1121  variable nfi = ItemsInList(temp_graph_files)
    +
    1122  variable ifi
    +
    1123  string sfi
    +
    1124  for (ifi = 0; ifi < nfi; ifi += 1)
    +
    1125  sfi = StringFromList(ifi, temp_graph_files)
    +
    1126  DeleteFile /Z sfi
    +
    1127  endfor
    +
    1128  temp_graph_files = ""
    +
    1129  endif
    +
    1130  endif
    +
    1131  return 0
    +
    1132 end
    +
    1133 
    +
    1134 static strconstant elog_success_msg = "Message successfully transmitted"
    +
    1135 static strconstant elog_parse_id = "ID=%u"
    +
    1136 
    +
    1142 static function parse_result()
    +
    1143  dfref df_general = get_elog_df("", kdfPersistent)
    +
    1144  nvar /sdfr=df_general loglevel
    +
    1145 
    +
    1146  string path = get_log_path()
    +
    1147  string line = ""
    +
    1148  string output = ""
    +
    1149  variable success = 0
    +
    1150  variable id = -1
    +
    1151  string part1 = ""
    +
    1152  string part2 = ""
    +
    1153 
    +
    1154  variable len = strlen(path)
    +
    1155  if (numtype(len) == 0)
    +
    1156  variable f1
    +
    1157  Open /R/Z f1 as path
    +
    1158  if (v_flag == 0)
    +
    1159  do
    +
    1160  FReadLine f1, line
    +
    1161  if (strlen(line) > 0)
    +
    1162  part1 = StringFromList(0, line, ",")
    +
    1163  part2 = ReplaceString(" ", StringFromList(1, line, ","), "")
    +
    1164  success = cmpstr(part1, elog_success_msg) == 0
    +
    1165  if (success)
    +
    1166  sscanf part2, elog_parse_id, id
    +
    1167  endif
    +
    1168  else
    +
    1169  break
    +
    1170  endif
    +
    1171  output += line
    +
    1172  while(!success)
    +
    1173  Close f1
    +
    1174  endif
    +
    1175  endif
    +
    1176  if (loglevel >= 5)
    +
    1177  print output
    +
    1178  endif
    +
    1179 
    +
    1180  return id
    +
    1181 end
    +
    1182 
    +
    1185 function /s elog_prompt_logbook()
    +
    1186  string logbooks = list_logbooks(templates=0)
    +
    1187  logbooks = AddListItem("(new)", logbooks)
    +
    1188  string templates = list_logbooks(templates=1)
    +
    1189  templates = AddListItem("(none)", templates)
    +
    1190 
    +
    1191  string logbook = StringFromList(0, logbooks)
    +
    1192  string template = StringFromList(0, logbooks)
    +
    1193  string name = ""
    +
    1194  string username = ""
    +
    1195  string password = ""
    +
    1196 
    +
    1197  prompt logbook, "logbook", popup logbooks
    +
    1198  prompt template, "template", popup templates
    +
    1199  prompt name, "new logbook name"
    +
    1200 
    +
    1201  doprompt "select logbook", logbook, template, name
    +
    1202  if (!v_flag)
    +
    1203  if (cmpstr(logbook, "(new)") == 0)
    +
    1204  elog_create_logbook(name, template=template)
    +
    1205  logbook = name
    +
    1206  endif
    +
    1207  else
    +
    1208  logbook = ""
    +
    1209  endif
    +
    1210  return logbook
    +
    1211 end
    +
    1212 
    +
    1215 function elog_prompt_login(logbook)
    +
    1216  string logbook
    +
    1217 
    +
    1218  string logbooks = list_logbooks(templates=0)
    +
    1219 
    +
    1220  string username = ""
    +
    1221  string password = ""
    +
    1222 
    +
    1223  prompt logbook, "logbook", popup logbooks
    +
    1224  prompt username, "user name"
    +
    1225  prompt password, "password (blank to log out)"
    +
    1226 
    +
    1227  doprompt "log in to logbook", logbook, username, password
    +
    1228  if (!v_flag)
    +
    1229  elog_login(logbook, username, password)
    +
    1230  endif
    +
    1231 
    +
    1232  return v_flag
    +
    1233 end
    +
    1234 
    +
    1242 function /s PearlElogPanel(logbook)
    +
    1243  string logbook
    +
    1244 
    +
    1245  dfref savedf = getdatafolderdfr()
    +
    1246  dfref df_general = get_elog_df("", kdfPersistent)
    +
    1247  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
    +
    1248  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    1249 
    +
    1250  string win_name = logbook + "ElogPanel"
    +
    1251  string win_title = "ELOG " + logbook
    +
    1252 
    +
    1253  NewPanel /K=1 /N=$win_name /W=(600,200,1200,700) as win_title
    +
    1254  win_name = s_name
    +
    1255  ModifyPanel /w=$win_name cbRGB=(52224,52224,65280)
    +
    1256 
    +
    1257  svar /sdfr=df_persistent attributes
    +
    1258  svar /sdfr=df_persistent controls
    +
    1259  svar /sdfr=df_persistent options
    +
    1260  wave /t /sdfr=df_volatile attach_list
    +
    1261  wave /sdfr=df_volatile attach_sel
    +
    1262  svar /sdfr=df_volatile url
    +
    1263 
    +
    1264  variable iattr
    +
    1265  variable nattr = ItemsInList(attributes, ";")
    +
    1266  string s_attr
    +
    1267  string s_control
    +
    1268  string s_option
    +
    1269  string persistent_path = GetDataFolder(1, df_persistent)
    +
    1270  string volatile_path = GetDataFolder(1, df_volatile)
    +
    1271  string options_path
    +
    1272  string variable_path
    +
    1273  variable ypos = 2
    +
    1274  variable height = 0
    +
    1275 
    +
    1276  for (iattr = 0; iattr < nattr; iattr += 1)
    +
    1277  s_attr = StringFromList(iattr, attributes, ";")
    +
    1278  s_control = StringFromList(iattr, controls, ";")
    +
    1279  strswitch(s_control[0,1])
    +
    1280  case "sv":
    +
    1281  SetVariable $s_control, win=$win_name, pos={0,ypos}, size={300,16}, bodyWidth=230
    +
    1282  SetVariable $s_control, win=$win_name, title=s_attr, value= _STR:""
    +
    1283  SetVariable $s_control, win=$win_name, userdata(attribute)=s_attr
    +
    1284  ypos += 18
    +
    1285  break
    +
    1286  case "pm":
    +
    1287  options_path = persistent_path + StringByKey(s_attr, options, "=", ";")
    +
    1288  PopupMenu $s_control, win=$win_name, pos={0,ypos}, size={300,21}, bodyWidth=230
    +
    1289  PopupMenu $s_control, win=$win_name, title=s_attr
    +
    1290  PopupMenu $s_control, win=$win_name, mode=1, popvalue="Test", value= #options_path
    +
    1291  PopupMenu $s_control, win=$win_name, userdata(attribute)=s_attr
    +
    1292  ypos += 23
    +
    1293  break
    +
    1294  case "cb":
    +
    1295  CheckBox $s_control, win=$win_name, pos={70,ypos}, size={300,14}
    +
    1296  CheckBox $s_control, win=$win_name, title=s_attr, value= 1
    +
    1297  CheckBox $s_control, win=$win_name, userdata(attribute)=s_attr
    +
    1298  ypos += 17
    +
    1299  break
    +
    1300  endswitch
    +
    1301  endfor
    +
    1302  ypos = max(ypos, 80)
    +
    1303 
    +
    1304  TitleBox t_attach, win=$win_name, pos={308,5}, size={70,14}, title="Attachments", frame=0
    +
    1305  height = ypos - 21 - 4
    +
    1306  ListBox lb_attach, win=$win_name, pos={308,21}, size={264,height}
    +
    1307  ListBox lb_attach, win=$win_name, listWave=attach_list
    +
    1308  ListBox lb_attach, win=$win_name, mode=1, selWave=attach_sel, selRow=-1
    +
    1309  ListBox lb_attach, win=$win_name, widths={20,160,80}
    +
    1310  ListBox lb_attach, win=$win_name, help={"Choose graphs to attach to the message."}
    +
    1311 
    +
    1312  Button b_attach_top, win=$win_name, pos={420,2}, size={40,18}, title="top"
    +
    1313  Button b_attach_top, win=$win_name, fcolor=(56576,60928,47872)
    +
    1314  Button b_attach_top, win=$win_name, proc=PearlElog#bp_attach_top
    +
    1315  Button b_attach_top, win=$win_name, help={"Select top graph for attachment."}
    +
    1316  Button b_attach_all, win=$win_name, pos={460,2}, size={40,18}, title="all"
    +
    1317  Button b_attach_all, win=$win_name, fcolor=(56576,60928,47872)
    +
    1318  Button b_attach_all, win=$win_name, proc=PearlElog#bp_attach_allnone
    +
    1319  Button b_attach_all, win=$win_name, help={"Select all graphs for attachment."}
    +
    1320  Button b_attach_none, win=$win_name, pos={500,2}, size={40,18}, title="none"
    +
    1321  Button b_attach_none, win=$win_name, fcolor=(56576,60928,47872)
    +
    1322  Button b_attach_none, win=$win_name, proc=PearlElog#bp_attach_allnone
    +
    1323  Button b_attach_none, win=$win_name, help={"Deselect all attachments."}
    +
    1324  Button b_save_graphs, win=$win_name, pos={540,2}, size={40,18}, title="save"
    +
    1325  Button b_save_graphs, win=$win_name, fcolor=(56576,60928,47872)
    +
    1326  Button b_save_graphs, win=$win_name, proc=PearlElog#bp_save_graphs
    +
    1327  Button b_save_graphs, win=$win_name, help={"Save selected graphs as PNG bitmap files."}
    +
    1328  Button b_attach_up, win=$win_name, pos={576,20}, size={20,20}, title="\\W517"
    +
    1329  Button b_attach_up, win=$win_name, fcolor=(56576,60928,47872)
    +
    1330  Button b_attach_up, win=$win_name, proc=PearlElog#bp_attach_updown
    +
    1331  Button b_attach_up, win=$win_name, help={"Move selected graph up."}
    +
    1332  Button b_attach_dw, win=$win_name, pos={576,40}, size={20,20}, title="\\W523"
    +
    1333  Button b_attach_dw, win=$win_name, fcolor=(56576,60928,47872)
    +
    1334  Button b_attach_dw, win=$win_name, proc=PearlElog#bp_attach_updown
    +
    1335  Button b_attach_dw, win=$win_name, help={"Move selected graph down."}
    +
    1336 
    +
    1337  ypos += 246-160
    +
    1338  Button b_submit,win=$win_name, pos={70,ypos},size={46,20},proc=PearlElog#bp_submit,title="Submit"
    +
    1339  Button b_submit,win=$win_name, help={"Submit form data to ELOG (new entry)."}
    +
    1340  Button b_submit,win=$win_name, fcolor=(56576,60928,47872)
    +
    1341  Button b_clear,win=$win_name, pos={120,ypos},size={46,20},proc=PearlElog#bp_clear,title="Clear"
    +
    1342  Button b_clear,win=$win_name, help={"Clear the form fields"}
    +
    1343  Button b_clear,win=$win_name, fcolor=(56576,60928,47872)
    +
    1344 
    +
    1345  ypos += 272-246
    +
    1346  variable_path = volatile_path + "msg_id"
    +
    1347  SetVariable sv_id,win=$win_name, pos={51,ypos},size={119,16},bodyWidth=77
    +
    1348  SetVariable sv_id,win=$win_name, title="ID",value=$variable_path
    +
    1349  SetVariable sv_id,win=$win_name, help={"ID of last submitted message, or message to attach or reply to."}
    +
    1350 
    +
    1351  TitleBox t_host, win=$win_name, pos={170,ypos+4}, size={112.00,14.00}, frame=0
    +
    1352  TitleBox t_host, win=$win_name, variable=url
    +
    1353 
    +
    1354  ypos += 270-272
    +
    1355  Button b_attach,win=$win_name, pos={170,ypos},size={48,20},proc=PearlElog#bp_attach,title="Attach"
    +
    1356  Button b_attach,win=$win_name, help={"Attach the selected graph to an existing ELOG entry (correct ID required)."}
    +
    1357  Button b_attach,win=$win_name, fcolor=(56576,60928,47872)
    +
    1358  Button b_reply,win=$win_name, pos={220,ypos},size={48,20},proc=PearlElog#bp_submit,title="Reply"
    +
    1359  Button b_reply,win=$win_name, help={"Submit form data to ELOG as a reply to an existing message (correct ID required)."}
    +
    1360  Button b_reply,win=$win_name, fcolor=(56576,60928,47872)
    +
    1361  Button b_login,win=$win_name, pos={550,ypos},size={46,20},proc=PearlElog#bp_login,title="Login"
    +
    1362  Button b_login,win=$win_name, help={"Enter user name and password."}
    +
    1363  Button b_login,win=$win_name, fcolor=(56576,60928,47872)
    +
    1364  Button b_logout,win=$win_name, pos={550,ypos},size={46,20},proc=PearlElog#bp_logout,title="Logout"
    +
    1365  Button b_logout,win=$win_name, help={"Clear user name and password."}
    +
    1366  Button b_logout,win=$win_name, fcolor=(56576,60928,47872), disable=3
    +
    1367 
    +
    1368  SetWindow $win_name, hook(elogPanelHook)=PearlElog#elog_panel_hook
    +
    1369  SetWindow $win_name, userdata(logbook)=logbook
    +
    1370 
    +
    1371  ypos += 160-270
    +
    1372  TitleBox t_message,win=$win_name, pos={10,ypos},size={58,16},fixedSize=1,frame=0,anchor=RT,title="Message"
    +
    1373  DefineGuide UGH0={FT,ypos},UGV0={FL,70},UGH1={FB,-52},UGV1={FR,-2}
    +
    1374  NewNotebook /F=0 /N=Message /OPTS=3 /W=(115,404,345,341)/FG=(UGV0,UGH0,UGV1,UGH1) /HOST=#
    +
    1375  Notebook kwTopWin, defaultTab=20, statusWidth=0, autoSave=0
    +
    1376  Notebook kwTopWin fSize=10, fStyle=0, textRGB=(0,0,0)
    +
    1377  RenameWindow #,Message
    +
    1378  string nb_name = win_name + "#Message"
    +
    1379  SetActiveSubwindow ##
    +
    1380 
    +
    1381  // restore recently used attributes and message
    +
    1382  svar /z /sdfr=df_persistent recent
    +
    1383  if (svar_exists(recent) && (strlen(recent) > 0))
    +
    1384  set_panel_attributes(win_name, recent)
    +
    1385  endif
    +
    1386  svar /z /sdfr=df_persistent recent_message
    +
    1387  if (svar_exists(recent_message) && (strlen(recent_message) > 0))
    +
    1388  set_panel_message(win_name, recent_message)
    +
    1389  endif
    +
    1390  Notebook $nb_name selection={startOfFile,startOfFile}, findText={"",1}
    +
    1391 
    +
    1392  setdatafolder savedf
    +
    1393  return win_name
    +
    1394 end
    +
    1395 
    +
    1396 static function elog_panel_hook(s)
    +
    1397  STRUCT WMWinHookStruct &s
    +
    1398 
    +
    1399  Variable hookResult = 0
    +
    1400 
    +
    1401  switch(s.eventCode)
    +
    1402  case 0: // activate
    +
    1403  string logbook = GetUserData(s.winName, "", "logbook")
    +
    1404  if (strlen(logbook) > 0)
    +
    1405  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    1406  svar /sdfr=df_volatile url
    +
    1407  url = format_url(logbook)
    +
    1408  update_attach_items(logbook)
    +
    1409  endif
    +
    1410  break
    +
    1411  case 6: // resize
    +
    1412  // move bottom-aligned controls when the window is resized
    +
    1413  variable b_top = s.winRect.bottom + 4
    +
    1414  Button b_submit,pos={70,b_top}
    +
    1415  Button b_clear,pos={120,b_top}
    +
    1416  TitleBox t_host, pos={170,b_top+4}
    +
    1417  b_top += 24
    +
    1418  Button b_attach,pos={170,b_top}
    +
    1419  Button b_reply,pos={220,b_top}
    +
    1420  Button b_login, pos={550,b_top}
    +
    1421  Button b_logout, pos={550,b_top}
    +
    1422  b_top += 2
    +
    1423  SetVariable sv_id,pos={51,b_top}
    +
    1424  break
    +
    1425  endswitch
    +
    1426 
    +
    1427  return hookResult // 0 if nothing done, else 1
    +
    1428 end
    +
    1429 
    +
    1430 static constant kAttachColSel = 0
    +
    1431 static constant kAttachColTitle = 1
    +
    1432 static constant kAttachColName = 2
    +
    1433 
    +
    1435 static function update_attach_items(logbook)
    +
    1436  string logbook
    +
    1437 
    +
    1438  dfref savedf = getdatafolderdfr()
    +
    1439  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    1440  wave /t /sdfr=df_volatile attach_list
    +
    1441  wave /sdfr=df_volatile attach_sel
    +
    1442 
    +
    1443  if (!waveexists(attach_list))
    +
    1444  return -1
    +
    1445  endif
    +
    1446  string names = WinList("*", ";", "WIN:1;VISIBLE:1")
    +
    1447  names = SortList(names, ";", 16)
    +
    1448 
    +
    1449  // remove closed graphs
    +
    1450  variable i
    +
    1451  variable k
    +
    1452  variable n = DimSize(attach_list, 0)
    +
    1453  string s
    +
    1454  for (i = n-1; i >= 0; i -= 1)
    +
    1455  s = attach_list[i][kAttachColName]
    +
    1456  if (WhichListItem(s, names) < 0)
    +
    1457  DeletePoints /M=0 i, 1, attach_list, attach_sel
    +
    1458  endif
    +
    1459  endfor
    +
    1460 
    +
    1461  // add new graphs
    +
    1462  n = ItemsInList(names)
    +
    1463  for (i = 0; i < n; i += 1)
    +
    1464  s = StringFromList(i, names)
    +
    1465  FindValue /text=s /txop=4 /z attach_list
    +
    1466  if (v_value < 0)
    +
    1467  k = DimSize(attach_list, 0)
    +
    1468  Redimension /n=(k+1,3) attach_list, attach_sel
    +
    1469  //InsertPoints /M=0 k, 1, attach_list, attach_sel
    +
    1470  attach_list[k][kAttachColSel] = ""
    +
    1471  attach_list[k][kAttachColTitle] = ""
    +
    1472  attach_list[k][kAttachColName] = s
    +
    1473  attach_sel[k][kAttachColSel] = 32
    +
    1474  attach_sel[k][kAttachColTitle] = 0
    +
    1475  attach_sel[k][kAttachColName] = 0
    +
    1476  endif
    +
    1477  endfor
    +
    1478 
    +
    1479  // update titles
    +
    1480  n = DimSize(attach_list, 0)
    +
    1481  for (i = n-1; i >= 0; i -= 1)
    +
    1482  s = attach_list[i][kAttachColName]
    +
    1483  getwindow /z $s, wtitle
    +
    1484  if (v_flag == 0)
    +
    1485  attach_list[i][kAttachColTitle] = s_value
    +
    1486  else
    +
    1487  attach_list[i][kAttachColTitle] = s
    +
    1488  endif
    +
    1489  endfor
    +
    1490 
    +
    1491  setdatafolder savedf
    +
    1492  return 0
    +
    1493 end
    +
    1494 
    +
    1496 static function move_attach_item(logbook, item, distance)
    +
    1497  string logbook
    +
    1498  variable item
    +
    1499  variable distance
    +
    1500 
    +
    1501  dfref savedf = getdatafolderdfr()
    +
    1502  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    1503  wave /t /sdfr=df_volatile attach_list
    +
    1504  wave /sdfr=df_volatile attach_sel
    +
    1505  variable n = DimSize(attach_list, 0)
    +
    1506  variable dest = item + distance
    +
    1507 
    +
    1508  if ((item >= 0) && (item < n) && (dest >= 0) && (dest < n))
    +
    1509  string name = attach_list[item][kAttachColName]
    +
    1510  variable sel = attach_sel[item][kAttachColSel]
    +
    1511  DeletePoints /M=0 item, 1, attach_list, attach_sel
    +
    1512  InsertPoints /M=0 dest, 1, attach_list, attach_sel
    +
    1513  attach_list[dest][kAttachColName] = name
    +
    1514  update_attach_items(logbook)
    +
    1515  attach_sel[dest][kAttachColSel] = sel
    +
    1516  endif
    +
    1517 end
    +
    1518 
    +
    1520 static function bp_attach_updown(ba) : ButtonControl
    +
    1521  STRUCT WMButtonAction &ba
    +
    1522 
    +
    1523  switch( ba.eventCode )
    +
    1524  case 2: // mouse up
    +
    1525  string logbook = GetUserData(ba.win, "", "logbook")
    +
    1526  ControlInfo /w=$ba.win lb_attach
    +
    1527  variable row = v_value
    +
    1528  dfref df = $s_datafolder
    +
    1529  wave /t /sdfr=df attach_list = $s_value
    +
    1530  if (cmpstr(ba.ctrlName, "b_attach_up") == 0)
    +
    1531  // up button
    +
    1532  if (row >= 1)
    +
    1533  move_attach_item(logbook, row, -1)
    +
    1534  ListBox lb_attach, win=$ba.win, selRow=(row-1)
    +
    1535  endif
    +
    1536  else
    +
    1537  // down button
    +
    1538  if (row < DimSize(attach_list, 0) - 1)
    +
    1539  move_attach_item(logbook, row, +1)
    +
    1540  ListBox lb_attach, win=$ba.win, selRow=(row+1)
    +
    1541  endif
    +
    1542  endif
    +
    1543  break
    +
    1544  case -1: // control being killed
    +
    1545  break
    +
    1546  endswitch
    +
    1547 
    +
    1548  return 0
    +
    1549 end
    +
    1550 
    +
    1552 static function bp_submit(ba) : ButtonControl
    +
    1553  STRUCT WMButtonAction &ba
    +
    1554 
    +
    1555  switch( ba.eventCode )
    +
    1556  case 2: // mouse up
    +
    1557  string logbook = GetUserData(ba.win, "", "logbook")
    +
    1558  string attributes
    +
    1559  string message
    +
    1560  string graphs
    +
    1561  attributes = get_panel_attributes(ba.win)
    +
    1562  message = get_panel_message(ba.win)
    +
    1563  graphs = get_panel_graphs(ba.win)
    +
    1564 
    +
    1565  variable id
    +
    1566  if (cmpstr(ba.ctrlName, "b_reply") == 0)
    +
    1567  // Reply button
    +
    1568  ControlInfo /w=$ba.win sv_id
    +
    1569  id = v_value
    +
    1570  else
    +
    1571  // Submit button
    +
    1572  id = 0
    +
    1573  endif
    +
    1574 
    +
    1575  if ((elog_validate_attributes(logbook, attributes) == 0) && (strlen(message) > 0))
    +
    1576  variable result
    +
    1577  result = elog_create_entry(logbook, attributes, message, graphs=graphs, replyto=id)
    +
    1578  if (result == 0)
    +
    1579  dfref df = get_elog_df(logbook, kdfPersistent)
    +
    1580  svar /sdfr=df recent
    +
    1581  recent = attributes
    +
    1582  svar /sdfr=df recent_message
    +
    1583  recent_message = message
    +
    1584  else
    +
    1585  abort "Submission failed. Error code " + num2str(result) + "."
    +
    1586  endif
    +
    1587  else
    +
    1588  abort "Submission failed due to missing/invalid attribute."
    +
    1589  endif
    +
    1590  break
    +
    1591  case -1: // control being killed
    +
    1592  break
    +
    1593  endswitch
    +
    1594 
    +
    1595  return 0
    +
    1596 end
    +
    1597 
    +
    1599 static function bp_attach_top(ba) : ButtonControl
    +
    1600  STRUCT WMButtonAction &ba
    +
    1601 
    +
    1602  switch( ba.eventCode )
    +
    1603  case 2: // mouse up
    +
    1604  string graphs = WinName(0, 1, 1)
    +
    1605  set_panel_graphs(ba.win, graphs)
    +
    1606  break
    +
    1607  case -1: // control being killed
    +
    1608  break
    +
    1609  endswitch
    +
    1610 
    +
    1611  return 0
    +
    1612 end
    +
    1613 
    +
    1615 static function bp_attach_allnone(ba) : ButtonControl
    +
    1616  STRUCT WMButtonAction &ba
    +
    1617 
    +
    1618  switch( ba.eventCode )
    +
    1619  case 2: // mouse up
    +
    1620  string logbook = GetUserData(ba.win, "", "logbook")
    +
    1621  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    1622  wave /sdfr=df_volatile attach_sel
    +
    1623  if (cmpstr(ba.ctrlName, "b_attach_all") == 0)
    +
    1624  attach_sel[][kAttachColSel] = attach_sel[p][kAttachColSel] | 16
    +
    1625  else
    +
    1626  attach_sel[][kAttachColSel] = attach_sel[p][kAttachColSel] & ~16
    +
    1627  endif
    +
    1628  break
    +
    1629  case -1: // control being killed
    +
    1630  break
    +
    1631  endswitch
    +
    1632 
    +
    1633  return 0
    +
    1634 end
    +
    1635 
    +
    1636 static function bp_attach(ba) : ButtonControl
    +
    1637  STRUCT WMButtonAction &ba
    +
    1638 
    +
    1639  switch( ba.eventCode )
    +
    1640  case 2: // mouse up
    +
    1641  string logbook = GetUserData(ba.win, "", "logbook")
    +
    1642  string graphs
    +
    1643  graphs = get_panel_graphs(ba.win)
    +
    1644 
    +
    1645  variable id
    +
    1646  ControlInfo /w=$ba.win sv_id
    +
    1647  id = v_value
    +
    1648 
    +
    1649  // TODO : is there a way around this restriction?
    +
    1650  DoAlert /T="ELOG" 1, "This operation will replace all existing attachments. Do you want to continue?"
    +
    1651 
    +
    1652  if ((id > 0) && (v_flag == 1))
    +
    1653  variable result
    +
    1654  result = elog_add_attachment(logbook, id, graphs)
    +
    1655  if (result != 0)
    +
    1656  abort "Submission failed. Error code " + num2str(result) + "."
    +
    1657  endif
    +
    1658  else
    +
    1659  abort "Submission failed due to missing/invalid attribute."
    +
    1660  endif
    +
    1661  break
    +
    1662  case -1: // control being killed
    +
    1663  break
    +
    1664  endswitch
    +
    1665 
    +
    1666  return 0
    +
    1667 end
    +
    1668 
    +
    1669 static function bp_save_graphs(ba) : ButtonControl
    +
    1670  STRUCT WMButtonAction &ba
    +
    1671 
    +
    1672  switch( ba.eventCode )
    +
    1673  case 2: // mouse up
    +
    1674  string logbook = GetUserData(ba.win, "", "logbook")
    +
    1675  string graphs = get_panel_graphs(ba.win)
    +
    1676  variable ngraphs = ItemsInList(graphs, ";")
    +
    1677 
    +
    1678  variable igraph
    +
    1679  string sgraph
    +
    1680  string graph_path
    +
    1681  for (igraph = 0; igraph < ngraphs; igraph += 1)
    +
    1682  sgraph = StringFromList(igraph, graphs, ";")
    +
    1683  graph_path = create_graph_file(sgraph, igraph)
    +
    1684  if (strlen(graph_path) > 0)
    +
    1685  print graph_path
    +
    1686  endif
    +
    1687  endfor
    +
    1688 
    +
    1689  break
    +
    1690  case -1: // control being killed
    +
    1691  break
    +
    1692  endswitch
    +
    1693 
    +
    1694  return 0
    +
    1695 end
    +
    1696 
    +
    1697 static function bp_clear(ba) : ButtonControl
    +
    1698  STRUCT WMButtonAction &ba
    +
    1699 
    +
    1700  switch( ba.eventCode )
    +
    1701  case 2: // mouse up
    +
    1702  set_panel_attributes(ba.win, "", clear=1)
    +
    1703  set_panel_message(ba.win, "")
    +
    1704  set_panel_graphs(ba.win, "")
    +
    1705  break
    +
    1706  case -1: // control being killed
    +
    1707  break
    +
    1708  endswitch
    +
    1709 
    +
    1710  return 0
    +
    1711 end
    +
    1712 
    +
    1713 static function bp_login(ba) : ButtonControl
    +
    1714  STRUCT WMButtonAction &ba
    +
    1715 
    +
    1716  switch( ba.eventCode )
    +
    1717  case 2: // mouse up
    +
    1718  string logbook = GetUserData(ba.win, "", "logbook")
    +
    1719  if (elog_prompt_login(logbook) == 0)
    +
    1720  Button b_login, win=$ba.win, disable=3
    +
    1721  Button b_logout, win=$ba.win, disable=0
    +
    1722  endif
    +
    1723  break
    +
    1724  case -1: // control being killed
    +
    1725  break
    +
    1726  endswitch
    +
    1727 
    +
    1728  return 0
    +
    1729 end
    +
    1730 
    +
    1731 static function bp_logout(ba) : ButtonControl
    +
    1732  STRUCT WMButtonAction &ba
    +
    1733 
    +
    1734  switch( ba.eventCode )
    +
    1735  case 2: // mouse up
    +
    1736  string logbook = GetUserData(ba.win, "", "logbook")
    +
    1737  elog_logout(logbook)
    +
    1738  Button b_login, win=$ba.win, disable=0
    +
    1739  Button b_logout, win=$ba.win, disable=3
    +
    1740  break
    +
    1741  case -1: // control being killed
    +
    1742  break
    +
    1743  endswitch
    +
    1744 
    +
    1745  return 0
    +
    1746 end
    +
    1747 
    +
    1748 static function /s get_default_panel_name()
    +
    1749  string windowname
    +
    1750  windowname = StringFromList(0, WinList("*ElogPanel*", ";", "WIN:64"), ";")
    +
    1751  return windowname
    +
    1752 end
    +
    1753 
    +
    1761 static function /s get_panel_attributes(windowname)
    +
    1762  string windowname
    +
    1763 
    +
    1764  if (strlen(windowname) == 0)
    +
    1765  windowname = get_default_panel_name()
    +
    1766  endif
    +
    1767  if (strlen(windowname) == 0)
    +
    1768  return ""
    +
    1769  endif
    +
    1770 
    +
    1771  string controls = ControlNameList(windowname, ";")
    +
    1772  string attributes = ""
    +
    1773  string control
    +
    1774  string attribute
    +
    1775  variable ico
    +
    1776  variable nco = ItemsInList(controls, ";")
    +
    1777  for (ico = 0; ico < nco; ico += 1)
    +
    1778  control = StringFromList(ico, controls, ";")
    +
    1779  attribute = GetUserData(windowname, control, "attribute")
    +
    1780  if (strlen(attribute) > 0)
    +
    1781  ControlInfo /w=$windowname $control
    +
    1782  switch(v_flag)
    +
    1783  case 2: // checkbox
    +
    1784  attributes = ReplaceNumberByKey(attribute, attributes, v_value, "=", ";")
    +
    1785  break
    +
    1786  case 3: // popupmenu
    +
    1787  case 5: // setvariable
    +
    1788  attributes = ReplaceStringByKey(attribute, attributes, s_value, "=", ";")
    +
    1789  break
    +
    1790  endswitch
    +
    1791  endif
    +
    1792  endfor
    +
    1793 
    +
    1794  return attributes
    +
    1795 end
    +
    1796 
    +
    1808 static function /s set_panel_attributes(windowname, attributes, [clear])
    +
    1809  string windowname
    +
    1810  string attributes
    +
    1811  variable clear
    +
    1812 
    +
    1813  if (strlen(windowname) == 0)
    +
    1814  windowname = get_default_panel_name()
    +
    1815  endif
    +
    1816  if (strlen(windowname) == 0)
    +
    1817  return ""
    +
    1818  endif
    +
    1819  if (ParamIsDefault(clear))
    +
    1820  clear = 0
    +
    1821  endif
    +
    1822 
    +
    1823  string path
    +
    1824 
    +
    1825  string logbook = GetUserData(windowname, "", "logbook")
    +
    1826  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
    +
    1827  string persistent_path = GetDataFolder(1, df_persistent)
    +
    1828  svar /sdfr=df_persistent options
    +
    1829  string options_path
    +
    1830 
    +
    1831  string controls = ControlNameList(windowname, ";")
    +
    1832  string control
    +
    1833  string attribute
    +
    1834  string value
    +
    1835  variable numval
    +
    1836  variable ico
    +
    1837  variable nco = ItemsInList(controls, ";")
    +
    1838  for (ico = 0; ico < nco; ico += 1)
    +
    1839  control = StringFromList(ico, controls, ";")
    +
    1840  attribute = GetUserData(windowname, control, "attribute")
    +
    1841  if (strlen(attribute))
    +
    1842  value = StringByKey(attribute, attributes, "=", ";")
    +
    1843  if (strlen(value) || clear)
    +
    1844  ControlInfo /w=$windowname $control
    +
    1845  switch(v_flag)
    +
    1846  case 2: // checkbox
    +
    1847  numval = NumberByKey(attribute, attributes, "=", ";")
    +
    1848  if ((numtype(numval) != 0) && clear)
    +
    1849  numval = 0
    +
    1850  endif
    +
    1851  if (numtype(numval) == 0)
    +
    1852  CheckBox $control, value=numval, win=$windowname
    +
    1853  endif
    +
    1854  break
    +
    1855  case 3: // popupmenu
    +
    1856  options_path = persistent_path + StringByKey(attribute, options, "=", ";")
    +
    1857  svar values = $options_path
    +
    1858  numval = WhichListItem(value, values, ";") + 1
    +
    1859  if (numval >= 1)
    +
    1860  PopupMenu $control, mode=numval, win=$windowname
    +
    1861  endif
    +
    1862  break
    +
    1863  case 5: // setvariable
    +
    1864  SetVariable /z $control, value= _STR:value, win=$windowname
    +
    1865  break
    +
    1866  endswitch
    +
    1867  endif
    +
    1868  endif
    +
    1869  endfor
    +
    1870 
    +
    1871  return attributes
    +
    1872 end
    +
    1873 
    +
    1881 static function /s get_panel_message(windowname)
    +
    1882  string windowname
    +
    1883 
    +
    1884  if (strlen(windowname) == 0)
    +
    1885  windowname = get_default_panel_name()
    +
    1886  endif
    +
    1887  if (strlen(windowname) == 0)
    +
    1888  return ""
    +
    1889  endif
    +
    1890 
    +
    1891  string nb = windowname + "#Message"
    +
    1892  notebook $nb selection={startOfFile, endOfFile}
    +
    1893  getselection notebook, $nb, 2
    +
    1894 
    +
    1895  return s_selection
    +
    1896 end
    +
    1897 
    +
    1907 static function /s set_panel_message(windowname, message)
    +
    1908  string windowname
    +
    1909  string message
    +
    1910 
    +
    1911  if (strlen(windowname) == 0)
    +
    1912  windowname = get_default_panel_name()
    +
    1913  endif
    +
    1914 
    +
    1915  string nb = windowname + "#Message"
    +
    1916  notebook $nb selection={startOfFile, endOfFile},text=message
    +
    1917 
    +
    1918  return message
    +
    1919 end
    +
    1920 
    +
    1927 static function /s get_panel_graphs(windowname)
    +
    1928  string windowname // panel window name
    +
    1929 
    +
    1930  dfref savedf = getdatafolderdfr()
    +
    1931  if (strlen(windowname) == 0)
    +
    1932  windowname = get_default_panel_name()
    +
    1933  endif
    +
    1934  if (strlen(windowname) == 0)
    +
    1935  return ""
    +
    1936  endif
    +
    1937 
    +
    1938  string logbook = GetUserData(windowname, "", "logbook")
    +
    1939  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    1940  wave /t /sdfr=df_volatile attach_list
    +
    1941  wave /sdfr=df_volatile attach_sel
    +
    1942  string graphs = ""
    +
    1943  string windows = ""
    +
    1944  string graphname
    +
    1945 
    +
    1946  variable n = DimSize(attach_sel, 0)
    +
    1947  variable i
    +
    1948  for (i = 0; i < n; i += 1)
    +
    1949  if (attach_sel[i][kAttachColSel] & 16)
    +
    1950  graphname = attach_list[i][kAttachColName]
    +
    1951  windows = WinList(graphname, ";", "WIN:1")
    +
    1952  if (ItemsInList(windows) == 1)
    +
    1953  graphs = AddListItem(graphname, graphs, ";", inf)
    +
    1954  endif
    +
    1955  endif
    +
    1956  endfor
    +
    1957 
    +
    1958  return graphs
    +
    1959 end
    +
    1960 
    +
    1967 static function /s set_panel_graphs(windowname, graphs)
    +
    1968  string windowname
    +
    1969  string graphs
    +
    1970 
    +
    1971  if (strlen(windowname) == 0)
    +
    1972  windowname = get_default_panel_name()
    +
    1973  endif
    +
    1974  if (strlen(windowname) == 0)
    +
    1975  return ""
    +
    1976  endif
    +
    1977 
    +
    1978  string logbook = GetUserData(windowname, "", "logbook")
    +
    1979  update_attach_items(logbook)
    +
    1980  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
    +
    1981  wave /t /sdfr=df_volatile attach_list
    +
    1982  wave /sdfr=df_volatile attach_sel
    +
    1983 
    +
    1984  variable n = DimSize(attach_sel, 0)
    +
    1985  variable i
    +
    1986  string graphname
    +
    1987  for (i = 0; i < n; i += 1)
    +
    1988  graphname = attach_list[i][kAttachColName]
    +
    1989  if (WhichListItem(graphname, graphs)>= 0)
    +
    1990  attach_sel[i][kAttachColSel] = 48
    +
    1991  else
    +
    1992  attach_sel[i][kAttachColSel] = 32
    +
    1993  endif
    +
    1994  endfor
    +
    1995 end
    +
    static variable IgorQuitHook(string igorApplicationNameStr)
    save preferences and recent values before Igor quits.
    Definition: pearl-elog.ipf:136
    +
    static variable bp_login(WMButtonAction *ba)
    +
    static string get_log_path()
    +
    variable elog_login(string logbook, string username, string password)
    set username and password for login to a logbook
    Definition: pearl-elog.ipf:514
    +
    static const variable kdfTemplates
    Definition: pearl-elog.ipf:157
    +
    static string list_logbooks(variable templates=defaultValue)
    get a list of configured logbooks or templates.
    Definition: pearl-elog.ipf:619
    +
    static string get_panel_graphs(string windowname)
    get the names of the graphs selected for attachment
    +
    static const string package_path
    Definition: pearl-elog.ipf:87
    +
    static variable bp_attach_top(WMButtonAction *ba)
    select top graph window for attachment
    +
    static string create_graph_file(string graphname, variable fileindex)
    save a graph to a temporary graphics file
    +
    static variable bp_attach(WMButtonAction *ba)
    +
    static variable bp_logout(WMButtonAction *ba)
    +
    static const variable kAttachColTitle
    +
    variable elog_init_pearl_templates()
    setup PEARL template logbooks.
    Definition: pearl-elog.ipf:263
    +
    variable elog_add_attachment(string logbook, variable id, string graphs)
    add one or more graphs to an existing ELOG entry
    Definition: pearl-elog.ipf:793
    +
    string PearlElogPanel(string logbook)
    open a new panel for submitting data to ELOG.
    +
    static variable move_attach_item(string logbook, variable item, variable distance)
    move an attachment item in the list of attachments
    +
    variable pearl_elog(string logbook)
    main function to initialize ELOG and to open an ELOG panel.
    Definition: pearl-elog.ipf:98
    +
    static variable bp_clear(WMButtonAction *ba)
    +
    static variable elog_panel_hook(WMWinHookStruct *s)
    +
    interface for writing ELOG entries with Igor graphs as attachment.
    +
    static string get_panel_attributes(string windowname)
    get a list of attributes from the fields of the ELOG panel.
    +
    static string get_timestamp(string sep)
    Definition: pearl-elog.ipf:959
    +
    static const string elog_success_msg
    +
    static variable bp_attach_updown(WMButtonAction *ba)
    button procedure for the attachment up and down buttons
    +
    string elog_prompt_logbook()
    prompt to open or create a logbook
    +
    static string set_panel_message(string windowname, string message)
    set the message field of the ELOG panel
    +
    static const variable kdfPersistent
    Definition: pearl-elog.ipf:156
    +
    variable elog_create_entry(string logbook, string attributes, string message, variable encoding=defaultValue, string graphs=defaultValue, variable replyto=defaultValue)
    create a new entry in ELOG
    Definition: pearl-elog.ipf:686
    +
    static string create_cmd_file(string cmd)
    write the command line to a file.
    +
    static string create_message_file(string message)
    save the message to a temporary text file
    Definition: pearl-elog.ipf:983
    +
    static variable bp_attach_allnone(WMButtonAction *ba)
    select/deselect all graph windows for attachment
    +
    static const string package_name
    Definition: pearl-elog.ipf:86
    +
    static string prepare_graph_attachments(string graphs)
    prepare screenshots of graph windows for attachments
    Definition: pearl-elog.ipf:940
    +
    static variable IgorBeforeNewHook(string igorApplicationNameStr)
    save preferences and recent values before Igor opens a new experiment.
    Definition: pearl-elog.ipf:128
    +
    static const string elog_parse_id
    +
    static dfr get_elog_df(string name, variable category)
    get the package, logbook, or template datafolder.
    Definition: pearl-elog.ipf:171
    +
    static variable parse_result()
    parse the result file from an elog invokation.
    +
    variable elog_config(string elog_path=defaultValue, string hostname=defaultValue, variable port=defaultValue, string subdir=defaultValue)
    set global module configuration parameters
    Definition: pearl-elog.ipf:474
    +
    variable elog_create_logbook(string name, string template=defaultValue)
    create a new logbook.
    Definition: pearl-elog.ipf:415
    +
    static string prepare_command_line(string logbook)
    format the ELOG command and essential address arguments.
    Definition: pearl-elog.ipf:854
    +
    static string set_panel_graphs(string windowname, string graphs)
    update selection of graphs for attachment
    +
    variable elog_prompt_login(string logbook)
    prompt the user for login to a logbook
    +
    static variable cleanup_temp_files()
    delete temporary files created by the ELOG module.
    +
    static variable save_prefs()
    save persistent package data to the preferences file.
    Definition: pearl-elog.ipf:565
    +
    static variable update_attach_items(string logbook)
    update the list of attachments
    +
    static const variable kdfVolatile
    Definition: pearl-elog.ipf:155
    +
    static const variable kAttachColSel
    +
    static variable bp_save_graphs(WMButtonAction *ba)
    +
    static string get_panel_message(string windowname)
    get the message field of the ELOG panel
    +
    variable elog_logout(string logbook)
    clear username and password of a logbook or all logbooks.
    Definition: pearl-elog.ipf:534
    +
    static variable init_volatile_vars()
    initialize volatile variables.
    Definition: pearl-elog.ipf:341
    +
    static string format_url(string logbook)
    format the URL for display to the user
    Definition: pearl-elog.ipf:903
    +
    static const variable kAttachColName
    +
    static variable bp_submit(WMButtonAction *ba)
    button procedure for the Submit and Reply buttons
    +
    static const variable kdfRoot
    Definition: pearl-elog.ipf:154
    +
    variable elog_validate_attributes(string logbook, string attributes)
    validate attributes
    Definition: pearl-elog.ipf:654
    +
    static variable load_prefs()
    load persistent package data from the preferences file.
    Definition: pearl-elog.ipf:585
    +
    static string get_default_panel_name()
    +
    static variable AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind)
    initialize the package and reload preferences after an experiment is loaded.
    Definition: pearl-elog.ipf:144
    +
    static variable init_package(variable clean=defaultValue)
    initialize the package data folder.
    Definition: pearl-elog.ipf:218
    +
    static string set_panel_attributes(string windowname, string attributes, variable clear=defaultValue)
    set the fields of the ELOG panel
    diff --git a/doc/html/pearl-fitfuncs_8ipf.html b/doc/html/pearl-fitfuncs_8ipf.html index 0e3fd44..14567c5 100644 --- a/doc/html/pearl-fitfuncs_8ipf.html +++ b/doc/html/pearl-fitfuncs_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-fitfuncs.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -110,23 +112,29 @@ Namespaces

    Functions

    threadsafe variable MultiGaussLinBG (wave w, variable x) - multiple gaussian peaks on a linear background fit function. More...
    + multiple gaussian peaks on a linear background fit function. More...
      threadsafe variable MultiGaussLinBG_AO (wave pw, wave yw, wave xw) - multiple gaussian peaks on a linear background fit function (all at once). More...
    + multiple gaussian peaks on a linear background fit function (all at once). More...
      threadsafe variable DoubletGaussLinBG_AO (wave pw, wave yw, wave xw) - doublet gaussian peaks on a linear background fit function (all at once). More...
    + doublet gaussian peaks on a linear background fit function (all at once). More...
      -variable MultiVoigtLinBG (wave w, variable x) - multiple voigt peaks on a linear background fit function. More...
    -  +threadsafe variable DblDoubletGaussLinBG_AO (wave pw, wave yw, wave xw) + two doublet gaussian peaks on a linear background fit function (all at once). More...
    +  +threadsafe variable MultiVoigtLinBG (wave w, variable x) + multiple voigt peaks on a linear background fit function. More...
    +  +threadsafe variable MultiVoigtLinBG_AO (wave pw, wave yw, wave xw) + multiple voigt peaks on a linear background fit function. More...
    +  threadsafe variable DoniachSunjic (variable x, variable amp, variable pos, variable sing, variable fwhm) - Doniach-Sunjic line shape. More...
    + Doniach-Sunjic line shape. More...
      -variable MultiDoniachSunjicLinBG (wave w, variable x) - multiple doniach-sunjic peaks on a linear background fit function. More...
    -  +threadsafe variable MultiDoniachSunjicLinBG (wave w, variable x) + multiple doniach-sunjic peaks on a linear background fit function. More...
    +  threadsafe variable ds1_bg (wave w, variable x)   threadsafe variable ds2_bg (wave w, variable x) @@ -154,19 +162,19 @@ Functions variable ShowComponents_Au4f_2p3 (wave coef_wave, wave fit_wave)   variable FermiGaussConv (wave pw, wave yw, wave xw) - convolution of Fermi-Dirac distribution and a Gaussian. More...
    + convolution of Fermi-Dirac distribution and a Gaussian. More...
      variable ShirleyBG (wave w, wave bg, variable p1, variable p2) - calculate the shirley background More...
    + calculate the shirley background More...
     

    Detailed Description

    various fit functions for photoelectron spectroscopy.

    this procedure contains various functions for curve fitting.

    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -
    -

    Definition at line 598 of file pearl-fitfuncs.ipf.

    +

    Definition at line 677 of file pearl-fitfuncs.ipf.

    @@ -227,7 +235,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 643 of file pearl-fitfuncs.ipf.

    +

    Definition at line 722 of file pearl-fitfuncs.ipf.

    @@ -257,7 +265,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 728 of file pearl-fitfuncs.ipf.

    +

    Definition at line 807 of file pearl-fitfuncs.ipf.

    @@ -287,7 +295,69 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 541 of file pearl-fitfuncs.ipf.

    +

    Definition at line 620 of file pearl-fitfuncs.ipf.

    + +
    + + +

    ◆ DblDoubletGaussLinBG_AO()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    threadsafe variable DblDoubletGaussLinBG_AO (wave pw,
    wave yw,
    wave xw 
    )
    +
    + +

    two doublet gaussian peaks on a linear background fit function (all at once).

    +

    this fits four gaussian peaks. peak positions are specified by center, splitting and shift rather than individually. amplitudes are specified as absolute values for peaks 1 and 3, and relative values for peaks 2 and 4.

    +

    can be used if a spin-orbit doublet is split by a chemical shift which affects both spin-orbit peaks equally.

    +
    Note
    FWHM = width * 2 * sqrt(ln(2)) = width * 1.665
    +
    Parameters
    + + + + +
    pwshape parameters.
      +
    • pw[0] = constant coefficient of background
    • +
    • pw[1] = linear coefficient of background
    • +
    • pw[2] = amplitude of peak 1
    • +
    • pw[3] = amplitude of peak 2
    • +
    • pw[4] = amplitude of peak 3, relative to peak 1
    • +
    • pw[5] = amplitude of peak 4, relative to peak 2
    • +
    • pw[6] = position of peak 1
    • +
    • pw[7] = splitting (distance between peaks 1 and 3)
    • +
    • pw[8] = shift (distance between peaks 1 and 2)
    • +
    • pw[9] = width of peaks 1 and 3
    • +
    • pw[10] = width of peaks 2 and 4
    • +
    +
    ywy (dependent) values.
    xwx (independent) independent values.
    +
    +
    + +

    Definition at line 157 of file pearl-fitfuncs.ipf.

    @@ -348,7 +418,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 174 of file pearl-fitfuncs.ipf.

    +

    Definition at line 253 of file pearl-fitfuncs.ipf.

    @@ -384,7 +454,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 480 of file pearl-fitfuncs.ipf.

    +

    Definition at line 559 of file pearl-fitfuncs.ipf.

    @@ -404,7 +474,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 391 of file pearl-fitfuncs.ipf.

    +

    Definition at line 470 of file pearl-fitfuncs.ipf.

    @@ -462,7 +532,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 117 of file pearl-fitfuncs.ipf.

    +

    Definition at line 118 of file pearl-fitfuncs.ipf.

    @@ -492,7 +562,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 217 of file pearl-fitfuncs.ipf.

    +

    Definition at line 296 of file pearl-fitfuncs.ipf.

    @@ -522,7 +592,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 240 of file pearl-fitfuncs.ipf.

    +

    Definition at line 319 of file pearl-fitfuncs.ipf.

    @@ -552,7 +622,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 268 of file pearl-fitfuncs.ipf.

    +

    Definition at line 347 of file pearl-fitfuncs.ipf.

    @@ -582,7 +652,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 309 of file pearl-fitfuncs.ipf.

    +

    Definition at line 388 of file pearl-fitfuncs.ipf.

    @@ -628,7 +698,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
  • pw[5] = gaussian width = FWHM / 1.66511
  • -

    Definition at line 851 of file pearl-fitfuncs.ipf.

    +

    Definition at line 930 of file pearl-fitfuncs.ipf.

    @@ -670,18 +740,18 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 562 of file pearl-fitfuncs.ipf.

    +

    Definition at line 641 of file pearl-fitfuncs.ipf.

    - -

    ◆ MultiDoniachSunjicLinBG()

    + +

    ◆ MultiDoniachSunjicLinBG()

    - + @@ -717,7 +787,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 201 of file pearl-fitfuncs.ipf.

    +

    Definition at line 280 of file pearl-fitfuncs.ipf.

    @@ -764,7 +834,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 44 of file pearl-fitfuncs.ipf.

    +

    Definition at line 45 of file pearl-fitfuncs.ipf.

    @@ -819,18 +889,18 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 79 of file pearl-fitfuncs.ipf.

    +

    Definition at line 80 of file pearl-fitfuncs.ipf.

    - -

    ◆ MultiVoigtLinBG()

    + +

    ◆ MultiVoigtLinBG()

    variable MultiDoniachSunjicLinBG threadsafe variable MultiDoniachSunjicLinBG ( wave  w,
    - + @@ -866,7 +936,62 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 144 of file pearl-fitfuncs.ipf.

    +

    Definition at line 190 of file pearl-fitfuncs.ipf.

    + + + + +

    ◆ MultiVoigtLinBG_AO()

    + +
    +
    +
    variable MultiVoigtLinBG threadsafe variable MultiVoigtLinBG ( wave  w,
    + + + + + + + + + + + + + + + + + + + + + + + +
    threadsafe variable MultiVoigtLinBG_AO (wave pw,
    wave yw,
    wave xw 
    )
    +
    + +

    multiple voigt peaks on a linear background fit function.

    +

    this is the all-at-once version of MultiVoigtLinBG. it runs slightly faster compared to the point-by-point function.

    +
    Parameters
    + + + + +
    pwshape parameters. the length of the wave defines the number of peaks.
      +
    • pw[0] = constant coefficient of background
    • +
    • pw[1] = linear coefficient of background
    • +
    • pw[2 + (i-1) * 4] = amplitude of peak i
    • +
    • pw[3 + (i-1) * 4] = position of peak i
    • +
    • pw[4 + (i-1) * 4] = width of peak i
    • +
    • pw[5 + (i-1) * 4] = shape of peak i
    • +
    +
    ywy (dependent) values.
    xwx (independent) independent values.
    +
    +
    + +

    Definition at line 224 of file pearl-fitfuncs.ipf.

    @@ -910,7 +1035,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    calculate the shirley background

    -

    Definition at line 901 of file pearl-fitfuncs.ipf.

    +

    Definition at line 980 of file pearl-fitfuncs.ipf.

    @@ -940,7 +1065,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 697 of file pearl-fitfuncs.ipf.

    +

    Definition at line 776 of file pearl-fitfuncs.ipf.

    @@ -970,7 +1095,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 796 of file pearl-fitfuncs.ipf.

    +

    Definition at line 875 of file pearl-fitfuncs.ipf.

    @@ -980,9 +1105,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
    diff --git a/doc/html/pearl-fitfuncs_8ipf.js b/doc/html/pearl-fitfuncs_8ipf.js index 57c4c9b..4c01889 100644 --- a/doc/html/pearl-fitfuncs_8ipf.js +++ b/doc/html/pearl-fitfuncs_8ipf.js @@ -5,6 +5,7 @@ var pearl_fitfuncs_8ipf = [ "Au4f_2p2", "pearl-fitfuncs_8ipf.html#a24cd6a0c96ef8c720e371bb31ac0a479", null ], [ "Au4f_2p3", "pearl-fitfuncs_8ipf.html#a709f7c4585b1d850ea8aae1885ac18cb", null ], [ "Calc_DoniachSunjicBroad", "pearl-fitfuncs_8ipf.html#aff8e8b103c32c8e723b57ce7ad5ef0f5", null ], + [ "DblDoubletGaussLinBG_AO", "pearl-fitfuncs_8ipf.html#aca0bf4ff35794a459e15a3b358dbfa04", null ], [ "DoniachSunjic", "pearl-fitfuncs_8ipf.html#aaa48428994f8720a12e7237ef43e86ea", null ], [ "DoniachSunjicBroad", "pearl-fitfuncs_8ipf.html#ae2d138beb7cb39e8042487893095b461", null ], [ "DoniachSunjicBroadS", "pearl-fitfuncs_8ipf.html#a9d110819fa3cd2173f3103724e394fdf", null ], @@ -15,10 +16,11 @@ var pearl_fitfuncs_8ipf = [ "ds6_bg", "pearl-fitfuncs_8ipf.html#a5a2a03026b88f3dd99214ab1b26e6f80", null ], [ "FermiGaussConv", "pearl-fitfuncs_8ipf.html#a4d20215153c0e0cee3870dfceded8bc9", null ], [ "Fit_DoniachSunjicBroad", "pearl-fitfuncs_8ipf.html#a819902ab9f541b75a0fd33a7b52465d0", null ], - [ "MultiDoniachSunjicLinBG", "pearl-fitfuncs_8ipf.html#a1520bd078ef77fd16ba20e95dbc6829d", null ], + [ "MultiDoniachSunjicLinBG", "pearl-fitfuncs_8ipf.html#af669aa08d0c32d3647007155f4b7ea3c", null ], [ "MultiGaussLinBG", "pearl-fitfuncs_8ipf.html#aad1418e71830c1ec71d7dd62b2ecf9ba", null ], [ "MultiGaussLinBG_AO", "pearl-fitfuncs_8ipf.html#a2c6547164c0b46efecf4d372ea04c263", null ], - [ "MultiVoigtLinBG", "pearl-fitfuncs_8ipf.html#a3a94468da285a31eed5e990cd90e5cdf", null ], + [ "MultiVoigtLinBG", "pearl-fitfuncs_8ipf.html#a704de4b170620d07b75f2093fe052272", null ], + [ "MultiVoigtLinBG_AO", "pearl-fitfuncs_8ipf.html#a81da09e30e2800703dd178248f0c55be", null ], [ "ShirleyBG", "pearl-fitfuncs_8ipf.html#af07f887f3ba8e3e35c9214df8bb6a49f", null ], [ "ShowComponents_Au4f_2p2", "pearl-fitfuncs_8ipf.html#a84a0278284332631682ce032018d1716", null ], [ "ShowComponents_Au4f_2p3", "pearl-fitfuncs_8ipf.html#a02368cc4adfbd746cd2f1e7d73884a61", null ] diff --git a/doc/html/pearl-fitfuncs_8ipf_source.html b/doc/html/pearl-fitfuncs_8ipf_source.html index 5e1916a..519cc3e 100644 --- a/doc/html/pearl-fitfuncs_8ipf_source.html +++ b/doc/html/pearl-fitfuncs_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-fitfuncs.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,37 +87,863 @@ $(document).ready(function(){initNavTree('pearl-fitfuncs_8ipf_source.html','');}
    pearl-fitfuncs.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.2
    3 #pragma ModuleName = PearlFitFuncs
    4 #pragma version = 1.02
    5 #include "mm-physconst"
    6 
    20 
    25 
    26 
    27 //------------------------------------------------------------------------------
    28 // Gaussian shapes
    29 //------------------------------------------------------------------------------
    30 
    44 threadsafe function MultiGaussLinBG(w,x) : FitFunc
    45  wave w
    46  variable x
    47 
    48  variable np = numpnts(w)
    49  variable ip
    50 
    51  variable v = w[0] + x * w[1]
    52  for (ip = 2; ip < np; ip += 3)
    53  v += w[ip] * exp( -( (x - w[ip+1]) / w[ip+2] )^2 )
    54  endfor
    55 
    56  return v
    57 end
    58 
    79 threadsafe function MultiGaussLinBG_AO(pw, yw, xw) : FitFunc
    80  wave pw
    81  wave yw
    82  wave xw
    83 
    84  variable np = numpnts(pw)
    85  variable ip
    86 
    87  yw = pw[0] + xw[p] * pw[1]
    88  for (ip = 2; ip < np; ip += 3)
    89  yw += pw[ip] * exp( -( (xw[p] - pw[ip+1]) / pw[ip+2] )^2 )
    90  endfor
    91 end
    92 
    117 threadsafe function DoubletGaussLinBG_AO(pw, yw, xw) : FitFunc
    118  wave pw
    119  wave yw
    120  wave xw
    121 
    122  yw = pw[0] + xw[p] * pw[1]
    123  yw += pw[2] * exp( -( (xw[p] - pw[4] - pw[5] /2) / pw[6] )^2 )
    124  yw += pw[2] * pw[3] * exp( -( (xw[p] - pw[4] + pw[5] /2) / pw[6] / pw[7] )^2 )
    125 end
    126 
    127 //------------------------------------------------------------------------------
    128 // Voigt shapes
    129 //------------------------------------------------------------------------------
    130 
    144 function MultiVoigtLinBG(w,x) : FitFunc
    145  wave w
    146  variable x
    147 
    148  variable np = numpnts(w)
    149  variable ip
    150 
    151  variable v = w[0] + x * w[1]
    152  for (ip = 2; ip < np; ip += 4)
    153  v += w[ip] * VoigtFunc((x - w[ip+1]) / w[ip+2], w[ip+3])
    154  endfor
    155 
    156  return v
    157 end
    158 
    159 
    160 //------------------------------------------------------------------------------
    161 // Doniach-Sunjic shapes
    162 //------------------------------------------------------------------------------
    163 
    174 threadsafe function DoniachSunjic(x, amp, pos, sing, fwhm)
    175  variable x
    176  variable amp
    177  variable pos
    178  variable sing
    179  variable fwhm
    180 
    181  variable nom, denom
    182  nom = cos(pi * sing / 2 + (1 - sing) * atan((x - pos) / fwhm * 2))
    183  denom = ((x - pos)^2 + fwhm^2 / 4)^((1 - sing) / 2)
    184 
    185  return amp * nom / denom * fwhm / 2
    186 end
    187 
    201 function MultiDoniachSunjicLinBG(w,x) : FitFunc
    202  wave w
    203  variable x
    204 
    205  variable np = numpnts(w)
    206  variable ip
    207 
    208  variable v = w[0] + x * w[1]
    209  for (ip = 2; ip < np; ip += 4)
    210  v += DoniachSunjic(x, w[ip], w[ip+1], w[ip+3], w[ip+2])
    211  endfor
    212 
    213  return v
    214 end
    215 
    216 
    217 threadsafe function ds1_bg(w, x): FitFunc
    218  // Doniach-Sunjic fit function
    219  // 0 <= sing < 1
    220  wave w // coefficients - see below
    221  variable x // independent variable
    222 
    223  //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    224  //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    225  //CurveFitDialog/ Equation:
    226  //CurveFitDialog/ f(x) = DoniachSunjic(x, amp, pos, sing, fwhm) + bg
    227  //CurveFitDialog/ End of Equation
    228  //CurveFitDialog/ Independent Variables 1
    229  //CurveFitDialog/ x
    230  //CurveFitDialog/ Coefficients 5
    231  //CurveFitDialog/ w[0] = bg
    232  //CurveFitDialog/ w[1] = amp
    233  //CurveFitDialog/ w[2] = pos
    234  //CurveFitDialog/ w[3] = sing
    235  //CurveFitDialog/ w[4] = FWHM
    236 
    237  return DoniachSunjic(x, w[1], w[2], w[3], w[4]) + w[0]
    238 end
    239 
    240 threadsafe function ds2_bg(w,x) : FitFunc
    241  Wave w
    242  Variable x
    243 
    244  //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    245  //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    246  //CurveFitDialog/ Equation:
    247  //CurveFitDialog/ f(x) = w_0+( w_1*cos(pi*w_3/2+(1-w_3)*atan((x-w_2)/w_4)))/(((x-w_2)^2+w_4^2)^((1-w_3)/2)) +(w_5*cos(pi*w_7/2+(1-w_7)*atan((x-(w_6))/w_8)))/(((x-w_6)^2+w_8^2)^((1-w_7)/2))
    248  //CurveFitDialog/ End of Equation
    249  //CurveFitDialog/ Independent Variables 1
    250  //CurveFitDialog/ x
    251  //CurveFitDialog/ Coefficients 9
    252  //CurveFitDialog/ w[0] = bg
    253  //CurveFitDialog/ w[1] = amp1
    254  //CurveFitDialog/ w[2] = pos1
    255  //CurveFitDialog/ w[3] = sing1
    256  //CurveFitDialog/ w[4] = wid1
    257  //CurveFitDialog/ w[5] = amp2
    258  //CurveFitDialog/ w[6] = pos2
    259  //CurveFitDialog/ w[7] = sing2
    260  //CurveFitDialog/ w[8] = wid2
    261 
    262  variable ds1 = DoniachSunjic(x, w[1], w[2], w[3], w[4])
    263  variable ds2 = DoniachSunjic(x, w[5], w[6], w[7], w[8])
    264 
    265  return w[0] + ds1 + ds2
    266 End
    267 
    268 Function ds4_bg(w,x) : FitFunc
    269  Wave w
    270  Variable x
    271 
    272  //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    273  //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    274  //CurveFitDialog/ Equation:
    275  //CurveFitDialog/ f(x) = w_0+( w_1*cos(pi*w_3/2+(1-w_3)*atan((x-w_2)/w_4)))/(((x-w_2)^2+w_4^2)^((1-w_3)/2)) +(w_5*cos(pi*w_7/2+(1-w_7)*atan((x-(w_6))/w_8)))/(((x-w_6)^2+w_8^2)^((1-w_7)/2)) +( w_9*cos(pi*w_11/2+(1-w_11)*atan((x-w_10)/w_12)))/(((x-w_10)^2+w_12^2)^((1-w_11)/2)) +( w_13*cos(pi*w_15/2+(1-w_15)*atan((x-w_14)/w_16)))/(((x-w_14)^2+w_16^2)^((1-w_15)/2))
    276  //CurveFitDialog/ End of Equation
    277  //CurveFitDialog/ Independent Variables 1
    278  //CurveFitDialog/ x
    279  //CurveFitDialog/ Coefficients 17
    280  //CurveFitDialog/ w[0] = w_0
    281  //CurveFitDialog/ w[1] = w_11
    282  //CurveFitDialog/ w[2] = w_12
    283  //CurveFitDialog/ w[3] = w_13
    284  //CurveFitDialog/ w[4] = w_14
    285  //CurveFitDialog/ w[5] = w_21
    286  //CurveFitDialog/ w[6] = w_22
    287  //CurveFitDialog/ w[7] = w_23
    288  //CurveFitDialog/ w[8] = w_24
    289  //CurveFitDialog/ w[9] = w_31
    290  //CurveFitDialog/ w[10] = w_32
    291  //CurveFitDialog/ w[11] = w_33
    292  //CurveFitDialog/ w[12] = w_34
    293  //CurveFitDialog/ w[13] = w_41
    294  //CurveFitDialog/ w[14] = w_42
    295  //CurveFitDialog/ w[15] = w_43
    296  //CurveFitDialog/ w[16] = w_44
    297  Variable ds1, ds2, ds3, ds4
    298  ds1=( w[1]*cos(pi*w[3]/2+(1-w[3])*atan((x-w[2])/w[4])))/(((x-w[2])^2+w[4]^2)^((1-w[3])/2))
    299  ds2=( w[5]*cos(pi*w[7]/2+(1-w[7])*atan((x-w[6])/w[8])))/(((x-w[6])^2+w[8]^2)^((1-w[7])/2))
    300  ds3=( w[9]*cos(pi*w[11]/2+(1-w[11])*atan((x-w[10])/w[12])))/(((x-w[10])^2+w[12]^2)^((1-w[11])/2))
    301  ds4=( w[13]*cos(pi*w[15]/2+(1-w[15])*atan((x-w[14])/w[16])))/(((x-w[14])^2+w[16]^2)^((1-w[15])/2))
    302 
    303 
    304  return w[0]+ds1+ds2+ds3+ds4
    305 
    306 
    307 End
    308 
    309 Function ds6_bg(w,x) : FitFunc
    310  Wave w
    311  Variable x
    312 
    313  //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    314  //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    315  //CurveFitDialog/ Equation:
    316  //CurveFitDialog/
    317  //CurveFitDialog/ Variable g, ds1, ds2, ds3, ds4, ds5, ds6
    318  //CurveFitDialog/ ds1=( w_11*cos(pi*w_13/2+(1-w_13)*atan((x-w_12)/w_14)))/(((x-w_12)^2+w_14^2)^((1-w_13)/2))
    319  //CurveFitDialog/ ds2=( w_21*cos(pi*w_23/2+(1-w_23)*atan((x-w_22)/w_24)))/(((x-w_22)^2+w_24^2)^((1-w_23)/2))
    320  //CurveFitDialog/ ds3=( w_31*cos(pi*w_33/2+(1-w_33)*atan((x-w_32)/w_34)))/(((x-w_32)^2+w_34^2)^((1-w_33)/2))
    321  //CurveFitDialog/ ds4=( w_41*cos(pi*w_43/2+(1-w_43)*atan((x-w_42)/w_44)))/(((x-w_42)^2+w_44^2)^((1-w_43)/2))
    322  //CurveFitDialog/ ds5=( w_51*cos(pi*w_53/2+(1-w_53)*atan((x-w_52)/w_54)))/(((x-w_52)^2+w_54^2)^((1-w_53)/2))
    323  //CurveFitDialog/ ds6=( w_61*cos(pi*w_63/2+(1-w_63)*atan((x-w_62)/w_64)))/(((x-w_62)^2+w_64^2)^((1-w_63)/2))
    324  //CurveFitDialog/
    325  //CurveFitDialog/ f(x) =w_0+ds1+ds2+ds3+ds4+ds5+ds6
    326  //CurveFitDialog/
    327  //CurveFitDialog/ End of Equation
    328  //CurveFitDialog/ Independent Variables 1
    329  //CurveFitDialog/ x
    330  //CurveFitDialog/ Coefficients 25
    331  //CurveFitDialog/ w[0] = w_0
    332  //CurveFitDialog/ w[1] = w_11
    333  //CurveFitDialog/ w[2] = w_12
    334  //CurveFitDialog/ w[3] = w_13
    335  //CurveFitDialog/ w[4] = w_14
    336  //CurveFitDialog/ w[5] = w_21
    337  //CurveFitDialog/ w[6] = w_22
    338  //CurveFitDialog/ w[7] = w_23
    339  //CurveFitDialog/ w[8] = w_24
    340  //CurveFitDialog/ w[9] = w_31
    341  //CurveFitDialog/ w[10] = w_32
    342  //CurveFitDialog/ w[11] = w_33
    343  //CurveFitDialog/ w[12] = w_34
    344  //CurveFitDialog/ w[13] = w_41
    345  //CurveFitDialog/ w[14] = w_42
    346  //CurveFitDialog/ w[15] = w_43
    347  //CurveFitDialog/ w[16] = w_44
    348  //CurveFitDialog/ w[17] = w_51
    349  //CurveFitDialog/ w[18] = w_52
    350  //CurveFitDialog/ w[19] = w_53
    351  //CurveFitDialog/ w[20] = w_54
    352  //CurveFitDialog/ w[21] = w_61
    353  //CurveFitDialog/ w[22] = w_62
    354  //CurveFitDialog/ w[23] = w_63
    355  //CurveFitDialog/ w[24] = w_64
    356 
    357 
    358  Variable ds1, ds2, ds3, ds4, ds5, ds6
    359  ds1=( w[1]*cos(pi*w[3]/2+(1-w[3])*atan((x-w[2])/w[4])))/(((x-w[2])^2+w[4]^2)^((1-w[3])/2))
    360  ds2=( w[5]*cos(pi*w[7]/2+(1-w[7])*atan((x-w[6])/w[8])))/(((x-w[6])^2+w[8]^2)^((1-w[7])/2))
    361  ds3=( w[9]*cos(pi*w[11]/2+(1-w[11])*atan((x-w[10])/w[12])))/(((x-w[10])^2+w[12]^2)^((1-w[11])/2))
    362  ds4=( w[13]*cos(pi*w[15]/2+(1-w[15])*atan((x-w[14])/w[16])))/(((x-w[14])^2+w[16]^2)^((1-w[15])/2))
    363  ds5=( w[17]*cos(pi*w[19]/2+(1-w[19])*atan((x-w[18])/w[20])))/(((x-w[18])^2+w[20]^2)^((1-w[19])/2))
    364  ds6=( w[21]*cos(pi*w[23]/2+(1-w[23])*atan((x-w[22])/w[24])))/(((x-w[22])^2+w[24]^2)^((1-w[23])/2))
    365 
    366  return w[0]+ds1+ds2+ds3+ds4+ds5+ds6
    367 
    368 End
    369 
    371  // data structure for DoniachSunjicBroadS structural function fit
    372 
    373  // waves populated by the FuncFit operation
    374  wave pw
    375  wave yw
    376  wave xw
    377 
    378  // convolution parameters to be set upon creation of the structure
    379  variable precision
    380  variable oversampling
    381 
    382  // auxiliary fields used internally by DoniachSunjicBroadS
    383  // do not touch these
    384  wave xdw
    385  wave model
    386  wave broadening
    387  wave convolution
    388 EndStructure
    389 
    390 //------------------------------------------------------------------------------
    391 threadsafe function DoniachSunjicBroadS(s) : FitFunc
    392 //------------------------------------------------------------------------------
    393  // Two-peak (bulk + surface) Doniach-Sunjic line shape with Gaussian broadening (convolution).
    394  // Hold parameter 5 at 0 to fit just one peak.
    395 
    396  // Structural fit function for efficient fitting in procedures.
    397  // Calculating the convolution requires auxiliary waves and additional, non-fitting parameters.
    398  // To eliminate the time-consuming overhead of creating and killing the auxiliary waves,
    399  // these waves are held in the fitting structure.
    400 
    401  // Caution: The function on its own is thread-safe.
    402  // However, since FuncFit uses the same structure in all threads, the fitting cannot run in parallel.
    403  // Set /NTHR=1.
    404 
    405  // See also Fit_DoniachSunjicBroad (example), DoniachSunjicBroad (conventional fit function)
    406  Struct DoniachSunjicStruct &s
    407 
    408  // pw[0] = bulk amplitude
    409  // pw[1] = bulk position
    410  // pw[2] = Lorentzian FWHM
    411  // pw[3] = Donjach-Sunjic singularity index (0..1)
    412  // pw[4] = surface shift
    413  // pw[5] = surface/bulk ratio
    414  // pw[6] = Gaussian FWHM
    415  // pw[7] = constant background
    416  // pw[8] = linear background
    417 
    418  wave xw = s.xw
    419  wave yw = s.yw
    420  wave pw = s.pw
    421 
    422  variable precision = s.precision
    423  variable oversampling = s.oversampling
    424 
    425  if (WaveExists(s.xdw))
    426  wave xdw = s.xdw
    427  wave model = s.model
    428  wave broadening = s.broadening
    429  wave convolution = s.convolution
    430  else
    431  make /n=0 /free xdw, model, broadening, convolution
    432  redimension /d xdw, model, broadening, convolution
    433  wave fs.xdw = xdw
    434  wave fs.model = model
    435  wave fs.broadening = broadening
    436  wave fs.convolution = convolution
    437  endif
    438 
    439  // calculate wave spacing based on minimum spacing of desired x points
    440  differentiate /p xw /d=xdw
    441  xdw = abs(xdw)
    442  variable xd = wavemin(xdw) / oversampling
    443 
    444  // calculate broadening wave size based on width and precision variable
    445  variable x0b = pw[6] * precision
    446  variable nb = 2 * floor(x0b / xd) + 1
    447 
    448  // calculate model size based on desired range for yw
    449  variable x0m = max(abs(wavemax(xw) - pw[1]), abs(wavemin(xw) - pw[1])) + x0b
    450  variable nm = 2 * floor(x0m / xd) + 1
    451  nb = min(nb, nm * 10) // limit wave size to avoid runtime errors for unphysically large parameter
    452 
    453  // create and calculate initial waves, normalize exponential
    454  redimension /n=(nb) broadening
    455  redimension /n=(nm) model
    456  setscale/i x -x0b, x0b, "", broadening
    457  setscale/i x -x0m, x0m, "", model
    458 
    459  broadening = exp( - (x / pw[6])^2 * 4 * ln(2))
    460  variable nrm = area(broadening)
    461  broadening /= nrm
    462  model = DoniachSunjic(x, 1, 0, pw[3], pw[2]) // bulk
    463  model += DoniachSunjic(x, pw[5], pw[4], pw[3], pw[2]) // surface
    464 
    465  // calculate the convolution
    466  Convolve /a broadening, model
    467  variable scale = pw[0] / wavemax(model)
    468  model *= scale
    469 
    470  // prepare output
    471  nm = numpnts(model)
    472  x0m = xd * (nm - 1) / 2
    473  setscale/i x -x0m, x0m, "", model
    474 
    475  yw = model(xw[p] - pw[1]) + pw[7] + pw[8] * xw[p]
    476  yw = numtype(yw) ? 0 : yw
    477 end
    478 
    479 //------------------------------------------------------------------------------
    480 function DoniachSunjicBroad(pw, yw, xw) : FitFunc
    481 //------------------------------------------------------------------------------
    482  // Two-peak (bulk + surface) Doniach-Sunjic line shape with Gaussian broadening (convolution).
    483  // Hold parameter 5 at 0 to fit just one peak.
    484  // Conventional fit function for use with the curve-fitting dialog.
    485  // Compared to DoniachSunjicBroadS this function incurs extra overhead
    486  // because auxiliary waves are created and killed between function calls.
    487  // See also DoniachSunjicBroadS (optimized structural fit function)
    488  Wave pw
    489  Wave yw
    490  Wave xw
    491 
    492  // pw[0] = bulk amplitude
    493  // pw[1] = bulk position
    494  // pw[2] = Lorentzian FWHM
    495  // pw[3] = Donjach-Sunjic singularity index (0..1)
    496  // pw[4] = surface shift
    497  // pw[5] = surface/bulk ratio
    498  // pw[6] = Gaussian FWHM
    499  // pw[7] = constant background
    500  // pw[8] = linear background
    501 
    502  // set up data structure
    503  struct DoniachSunjicStruct fs
    504  fs.precision = 5
    505  fs.oversampling = 4
    506 
    507  wave fs.pw = pw
    508  wave fs.xw = xw
    509  wave fs.yw = yw
    510 
    511  // create temporary calculation waves in a global folder
    512  dfref df = root:packages:pearl_fitfuncs:doniach_sunjic
    513  if (DataFolderRefStatus(df) == 0)
    514  newdatafolder root:packages:pearl_fitfuncs:doniach_sunjic
    515  dfref df = root:packages:pearl_fitfuncs:doniach_sunjic
    516  endif
    517 
    518  wave /z /sdfr=df fs.xdw = xdw
    519  wave /z /sdfr=df fs.model = model
    520  wave /z /sdfr=df fs.broadening = broadening
    521  wave /z /sdfr=df fs.convolution = convolution
    522 
    523  if (WaveExists(fs.xdw) == 0)
    524  dfref savedf = GetDataFolderDFR()
    525  setdatafolder df
    526  make /n=0 /d xdw, model, broadening, convolution
    527  wave fs.xdw = xdw
    528  wave fs.model = model
    529  wave fs.broadening = broadening
    530  wave fs.convolution = convolution
    531  setdatafolder savedf
    532  endif
    533 
    534  // calculate
    536 
    537  yw = fs.yw
    538 end
    539 
    540 //------------------------------------------------------------------------------
    541 function Calc_DoniachSunjicBroad(pw, yw)
    542 //------------------------------------------------------------------------------
    543  // Calculate the DoniachSunjicBroadS line shape
    544  Wave pw // coefficient wave
    545  Wave yw // output wave, correct x-scaling required on input
    546 
    547  struct DoniachSunjicStruct fs
    548  fs.precision = 5
    549  fs.oversampling = 4
    550 
    551  duplicate /free pw, fs.pw
    552  duplicate /free yw, fs.xw
    553  fs.xw = x
    554  duplicate /free yw, fs.yw
    555 
    557 
    558  yw = fs.yw
    559 end
    560 
    561 //------------------------------------------------------------------------------
    562 Function Fit_DoniachSunjicBroad(pw, yw, xw, ww)
    563 //------------------------------------------------------------------------------
    564  // Fit the DoniachSunjicBroadS line shape.
    565  // The function applies constraints which assume that the energy scale is in eV.
    566  // Returns chi^2.
    567  wave pw // coefficient wave- pre-load it with initial guess
    568  wave yw
    569  wave /z xw
    570  wave /z ww // weights (standard deviation)
    571 
    572  struct DoniachSunjicStruct fs
    573  fs.precision = 5
    574  fs.oversampling = 4
    575 
    576  duplicate /free pw, fs.pw
    577  if (WaveExists(xw))
    578  duplicate /free xw, fs.xw
    579  else
    580  duplicate /free yw, fs.xw
    581  fs.xw = x
    582  endif
    583  duplicate /free yw, fs.yw
    584 
    585  variable v_chisq = nan
    586  variable V_FitMaxIters = 100
    587  make /n=1 /t /free constraints = {"K0 >= 0", "K2 > 0", "K2 < 10", "K3 >= 0", "K3 < 1", "K4 >= -10", "K4 <= 10", "K5 >= 0", "K5 <= 1", "K6 >= 0", "K6 < 10"}
    588  // note: only single thread allowed
    589  FuncFit /NTHR=1 DoniachSunjicBroadS, pw, yw /X=xw /D /STRC=fs /C=constraints /NWOK /I=1 /W=ww
    590 
    591  return v_chisq
    592 End
    593 
    594 //------------------------------------------------------------------------------
    595 // peak-specific fit functions
    596 //------------------------------------------------------------------------------
    597 
    598 function Au4f(w, x): fitfunc
    599  // fit function for a nitrogen 1s-pi* absorption spectrum
    600  // modelled as multiple Voigt shapes on a constant background
    601  // similar to the Igor VoigtFit function
    602  // but with a constant gaussian width (instrumental broadening) for all peaks
    603  // gaussian and lorentzian widths are specified as FWHM
    604  wave w // parameters
    605  // w[0] constant background
    606  // w[1] linear background
    607  // w[2] global gaussian FWHM
    608  // w[3 + 0 + (n-1) * 3] peak n area
    609  // w[3 + 1 + (n-1) * 3] peak n position
    610  // w[3 + 2 + (n-1) * 3] peak n lorentzian FWHM
    611  // length of wave defines number of peaks
    612 
    613  // for compatibility with older code the linear background term can be omitted.
    614  // if the number of parameters divides by 3, the linear background term is added,
    615  // otherwise only the constant background.
    616  variable x
    617 
    618  variable np = numpnts(w)
    619  variable ip, ip0
    620 
    621  variable bg = w[0]
    622  variable v = bg
    623  if (mod(np, 3) == 0)
    624  v += w[1] * x
    625  ip0 = 3
    626  else
    627  ip0 = 2
    628  endif
    629 
    630  variable vc1, vc2, vc3, vc4
    631  vc2 = 2 * sqrt(ln(2)) / w[ip0-1]
    632  for (ip = ip0; ip < np; ip += 3)
    633  vc1 = w[ip] / sqrt(pi) * vc2
    634  vc3 = w[ip+1]
    635  vc4 = vc2 * w[ip+2] / 2
    636  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    637  endfor
    638 
    639  return v
    640 
    641 end
    642 
    643 function Au4f_2p2(w, x): fitfunc
    644  // Au 4f 5/2 and 7/2 2-component Voigt fit with a common gaussian width
    645  // gaussian and lorentzian widths are specified as FWHM
    646  wave w // parameters
    647  // w[0] constant background
    648  // w[1] linear background
    649  // w[2] global gaussian FWHM
    650  // w[3] 5/2 bulk area
    651  // w[4] 5/2 bulk position
    652  // w[5] 5/2 lorentzian FWHM
    653  // w[6] 7/2 bulk area
    654  // w[7] 7/2 bulk position
    655  // w[8] 7/2 lorentzian FWHM
    656  // w[9] surface/bulk area ratio
    657  // w[10] surface core level shift
    658  variable x
    659 
    660  variable bg = w[0] + w[1] * x
    661  variable v = bg
    662 
    663  variable vc1 // amplitude
    664  variable vc2 // width
    665  variable vc3 // position
    666  variable vc4 // shape
    667  vc2 = 2 * sqrt(ln(2)) / w[2]
    668 
    669  // 5/2 bulk
    670  vc1 = w[3] / sqrt(pi) * vc2
    671  vc3 = w[4]
    672  vc4 = vc2 * w[5] / 2
    673  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    674 
    675  // 5/2 surface
    676  vc1 = w[3] / sqrt(pi) * vc2 * w[9]
    677  vc3 = w[4] + w[10]
    678  vc4 = vc2 * w[5] / 2
    679  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    680 
    681  // 7/2 bulk
    682  vc1 = w[6] / sqrt(pi) * vc2
    683  vc3 = w[7]
    684  vc4 = vc2 * w[8] / 2
    685  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    686 
    687  // 7/2 surface
    688  vc1 = w[6] / sqrt(pi) * vc2 * w[9]
    689  vc3 = w[7] + w[10]
    690  vc4 = vc2 * w[8] / 2
    691  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    692 
    693  return v
    694 
    695 end
    696 
    697 function ShowComponents_Au4f_2p2(coef_wave, fit_wave)
    698  wave coef_wave
    699  wave fit_wave
    700 
    701  duplicate /free coef_wave, coef1, coef2
    702  coef1[9] = 0
    703  coef2[3] *= coef_wave[9]
    704  coef2[4] += coef_wave[10]
    705  coef2[6] *= coef_wave[9]
    706  coef2[7] += coef_wave[10]
    707  coef2[9] = 0
    708 
    709  string s_fit_wave = NameOfWave(fit_wave)
    710  string s_fit_p1 = s_fit_wave + "_p1"
    711  string s_fit_p2 = s_fit_wave + "_p2"
    712  duplicate /o fit_wave, $(s_fit_p1) /wave=fit_p1
    713  duplicate /o fit_wave, $(s_fit_p2) /wave=fit_p2
    714 
    715  fit_p1 = Au4f_2p2(coef1, x)
    716  fit_p2 = Au4f_2p2(coef2, x)
    717 
    718  string traces = TraceNameList("", ";", 1)
    719  if ((WhichListItem(s_fit_wave, traces, ";") >= 0) && (WhichListItem(s_fit_p1, traces, ";") < 0))
    720  appendtograph fit_p1, fit_p2
    721  ModifyGraph lstyle($s_fit_p1)=2
    722  ModifyGraph lstyle($s_fit_p2)=2
    723  ModifyGraph rgb($s_fit_p1)=(0,0,65280)
    724  ModifyGraph rgb($s_fit_p2)=(0,0,65280)
    725  endif
    726 end
    727 
    728 function Au4f_2p3(w, x): fitfunc
    729  // Au 4f 5/2 and 7/2 3-component Voigt fit with a common gaussian width
    730  // gaussian and lorentzian widths are specified as FWHM
    731  wave w // parameters
    732  // w[0] constant background
    733  // w[1] linear background
    734  // w[2] global gaussian FWHM
    735  // w[3] 5/2 bulk area
    736  // w[4] 5/2 bulk position
    737  // w[5] 5/2 lorentzian FWHM
    738  // w[6] 7/2 bulk area
    739  // w[7] 7/2 bulk position
    740  // w[8] 7/2 lorentzian FWHM
    741  // w[9] surface/bulk area ratio
    742  // w[10] surface core level shift
    743  // w[11] 2nd layer/bulk area ratio
    744  // w[12] 2nd layer core level shift
    745  variable x
    746 
    747  variable bg = w[0] + w[1] * x
    748  variable v = bg
    749 
    750  variable vc1 // amplitude
    751  variable vc2 // width
    752  variable vc3 // position
    753  variable vc4 // shape
    754  vc2 = 2 * sqrt(ln(2)) / w[2]
    755 
    756  // 5/2 bulk
    757  vc1 = w[3] / sqrt(pi) * vc2
    758  vc3 = w[4]
    759  vc4 = vc2 * w[5] / 2
    760  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    761 
    762  // 5/2 surface
    763  vc1 = w[3] / sqrt(pi) * vc2 * w[9]
    764  vc3 = w[4] + w[10]
    765  vc4 = vc2 * w[5] / 2
    766  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    767 
    768  // 5/2 2nd layer
    769  vc1 = w[3] / sqrt(pi) * vc2 * w[11]
    770  vc3 = w[4] + w[12]
    771  vc4 = vc2 * w[5] / 2
    772  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    773 
    774  // 7/2 bulk
    775  vc1 = w[6] / sqrt(pi) * vc2
    776  vc3 = w[7]
    777  vc4 = vc2 * w[8] / 2
    778  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    779 
    780  // 7/2 surface
    781  vc1 = w[6] / sqrt(pi) * vc2 * w[9]
    782  vc3 = w[7] + w[10]
    783  vc4 = vc2 * w[8] / 2
    784  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    785 
    786  // 7/2 2nd layer
    787  vc1 = w[6] / sqrt(pi) * vc2 * w[11]
    788  vc3 = w[7] + w[12]
    789  vc4 = vc2 * w[8] / 2
    790  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    791 
    792  return v
    793 
    794 end
    795 
    796 function ShowComponents_Au4f_2p3(coef_wave, fit_wave)
    797  wave coef_wave
    798  wave fit_wave
    799 
    800  duplicate /free coef_wave, coef1, coef2, coef3
    801  coef1[9] = 0
    802  coef1[11] = 0
    803 
    804  coef2[3] *= coef_wave[9]
    805  coef2[4] += coef_wave[10]
    806  coef2[6] *= coef_wave[9]
    807  coef2[7] += coef_wave[10]
    808  coef2[9] = 0
    809  coef2[11] = 0
    810 
    811  coef3[3] *= coef_wave[11]
    812  coef3[4] += coef_wave[12]
    813  coef3[6] *= coef_wave[11]
    814  coef3[7] += coef_wave[12]
    815  coef3[9] = 0
    816  coef3[11] = 0
    817 
    818  string s_fit_wave = NameOfWave(fit_wave)
    819  string s_fit_p1 = s_fit_wave + "_p1"
    820  string s_fit_p2 = s_fit_wave + "_p2"
    821  string s_fit_p3 = s_fit_wave + "_p3"
    822  duplicate /o fit_wave, $(s_fit_p1) /wave=fit_p1
    823  duplicate /o fit_wave, $(s_fit_p2) /wave=fit_p2
    824  duplicate /o fit_wave, $(s_fit_p3) /wave=fit_p3
    825 
    826  fit_p1 = Au4f_2p2(coef1, x)
    827  fit_p2 = Au4f_2p2(coef2, x)
    828  fit_p3 = Au4f_2p2(coef3, x)
    829 
    830  string traces = TraceNameList("", ";", 1)
    831  if ((WhichListItem(s_fit_wave, traces, ";") >= 0) && (WhichListItem(s_fit_p1, traces, ";") < 0))
    832  appendtograph fit_p1, fit_p2, fit_p3
    833  ModifyGraph lstyle($s_fit_p1)=2
    834  ModifyGraph lstyle($s_fit_p2)=2
    835  ModifyGraph lstyle($s_fit_p3)=2
    836  ModifyGraph rgb($s_fit_p1)=(0,0,65280)
    837  ModifyGraph rgb($s_fit_p2)=(0,0,65280)
    838  ModifyGraph rgb($s_fit_p3)=(0,0,65280)
    839  endif
    840 end
    841 
    851 function FermiGaussConv(pw, yw, xw) : FitFunc
    852  WAVE pw, yw, xw
    853 
    854  // half width of temporary gaussian wave is pw[5] multiplied by this factor (may be fractional)
    855  variable precision_g = 5
    856  variable oversampling = 4
    857 
    858  // calculate wave spacing based on minimum spacing of desired x points
    859  duplicate /free xw, xdw
    860  differentiate /p xw /d=xdw
    861  xdw = abs(xdw)
    862  variable xd = wavemin(xdw) / oversampling
    863 
    864  // calculate gausswave size based on pw[5] and precision variable
    865  variable x0g = abs(pw[5]) * precision_g
    866  variable ng = 2 * floor(x0g / xd) + 1
    867 
    868  // calculate fermiwave size based on desired range for yw
    869  variable emax = wavemax(xw)
    870  variable emin = wavemin(xw)
    871  variable x0f = max(abs(emax - pw[3]), abs(emin - pw[3])) + x0g
    872  variable ne = 2 * floor(x0f / xd) + 1
    873 
    874  // create and calculate initial waves, normalize exponential
    875  make /d /n=(ng) /free gausswave
    876  make /d /n=(ne) /free fermiwave
    877  setscale/i x -x0g, x0g, "", gausswave
    878  setscale/i x -x0f, x0f, "", fermiwave
    879 
    880  gausswave = exp( - (x / pw[5] )^2 )
    881  fermiwave = 1 / (exp( x / (kBoltzmann * pw[4])) + 1.0 )
    882 
    883  // calculate the convolution
    884  duplicate /free fermiwave, resultwave
    885  Convolve /a gausswave, resultwave
    886  variable rmax = wavemax(resultwave)
    887  resultwave /= rmax
    888 
    889  // prepare output
    890  ng = numpnts(resultwave)
    891  x0g = xd * (ng - 1) / 2
    892  setscale/i x -x0g, x0g, "", resultwave
    893 
    894  yw = pw[2] * resultwave(xw[p] - pw[3]) + pw[0] + pw[1] * xw[p]
    895 end
    896 
    897 
    901 function ShirleyBG(w, bg, p1, p2)
    902  wave w
    903  wave bg
    904  variable p1, p2
    905 
    906  duplicate /o w, bg
    907  integrate /meth=1 w /d=bg
    908 
    909  variable bg1 = bg[p1]
    910  variable bg2 = bg[p2]
    911  bg -= bg1
    912  bg /= bg2 - bg1
    913  bg *= w[p2] - w[p1]
    914  bg += w[p1]
    915 end
    threadsafe variable MultiGaussLinBG(wave w, variable x)
    multiple gaussian peaks on a linear background fit function.
    -
    threadsafe variable DoubletGaussLinBG_AO(wave pw, wave yw, wave xw)
    doublet gaussian peaks on a linear background fit function (all at once).
    -
    variable DoniachSunjicBroad(wave pw, wave yw, wave xw)
    -
    threadsafe variable MultiGaussLinBG_AO(wave pw, wave yw, wave xw)
    multiple gaussian peaks on a linear background fit function (all at once).
    -
    variable ds4_bg(wave w, variable x)
    - -
    variable FermiGaussConv(wave pw, wave yw, wave xw)
    convolution of Fermi-Dirac distribution and a Gaussian.
    -
    threadsafe variable DoniachSunjicBroadS(DoniachSunjicStruct *s)
    -
    threadsafe variable DoniachSunjic(variable x, variable amp, variable pos, variable sing, variable fwhm)
    Doniach-Sunjic line shape.
    -
    variable Au4f(wave w, variable x)
    -
    variable Au4f_2p3(wave w, variable x)
    -
    variable Au4f_2p2(wave w, variable x)
    -
    variable ShowComponents_Au4f_2p2(wave coef_wave, wave fit_wave)
    -
    variable Calc_DoniachSunjicBroad(wave pw, wave yw)
    -
    variable ShowComponents_Au4f_2p3(wave coef_wave, wave fit_wave)
    -
    variable Fit_DoniachSunjicBroad(wave pw, wave yw, wave xw, wave ww)
    -
    threadsafe variable ds2_bg(wave w, variable x)
    -
    variable ds6_bg(wave w, variable x)
    -
    variable ShirleyBG(wave w, wave bg, variable p1, variable p2)
    calculate the shirley background
    -
    variable MultiDoniachSunjicLinBG(wave w, variable x)
    multiple doniach-sunjic peaks on a linear background fit function.
    -
    threadsafe variable ds1_bg(wave w, variable x)
    -
    variable MultiVoigtLinBG(wave w, variable x)
    multiple voigt peaks on a linear background fit function.
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.2
    +
    4 #pragma ModuleName = PearlFitFuncs
    +
    5 #pragma version = 1.02
    +
    6 #include "mm-physconst"
    +
    7 
    +
    21 
    +
    26 
    +
    27 
    +
    28 //------------------------------------------------------------------------------
    +
    29 // Gaussian shapes
    +
    30 //------------------------------------------------------------------------------
    +
    31 
    +
    45 threadsafe function MultiGaussLinBG(w,x) : FitFunc
    +
    46  wave w
    +
    47  variable x
    +
    48 
    +
    49  variable np = numpnts(w)
    +
    50  variable ip
    +
    51 
    +
    52  variable v = w[0] + x * w[1]
    +
    53  for (ip = 2; ip < np; ip += 3)
    +
    54  v += w[ip] * exp( -( (x - w[ip+1]) / w[ip+2] )^2 )
    +
    55  endfor
    +
    56 
    +
    57  return v
    +
    58 end
    +
    59 
    +
    80 threadsafe function MultiGaussLinBG_AO(pw, yw, xw) : FitFunc
    +
    81  wave pw
    +
    82  wave yw
    +
    83  wave xw
    +
    84 
    +
    85  variable np = numpnts(pw)
    +
    86  variable ip
    +
    87 
    +
    88  yw = pw[0] + xw[p] * pw[1]
    +
    89  for (ip = 2; ip < np; ip += 3)
    +
    90  yw += pw[ip] * exp( -( (xw[p] - pw[ip+1]) / pw[ip+2] )^2 )
    +
    91  endfor
    +
    92 end
    +
    93 
    +
    118 threadsafe function DoubletGaussLinBG_AO(pw, yw, xw) : FitFunc
    +
    119  wave pw
    +
    120  wave yw
    +
    121  wave xw
    +
    122 
    +
    123  yw = pw[0] + xw[p] * pw[1]
    +
    124  yw += pw[2] * exp( -( (xw[p] - pw[4] - pw[5] /2) / pw[6] )^2 )
    +
    125  yw += pw[2] * pw[3] * exp( -( (xw[p] - pw[4] + pw[5] /2) / pw[6] / pw[7] )^2 )
    +
    126 end
    +
    127 
    +
    157 threadsafe function DblDoubletGaussLinBG_AO(pw, yw, xw) : FitFunc
    +
    158  wave pw
    +
    159  wave yw
    +
    160  wave xw
    +
    161 
    +
    162  yw = pw[0] + xw[p] * pw[1]
    +
    163  // peak 1
    +
    164  yw += pw[2] * exp( -( (xw[p] - pw[6]) / pw[9] )^2 )
    +
    165  // peak 2
    +
    166  yw += pw[3] * exp( -( (xw[p] - pw[6] - pw[8]) / pw[10] )^2 )
    +
    167  // peak 3
    +
    168  yw += pw[2] * pw[4] * exp( -( (xw[p] - pw[6] - pw[7]) / pw[9] )^2 )
    +
    169  // peak 4
    +
    170  yw += pw[3] * pw[5] * exp( -( (xw[p] - pw[6] - pw[7] - pw[8]) / pw[10] )^2 )
    +
    171 end
    +
    172 
    +
    173 //------------------------------------------------------------------------------
    +
    174 // Voigt shapes
    +
    175 //------------------------------------------------------------------------------
    +
    176 
    +
    190 threadsafe function MultiVoigtLinBG(w,x) : FitFunc
    +
    191  wave w
    +
    192  variable x
    +
    193 
    +
    194  variable np = numpnts(w)
    +
    195  variable ip
    +
    196 
    +
    197  variable v = w[0] + x * w[1]
    +
    198  for (ip = 2; ip < np; ip += 4)
    +
    199  v += w[ip] * VoigtFunc((x - w[ip+1]) / w[ip+2], w[ip+3])
    +
    200  endfor
    +
    201 
    +
    202  return v
    +
    203 end
    +
    204 
    +
    224 threadsafe function MultiVoigtLinBG_AO(pw, yw, xw) : FitFunc
    +
    225  wave pw
    +
    226  wave yw
    +
    227  wave xw
    +
    228 
    +
    229  variable np = numpnts(pw)
    +
    230  variable ip
    +
    231 
    +
    232  yw = pw[0] + xw[p] * pw[1]
    +
    233  for (ip = 2; ip < np; ip += 4)
    +
    234  yw += pw[ip] * VoigtFunc((xw[p] - pw[ip+1]) / pw[ip+2], pw[ip+3])
    +
    235  endfor
    +
    236 end
    +
    237 
    +
    238 
    +
    239 //------------------------------------------------------------------------------
    +
    240 // Doniach-Sunjic shapes
    +
    241 //------------------------------------------------------------------------------
    +
    242 
    +
    253 threadsafe function DoniachSunjic(x, amp, pos, sing, fwhm)
    +
    254  variable x
    +
    255  variable amp
    +
    256  variable pos
    +
    257  variable sing
    +
    258  variable fwhm
    +
    259 
    +
    260  variable nom, denom
    +
    261  nom = cos(pi * sing / 2 + (1 - sing) * atan((x - pos) / fwhm * 2))
    +
    262  denom = ((x - pos)^2 + fwhm^2 / 4)^((1 - sing) / 2)
    +
    263 
    +
    264  return amp * nom / denom * fwhm / 2
    +
    265 end
    +
    266 
    +
    280 threadsafe function MultiDoniachSunjicLinBG(w,x) : FitFunc
    +
    281  wave w
    +
    282  variable x
    +
    283 
    +
    284  variable np = numpnts(w)
    +
    285  variable ip
    +
    286 
    +
    287  variable v = w[0] + x * w[1]
    +
    288  for (ip = 2; ip < np; ip += 4)
    +
    289  v += DoniachSunjic(x, w[ip], w[ip+1], w[ip+3], w[ip+2])
    +
    290  endfor
    +
    291 
    +
    292  return v
    +
    293 end
    +
    294 
    +
    295 
    +
    296 threadsafe function ds1_bg(w, x): FitFunc
    +
    297  // Doniach-Sunjic fit function
    +
    298  // 0 <= sing < 1
    +
    299  wave w // coefficients - see below
    +
    300  variable x // independent variable
    +
    301 
    +
    302  //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    +
    303  //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    +
    304  //CurveFitDialog/ Equation:
    +
    305  //CurveFitDialog/ f(x) = DoniachSunjic(x, amp, pos, sing, fwhm) + bg
    +
    306  //CurveFitDialog/ End of Equation
    +
    307  //CurveFitDialog/ Independent Variables 1
    +
    308  //CurveFitDialog/ x
    +
    309  //CurveFitDialog/ Coefficients 5
    +
    310  //CurveFitDialog/ w[0] = bg
    +
    311  //CurveFitDialog/ w[1] = amp
    +
    312  //CurveFitDialog/ w[2] = pos
    +
    313  //CurveFitDialog/ w[3] = sing
    +
    314  //CurveFitDialog/ w[4] = FWHM
    +
    315 
    +
    316  return DoniachSunjic(x, w[1], w[2], w[3], w[4]) + w[0]
    +
    317 end
    +
    318 
    +
    319 threadsafe function ds2_bg(w,x) : FitFunc
    +
    320  Wave w
    +
    321  Variable x
    +
    322 
    +
    323  //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    +
    324  //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    +
    325  //CurveFitDialog/ Equation:
    +
    326  //CurveFitDialog/ f(x) = w_0+( w_1*cos(pi*w_3/2+(1-w_3)*atan((x-w_2)/w_4)))/(((x-w_2)^2+w_4^2)^((1-w_3)/2)) +(w_5*cos(pi*w_7/2+(1-w_7)*atan((x-(w_6))/w_8)))/(((x-w_6)^2+w_8^2)^((1-w_7)/2))
    +
    327  //CurveFitDialog/ End of Equation
    +
    328  //CurveFitDialog/ Independent Variables 1
    +
    329  //CurveFitDialog/ x
    +
    330  //CurveFitDialog/ Coefficients 9
    +
    331  //CurveFitDialog/ w[0] = bg
    +
    332  //CurveFitDialog/ w[1] = amp1
    +
    333  //CurveFitDialog/ w[2] = pos1
    +
    334  //CurveFitDialog/ w[3] = sing1
    +
    335  //CurveFitDialog/ w[4] = wid1
    +
    336  //CurveFitDialog/ w[5] = amp2
    +
    337  //CurveFitDialog/ w[6] = pos2
    +
    338  //CurveFitDialog/ w[7] = sing2
    +
    339  //CurveFitDialog/ w[8] = wid2
    +
    340 
    +
    341  variable ds1 = DoniachSunjic(x, w[1], w[2], w[3], w[4])
    +
    342  variable ds2 = DoniachSunjic(x, w[5], w[6], w[7], w[8])
    +
    343 
    +
    344  return w[0] + ds1 + ds2
    +
    345 End
    +
    346 
    +
    347 Function ds4_bg(w,x) : FitFunc
    +
    348  Wave w
    +
    349  Variable x
    +
    350 
    +
    351  //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    +
    352  //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    +
    353  //CurveFitDialog/ Equation:
    +
    354  //CurveFitDialog/ f(x) = w_0+( w_1*cos(pi*w_3/2+(1-w_3)*atan((x-w_2)/w_4)))/(((x-w_2)^2+w_4^2)^((1-w_3)/2)) +(w_5*cos(pi*w_7/2+(1-w_7)*atan((x-(w_6))/w_8)))/(((x-w_6)^2+w_8^2)^((1-w_7)/2)) +( w_9*cos(pi*w_11/2+(1-w_11)*atan((x-w_10)/w_12)))/(((x-w_10)^2+w_12^2)^((1-w_11)/2)) +( w_13*cos(pi*w_15/2+(1-w_15)*atan((x-w_14)/w_16)))/(((x-w_14)^2+w_16^2)^((1-w_15)/2))
    +
    355  //CurveFitDialog/ End of Equation
    +
    356  //CurveFitDialog/ Independent Variables 1
    +
    357  //CurveFitDialog/ x
    +
    358  //CurveFitDialog/ Coefficients 17
    +
    359  //CurveFitDialog/ w[0] = w_0
    +
    360  //CurveFitDialog/ w[1] = w_11
    +
    361  //CurveFitDialog/ w[2] = w_12
    +
    362  //CurveFitDialog/ w[3] = w_13
    +
    363  //CurveFitDialog/ w[4] = w_14
    +
    364  //CurveFitDialog/ w[5] = w_21
    +
    365  //CurveFitDialog/ w[6] = w_22
    +
    366  //CurveFitDialog/ w[7] = w_23
    +
    367  //CurveFitDialog/ w[8] = w_24
    +
    368  //CurveFitDialog/ w[9] = w_31
    +
    369  //CurveFitDialog/ w[10] = w_32
    +
    370  //CurveFitDialog/ w[11] = w_33
    +
    371  //CurveFitDialog/ w[12] = w_34
    +
    372  //CurveFitDialog/ w[13] = w_41
    +
    373  //CurveFitDialog/ w[14] = w_42
    +
    374  //CurveFitDialog/ w[15] = w_43
    +
    375  //CurveFitDialog/ w[16] = w_44
    +
    376  Variable ds1, ds2, ds3, ds4
    +
    377  ds1=( w[1]*cos(pi*w[3]/2+(1-w[3])*atan((x-w[2])/w[4])))/(((x-w[2])^2+w[4]^2)^((1-w[3])/2))
    +
    378  ds2=( w[5]*cos(pi*w[7]/2+(1-w[7])*atan((x-w[6])/w[8])))/(((x-w[6])^2+w[8]^2)^((1-w[7])/2))
    +
    379  ds3=( w[9]*cos(pi*w[11]/2+(1-w[11])*atan((x-w[10])/w[12])))/(((x-w[10])^2+w[12]^2)^((1-w[11])/2))
    +
    380  ds4=( w[13]*cos(pi*w[15]/2+(1-w[15])*atan((x-w[14])/w[16])))/(((x-w[14])^2+w[16]^2)^((1-w[15])/2))
    +
    381 
    +
    382 
    +
    383  return w[0]+ds1+ds2+ds3+ds4
    +
    384 
    +
    385 
    +
    386 End
    +
    387 
    +
    388 Function ds6_bg(w,x) : FitFunc
    +
    389  Wave w
    +
    390  Variable x
    +
    391 
    +
    392  //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    +
    393  //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    +
    394  //CurveFitDialog/ Equation:
    +
    395  //CurveFitDialog/
    +
    396  //CurveFitDialog/ Variable g, ds1, ds2, ds3, ds4, ds5, ds6
    +
    397  //CurveFitDialog/ ds1=( w_11*cos(pi*w_13/2+(1-w_13)*atan((x-w_12)/w_14)))/(((x-w_12)^2+w_14^2)^((1-w_13)/2))
    +
    398  //CurveFitDialog/ ds2=( w_21*cos(pi*w_23/2+(1-w_23)*atan((x-w_22)/w_24)))/(((x-w_22)^2+w_24^2)^((1-w_23)/2))
    +
    399  //CurveFitDialog/ ds3=( w_31*cos(pi*w_33/2+(1-w_33)*atan((x-w_32)/w_34)))/(((x-w_32)^2+w_34^2)^((1-w_33)/2))
    +
    400  //CurveFitDialog/ ds4=( w_41*cos(pi*w_43/2+(1-w_43)*atan((x-w_42)/w_44)))/(((x-w_42)^2+w_44^2)^((1-w_43)/2))
    +
    401  //CurveFitDialog/ ds5=( w_51*cos(pi*w_53/2+(1-w_53)*atan((x-w_52)/w_54)))/(((x-w_52)^2+w_54^2)^((1-w_53)/2))
    +
    402  //CurveFitDialog/ ds6=( w_61*cos(pi*w_63/2+(1-w_63)*atan((x-w_62)/w_64)))/(((x-w_62)^2+w_64^2)^((1-w_63)/2))
    +
    403  //CurveFitDialog/
    +
    404  //CurveFitDialog/ f(x) =w_0+ds1+ds2+ds3+ds4+ds5+ds6
    +
    405  //CurveFitDialog/
    +
    406  //CurveFitDialog/ End of Equation
    +
    407  //CurveFitDialog/ Independent Variables 1
    +
    408  //CurveFitDialog/ x
    +
    409  //CurveFitDialog/ Coefficients 25
    +
    410  //CurveFitDialog/ w[0] = w_0
    +
    411  //CurveFitDialog/ w[1] = w_11
    +
    412  //CurveFitDialog/ w[2] = w_12
    +
    413  //CurveFitDialog/ w[3] = w_13
    +
    414  //CurveFitDialog/ w[4] = w_14
    +
    415  //CurveFitDialog/ w[5] = w_21
    +
    416  //CurveFitDialog/ w[6] = w_22
    +
    417  //CurveFitDialog/ w[7] = w_23
    +
    418  //CurveFitDialog/ w[8] = w_24
    +
    419  //CurveFitDialog/ w[9] = w_31
    +
    420  //CurveFitDialog/ w[10] = w_32
    +
    421  //CurveFitDialog/ w[11] = w_33
    +
    422  //CurveFitDialog/ w[12] = w_34
    +
    423  //CurveFitDialog/ w[13] = w_41
    +
    424  //CurveFitDialog/ w[14] = w_42
    +
    425  //CurveFitDialog/ w[15] = w_43
    +
    426  //CurveFitDialog/ w[16] = w_44
    +
    427  //CurveFitDialog/ w[17] = w_51
    +
    428  //CurveFitDialog/ w[18] = w_52
    +
    429  //CurveFitDialog/ w[19] = w_53
    +
    430  //CurveFitDialog/ w[20] = w_54
    +
    431  //CurveFitDialog/ w[21] = w_61
    +
    432  //CurveFitDialog/ w[22] = w_62
    +
    433  //CurveFitDialog/ w[23] = w_63
    +
    434  //CurveFitDialog/ w[24] = w_64
    +
    435 
    +
    436 
    +
    437  Variable ds1, ds2, ds3, ds4, ds5, ds6
    +
    438  ds1=( w[1]*cos(pi*w[3]/2+(1-w[3])*atan((x-w[2])/w[4])))/(((x-w[2])^2+w[4]^2)^((1-w[3])/2))
    +
    439  ds2=( w[5]*cos(pi*w[7]/2+(1-w[7])*atan((x-w[6])/w[8])))/(((x-w[6])^2+w[8]^2)^((1-w[7])/2))
    +
    440  ds3=( w[9]*cos(pi*w[11]/2+(1-w[11])*atan((x-w[10])/w[12])))/(((x-w[10])^2+w[12]^2)^((1-w[11])/2))
    +
    441  ds4=( w[13]*cos(pi*w[15]/2+(1-w[15])*atan((x-w[14])/w[16])))/(((x-w[14])^2+w[16]^2)^((1-w[15])/2))
    +
    442  ds5=( w[17]*cos(pi*w[19]/2+(1-w[19])*atan((x-w[18])/w[20])))/(((x-w[18])^2+w[20]^2)^((1-w[19])/2))
    +
    443  ds6=( w[21]*cos(pi*w[23]/2+(1-w[23])*atan((x-w[22])/w[24])))/(((x-w[22])^2+w[24]^2)^((1-w[23])/2))
    +
    444 
    +
    445  return w[0]+ds1+ds2+ds3+ds4+ds5+ds6
    +
    446 
    +
    447 End
    +
    448 
    + +
    450  // data structure for DoniachSunjicBroadS structural function fit
    +
    451 
    +
    452  // waves populated by the FuncFit operation
    +
    453  wave pw
    +
    454  wave yw
    +
    455  wave xw
    +
    456 
    +
    457  // convolution parameters to be set upon creation of the structure
    +
    458  variable precision
    +
    459  variable oversampling
    +
    460 
    +
    461  // auxiliary fields used internally by DoniachSunjicBroadS
    +
    462  // do not touch these
    +
    463  wave xdw
    +
    464  wave model
    +
    465  wave broadening
    +
    466  wave convolution
    +
    467 EndStructure
    +
    468 
    +
    469 //------------------------------------------------------------------------------
    +
    470 threadsafe function DoniachSunjicBroadS(s) : FitFunc
    +
    471 //------------------------------------------------------------------------------
    +
    472  // Two-peak (bulk + surface) Doniach-Sunjic line shape with Gaussian broadening (convolution).
    +
    473  // Hold parameter 5 at 0 to fit just one peak.
    +
    474 
    +
    475  // Structural fit function for efficient fitting in procedures.
    +
    476  // Calculating the convolution requires auxiliary waves and additional, non-fitting parameters.
    +
    477  // To eliminate the time-consuming overhead of creating and killing the auxiliary waves,
    +
    478  // these waves are held in the fitting structure.
    +
    479 
    +
    480  // Caution: The function on its own is thread-safe.
    +
    481  // However, since FuncFit uses the same structure in all threads, the fitting cannot run in parallel.
    +
    482  // Set /NTHR=1.
    +
    483 
    +
    484  // See also Fit_DoniachSunjicBroad (example), DoniachSunjicBroad (conventional fit function)
    +
    485  Struct DoniachSunjicStruct &s
    +
    486 
    +
    487  // pw[0] = bulk amplitude
    +
    488  // pw[1] = bulk position
    +
    489  // pw[2] = Lorentzian FWHM
    +
    490  // pw[3] = Donjach-Sunjic singularity index (0..1)
    +
    491  // pw[4] = surface shift
    +
    492  // pw[5] = surface/bulk ratio
    +
    493  // pw[6] = Gaussian FWHM
    +
    494  // pw[7] = constant background
    +
    495  // pw[8] = linear background
    +
    496 
    +
    497  wave xw = s.xw
    +
    498  wave yw = s.yw
    +
    499  wave pw = s.pw
    +
    500 
    +
    501  variable precision = s.precision
    +
    502  variable oversampling = s.oversampling
    +
    503 
    +
    504  if (WaveExists(s.xdw))
    +
    505  wave xdw = s.xdw
    +
    506  wave model = s.model
    +
    507  wave broadening = s.broadening
    +
    508  wave convolution = s.convolution
    +
    509  else
    +
    510  make /n=0 /free xdw, model, broadening, convolution
    +
    511  redimension /d xdw, model, broadening, convolution
    +
    512  wave fs.xdw = xdw
    +
    513  wave fs.model = model
    +
    514  wave fs.broadening = broadening
    +
    515  wave fs.convolution = convolution
    +
    516  endif
    +
    517 
    +
    518  // calculate wave spacing based on minimum spacing of desired x points
    +
    519  differentiate /p xw /d=xdw
    +
    520  xdw = abs(xdw)
    +
    521  variable xd = wavemin(xdw) / oversampling
    +
    522 
    +
    523  // calculate broadening wave size based on width and precision variable
    +
    524  variable x0b = pw[6] * precision
    +
    525  variable nb = 2 * floor(x0b / xd) + 1
    +
    526 
    +
    527  // calculate model size based on desired range for yw
    +
    528  variable x0m = max(abs(wavemax(xw) - pw[1]), abs(wavemin(xw) - pw[1])) + x0b
    +
    529  variable nm = 2 * floor(x0m / xd) + 1
    +
    530  nb = min(nb, nm * 10) // limit wave size to avoid runtime errors for unphysically large parameter
    +
    531 
    +
    532  // create and calculate initial waves, normalize exponential
    +
    533  redimension /n=(nb) broadening
    +
    534  redimension /n=(nm) model
    +
    535  setscale/i x -x0b, x0b, "", broadening
    +
    536  setscale/i x -x0m, x0m, "", model
    +
    537 
    +
    538  broadening = exp( - (x / pw[6])^2 * 4 * ln(2))
    +
    539  variable nrm = area(broadening)
    +
    540  broadening /= nrm
    +
    541  model = DoniachSunjic(x, 1, 0, pw[3], pw[2]) // bulk
    +
    542  model += DoniachSunjic(x, pw[5], pw[4], pw[3], pw[2]) // surface
    +
    543 
    +
    544  // calculate the convolution
    +
    545  Convolve /a broadening, model
    +
    546  variable scale = pw[0] / wavemax(model)
    +
    547  model *= scale
    +
    548 
    +
    549  // prepare output
    +
    550  nm = numpnts(model)
    +
    551  x0m = xd * (nm - 1) / 2
    +
    552  setscale/i x -x0m, x0m, "", model
    +
    553 
    +
    554  yw = model(xw[p] - pw[1]) + pw[7] + pw[8] * xw[p]
    +
    555  yw = numtype(yw) ? 0 : yw
    +
    556 end
    +
    557 
    +
    558 //------------------------------------------------------------------------------
    +
    559 function DoniachSunjicBroad(pw, yw, xw) : FitFunc
    +
    560 //------------------------------------------------------------------------------
    +
    561  // Two-peak (bulk + surface) Doniach-Sunjic line shape with Gaussian broadening (convolution).
    +
    562  // Hold parameter 5 at 0 to fit just one peak.
    +
    563  // Conventional fit function for use with the curve-fitting dialog.
    +
    564  // Compared to DoniachSunjicBroadS this function incurs extra overhead
    +
    565  // because auxiliary waves are created and killed between function calls.
    +
    566  // See also DoniachSunjicBroadS (optimized structural fit function)
    +
    567  Wave pw
    +
    568  Wave yw
    +
    569  Wave xw
    +
    570 
    +
    571  // pw[0] = bulk amplitude
    +
    572  // pw[1] = bulk position
    +
    573  // pw[2] = Lorentzian FWHM
    +
    574  // pw[3] = Donjach-Sunjic singularity index (0..1)
    +
    575  // pw[4] = surface shift
    +
    576  // pw[5] = surface/bulk ratio
    +
    577  // pw[6] = Gaussian FWHM
    +
    578  // pw[7] = constant background
    +
    579  // pw[8] = linear background
    +
    580 
    +
    581  // set up data structure
    +
    582  struct DoniachSunjicStruct fs
    +
    583  fs.precision = 5
    +
    584  fs.oversampling = 4
    +
    585 
    +
    586  wave fs.pw = pw
    +
    587  wave fs.xw = xw
    +
    588  wave fs.yw = yw
    +
    589 
    +
    590  // create temporary calculation waves in a global folder
    +
    591  dfref df = root:packages:pearl_fitfuncs:doniach_sunjic
    +
    592  if (DataFolderRefStatus(df) == 0)
    +
    593  newdatafolder root:packages:pearl_fitfuncs:doniach_sunjic
    +
    594  dfref df = root:packages:pearl_fitfuncs:doniach_sunjic
    +
    595  endif
    +
    596 
    +
    597  wave /z /sdfr=df fs.xdw = xdw
    +
    598  wave /z /sdfr=df fs.model = model
    +
    599  wave /z /sdfr=df fs.broadening = broadening
    +
    600  wave /z /sdfr=df fs.convolution = convolution
    +
    601 
    +
    602  if (WaveExists(fs.xdw) == 0)
    +
    603  dfref savedf = GetDataFolderDFR()
    +
    604  setdatafolder df
    +
    605  make /n=0 /d xdw, model, broadening, convolution
    +
    606  wave fs.xdw = xdw
    +
    607  wave fs.model = model
    +
    608  wave fs.broadening = broadening
    +
    609  wave fs.convolution = convolution
    +
    610  setdatafolder savedf
    +
    611  endif
    +
    612 
    +
    613  // calculate
    + +
    615 
    +
    616  yw = fs.yw
    +
    617 end
    +
    618 
    +
    619 //------------------------------------------------------------------------------
    +
    620 function Calc_DoniachSunjicBroad(pw, yw)
    +
    621 //------------------------------------------------------------------------------
    +
    622  // Calculate the DoniachSunjicBroadS line shape
    +
    623  Wave pw // coefficient wave
    +
    624  Wave yw // output wave, correct x-scaling required on input
    +
    625 
    +
    626  struct DoniachSunjicStruct fs
    +
    627  fs.precision = 5
    +
    628  fs.oversampling = 4
    +
    629 
    +
    630  duplicate /free pw, fs.pw
    +
    631  duplicate /free yw, fs.xw
    +
    632  fs.xw = x
    +
    633  duplicate /free yw, fs.yw
    +
    634 
    + +
    636 
    +
    637  yw = fs.yw
    +
    638 end
    +
    639 
    +
    640 //------------------------------------------------------------------------------
    +
    641 Function Fit_DoniachSunjicBroad(pw, yw, xw, ww)
    +
    642 //------------------------------------------------------------------------------
    +
    643  // Fit the DoniachSunjicBroadS line shape.
    +
    644  // The function applies constraints which assume that the energy scale is in eV.
    +
    645  // Returns chi^2.
    +
    646  wave pw // coefficient wave- pre-load it with initial guess
    +
    647  wave yw
    +
    648  wave /z xw
    +
    649  wave /z ww // weights (standard deviation)
    +
    650 
    +
    651  struct DoniachSunjicStruct fs
    +
    652  fs.precision = 5
    +
    653  fs.oversampling = 4
    +
    654 
    +
    655  duplicate /free pw, fs.pw
    +
    656  if (WaveExists(xw))
    +
    657  duplicate /free xw, fs.xw
    +
    658  else
    +
    659  duplicate /free yw, fs.xw
    +
    660  fs.xw = x
    +
    661  endif
    +
    662  duplicate /free yw, fs.yw
    +
    663 
    +
    664  variable v_chisq = nan
    +
    665  variable V_FitMaxIters = 100
    +
    666  make /n=1 /t /free constraints = {"K0 >= 0", "K2 > 0", "K2 < 10", "K3 >= 0", "K3 < 1", "K4 >= -10", "K4 <= 10", "K5 >= 0", "K5 <= 1", "K6 >= 0", "K6 < 10"}
    +
    667  // note: only single thread allowed
    +
    668  FuncFit /NTHR=1 DoniachSunjicBroadS, pw, yw /X=xw /D /STRC=fs /C=constraints /NWOK /I=1 /W=ww
    +
    669 
    +
    670  return v_chisq
    +
    671 End
    +
    672 
    +
    673 //------------------------------------------------------------------------------
    +
    674 // peak-specific fit functions
    +
    675 //------------------------------------------------------------------------------
    +
    676 
    +
    677 function Au4f(w, x): fitfunc
    +
    678  // fit function for a nitrogen 1s-pi* absorption spectrum
    +
    679  // modelled as multiple Voigt shapes on a constant background
    +
    680  // similar to the Igor VoigtFit function
    +
    681  // but with a constant gaussian width (instrumental broadening) for all peaks
    +
    682  // gaussian and lorentzian widths are specified as FWHM
    +
    683  wave w // parameters
    +
    684  // w[0] constant background
    +
    685  // w[1] linear background
    +
    686  // w[2] global gaussian FWHM
    +
    687  // w[3 + 0 + (n-1) * 3] peak n area
    +
    688  // w[3 + 1 + (n-1) * 3] peak n position
    +
    689  // w[3 + 2 + (n-1) * 3] peak n lorentzian FWHM
    +
    690  // length of wave defines number of peaks
    +
    691 
    +
    692  // for compatibility with older code the linear background term can be omitted.
    +
    693  // if the number of parameters divides by 3, the linear background term is added,
    +
    694  // otherwise only the constant background.
    +
    695  variable x
    +
    696 
    +
    697  variable np = numpnts(w)
    +
    698  variable ip, ip0
    +
    699 
    +
    700  variable bg = w[0]
    +
    701  variable v = bg
    +
    702  if (mod(np, 3) == 0)
    +
    703  v += w[1] * x
    +
    704  ip0 = 3
    +
    705  else
    +
    706  ip0 = 2
    +
    707  endif
    +
    708 
    +
    709  variable vc1, vc2, vc3, vc4
    +
    710  vc2 = 2 * sqrt(ln(2)) / w[ip0-1]
    +
    711  for (ip = ip0; ip < np; ip += 3)
    +
    712  vc1 = w[ip] / sqrt(pi) * vc2
    +
    713  vc3 = w[ip+1]
    +
    714  vc4 = vc2 * w[ip+2] / 2
    +
    715  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    716  endfor
    +
    717 
    +
    718  return v
    +
    719 
    +
    720 end
    +
    721 
    +
    722 function Au4f_2p2(w, x): fitfunc
    +
    723  // Au 4f 5/2 and 7/2 2-component Voigt fit with a common gaussian width
    +
    724  // gaussian and lorentzian widths are specified as FWHM
    +
    725  wave w // parameters
    +
    726  // w[0] constant background
    +
    727  // w[1] linear background
    +
    728  // w[2] global gaussian FWHM
    +
    729  // w[3] 5/2 bulk area
    +
    730  // w[4] 5/2 bulk position
    +
    731  // w[5] 5/2 lorentzian FWHM
    +
    732  // w[6] 7/2 bulk area
    +
    733  // w[7] 7/2 bulk position
    +
    734  // w[8] 7/2 lorentzian FWHM
    +
    735  // w[9] surface/bulk area ratio
    +
    736  // w[10] surface core level shift
    +
    737  variable x
    +
    738 
    +
    739  variable bg = w[0] + w[1] * x
    +
    740  variable v = bg
    +
    741 
    +
    742  variable vc1 // amplitude
    +
    743  variable vc2 // width
    +
    744  variable vc3 // position
    +
    745  variable vc4 // shape
    +
    746  vc2 = 2 * sqrt(ln(2)) / w[2]
    +
    747 
    +
    748  // 5/2 bulk
    +
    749  vc1 = w[3] / sqrt(pi) * vc2
    +
    750  vc3 = w[4]
    +
    751  vc4 = vc2 * w[5] / 2
    +
    752  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    753 
    +
    754  // 5/2 surface
    +
    755  vc1 = w[3] / sqrt(pi) * vc2 * w[9]
    +
    756  vc3 = w[4] + w[10]
    +
    757  vc4 = vc2 * w[5] / 2
    +
    758  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    759 
    +
    760  // 7/2 bulk
    +
    761  vc1 = w[6] / sqrt(pi) * vc2
    +
    762  vc3 = w[7]
    +
    763  vc4 = vc2 * w[8] / 2
    +
    764  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    765 
    +
    766  // 7/2 surface
    +
    767  vc1 = w[6] / sqrt(pi) * vc2 * w[9]
    +
    768  vc3 = w[7] + w[10]
    +
    769  vc4 = vc2 * w[8] / 2
    +
    770  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    771 
    +
    772  return v
    +
    773 
    +
    774 end
    +
    775 
    +
    776 function ShowComponents_Au4f_2p2(coef_wave, fit_wave)
    +
    777  wave coef_wave
    +
    778  wave fit_wave
    +
    779 
    +
    780  duplicate /free coef_wave, coef1, coef2
    +
    781  coef1[9] = 0
    +
    782  coef2[3] *= coef_wave[9]
    +
    783  coef2[4] += coef_wave[10]
    +
    784  coef2[6] *= coef_wave[9]
    +
    785  coef2[7] += coef_wave[10]
    +
    786  coef2[9] = 0
    +
    787 
    +
    788  string s_fit_wave = NameOfWave(fit_wave)
    +
    789  string s_fit_p1 = s_fit_wave + "_p1"
    +
    790  string s_fit_p2 = s_fit_wave + "_p2"
    +
    791  duplicate /o fit_wave, $(s_fit_p1) /wave=fit_p1
    +
    792  duplicate /o fit_wave, $(s_fit_p2) /wave=fit_p2
    +
    793 
    +
    794  fit_p1 = Au4f_2p2(coef1, x)
    +
    795  fit_p2 = Au4f_2p2(coef2, x)
    +
    796 
    +
    797  string traces = TraceNameList("", ";", 1)
    +
    798  if ((WhichListItem(s_fit_wave, traces, ";") >= 0) && (WhichListItem(s_fit_p1, traces, ";") < 0))
    +
    799  appendtograph fit_p1, fit_p2
    +
    800  ModifyGraph lstyle($s_fit_p1)=2
    +
    801  ModifyGraph lstyle($s_fit_p2)=2
    +
    802  ModifyGraph rgb($s_fit_p1)=(0,0,65280)
    +
    803  ModifyGraph rgb($s_fit_p2)=(0,0,65280)
    +
    804  endif
    +
    805 end
    +
    806 
    +
    807 function Au4f_2p3(w, x): fitfunc
    +
    808  // Au 4f 5/2 and 7/2 3-component Voigt fit with a common gaussian width
    +
    809  // gaussian and lorentzian widths are specified as FWHM
    +
    810  wave w // parameters
    +
    811  // w[0] constant background
    +
    812  // w[1] linear background
    +
    813  // w[2] global gaussian FWHM
    +
    814  // w[3] 5/2 bulk area
    +
    815  // w[4] 5/2 bulk position
    +
    816  // w[5] 5/2 lorentzian FWHM
    +
    817  // w[6] 7/2 bulk area
    +
    818  // w[7] 7/2 bulk position
    +
    819  // w[8] 7/2 lorentzian FWHM
    +
    820  // w[9] surface/bulk area ratio
    +
    821  // w[10] surface core level shift
    +
    822  // w[11] 2nd layer/bulk area ratio
    +
    823  // w[12] 2nd layer core level shift
    +
    824  variable x
    +
    825 
    +
    826  variable bg = w[0] + w[1] * x
    +
    827  variable v = bg
    +
    828 
    +
    829  variable vc1 // amplitude
    +
    830  variable vc2 // width
    +
    831  variable vc3 // position
    +
    832  variable vc4 // shape
    +
    833  vc2 = 2 * sqrt(ln(2)) / w[2]
    +
    834 
    +
    835  // 5/2 bulk
    +
    836  vc1 = w[3] / sqrt(pi) * vc2
    +
    837  vc3 = w[4]
    +
    838  vc4 = vc2 * w[5] / 2
    +
    839  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    840 
    +
    841  // 5/2 surface
    +
    842  vc1 = w[3] / sqrt(pi) * vc2 * w[9]
    +
    843  vc3 = w[4] + w[10]
    +
    844  vc4 = vc2 * w[5] / 2
    +
    845  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    846 
    +
    847  // 5/2 2nd layer
    +
    848  vc1 = w[3] / sqrt(pi) * vc2 * w[11]
    +
    849  vc3 = w[4] + w[12]
    +
    850  vc4 = vc2 * w[5] / 2
    +
    851  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    852 
    +
    853  // 7/2 bulk
    +
    854  vc1 = w[6] / sqrt(pi) * vc2
    +
    855  vc3 = w[7]
    +
    856  vc4 = vc2 * w[8] / 2
    +
    857  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    858 
    +
    859  // 7/2 surface
    +
    860  vc1 = w[6] / sqrt(pi) * vc2 * w[9]
    +
    861  vc3 = w[7] + w[10]
    +
    862  vc4 = vc2 * w[8] / 2
    +
    863  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    864 
    +
    865  // 7/2 2nd layer
    +
    866  vc1 = w[6] / sqrt(pi) * vc2 * w[11]
    +
    867  vc3 = w[7] + w[12]
    +
    868  vc4 = vc2 * w[8] / 2
    +
    869  v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
    +
    870 
    +
    871  return v
    +
    872 
    +
    873 end
    +
    874 
    +
    875 function ShowComponents_Au4f_2p3(coef_wave, fit_wave)
    +
    876  wave coef_wave
    +
    877  wave fit_wave
    +
    878 
    +
    879  duplicate /free coef_wave, coef1, coef2, coef3
    +
    880  coef1[9] = 0
    +
    881  coef1[11] = 0
    +
    882 
    +
    883  coef2[3] *= coef_wave[9]
    +
    884  coef2[4] += coef_wave[10]
    +
    885  coef2[6] *= coef_wave[9]
    +
    886  coef2[7] += coef_wave[10]
    +
    887  coef2[9] = 0
    +
    888  coef2[11] = 0
    +
    889 
    +
    890  coef3[3] *= coef_wave[11]
    +
    891  coef3[4] += coef_wave[12]
    +
    892  coef3[6] *= coef_wave[11]
    +
    893  coef3[7] += coef_wave[12]
    +
    894  coef3[9] = 0
    +
    895  coef3[11] = 0
    +
    896 
    +
    897  string s_fit_wave = NameOfWave(fit_wave)
    +
    898  string s_fit_p1 = s_fit_wave + "_p1"
    +
    899  string s_fit_p2 = s_fit_wave + "_p2"
    +
    900  string s_fit_p3 = s_fit_wave + "_p3"
    +
    901  duplicate /o fit_wave, $(s_fit_p1) /wave=fit_p1
    +
    902  duplicate /o fit_wave, $(s_fit_p2) /wave=fit_p2
    +
    903  duplicate /o fit_wave, $(s_fit_p3) /wave=fit_p3
    +
    904 
    +
    905  fit_p1 = Au4f_2p2(coef1, x)
    +
    906  fit_p2 = Au4f_2p2(coef2, x)
    +
    907  fit_p3 = Au4f_2p2(coef3, x)
    +
    908 
    +
    909  string traces = TraceNameList("", ";", 1)
    +
    910  if ((WhichListItem(s_fit_wave, traces, ";") >= 0) && (WhichListItem(s_fit_p1, traces, ";") < 0))
    +
    911  appendtograph fit_p1, fit_p2, fit_p3
    +
    912  ModifyGraph lstyle($s_fit_p1)=2
    +
    913  ModifyGraph lstyle($s_fit_p2)=2
    +
    914  ModifyGraph lstyle($s_fit_p3)=2
    +
    915  ModifyGraph rgb($s_fit_p1)=(0,0,65280)
    +
    916  ModifyGraph rgb($s_fit_p2)=(0,0,65280)
    +
    917  ModifyGraph rgb($s_fit_p3)=(0,0,65280)
    +
    918  endif
    +
    919 end
    +
    920 
    +
    930 function FermiGaussConv(pw, yw, xw) : FitFunc
    +
    931  WAVE pw, yw, xw
    +
    932 
    +
    933  // half width of temporary gaussian wave is pw[5] multiplied by this factor (may be fractional)
    +
    934  variable precision_g = 5
    +
    935  variable oversampling = 4
    +
    936 
    +
    937  // calculate wave spacing based on minimum spacing of desired x points
    +
    938  duplicate /free xw, xdw
    +
    939  differentiate /p xw /d=xdw
    +
    940  xdw = abs(xdw)
    +
    941  variable xd = wavemin(xdw) / oversampling
    +
    942 
    +
    943  // calculate gausswave size based on pw[5] and precision variable
    +
    944  variable x0g = abs(pw[5]) * precision_g
    +
    945  variable ng = 2 * floor(x0g / xd) + 1
    +
    946 
    +
    947  // calculate fermiwave size based on desired range for yw
    +
    948  variable emax = wavemax(xw)
    +
    949  variable emin = wavemin(xw)
    +
    950  variable x0f = max(abs(emax - pw[3]), abs(emin - pw[3])) + x0g
    +
    951  variable ne = 2 * floor(x0f / xd) + 1
    +
    952 
    +
    953  // create and calculate initial waves, normalize exponential
    +
    954  make /d /n=(ng) /free gausswave
    +
    955  make /d /n=(ne) /free fermiwave
    +
    956  setscale/i x -x0g, x0g, "", gausswave
    +
    957  setscale/i x -x0f, x0f, "", fermiwave
    +
    958 
    +
    959  gausswave = exp( - (x / pw[5] )^2 )
    +
    960  fermiwave = 1 / (exp( x / (kBoltzmann * pw[4])) + 1.0 )
    +
    961 
    +
    962  // calculate the convolution
    +
    963  duplicate /free fermiwave, resultwave
    +
    964  Convolve /a gausswave, resultwave
    +
    965  variable rmax = wavemax(resultwave)
    +
    966  resultwave /= rmax
    +
    967 
    +
    968  // prepare output
    +
    969  ng = numpnts(resultwave)
    +
    970  x0g = xd * (ng - 1) / 2
    +
    971  setscale/i x -x0g, x0g, "", resultwave
    +
    972 
    +
    973  yw = pw[2] * resultwave(xw[p] - pw[3]) + pw[0] + pw[1] * xw[p]
    +
    974 end
    +
    975 
    +
    976 
    +
    980 function ShirleyBG(w, bg, p1, p2)
    +
    981  wave w
    +
    982  wave bg
    +
    983  variable p1, p2
    +
    984 
    +
    985  duplicate /o w, bg
    +
    986  integrate /meth=1 w /d=bg
    +
    987 
    +
    988  variable bg1 = bg[p1]
    +
    989  variable bg2 = bg[p2]
    +
    990  bg -= bg1
    +
    991  bg /= bg2 - bg1
    +
    992  bg *= w[p2] - w[p1]
    +
    993  bg += w[p1]
    +
    994 end
    +
    threadsafe variable DoniachSunjicBroadS(DoniachSunjicStruct *s)
    +
    variable DoniachSunjicBroad(wave pw, wave yw, wave xw)
    +
    threadsafe variable DblDoubletGaussLinBG_AO(wave pw, wave yw, wave xw)
    two doublet gaussian peaks on a linear background fit function (all at once).
    +
    variable Calc_DoniachSunjicBroad(wave pw, wave yw)
    +
    threadsafe variable MultiVoigtLinBG_AO(wave pw, wave yw, wave xw)
    multiple voigt peaks on a linear background fit function.
    +
    threadsafe variable MultiGaussLinBG_AO(wave pw, wave yw, wave xw)
    multiple gaussian peaks on a linear background fit function (all at once).
    + +
    threadsafe variable DoubletGaussLinBG_AO(wave pw, wave yw, wave xw)
    doublet gaussian peaks on a linear background fit function (all at once).
    +
    threadsafe variable MultiVoigtLinBG(wave w, variable x)
    multiple voigt peaks on a linear background fit function.
    +
    threadsafe variable ds2_bg(wave w, variable x)
    +
    variable ShowComponents_Au4f_2p3(wave coef_wave, wave fit_wave)
    +
    variable Fit_DoniachSunjicBroad(wave pw, wave yw, wave xw, wave ww)
    +
    variable Au4f_2p3(wave w, variable x)
    +
    variable ds6_bg(wave w, variable x)
    +
    variable Au4f(wave w, variable x)
    +
    variable Au4f_2p2(wave w, variable x)
    +
    variable ShowComponents_Au4f_2p2(wave coef_wave, wave fit_wave)
    +
    threadsafe variable ds1_bg(wave w, variable x)
    +
    variable ShirleyBG(wave w, wave bg, variable p1, variable p2)
    calculate the shirley background
    +
    variable ds4_bg(wave w, variable x)
    +
    threadsafe variable MultiDoniachSunjicLinBG(wave w, variable x)
    multiple doniach-sunjic peaks on a linear background fit function.
    +
    threadsafe variable DoniachSunjic(variable x, variable amp, variable pos, variable sing, variable fwhm)
    Doniach-Sunjic line shape.
    +
    threadsafe variable MultiGaussLinBG(wave w, variable x)
    multiple gaussian peaks on a linear background fit function.
    +
    variable FermiGaussConv(wave pw, wave yw, wave xw)
    convolution of Fermi-Dirac distribution and a Gaussian.
    diff --git a/doc/html/pearl-gui-tools_8ipf.html b/doc/html/pearl-gui-tools_8ipf.html index 7b1ba67..2886e1a 100644 --- a/doc/html/pearl-gui-tools_8ipf.html +++ b/doc/html/pearl-gui-tools_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-gui-tools.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -132,7 +134,7 @@ Functions
    -

    Definition at line 18 of file pearl-gui-tools.ipf.

    +

    Definition at line 19 of file pearl-gui-tools.ipf.

    @@ -151,7 +153,7 @@ Functions
    -

    Definition at line 50 of file pearl-gui-tools.ipf.

    +

    Definition at line 51 of file pearl-gui-tools.ipf.

    @@ -187,7 +189,7 @@ Functions
    -

    Definition at line 32 of file pearl-gui-tools.ipf.

    +

    Definition at line 33 of file pearl-gui-tools.ipf.

    @@ -197,9 +199,9 @@ Functions diff --git a/doc/html/pearl-gui-tools_8ipf_source.html b/doc/html/pearl-gui-tools_8ipf_source.html index e64b1ca..6a429b6 100644 --- a/doc/html/pearl-gui-tools_8ipf_source.html +++ b/doc/html/pearl-gui-tools_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-gui-tools.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,18 +87,71 @@ $(document).ready(function(){initNavTree('pearl-gui-tools_8ipf_source.html','');
    pearl-gui-tools.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.1
    3 #pragma ModuleName = PearlGuiTools
    4 #pragma version = 1.01
    5 
    6 // Miscellaneous GUI tools
    7 // * progress bar
    8 
    9 // created: matthias.muntwiler@psi.ch, 2013-11-14
    10 // Copyright (c) 2013 Paul Scherrer Institut
    11 // $Id$
    12 
    13 // Licensed under the Apache License, Version 2.0 (the "License");
    14 // you may not use this file except in compliance with the License.
    15 // You may obtain a copy of the License at
    16 // http://www.apache.org/licenses/LICENSE-2.0
    17 
    18 function display_progress_panel(title, message, progress_max)
    19  string title
    20  string message
    21  variable progress_max
    22 
    23  NewPanel /K=1 /N=ProgressPanel /W=(200,200,402,260) as title
    24  TitleBox t_message,pos={2,2},size={189,13},title=message
    25  TitleBox t_message,frame=0
    26  ValDisplay vd_progress,pos={2,20},size={198,13}
    27  ValDisplay vd_progress,limits={0,progress_max,0},barmisc={0,0},mode= 3,value= _NUM:0
    28  Button b_abort,pos={74,38},size={50,20},title="Abort"
    29  DoUpdate /W=ProgressPanel /E=1
    30 end
    31 
    32 function update_progress_panel(progress, [message, progress_max])
    33  // returns true if the user clicked the Abort button
    34  variable progress
    35  string message
    36  variable progress_max
    37 
    38  if (!ParamIsDefault(message))
    39  TitleBox t_message,title=message,win=ProgressPanel
    40  endif
    41  if (ParamIsDefault(progress_max))
    42  ValDisplay vd_progress,value=_NUM:progress,win=ProgressPanel
    43  else
    44  ValDisplay vd_progress,limits={0,progress_max,0},value=_NUM:progress,win=ProgressPanel
    45  endif
    46  DoUpdate /W=ProgressPanel
    47  return (v_flag == 2)
    48 end
    49 
    51  KillWindow ProgressPanel
    52 end
    variable kill_progress_panel()
    -
    variable display_progress_panel(string title, string message, variable progress_max)
    -
    variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.1
    +
    4 #pragma ModuleName = PearlGuiTools
    +
    5 #pragma version = 1.01
    +
    6 
    +
    7 // Miscellaneous GUI tools
    +
    8 // * progress bar
    +
    9 
    +
    10 // created: matthias.muntwiler@psi.ch, 2013-11-14
    +
    11 // Copyright (c) 2013 Paul Scherrer Institut
    +
    12 // $Id$
    +
    13 
    +
    14 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    15 // you may not use this file except in compliance with the License.
    +
    16 // You may obtain a copy of the License at
    +
    17 // http://www.apache.org/licenses/LICENSE-2.0
    +
    18 
    +
    19 function display_progress_panel(title, message, progress_max)
    +
    20  string title
    +
    21  string message
    +
    22  variable progress_max
    +
    23 
    +
    24  NewPanel /K=1 /N=ProgressPanel /W=(200,200,402,260) as title
    +
    25  TitleBox t_message,pos={2,2},size={189,13},title=message
    +
    26  TitleBox t_message,frame=0
    +
    27  ValDisplay vd_progress,pos={2,20},size={198,13}
    +
    28  ValDisplay vd_progress,limits={0,progress_max,0},barmisc={0,0},mode= 3,value= _NUM:0
    +
    29  Button b_abort,pos={74,38},size={50,20},title="Abort"
    +
    30  DoUpdate /W=ProgressPanel /E=1
    +
    31 end
    +
    32 
    +
    33 function update_progress_panel(progress, [message, progress_max])
    +
    34  // returns true if the user clicked the Abort button
    +
    35  variable progress
    +
    36  string message
    +
    37  variable progress_max
    +
    38 
    +
    39  if (!ParamIsDefault(message))
    +
    40  TitleBox t_message,title=message,win=ProgressPanel
    +
    41  endif
    +
    42  if (ParamIsDefault(progress_max))
    +
    43  ValDisplay vd_progress,value=_NUM:progress,win=ProgressPanel
    +
    44  else
    +
    45  ValDisplay vd_progress,limits={0,progress_max,0},value=_NUM:progress,win=ProgressPanel
    +
    46  endif
    +
    47  DoUpdate /W=ProgressPanel
    +
    48  return (v_flag == 2)
    +
    49 end
    +
    50 
    + +
    52  KillWindow ProgressPanel
    +
    53 end
    +
    variable kill_progress_panel()
    +
    variable display_progress_panel(string title, string message, variable progress_max)
    +
    variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
    diff --git a/doc/html/pearl-matrix-import_8ipf.html b/doc/html/pearl-matrix-import_8ipf.html index 42bf875..7da8230 100644 --- a/doc/html/pearl-matrix-import_8ipf.html +++ b/doc/html/pearl-matrix-import_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-matrix-import.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -111,62 +113,62 @@ Namespaces

    Functions

    static variable init_package () - initialize the package data folder. More...
    + initialize the package data folder. More...
      static variable check_package_folder () - check that the package data folder exists More...
    + check that the package data folder exists More...
      static variable AfterFileOpenHook (variable refNum, string file, string pathName, string type, string creator, variable kind) - initialize the package and reload preferences after an experiment is loaded. More...
    + initialize the package and reload preferences after an experiment is loaded. More...
      static variable BeforeFileOpenHook (variable refNum, string fileName, string path, string type, string creator, variable kind) - open a matrix file that was dropped into Igor. More...
    + open a matrix file that was dropped into Igor. More...
      string matrix_format_elog_message (wave metadata) - generate elog message from bricklet metadata More...
    + generate elog message from bricklet metadata More...
      variable matrix_preview_2d (wave data, wave metadata)   static wave preview_matrix_file (string filename) - load the preview of a Matrix data file More...
    + load the preview of a Matrix data file More...
      static variable initStruct (errorCode *errorCode) - from matrixfilereader help More...
    + from matrixfilereader help More...
      variable mtrx_load_all () - load all data from a Matrix data file. More...
    + load all data from a Matrix data file. More...
      variable mtrx_parse_filename (string fileName, string *resultFile, variable *runCycle, variable *scanCycle, string *channel) - parse matrix file names More...
    + parse matrix file names More...
      string mtrx_split_filename (string fileName, string *prefix, string *datepart, string *timepart) - split a matrix filename and return the first three parts More...
    + split a matrix filename and return the first three parts More...
      dfr mtrx_create_folder (string fileName, dfref df_base=defaultValue) - create or look up a data folder based on a matrix file name. More...
    + create or look up a data folder based on a matrix file name. More...
      dfr mtrx_get_cycle_folder (dfref df_base=defaultValue, variable runCycle=defaultValue, variable scanCycle=defaultValue) - create a data folder for bricklet data. More...
    + create a data folder for bricklet data. More...
      variable mtrx_file_brickletID (string resultFile, variable runCycle, variable scanCycle, string channel) - find out bricklet ID of a file More...
    + find out bricklet ID of a file More...
      variable mtrx_open_file (string pathName, string fileNameOrPath) - open a matrix result or data file More...
    + open a matrix result or data file More...
      string mtrx_load_preview (string destName, string pathName, string fileName, string traces=defaultValue) - load a preview image from a Matrix data file. More...
    + load a preview image from a Matrix data file. More...
      string mtrx_load_file (string pathName, string fileName, string traces=defaultValue) - load all data from a Matrix data file. More...
    + load all data from a Matrix data file. More...
      variable mtrx_scale_dataset (wave data)   string mtrx_load_info (string APathName, string AFileName) - load descriptive info from a Matrix data file. More...
    + load descriptive info from a Matrix data file. More...
      variable subtract_line_bg (wave img) - remove linear background line-by-line More...
    + remove linear background line-by-line More...
     

    the matrix file import requires the matrix file reader XOP by thomas braun (http://www.igorexchange.com/project/matrixFileReader) which in turn requires an installation of vernissage by omicron nanotechnology.

    Warning
    EXPERIMENTAL the matrix import module and its interface may change radically in future revisions!
    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    - -

    Definition at line 120 of file pearl-matrix-import.ipf.

    +

    Definition at line 121 of file pearl-matrix-import.ipf.

    @@ -462,7 +464,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    @@ -183,9 +185,9 @@ Variables

    -

    Definition at line 145 of file pearl-matrix-import.ipf.

    +

    Definition at line 146 of file pearl-matrix-import.ipf.

    @@ -504,7 +506,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    reference of the newly created or existing data folder.
    -

    Definition at line 360 of file pearl-matrix-import.ipf.

    +

    Definition at line 361 of file pearl-matrix-import.ipf.

    @@ -559,7 +561,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    bricklet ID, or -1 if an error occurred.
    -

    Definition at line 461 of file pearl-matrix-import.ipf.

    +

    Definition at line 462 of file pearl-matrix-import.ipf.

    @@ -608,7 +610,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    reference of the newly created or existing data folder.
    -

    Definition at line 405 of file pearl-matrix-import.ipf.

    +

    Definition at line 406 of file pearl-matrix-import.ipf.

    @@ -629,7 +631,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    load all data from a Matrix data file.

    -

    Definition at line 231 of file pearl-matrix-import.ipf.

    +

    Definition at line 232 of file pearl-matrix-import.ipf.

    @@ -677,7 +679,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    semicolon-separated list of loaded waves including partial path from current data folder.
    -

    Definition at line 767 of file pearl-matrix-import.ipf.

    +

    Definition at line 768 of file pearl-matrix-import.ipf.

    @@ -723,7 +725,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    newline terminated string.
    -

    Definition at line 863 of file pearl-matrix-import.ipf.

    +

    Definition at line 864 of file pearl-matrix-import.ipf.

    @@ -778,7 +780,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    semicolon-separated list of loaded waves including partial path from current data folder.
    -

    Definition at line 682 of file pearl-matrix-import.ipf.

    +

    Definition at line 683 of file pearl-matrix-import.ipf.

    @@ -829,7 +831,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 545 of file pearl-matrix-import.ipf.

    +

    Definition at line 546 of file pearl-matrix-import.ipf.

    @@ -896,7 +898,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0001.mtrx, default_2015Apr20-124353_STM-STM_AtomManipulation_0002.mtrx, etc. the function returns the first part up to the experiment name ("AtomManipulation" in the examples). all other return values set to defaults and must not be regarded.

    result data files look like: default_2015Apr20-124353_STM-STM_AtomManipulation–136_1.Aux1(V)_mtrx, default_2015Apr20-124353_STM-STM_AtomManipulation–136_1.I(V)_mtrx, default_2015Apr20-124353_STM-STM_AtomManipulation–14_1.I_mtrx, default_2015Apr20-124353_STM-STM_AtomManipulation–14_1.Z_mtrx, etc. the function returns all results as described in the parameter list.

    -

    Definition at line 294 of file pearl-matrix-import.ipf.

    +

    Definition at line 295 of file pearl-matrix-import.ipf.

    @@ -916,7 +918,7 @@ result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0
    -

    Definition at line 829 of file pearl-matrix-import.ipf.

    +

    Definition at line 830 of file pearl-matrix-import.ipf.

    @@ -961,7 +963,7 @@ result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0

    split a matrix filename and return the first three parts

    we assume that the second (third) part contains the date (time). the parts are separated by dash or underscore.

    -

    Definition at line 332 of file pearl-matrix-import.ipf.

    +

    Definition at line 333 of file pearl-matrix-import.ipf.

    @@ -1000,7 +1002,7 @@ result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0
    Returns
    wave reference of the preview image
    -

    Definition at line 170 of file pearl-matrix-import.ipf.

    +

    Definition at line 171 of file pearl-matrix-import.ipf.

    @@ -1022,7 +1024,7 @@ result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0

    remove linear background line-by-line

    -

    Definition at line 886 of file pearl-matrix-import.ipf.

    +

    Definition at line 887 of file pearl-matrix-import.ipf.

    @@ -1047,7 +1049,7 @@ result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0
    -

    Definition at line 40 of file pearl-matrix-import.ipf.

    +

    Definition at line 41 of file pearl-matrix-import.ipf.

    @@ -1071,7 +1073,7 @@ result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0
    -

    Definition at line 37 of file pearl-matrix-import.ipf.

    +

    Definition at line 38 of file pearl-matrix-import.ipf.

    @@ -1095,7 +1097,7 @@ result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0
    -

    Definition at line 38 of file pearl-matrix-import.ipf.

    +

    Definition at line 39 of file pearl-matrix-import.ipf.

    @@ -1105,9 +1107,9 @@ result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0 diff --git a/doc/html/pearl-matrix-import_8ipf_source.html b/doc/html/pearl-matrix-import_8ipf_source.html index 2025116..2459cfc 100644 --- a/doc/html/pearl-matrix-import_8ipf_source.html +++ b/doc/html/pearl-matrix-import_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-matrix-import.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,36 +87,700 @@ $(document).ready(function(){initNavTree('pearl-matrix-import_8ipf_source.html',
    pearl-matrix-import.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3
    2 #pragma version = 1.00
    3 #pragma IgorVersion = 6.36
    4 #pragma ModuleName = PearlMatrixImport
    5 
    6 // author: matthias.muntwiler@psi.ch
    7 // Copyright (c) 2016 Paul Scherrer Institut
    8 
    9 // Licensed under the Apache License, Version 2.0 (the "License");
    10 // you may not use this file except in compliance with the License.
    11 // You may obtain a copy of the License at
    12 // http://www.apache.org/licenses/LICENSE-2.0
    13 
    31 
    36 
    37 static strconstant package_name = "pearl_matrix_import"
    38 static strconstant package_path = "root:packages:pearl_matrix_import:"
    39 
    40 static strconstant ks_filematch_mtrx = "*_mtrx"
    41 
    45 static function init_package()
    46 
    47  dfref savedf = getdatafolderdfr()
    48 
    49  setdatafolder root:
    50  newdatafolder /o/s packages
    51  newdatafolder /o/s $package_name
    52 
    53  variable /g loglevel = 3
    54  string /g dataFilePath = ""
    55  string /g resultFilePath = ""
    56  variable /g runCycle = 0
    57  variable /g scanCycle = 0
    58  string /g channelName = ""
    59  variable /g brickletID = 0
    60  variable /g V_MatrixFileReaderOverwrite = 1
    61  variable /g V_MatrixFileReaderFolder = 0
    62  variable /g V_MatrixFileReaderDouble = 0
    63 
    64  setdatafolder savedf
    65  return 0
    66 end
    67 
    72 static function check_package_folder()
    73  dfref df_pack = $(package_path)
    74  if (DataFolderRefStatus(df_pack))
    75  svar /sdfr=df_pack /z resultFilePath
    76  if (!svar_exists(resultFilePath))
    77  init_package()
    78  endif
    79  else
    80  init_package()
    81  endif
    82 end
    83 
    85 static function AfterFileOpenHook(refNum,file,pathName,type,creator,kind)
    86  Variable refNum,kind
    87  String file,pathName,type,creator
    88  if( (kind >= 1) && (kind <= 2))
    89  init_package()
    90  //load_prefs()
    91  endif
    92  return 0
    93 end
    94 
    102 static function BeforeFileOpenHook(refNum,fileName,path,type,creator,kind)
    103  Variable refNum,kind
    104  String fileName,path,type,creator
    105 
    106  Variable handledOpen = 0
    107  if (StringMatch(fileName, ks_filematch_mtrx))
    108  setdatafolder root:
    109  newdatafolder /o /s matrix
    110  mtrx_load_preview("matrix", path, fileName)
    111  handledOpen = 1
    112  endif
    113  return handledOpen
    114 End
    115 
    120 function /s matrix_format_elog_message(metadata)
    121  wave /t metadata
    122 
    123  string key
    124  string value
    125  variable nkeys = dimsize(metadata, 0)
    126  variable ikey
    127  string message_keys
    128  message_keys = "resultFileName;sampleName;channelName;"
    129  message_keys += "XYScanner.Points.value;XYScanner.Raster_Time.value;XYScanner.Raster_Time.unit;XYScanner.Width.value;XYScanner.Width.unit;XYScanner.Height.value;XYScanner.Height.unit;"
    130  message_keys += "GapVoltageControl.Voltage.value;GapVoltageControl.Voltage.unit;"
    131  message_keys += "Regulator.Loop_Gain_1_I.value;Regulator.Loop_Gain_1_I.unit;Regulator.Setpoint_1.value;Regulator.Setpoint_1.unit;"
    132  message_keys += "Spectroscopy.Device_1_Start.value;Spectroscopy.Device_1_Start.unit;Spectroscopy.Spectroscopy_Mode.value;"
    133  string message
    134 
    135  message_keys = ""
    136  for (ikey = 0; ikey < nkeys; ikey += 1)
    137  key = metadata[ikey][0]
    138  value = metadata[ikey][1]
    139  if (WhichListItem(key, message_keys) >= 0)
    140  message += key + " = " + value + "\r"
    141  endif
    142  endfor
    143 end
    144 
    145 function matrix_preview_2d(data, metadata)
    146  wave data
    147  wave /t metadata
    148 
    149  Display
    150  AppendImage data
    151  ModifyImage data ctab= {*,*,Mud,0}
    152  ModifyGraph margin(left)=30,margin(bottom)=30,margin(top)=5,margin(right)=5,height={Plan,1,left,bottom}
    153  ModifyGraph mirror=2
    154  ModifyGraph nticks=3
    155  ModifyGraph axThick=0.5
    156  ModifyGraph btLen=4
    157 
    158 end
    159 
    170 static function /wave preview_matrix_file(filename)
    171  string filename
    172 
    173  dfref saveDF = GetDataFolderDFR()
    174  setdatafolder $package_path
    175  svar s_preview_file
    176  svar s_preview_source
    177  mtrx_load_preview("preview_image", "pearl_explorer_filepath", filename)
    178  s_preview_file = filename
    179  s_preview_source = ""
    180  wave /z preview_image
    181 
    182  svar /z s_file_info
    183  if (! svar_exists(s_file_info))
    184  string /g s_file_info
    185  endif
    186  if (strlen(s_preview_file) > 0)
    187  s_file_info = mtrx_load_info("pearl_explorer_filepath", filename)
    188  else
    189  s_file_info = ""
    190  endif
    191 
    192  setdatafolder saveDF
    193  return preview_image
    194 end
    195 
    197 Structure errorCode
    198  int32 SUCCESS
    199  int32 UNKNOWN_ERROR
    200  int32 ALREADY_FILE_OPEN
    201  int32 EMPTY_RESULTFILE
    202  int32 FILE_NOT_READABLE
    203  int32 NO_NEW_BRICKLETS
    204  int32 WRONG_PARAMETER
    205  int32 INTERNAL_ERROR_CONVERTING_DATA
    206  int32 NO_FILE_OPEN
    207  int32 INVALID_RANGE
    208  int32 WAVE_EXIST
    209 EndStructure
    210 
    212 static Function initStruct(errorCode)
    213  Struct errorCode &errorCode
    214 
    215  errorCode.SUCCESS =0
    216  errorCode.UNKNOWN_ERROR=10001
    217  errorCode.ALREADY_FILE_OPEN=10002
    218  errorCode.EMPTY_RESULTFILE=10004
    219  errorCode.FILE_NOT_READABLE=10008
    220  errorCode.NO_NEW_BRICKLETS=10016
    221  errorCode.WRONG_PARAMETER=10032
    222  errorCode.INTERNAL_ERROR_CONVERTING_DATA=10064
    223  errorCode.NO_FILE_OPEN=10128
    224  errorCode.INVALID_RANGE=10256
    225  errorCode.WAVE_EXIST=10512
    226 
    227 end
    228 
    231 function mtrx_load_all()
    232 
    233  struct errorCode errorCode
    235 
    236 #if exists("MFR_OpenResultFile")
    237  MFR_OpenResultFile
    238  if(V_flag != errorCode.SUCCESS)
    239  MFR_GetXOPErrorMessage
    240  return -1
    241  endif
    242 
    243  MFR_GetBrickletData
    244  if(V_flag != errorCode.SUCCESS)
    245  MFR_GetXOPErrorMessage
    246  return -1
    247  endif
    248 
    249  MFR_GetBrickletMetaData
    250  if(V_flag != errorCode.SUCCESS)
    251  MFR_GetXOPErrorMessage
    252  return -1
    253  endif
    254 
    255  return 0
    256 #else
    257  return -1
    258 #endif
    259 end
    260 
    294 function mtrx_parse_filename(fileName, resultFile, runCycle, scanCycle, channel)
    295  string fileName
    296  string &resultFile
    297  variable &runCycle
    298  variable &scanCycle
    299  string &channel
    300 
    301  variable fileType = 0
    302  resultFile = ""
    303  channel = ""
    304  runCycle = 0
    305  scanCycle = 0
    306 
    307  string regexp = ""
    308  string index1 = ""
    309  string index2 = ""
    310  string extension = ""
    311 
    312  if (StringMatch(fileName, "*.mtrx"))
    313  regexp = "(.+)_([[:digit:]]+)\.(.+)"
    314  SplitString /E=regexp fileName, resultFile, index1, extension
    315  fileType = 0
    316  else
    317  regexp = "(.+)--([[:digit:]]+)_([[:digit:]]+)\.((.+)_mtrx)"
    318  SplitString /E=regexp fileName, resultFile, index1, index2, extension, channel
    319  fileType = 1
    320  runCycle = str2num(index1)
    321  scanCycle = str2num(index2)
    322  endif
    323 
    324  return fileType
    325 end
    326 
    332 function /s mtrx_split_filename(fileName, prefix, datepart, timepart)
    333  string fileName
    334  string &prefix
    335  string &datepart
    336  string &timepart
    337 
    338  string regexp
    339  regexp = "([[:alpha:][:digit:]]+)[-_]([[:alpha:][:digit:]]+)[-_]([[:alpha:][:digit:]]+)[-_].+"
    340  SplitString /E=regexp fileName, prefix, datepart, timepart
    341  return datepart
    342 end
    343 
    360 function /df mtrx_create_folder(fileName, [df_base])
    361  string fileName
    362  dfref df_base
    363 
    364  if (ParamIsDefault(df_base))
    365  df_base = GetDataFolderDFR()
    366  endif
    367 
    368  string prefix
    369  string datepart
    370  string timepart
    371  string folderName
    372 
    373  mtrx_split_filename(fileName, prefix, datepart, timepart)
    374  folderName = "mtrx_" + datepart + "_" + timepart
    375  folderName = CleanupName(folderName, 0)
    376 
    377  dfref df_save = GetDataFolderDFR()
    378  setdatafolder root:
    379  newdatafolder /o /s $foldername
    380  dfref df = GetDataFolderDFR()
    381 
    382  setdatafolder df_save
    383  return df
    384 end
    385 
    405 function /df mtrx_get_cycle_folder([df_base, runCycle, scanCycle])
    406  dfref df_base
    407  variable runCycle
    408  variable scanCycle
    409 
    410  dfref df_save = GetDataFolderDFR()
    411  dfref df_pack = $(package_path)
    412  if (ParamIsDefault(df_base))
    413  df_base = GetDataFolderDFR()
    414  endif
    415  if (ParamIsDefault(runCycle))
    416  nvar /sdfr=df_pack defRunCycle = runCycle
    417  runCycle = defRunCycle
    418  endif
    419  if (ParamIsDefault(scanCycle))
    420  nvar /sdfr=df_pack defScanCycle = scanCycle
    421  scanCycle = defScanCycle
    422  endif
    423 
    424  string dfname
    425  if ((runCycle >= 1) && (scanCycle >= 1))
    426  sprintf dfname, "r%us%u", runCycle, scanCycle
    427  setdatafolder df_base
    428  dfref df = $dfname
    429  if (DataFolderRefStatus(df) == 0)
    430  newdatafolder $dfname
    431  dfref df = $dfname
    432  endif
    433  else
    434  dfref df = df_base
    435  endif
    436 
    437  setdatafolder df_save
    438  return df
    439 end
    440 
    461 function mtrx_file_brickletID(resultFile, runCycle, scanCycle, channel)
    462  string resultFile
    463  variable runCycle
    464  variable scanCycle
    465  string channel
    466 
    467  dfref df_overview = NewFreeDataFolder()
    468  variable link = 1
    469  variable id = -1
    470  variable idx = 0
    471 
    472  string resultFileName
    473 #if exists("MFR_OpenResultFile")
    474  struct errorCode errorCode
    476  do
    477  sprintf resultFileName, "%s_%04u.mtrx", resultFile, link
    478  MFR_OpenResultFile /K resultFileName
    479  if(V_flag != errorCode.SUCCESS)
    480  return -1
    481  endif
    482  MFR_CreateOverviewTable /DEST=df_overview
    483  // dimension labels are: brickletID, scanCycleCount, runCycleCount, sequenceID, dimension, channelName
    484  wave /t /sdfr=df_overview overviewTable
    485  make /n=(dimsize(overviewTable, 0)) /i /u /free runcycles, scancycles, ids, match
    486  make /n=(dimsize(overviewTable, 0)) /t /free channels
    487  ids = str2num(overviewtable[p][%brickletID])
    488  if (runcycle > 0)
    489  runcycles = str2num(overviewtable[p][%runCycleCount])
    490  else
    491  runcycles = runcycle
    492  endif
    493  if (scancycle > 0)
    494  scancycles = str2num(overviewtable[p][%scanCycleCount])
    495  else
    496  scancycles = scancycle
    497  endif
    498  if (strlen(channel) > 0)
    499  channels = overviewTable[p][%channelName]
    500  else
    501  channels = channel
    502  endif
    503  Extract /FREE ids, match_ids, (scancycles == scanCycle) && (runcycles == runCycle) && (cmpstr(channels, channel) == 0)
    504  if (numpnts(match_ids) > 0)
    505  id = match_ids[0]
    506  else
    507  link += 1
    508  endif
    509  while (id < 0)
    510 #endif
    511  return id
    512 end
    513 
    545 function mtrx_open_file(pathName, fileNameOrPath)
    546  string pathName
    547  string fileNameOrPath
    548 
    549  check_package_folder()
    550  dfref df_save = GetDataFolderDFR()
    551  dfref df_pack = $(package_path)
    552  svar /sdfr=df_pack dataFilePath
    553  svar /sdfr=df_pack resultFilePath
    554  nvar /sdfr=df_pack runCycle
    555  nvar /sdfr=df_pack scanCycle
    556  svar /sdfr=df_pack channelName
    557  nvar /sdfr=df_pack brickletID
    558 
    559  string loc_resultFileName
    560  string loc_resultFilePath
    561  variable loc_runCycle
    562  variable loc_scanCycle
    563  string loc_channelName
    564 
    565  // make sure we have a valid and complete file path
    566  GetFileFolderInfo /P=$pathName /Q /Z=2 fileNameOrPath
    567  string filePath
    568  if ((v_flag == 0) && (v_isFile))
    569  filePath = s_path
    570  else
    571  return -1
    572  endif
    573 
    574  // get base file name
    575  string fileName
    576  string fileDir
    577  string baseFileName
    578  variable fileType
    579  fileName = ParseFilePath(0, filePath, ":", 1, 0)
    580  fileDir = ParseFilePath(1, filePath, ":", 1, 0)
    581  fileType = mtrx_parse_filename(fileName, baseFileName, loc_runCycle, loc_scanCycle, loc_channelName)
    582 
    583  variable link = 1
    584  variable id = -1
    585  variable result = -1
    586  variable using_cache = 0
    587 
    588  struct errorCode errorCode
    589  initStruct(errorCode)
    590  do
    591  sprintf loc_resultFileName, "%s_%04u.mtrx", baseFileName, link
    592  loc_resultFilePath = fileDir + loc_resultFileName
    593 #if exists("MFR_OpenResultFile")
    594  if ((strlen(resultFilePath) == 0) || (cmpstr(loc_resultFilePath, resultFilePath) != 0))
    595  MFR_OpenResultFile /K loc_resultFilePath
    596  if(V_flag != errorCode.SUCCESS)
    597  MFR_GetXOPErrorMessage
    598  result = -1
    599  break
    600  endif
    601  resultFilePath = loc_resultFilePath
    602  if (fileType == 1)
    603  dataFilePath = filePath
    604  else
    605  dataFilePath = ""
    606  endif
    607  runCycle = 0
    608  scanCycle = 0
    609  channelName = ""
    610  brickletID = 0
    611  MFR_CreateOverviewTable /DEST=df_pack
    612  if(V_flag != errorCode.SUCCESS)
    613  MFR_GetXOPErrorMessage
    614  result = -1
    615  break
    616  endif
    617  using_cache = 0
    618  else
    619  using_cache = 1
    620  endif
    621 #else
    622  print "matrixfilereader.xop not installed"
    623  result = -2
    624  break
    625 #endif
    626  // dimension labels are: brickletID, scanCycleCount, runCycleCount, sequenceID, dimension, channelName
    627  wave /t /sdfr=df_pack overviewTable
    628  make /n=(dimsize(overviewTable, 0)) /i /u /o df_pack:runCycles, df_pack:scanCycles, df_pack:ids
    629  make /n=(dimsize(overviewTable, 0)) /t /o df_pack:channels
    630  wave /sdfr=df_pack ids, runCycles, scanCycles
    631  wave /t /sdfr=df_pack channels
    632  ids = str2num(overviewtable[p][%brickletID])
    633  runCycles = str2num(overviewtable[p][%runCycleCount])
    634  scanCycles = str2num(overviewtable[p][%scanCycleCount])
    635  channels = overviewTable[p][%channelName]
    636  result = fileType
    637 
    638  // if a data file is opened, make sure we found the right result file
    639  if ((loc_runCycle > 0) && (loc_scanCycle > 0))
    640  Extract /FREE ids, match_ids, (runCycles == loc_runCycle) && (scanCycles == loc_scanCycle) && (cmpstr(channels, loc_channelName) == 0)
    641  if (numpnts(match_ids) > 0)
    642  id = match_ids[0]
    643  runCycle = loc_runCycle
    644  scanCycle = loc_scanCycle
    645  channelName = loc_channelName
    646  brickletID = id
    647  break
    648  elseif (using_cache)
    649  resultFilePath = ""
    650  else
    651  link += 1
    652  endif
    653  else
    654  break
    655  endif
    656  while (id < 0)
    657 
    658  return result
    659 end
    660 
    682 function /s mtrx_load_preview(destName, pathName, fileName, [traces])
    683  string destName
    684  string pathName
    685  string fileName
    686  string traces
    687 
    688  if (ParamIsDefault(traces))
    689  traces = "*Up;*Down;*ReUp;*ReDown;"
    690  endif
    691 
    692  dfref df_save = GetDataFolderDFR()
    693 
    694  string datanames = ""
    695  string datapaths = ""
    696  variable filestatus = mtrx_open_file(pathName, fileName)
    697  if (filestatus != 1)
    698  return ""
    699  endif
    700 
    701  dfref df_pack = $(package_path)
    702  svar /sdfr=df_pack dataFilePath
    703  svar /sdfr=df_pack resultFilePath
    704  nvar /sdfr=df_pack runCycle
    705  nvar /sdfr=df_pack scanCycle
    706  svar /sdfr=df_pack channelName
    707  nvar /sdfr=df_pack brickletID
    708 
    709 #if exists("MFR_OpenResultFile")
    710  dfref df_data = df_save
    711  variable /g df_data:V_MatrixFileReaderOverwrite = 1
    712  variable /g df_data:V_MatrixFileReaderFolder = 0
    713  variable /g df_data:V_MatrixFileReaderDouble = 0
    714  struct errorCode errorCode
    715  initStruct(errorCode)
    716  MFR_GetBrickletData /N=destName /R=(brickletID) /S=2 /DEST=df_data
    717  if(V_flag == errorCode.SUCCESS)
    718  datanames = S_waveNames
    719  variable i
    720  variable n = ItemsInList(datanames)
    721  string s
    722  s = StringFromList(0, datanames)
    723  wave data = $s
    724  mtrx_scale_dataset(data)
    725  if (WaveDims(data) == 2)
    726  subtract_line_bg(data)
    727  endif
    728  datapaths = AddListItem(GetWavesDataFolder(data, 4), datapaths, ";", inf)
    729  for (i = 1; i < n; i += 1)
    730  s = StringFromList(i, datanames)
    731  killwaves /z $s
    732  endfor
    733  else
    734  MFR_GetXOPErrorMessage
    735  endif
    736  //MFR_GetBrickletMetaData /N=ANickName /R=(brickletID) // /DEST=dfref
    737 #else
    738  print "matrixfilereader.xop not installed"
    739 #endif
    740 
    741  setdatafolder df_save
    742  return datapaths
    743 end
    744 
    767 function /s mtrx_load_file(pathName, fileName, [traces])
    768  string pathName
    769  string fileName
    770  string traces
    771 
    772  if (ParamIsDefault(traces))
    773  traces = "*Up;*Down;*ReUp;*ReDown;"
    774  endif
    775 
    776  dfref df_save = GetDataFolderDFR()
    777 
    778  string datanames = ""
    779  string datapaths = ""
    780  variable filestatus = mtrx_open_file(pathName, fileName)
    781  if (filestatus != 1)
    782  return ""
    783  endif
    784 
    785  dfref df_pack = $(package_path)
    786  svar /sdfr=df_pack dataFilePath
    787  svar /sdfr=df_pack resultFilePath
    788  nvar /sdfr=df_pack runCycle
    789  nvar /sdfr=df_pack scanCycle
    790  svar /sdfr=df_pack channelName
    791  nvar /sdfr=df_pack brickletID
    792 
    793 #if exists("MFR_OpenResultFile")
    794  string resultFileName = ParseFilePath(0, resultFilePath, ":", 1, 0)
    795  dfref df_result = mtrx_create_folder(resultFileName, df_base=df_save)
    796  dfref df_data = mtrx_get_cycle_folder(df_base = df_result)
    797  variable /g df_data:V_MatrixFileReaderOverwrite = 1
    798  variable /g df_data:V_MatrixFileReaderFolder = 0
    799  variable /g df_data:V_MatrixFileReaderDouble = 0
    800 
    801  struct errorCode errorCode
    802  initStruct(errorCode)
    803  string name
    804  name = CleanupName(channelName, 0)
    805  MFR_GetBrickletData /N=name /R=(brickletID) /DEST=df_data
    806  if(V_flag == errorCode.SUCCESS)
    807  datanames = S_waveNames
    808  variable i
    809  variable n = ItemsInList(datanames)
    810  string s
    811  for (i = 0; i < n; i += 1)
    812  s = StringFromList(i, datanames)
    813  wave /sdfr=df_data data = $s
    814  mtrx_scale_dataset(data)
    815  datapaths = AddListItem(GetWavesDataFolder(data, 4), datapaths, ";", inf)
    816  endfor
    817  else
    818  MFR_GetXOPErrorMessage
    819  endif
    820  //MFR_GetBrickletMetaData /N=ANickName /R=(brickletID) // /DEST=dfref
    821 #else
    822  print "matrixfilereader.xop not installed"
    823 #endif
    824 
    825  setdatafolder df_save
    826  return datapaths
    827 end
    828 
    829 function mtrx_scale_dataset(data)
    830  wave data
    831 
    832  dfref df_pack = $(package_path)
    833  nvar /sdfr=df_pack runCycle
    834  nvar /sdfr=df_pack scanCycle
    835  svar /sdfr=df_pack channelName
    836  nvar /sdfr=df_pack brickletID
    837 
    838  string scanDir = StringFromList(2, NameOfWave(data), "_")
    839  if (WaveDims(data) == 2)
    840  Note data, "AxisLabelX=X"
    841  Note data, "AxisLabelY=Y"
    842  endif
    843  Note data, "AxisLabelD=" + channelName
    844  string title
    845  sprintf title, "%u-%u %s %s", runCycle, scanCycle, channelName, scanDir
    846  Note data, "Dataset=" + title
    847 end
    848 
    863 function /s mtrx_load_info(APathName, AFileName)
    864  string APathName
    865  string AFileName
    866 
    867  dfref saveDF = GetDataFolderDFR()
    868  dfref fileDF = NewFreeDataFolder()
    869  setdatafolder fileDF
    870 
    871  variable fileID
    872  string filepath
    873  string scanpaths
    874  variable nscans
    875  variable iscan
    876  string scanpath
    877  string info = ""
    878 
    879 
    880  setdatafolder saveDF
    881  return info
    882 end
    883 
    886 function subtract_line_bg(img)
    887  wave img
    888 
    889  variable nx = dimsize(img, 0)
    890  variable ny = dimsize(img, 1)
    891  variable iy
    892  make /n=(nx) /free line, fit
    893  for (iy = 0; iy < ny; iy += 1)
    894  line = img[p][iy]
    895  if (numtype(sum(line)) == 0)
    896  CurveFit /N /Q /NTHR=0 line line /D=fit
    897  img[][iy] = line[p] - fit[p]
    898  endif
    899  endfor
    900 end
    static const string package_path
    -
    dfr mtrx_create_folder(string fileName, dfref df_base=defaultValue)
    create or look up a data folder based on a matrix file name.
    -
    variable mtrx_file_brickletID(string resultFile, variable runCycle, variable scanCycle, string channel)
    find out bricklet ID of a file
    -
    static variable initStruct(errorCode *errorCode)
    from matrixfilereader help
    -
    string mtrx_split_filename(string fileName, string *prefix, string *datepart, string *timepart)
    split a matrix filename and return the first three parts
    -
    variable matrix_preview_2d(wave data, wave metadata)
    -
    static wave preview_matrix_file(string filename)
    load the preview of a Matrix data file
    -
    string mtrx_load_info(string APathName, string AFileName)
    load descriptive info from a Matrix data file.
    -
    string matrix_format_elog_message(wave metadata)
    generate elog message from bricklet metadata
    -
    from matrixfilereader help
    -
    variable mtrx_load_all()
    load all data from a Matrix data file.
    - -
    static const string ks_filematch_mtrx
    -
    static variable AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind)
    initialize the package and reload preferences after an experiment is loaded.
    -
    dfr mtrx_get_cycle_folder(dfref df_base=defaultValue, variable runCycle=defaultValue, variable scanCycle=defaultValue)
    create a data folder for bricklet data.
    -
    static variable init_package()
    initialize the package data folder.
    -
    variable mtrx_parse_filename(string fileName, string *resultFile, variable *runCycle, variable *scanCycle, string *channel)
    parse matrix file names
    -
    string mtrx_load_preview(string destName, string pathName, string fileName, string traces=defaultValue)
    load a preview image from a Matrix data file.
    -
    static variable BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind)
    open a matrix file that was dropped into Igor.
    -
    static const string package_name
    -
    static variable check_package_folder()
    check that the package data folder exists
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3
    +
    3 #pragma version = 1.00
    +
    4 #pragma IgorVersion = 6.36
    +
    5 #pragma ModuleName = PearlMatrixImport
    +
    6 
    +
    7 // author: matthias.muntwiler@psi.ch
    +
    8 // Copyright (c) 2016 Paul Scherrer Institut
    +
    9 
    +
    10 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    11 // you may not use this file except in compliance with the License.
    +
    12 // You may obtain a copy of the License at
    +
    13 // http://www.apache.org/licenses/LICENSE-2.0
    +
    14 
    +
    32 
    +
    37 
    +
    38 static strconstant package_name = "pearl_matrix_import"
    +
    39 static strconstant package_path = "root:packages:pearl_matrix_import:"
    +
    40 
    +
    41 static strconstant ks_filematch_mtrx = "*_mtrx"
    +
    42 
    +
    46 static function init_package()
    +
    47 
    +
    48  dfref savedf = getdatafolderdfr()
    +
    49 
    +
    50  setdatafolder root:
    +
    51  newdatafolder /o/s packages
    +
    52  newdatafolder /o/s $package_name
    +
    53 
    +
    54  variable /g loglevel = 3
    +
    55  string /g dataFilePath = ""
    +
    56  string /g resultFilePath = ""
    +
    57  variable /g runCycle = 0
    +
    58  variable /g scanCycle = 0
    +
    59  string /g channelName = ""
    +
    60  variable /g brickletID = 0
    +
    61  variable /g V_MatrixFileReaderOverwrite = 1
    +
    62  variable /g V_MatrixFileReaderFolder = 0
    +
    63  variable /g V_MatrixFileReaderDouble = 0
    +
    64 
    +
    65  setdatafolder savedf
    +
    66  return 0
    +
    67 end
    +
    68 
    +
    73 static function check_package_folder()
    +
    74  dfref df_pack = $(package_path)
    +
    75  if (DataFolderRefStatus(df_pack))
    +
    76  svar /sdfr=df_pack /z resultFilePath
    +
    77  if (!svar_exists(resultFilePath))
    +
    78  init_package()
    +
    79  endif
    +
    80  else
    +
    81  init_package()
    +
    82  endif
    +
    83 end
    +
    84 
    +
    86 static function AfterFileOpenHook(refNum,file,pathName,type,creator,kind)
    +
    87  Variable refNum,kind
    +
    88  String file,pathName,type,creator
    +
    89  if( (kind >= 1) && (kind <= 2))
    +
    90  init_package()
    +
    91  //load_prefs()
    +
    92  endif
    +
    93  return 0
    +
    94 end
    +
    95 
    +
    103 static function BeforeFileOpenHook(refNum,fileName,path,type,creator,kind)
    +
    104  Variable refNum,kind
    +
    105  String fileName,path,type,creator
    +
    106 
    +
    107  Variable handledOpen = 0
    +
    108  if (StringMatch(fileName, ks_filematch_mtrx))
    +
    109  setdatafolder root:
    +
    110  newdatafolder /o /s matrix
    +
    111  mtrx_load_preview("matrix", path, fileName)
    +
    112  handledOpen = 1
    +
    113  endif
    +
    114  return handledOpen
    +
    115 End
    +
    116 
    +
    121 function /s matrix_format_elog_message(metadata)
    +
    122  wave /t metadata
    +
    123 
    +
    124  string key
    +
    125  string value
    +
    126  variable nkeys = dimsize(metadata, 0)
    +
    127  variable ikey
    +
    128  string message_keys
    +
    129  message_keys = "resultFileName;sampleName;channelName;"
    +
    130  message_keys += "XYScanner.Points.value;XYScanner.Raster_Time.value;XYScanner.Raster_Time.unit;XYScanner.Width.value;XYScanner.Width.unit;XYScanner.Height.value;XYScanner.Height.unit;"
    +
    131  message_keys += "GapVoltageControl.Voltage.value;GapVoltageControl.Voltage.unit;"
    +
    132  message_keys += "Regulator.Loop_Gain_1_I.value;Regulator.Loop_Gain_1_I.unit;Regulator.Setpoint_1.value;Regulator.Setpoint_1.unit;"
    +
    133  message_keys += "Spectroscopy.Device_1_Start.value;Spectroscopy.Device_1_Start.unit;Spectroscopy.Spectroscopy_Mode.value;"
    +
    134  string message
    +
    135 
    +
    136  message_keys = ""
    +
    137  for (ikey = 0; ikey < nkeys; ikey += 1)
    +
    138  key = metadata[ikey][0]
    +
    139  value = metadata[ikey][1]
    +
    140  if (WhichListItem(key, message_keys) >= 0)
    +
    141  message += key + " = " + value + "\r"
    +
    142  endif
    +
    143  endfor
    +
    144 end
    +
    145 
    +
    146 function matrix_preview_2d(data, metadata)
    +
    147  wave data
    +
    148  wave /t metadata
    +
    149 
    +
    150  Display
    +
    151  AppendImage data
    +
    152  ModifyImage data ctab= {*,*,Mud,0}
    +
    153  ModifyGraph margin(left)=30,margin(bottom)=30,margin(top)=5,margin(right)=5,height={Plan,1,left,bottom}
    +
    154  ModifyGraph mirror=2
    +
    155  ModifyGraph nticks=3
    +
    156  ModifyGraph axThick=0.5
    +
    157  ModifyGraph btLen=4
    +
    158 
    +
    159 end
    +
    160 
    +
    171 static function /wave preview_matrix_file(filename)
    +
    172  string filename
    +
    173 
    +
    174  dfref saveDF = GetDataFolderDFR()
    +
    175  setdatafolder $package_path
    +
    176  svar s_preview_file
    +
    177  svar s_preview_source
    +
    178  mtrx_load_preview("preview_image", "pearl_explorer_filepath", filename)
    +
    179  s_preview_file = filename
    +
    180  s_preview_source = ""
    +
    181  wave /z preview_image
    +
    182 
    +
    183  svar /z s_file_info
    +
    184  if (! svar_exists(s_file_info))
    +
    185  string /g s_file_info
    +
    186  endif
    +
    187  if (strlen(s_preview_file) > 0)
    +
    188  s_file_info = mtrx_load_info("pearl_explorer_filepath", filename)
    +
    189  else
    +
    190  s_file_info = ""
    +
    191  endif
    +
    192 
    +
    193  setdatafolder saveDF
    +
    194  return preview_image
    +
    195 end
    +
    196 
    +
    198 Structure errorCode
    +
    199  int32 SUCCESS
    +
    200  int32 UNKNOWN_ERROR
    +
    201  int32 ALREADY_FILE_OPEN
    +
    202  int32 EMPTY_RESULTFILE
    +
    203  int32 FILE_NOT_READABLE
    +
    204  int32 NO_NEW_BRICKLETS
    +
    205  int32 WRONG_PARAMETER
    +
    206  int32 INTERNAL_ERROR_CONVERTING_DATA
    +
    207  int32 NO_FILE_OPEN
    +
    208  int32 INVALID_RANGE
    +
    209  int32 WAVE_EXIST
    +
    210 EndStructure
    +
    211 
    +
    213 static Function initStruct(errorCode)
    +
    214  Struct errorCode &errorCode
    +
    215 
    +
    216  errorCode.SUCCESS =0
    +
    217  errorCode.UNKNOWN_ERROR=10001
    +
    218  errorCode.ALREADY_FILE_OPEN=10002
    +
    219  errorCode.EMPTY_RESULTFILE=10004
    +
    220  errorCode.FILE_NOT_READABLE=10008
    +
    221  errorCode.NO_NEW_BRICKLETS=10016
    +
    222  errorCode.WRONG_PARAMETER=10032
    +
    223  errorCode.INTERNAL_ERROR_CONVERTING_DATA=10064
    +
    224  errorCode.NO_FILE_OPEN=10128
    +
    225  errorCode.INVALID_RANGE=10256
    +
    226  errorCode.WAVE_EXIST=10512
    +
    227 
    +
    228 end
    +
    229 
    +
    232 function mtrx_load_all()
    +
    233 
    +
    234  struct errorCode errorCode
    + +
    236 
    +
    237 #if exists("MFR_OpenResultFile")
    +
    238  MFR_OpenResultFile
    +
    239  if(V_flag != errorCode.SUCCESS)
    +
    240  MFR_GetXOPErrorMessage
    +
    241  return -1
    +
    242  endif
    +
    243 
    +
    244  MFR_GetBrickletData
    +
    245  if(V_flag != errorCode.SUCCESS)
    +
    246  MFR_GetXOPErrorMessage
    +
    247  return -1
    +
    248  endif
    +
    249 
    +
    250  MFR_GetBrickletMetaData
    +
    251  if(V_flag != errorCode.SUCCESS)
    +
    252  MFR_GetXOPErrorMessage
    +
    253  return -1
    +
    254  endif
    +
    255 
    +
    256  return 0
    +
    257 #else
    +
    258  return -1
    +
    259 #endif
    +
    260 end
    +
    261 
    +
    295 function mtrx_parse_filename(fileName, resultFile, runCycle, scanCycle, channel)
    +
    296  string fileName
    +
    297  string &resultFile
    +
    298  variable &runCycle
    +
    299  variable &scanCycle
    +
    300  string &channel
    +
    301 
    +
    302  variable fileType = 0
    +
    303  resultFile = ""
    +
    304  channel = ""
    +
    305  runCycle = 0
    +
    306  scanCycle = 0
    +
    307 
    +
    308  string regexp = ""
    +
    309  string index1 = ""
    +
    310  string index2 = ""
    +
    311  string extension = ""
    +
    312 
    +
    313  if (StringMatch(fileName, "*.mtrx"))
    +
    314  regexp = "(.+)_([[:digit:]]+)\.(.+)"
    +
    315  SplitString /E=regexp fileName, resultFile, index1, extension
    +
    316  fileType = 0
    +
    317  else
    +
    318  regexp = "(.+)--([[:digit:]]+)_([[:digit:]]+)\.((.+)_mtrx)"
    +
    319  SplitString /E=regexp fileName, resultFile, index1, index2, extension, channel
    +
    320  fileType = 1
    +
    321  runCycle = str2num(index1)
    +
    322  scanCycle = str2num(index2)
    +
    323  endif
    +
    324 
    +
    325  return fileType
    +
    326 end
    +
    327 
    +
    333 function /s mtrx_split_filename(fileName, prefix, datepart, timepart)
    +
    334  string fileName
    +
    335  string &prefix
    +
    336  string &datepart
    +
    337  string &timepart
    +
    338 
    +
    339  string regexp
    +
    340  regexp = "([[:alpha:][:digit:]]+)[-_]([[:alpha:][:digit:]]+)[-_]([[:alpha:][:digit:]]+)[-_].+"
    +
    341  SplitString /E=regexp fileName, prefix, datepart, timepart
    +
    342  return datepart
    +
    343 end
    +
    344 
    +
    361 function /df mtrx_create_folder(fileName, [df_base])
    +
    362  string fileName
    +
    363  dfref df_base
    +
    364 
    +
    365  if (ParamIsDefault(df_base))
    +
    366  df_base = GetDataFolderDFR()
    +
    367  endif
    +
    368 
    +
    369  string prefix
    +
    370  string datepart
    +
    371  string timepart
    +
    372  string folderName
    +
    373 
    +
    374  mtrx_split_filename(fileName, prefix, datepart, timepart)
    +
    375  folderName = "mtrx_" + datepart + "_" + timepart
    +
    376  folderName = CleanupName(folderName, 0)
    +
    377 
    +
    378  dfref df_save = GetDataFolderDFR()
    +
    379  setdatafolder root:
    +
    380  newdatafolder /o /s $foldername
    +
    381  dfref df = GetDataFolderDFR()
    +
    382 
    +
    383  setdatafolder df_save
    +
    384  return df
    +
    385 end
    +
    386 
    +
    406 function /df mtrx_get_cycle_folder([df_base, runCycle, scanCycle])
    +
    407  dfref df_base
    +
    408  variable runCycle
    +
    409  variable scanCycle
    +
    410 
    +
    411  dfref df_save = GetDataFolderDFR()
    +
    412  dfref df_pack = $(package_path)
    +
    413  if (ParamIsDefault(df_base))
    +
    414  df_base = GetDataFolderDFR()
    +
    415  endif
    +
    416  if (ParamIsDefault(runCycle))
    +
    417  nvar /sdfr=df_pack defRunCycle = runCycle
    +
    418  runCycle = defRunCycle
    +
    419  endif
    +
    420  if (ParamIsDefault(scanCycle))
    +
    421  nvar /sdfr=df_pack defScanCycle = scanCycle
    +
    422  scanCycle = defScanCycle
    +
    423  endif
    +
    424 
    +
    425  string dfname
    +
    426  if ((runCycle >= 1) && (scanCycle >= 1))
    +
    427  sprintf dfname, "r%us%u", runCycle, scanCycle
    +
    428  setdatafolder df_base
    +
    429  dfref df = $dfname
    +
    430  if (DataFolderRefStatus(df) == 0)
    +
    431  newdatafolder $dfname
    +
    432  dfref df = $dfname
    +
    433  endif
    +
    434  else
    +
    435  dfref df = df_base
    +
    436  endif
    +
    437 
    +
    438  setdatafolder df_save
    +
    439  return df
    +
    440 end
    +
    441 
    +
    462 function mtrx_file_brickletID(resultFile, runCycle, scanCycle, channel)
    +
    463  string resultFile
    +
    464  variable runCycle
    +
    465  variable scanCycle
    +
    466  string channel
    +
    467 
    +
    468  dfref df_overview = NewFreeDataFolder()
    +
    469  variable link = 1
    +
    470  variable id = -1
    +
    471  variable idx = 0
    +
    472 
    +
    473  string resultFileName
    +
    474 #if exists("MFR_OpenResultFile")
    +
    475  struct errorCode errorCode
    + +
    477  do
    +
    478  sprintf resultFileName, "%s_%04u.mtrx", resultFile, link
    +
    479  MFR_OpenResultFile /K resultFileName
    +
    480  if(V_flag != errorCode.SUCCESS)
    +
    481  return -1
    +
    482  endif
    +
    483  MFR_CreateOverviewTable /DEST=df_overview
    +
    484  // dimension labels are: brickletID, scanCycleCount, runCycleCount, sequenceID, dimension, channelName
    +
    485  wave /t /sdfr=df_overview overviewTable
    +
    486  make /n=(dimsize(overviewTable, 0)) /i /u /free runcycles, scancycles, ids, match
    +
    487  make /n=(dimsize(overviewTable, 0)) /t /free channels
    +
    488  ids = str2num(overviewtable[p][%brickletID])
    +
    489  if (runcycle > 0)
    +
    490  runcycles = str2num(overviewtable[p][%runCycleCount])
    +
    491  else
    +
    492  runcycles = runcycle
    +
    493  endif
    +
    494  if (scancycle > 0)
    +
    495  scancycles = str2num(overviewtable[p][%scanCycleCount])
    +
    496  else
    +
    497  scancycles = scancycle
    +
    498  endif
    +
    499  if (strlen(channel) > 0)
    +
    500  channels = overviewTable[p][%channelName]
    +
    501  else
    +
    502  channels = channel
    +
    503  endif
    +
    504  Extract /FREE ids, match_ids, (scancycles == scanCycle) && (runcycles == runCycle) && (cmpstr(channels, channel) == 0)
    +
    505  if (numpnts(match_ids) > 0)
    +
    506  id = match_ids[0]
    +
    507  else
    +
    508  link += 1
    +
    509  endif
    +
    510  while (id < 0)
    +
    511 #endif
    +
    512  return id
    +
    513 end
    +
    514 
    +
    546 function mtrx_open_file(pathName, fileNameOrPath)
    +
    547  string pathName
    +
    548  string fileNameOrPath
    +
    549 
    +
    550  check_package_folder()
    +
    551  dfref df_save = GetDataFolderDFR()
    +
    552  dfref df_pack = $(package_path)
    +
    553  svar /sdfr=df_pack dataFilePath
    +
    554  svar /sdfr=df_pack resultFilePath
    +
    555  nvar /sdfr=df_pack runCycle
    +
    556  nvar /sdfr=df_pack scanCycle
    +
    557  svar /sdfr=df_pack channelName
    +
    558  nvar /sdfr=df_pack brickletID
    +
    559 
    +
    560  string loc_resultFileName
    +
    561  string loc_resultFilePath
    +
    562  variable loc_runCycle
    +
    563  variable loc_scanCycle
    +
    564  string loc_channelName
    +
    565 
    +
    566  // make sure we have a valid and complete file path
    +
    567  GetFileFolderInfo /P=$pathName /Q /Z=2 fileNameOrPath
    +
    568  string filePath
    +
    569  if ((v_flag == 0) && (v_isFile))
    +
    570  filePath = s_path
    +
    571  else
    +
    572  return -1
    +
    573  endif
    +
    574 
    +
    575  // get base file name
    +
    576  string fileName
    +
    577  string fileDir
    +
    578  string baseFileName
    +
    579  variable fileType
    +
    580  fileName = ParseFilePath(0, filePath, ":", 1, 0)
    +
    581  fileDir = ParseFilePath(1, filePath, ":", 1, 0)
    +
    582  fileType = mtrx_parse_filename(fileName, baseFileName, loc_runCycle, loc_scanCycle, loc_channelName)
    +
    583 
    +
    584  variable link = 1
    +
    585  variable id = -1
    +
    586  variable result = -1
    +
    587  variable using_cache = 0
    +
    588 
    +
    589  struct errorCode errorCode
    +
    590  initStruct(errorCode)
    +
    591  do
    +
    592  sprintf loc_resultFileName, "%s_%04u.mtrx", baseFileName, link
    +
    593  loc_resultFilePath = fileDir + loc_resultFileName
    +
    594 #if exists("MFR_OpenResultFile")
    +
    595  if ((strlen(resultFilePath) == 0) || (cmpstr(loc_resultFilePath, resultFilePath) != 0))
    +
    596  MFR_OpenResultFile /K loc_resultFilePath
    +
    597  if(V_flag != errorCode.SUCCESS)
    +
    598  MFR_GetXOPErrorMessage
    +
    599  result = -1
    +
    600  break
    +
    601  endif
    +
    602  resultFilePath = loc_resultFilePath
    +
    603  if (fileType == 1)
    +
    604  dataFilePath = filePath
    +
    605  else
    +
    606  dataFilePath = ""
    +
    607  endif
    +
    608  runCycle = 0
    +
    609  scanCycle = 0
    +
    610  channelName = ""
    +
    611  brickletID = 0
    +
    612  MFR_CreateOverviewTable /DEST=df_pack
    +
    613  if(V_flag != errorCode.SUCCESS)
    +
    614  MFR_GetXOPErrorMessage
    +
    615  result = -1
    +
    616  break
    +
    617  endif
    +
    618  using_cache = 0
    +
    619  else
    +
    620  using_cache = 1
    +
    621  endif
    +
    622 #else
    +
    623  print "matrixfilereader.xop not installed"
    +
    624  result = -2
    +
    625  break
    +
    626 #endif
    +
    627  // dimension labels are: brickletID, scanCycleCount, runCycleCount, sequenceID, dimension, channelName
    +
    628  wave /t /sdfr=df_pack overviewTable
    +
    629  make /n=(dimsize(overviewTable, 0)) /i /u /o df_pack:runCycles, df_pack:scanCycles, df_pack:ids
    +
    630  make /n=(dimsize(overviewTable, 0)) /t /o df_pack:channels
    +
    631  wave /sdfr=df_pack ids, runCycles, scanCycles
    +
    632  wave /t /sdfr=df_pack channels
    +
    633  ids = str2num(overviewtable[p][%brickletID])
    +
    634  runCycles = str2num(overviewtable[p][%runCycleCount])
    +
    635  scanCycles = str2num(overviewtable[p][%scanCycleCount])
    +
    636  channels = overviewTable[p][%channelName]
    +
    637  result = fileType
    +
    638 
    +
    639  // if a data file is opened, make sure we found the right result file
    +
    640  if ((loc_runCycle > 0) && (loc_scanCycle > 0))
    +
    641  Extract /FREE ids, match_ids, (runCycles == loc_runCycle) && (scanCycles == loc_scanCycle) && (cmpstr(channels, loc_channelName) == 0)
    +
    642  if (numpnts(match_ids) > 0)
    +
    643  id = match_ids[0]
    +
    644  runCycle = loc_runCycle
    +
    645  scanCycle = loc_scanCycle
    +
    646  channelName = loc_channelName
    +
    647  brickletID = id
    +
    648  break
    +
    649  elseif (using_cache)
    +
    650  resultFilePath = ""
    +
    651  else
    +
    652  link += 1
    +
    653  endif
    +
    654  else
    +
    655  break
    +
    656  endif
    +
    657  while (id < 0)
    +
    658 
    +
    659  return result
    +
    660 end
    +
    661 
    +
    683 function /s mtrx_load_preview(destName, pathName, fileName, [traces])
    +
    684  string destName
    +
    685  string pathName
    +
    686  string fileName
    +
    687  string traces
    +
    688 
    +
    689  if (ParamIsDefault(traces))
    +
    690  traces = "*Up;*Down;*ReUp;*ReDown;"
    +
    691  endif
    +
    692 
    +
    693  dfref df_save = GetDataFolderDFR()
    +
    694 
    +
    695  string datanames = ""
    +
    696  string datapaths = ""
    +
    697  variable filestatus = mtrx_open_file(pathName, fileName)
    +
    698  if (filestatus != 1)
    +
    699  return ""
    +
    700  endif
    +
    701 
    +
    702  dfref df_pack = $(package_path)
    +
    703  svar /sdfr=df_pack dataFilePath
    +
    704  svar /sdfr=df_pack resultFilePath
    +
    705  nvar /sdfr=df_pack runCycle
    +
    706  nvar /sdfr=df_pack scanCycle
    +
    707  svar /sdfr=df_pack channelName
    +
    708  nvar /sdfr=df_pack brickletID
    +
    709 
    +
    710 #if exists("MFR_OpenResultFile")
    +
    711  dfref df_data = df_save
    +
    712  variable /g df_data:V_MatrixFileReaderOverwrite = 1
    +
    713  variable /g df_data:V_MatrixFileReaderFolder = 0
    +
    714  variable /g df_data:V_MatrixFileReaderDouble = 0
    +
    715  struct errorCode errorCode
    +
    716  initStruct(errorCode)
    +
    717  MFR_GetBrickletData /N=destName /R=(brickletID) /S=2 /DEST=df_data
    +
    718  if(V_flag == errorCode.SUCCESS)
    +
    719  datanames = S_waveNames
    +
    720  variable i
    +
    721  variable n = ItemsInList(datanames)
    +
    722  string s
    +
    723  s = StringFromList(0, datanames)
    +
    724  wave data = $s
    +
    725  mtrx_scale_dataset(data)
    +
    726  if (WaveDims(data) == 2)
    +
    727  subtract_line_bg(data)
    +
    728  endif
    +
    729  datapaths = AddListItem(GetWavesDataFolder(data, 4), datapaths, ";", inf)
    +
    730  for (i = 1; i < n; i += 1)
    +
    731  s = StringFromList(i, datanames)
    +
    732  killwaves /z $s
    +
    733  endfor
    +
    734  else
    +
    735  MFR_GetXOPErrorMessage
    +
    736  endif
    +
    737  //MFR_GetBrickletMetaData /N=ANickName /R=(brickletID) // /DEST=dfref
    +
    738 #else
    +
    739  print "matrixfilereader.xop not installed"
    +
    740 #endif
    +
    741 
    +
    742  setdatafolder df_save
    +
    743  return datapaths
    +
    744 end
    +
    745 
    +
    768 function /s mtrx_load_file(pathName, fileName, [traces])
    +
    769  string pathName
    +
    770  string fileName
    +
    771  string traces
    +
    772 
    +
    773  if (ParamIsDefault(traces))
    +
    774  traces = "*Up;*Down;*ReUp;*ReDown;"
    +
    775  endif
    +
    776 
    +
    777  dfref df_save = GetDataFolderDFR()
    +
    778 
    +
    779  string datanames = ""
    +
    780  string datapaths = ""
    +
    781  variable filestatus = mtrx_open_file(pathName, fileName)
    +
    782  if (filestatus != 1)
    +
    783  return ""
    +
    784  endif
    +
    785 
    +
    786  dfref df_pack = $(package_path)
    +
    787  svar /sdfr=df_pack dataFilePath
    +
    788  svar /sdfr=df_pack resultFilePath
    +
    789  nvar /sdfr=df_pack runCycle
    +
    790  nvar /sdfr=df_pack scanCycle
    +
    791  svar /sdfr=df_pack channelName
    +
    792  nvar /sdfr=df_pack brickletID
    +
    793 
    +
    794 #if exists("MFR_OpenResultFile")
    +
    795  string resultFileName = ParseFilePath(0, resultFilePath, ":", 1, 0)
    +
    796  dfref df_result = mtrx_create_folder(resultFileName, df_base=df_save)
    +
    797  dfref df_data = mtrx_get_cycle_folder(df_base = df_result)
    +
    798  variable /g df_data:V_MatrixFileReaderOverwrite = 1
    +
    799  variable /g df_data:V_MatrixFileReaderFolder = 0
    +
    800  variable /g df_data:V_MatrixFileReaderDouble = 0
    +
    801 
    +
    802  struct errorCode errorCode
    +
    803  initStruct(errorCode)
    +
    804  string name
    +
    805  name = CleanupName(channelName, 0)
    +
    806  MFR_GetBrickletData /N=name /R=(brickletID) /DEST=df_data
    +
    807  if(V_flag == errorCode.SUCCESS)
    +
    808  datanames = S_waveNames
    +
    809  variable i
    +
    810  variable n = ItemsInList(datanames)
    +
    811  string s
    +
    812  for (i = 0; i < n; i += 1)
    +
    813  s = StringFromList(i, datanames)
    +
    814  wave /sdfr=df_data data = $s
    +
    815  mtrx_scale_dataset(data)
    +
    816  datapaths = AddListItem(GetWavesDataFolder(data, 4), datapaths, ";", inf)
    +
    817  endfor
    +
    818  else
    +
    819  MFR_GetXOPErrorMessage
    +
    820  endif
    +
    821  //MFR_GetBrickletMetaData /N=ANickName /R=(brickletID) // /DEST=dfref
    +
    822 #else
    +
    823  print "matrixfilereader.xop not installed"
    +
    824 #endif
    +
    825 
    +
    826  setdatafolder df_save
    +
    827  return datapaths
    +
    828 end
    +
    829 
    +
    830 function mtrx_scale_dataset(data)
    +
    831  wave data
    +
    832 
    +
    833  dfref df_pack = $(package_path)
    +
    834  nvar /sdfr=df_pack runCycle
    +
    835  nvar /sdfr=df_pack scanCycle
    +
    836  svar /sdfr=df_pack channelName
    +
    837  nvar /sdfr=df_pack brickletID
    +
    838 
    +
    839  string scanDir = StringFromList(2, NameOfWave(data), "_")
    +
    840  if (WaveDims(data) == 2)
    +
    841  Note data, "AxisLabelX=X"
    +
    842  Note data, "AxisLabelY=Y"
    +
    843  endif
    +
    844  Note data, "AxisLabelD=" + channelName
    +
    845  string title
    +
    846  sprintf title, "%u-%u %s %s", runCycle, scanCycle, channelName, scanDir
    +
    847  Note data, "Dataset=" + title
    +
    848 end
    +
    849 
    +
    864 function /s mtrx_load_info(APathName, AFileName)
    +
    865  string APathName
    +
    866  string AFileName
    +
    867 
    +
    868  dfref saveDF = GetDataFolderDFR()
    +
    869  dfref fileDF = NewFreeDataFolder()
    +
    870  setdatafolder fileDF
    +
    871 
    +
    872  variable fileID
    +
    873  string filepath
    +
    874  string scanpaths
    +
    875  variable nscans
    +
    876  variable iscan
    +
    877  string scanpath
    +
    878  string info = ""
    +
    879 
    +
    880 
    +
    881  setdatafolder saveDF
    +
    882  return info
    +
    883 end
    +
    884 
    +
    887 function subtract_line_bg(img)
    +
    888  wave img
    +
    889 
    +
    890  variable nx = dimsize(img, 0)
    +
    891  variable ny = dimsize(img, 1)
    +
    892  variable iy
    +
    893  make /n=(nx) /free line, fit
    +
    894  for (iy = 0; iy < ny; iy += 1)
    +
    895  line = img[p][iy]
    +
    896  if (numtype(sum(line)) == 0)
    +
    897  CurveFit /N /Q /NTHR=0 line line /D=fit
    +
    898  img[][iy] = line[p] - fit[p]
    +
    899  endif
    +
    900  endfor
    +
    901 end
    +
    static const string package_path
    +
    static const string package_name
    +
    variable mtrx_load_all()
    load all data from a Matrix data file.
    +
    variable mtrx_file_brickletID(string resultFile, variable runCycle, variable scanCycle, string channel)
    find out bricklet ID of a file
    +
    variable matrix_preview_2d(wave data, wave metadata)
    +
    variable mtrx_parse_filename(string fileName, string *resultFile, variable *runCycle, variable *scanCycle, string *channel)
    parse matrix file names
    +
    dfr mtrx_get_cycle_folder(dfref df_base=defaultValue, variable runCycle=defaultValue, variable scanCycle=defaultValue)
    create a data folder for bricklet data.
    +
    static variable BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind)
    open a matrix file that was dropped into Igor.
    +
    static const string ks_filematch_mtrx
    + +
    static variable AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind)
    initialize the package and reload preferences after an experiment is loaded.
    +
    string mtrx_load_info(string APathName, string AFileName)
    load descriptive info from a Matrix data file.
    +
    string matrix_format_elog_message(wave metadata)
    generate elog message from bricklet metadata
    +
    dfr mtrx_create_folder(string fileName, dfref df_base=defaultValue)
    create or look up a data folder based on a matrix file name.
    +
    static wave preview_matrix_file(string filename)
    load the preview of a Matrix data file
    +
    from matrixfilereader help
    +
    static variable initStruct(errorCode *errorCode)
    from matrixfilereader help
    +
    static variable check_package_folder()
    check that the package data folder exists
    +
    string mtrx_load_preview(string destName, string pathName, string fileName, string traces=defaultValue)
    load a preview image from a Matrix data file.
    +
    static variable init_package()
    initialize the package data folder.
    +
    string mtrx_split_filename(string fileName, string *prefix, string *datepart, string *timepart)
    split a matrix filename and return the first three parts
    diff --git a/doc/html/pearl-menu_8ipf.html b/doc/html/pearl-menu_8ipf.html index 4afcf93..f132415 100644 --- a/doc/html/pearl-menu_8ipf.html +++ b/doc/html/pearl-menu_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-menu.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -93,7 +95,7 @@ $(document).ready(function(){initNavTree('pearl-menu_8ipf.html','');});

    Functions

    string PearlMenuEnableFunc (string funcname) - check whether a function name exists More...
    + check whether a function name exists More...
      variable LoadPearlOptics ()   @@ -108,16 +110,16 @@ Functions variable DisplayGizmoSlicer ()   variable PearlLiveDisplay (string epicsname, string nickname, string wbRGB) - area detector live display More...
    + area detector live display More...
      variable PearlCameraDisplay (string epicsname, string nickname, string wbRGB) - area detector surveillance camera display More...
    + area detector surveillance camera display More...
      variable PearlAnglescanTracker (string epicsname, string wbRGB) - display the angle scan tracker window More...
    + display the angle scan tracker window More...
      variable PearlSampleTracker (variable action) - display the sample tracker window More...
    + display the sample tracker window More...
     

    Function Documentation

    @@ -136,7 +138,7 @@ Functions
    -

    Definition at line 116 of file pearl-menu.ipf.

    +

    Definition at line 117 of file pearl-menu.ipf.

    @@ -155,7 +157,7 @@ Functions
    -

    Definition at line 133 of file pearl-menu.ipf.

    +

    Definition at line 134 of file pearl-menu.ipf.

    @@ -174,7 +176,7 @@ Functions
    -

    Definition at line 152 of file pearl-menu.ipf.

    +

    Definition at line 153 of file pearl-menu.ipf.

    @@ -193,7 +195,7 @@ Functions
    -

    Definition at line 104 of file pearl-menu.ipf.

    +

    Definition at line 105 of file pearl-menu.ipf.

    @@ -212,7 +214,7 @@ Functions
    -

    Definition at line 98 of file pearl-menu.ipf.

    +

    Definition at line 99 of file pearl-menu.ipf.

    @@ -231,7 +233,7 @@ Functions
    -

    Definition at line 110 of file pearl-menu.ipf.

    +

    Definition at line 111 of file pearl-menu.ipf.

    @@ -270,7 +272,7 @@ Functions -

    Definition at line 242 of file pearl-menu.ipf.

    +

    Definition at line 243 of file pearl-menu.ipf.

    @@ -317,7 +319,7 @@ Functions -

    Definition at line 218 of file pearl-menu.ipf.

    +

    Definition at line 219 of file pearl-menu.ipf.

    @@ -354,7 +356,7 @@ Functions

    area detector live display

    -

    display an area detector channel in an ad_display_profiles() window.

    +

    display an area detector channel in an ad_display_profiles() window.

    Parameters
    @@ -364,7 +366,7 @@ Functions -

    Definition at line 185 of file pearl-menu.ipf.

    +

    Definition at line 186 of file pearl-menu.ipf.

    @@ -387,7 +389,7 @@ Functions

    check whether a function name exists

    return a prefix which disables the menu item if the function does not exist

    -

    Definition at line 89 of file pearl-menu.ipf.

    +

    Definition at line 90 of file pearl-menu.ipf.

    @@ -416,7 +418,7 @@ Functions -

    Definition at line 261 of file pearl-menu.ipf.

    +

    Definition at line 262 of file pearl-menu.ipf.

    @@ -426,9 +428,9 @@ Functions diff --git a/doc/html/pearl-menu_8ipf_source.html b/doc/html/pearl-menu_8ipf_source.html index 491133a..69dee94 100644 --- a/doc/html/pearl-menu_8ipf_source.html +++ b/doc/html/pearl-menu_8ipf_source.html @@ -1,9 +1,9 @@ - + - +PEARL Procedures: pearl-menu.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@ @@ -38,18 +35,21 @@
    epicsnamebase name of the detector, e.g. X03DA-SCIENTA: image1: and cam1: are appended by the function. see ad_connect().
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,37 +87,255 @@ $(document).ready(function(){initNavTree('pearl-menu_8ipf_source.html','');});
    pearl-menu.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=1 // Use modern global access method.
    2 #pragma ModuleName = PearlMenu
    3 #pragma version = 1.02
    4 
    5 // main menu for PEARL data acquisition and analysis packages
    6 
    7 // $Id$
    8 // author: matthias.muntwiler@psi.ch
    9 // Copyright (c) 2013-14 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 menu "PEARL"
    17 
    18  submenu "Data Files"
    19  PearlMenuEnableFunc("pearl_data_explorer") + "Data Explorer", /Q, pearl_data_explorer()
    20  help = {"Data explorer panel with file import and preview", "Requires ARPES package and HDF5 XOP"}
    21  PearlMenuEnableFunc("ad_load_dialog") + "AD HDF5", /Q, ad_load_dialog("")
    22  help = {"Import area detector HDF5 data file", "Requires ARPES package and HDF5 XOP"}
    23  end
    24 
    25  submenu "On-the-Fly Data"
    26  PearlMenuEnableFunc("otf_rename_folders") + "Shorten OTF Folder Names", /Q, otf_rename_folders("010")
    27  help = {"Renames otf_xxxxxx_yyyyyy_zzzz data folders to otf_yyyyyy (removing date and suffix)", "Requires Optics package"}
    28  PearlMenuEnableFunc("otf_gather_batch") + "Gather OTF Batch", /Q, otf_gather_batch("current_ch1", "photonenergy", "otf_batch")
    29  help = {"Copies data from all otf_* folders into otf_batch folder", "Requires Optics package"}
    30  PearlMenuEnableFunc("PearlOpticsPreviewPanel") + "OTF Preview", /Q, PearlOpticsPreviewPanel()
    31  help = {"Opens a preview panel for OTF data in otf_* folders", "Requires Optics package"}
    32  end
    33 
    34  submenu "Scienta Analyser"
    35  PearlMenuEnableFunc("ad_display_profiles") + "Scienta Live View", /Q, PearlLiveDisplay("X03DA-SCIENTA:", "EA", "(65280,54528,48896)")
    36  help = {"Display preview panel with latest image from Scienta", "Requires ARPES package and EPICS XOP"}
    37  PearlMenuEnableFunc("ast_setup") + "Angle Scan Tracker", /Q, PearlAnglescanTracker("X03DA-SCIENTA:", "(65280,54528,48896)")
    38  help = {"Preview of acquired angle scan data and current detection angles.", "Requires ARPES package and EPICS XOP"}
    39  PearlMenuEnableFunc("sample_tracker") + "Sample Tracker", /Q, PearlSampleTracker(1)
    40  help = {"Live tracking and adjustment of sample position.", "Requires ARPES package and EPICS XOP"}
    41  end
    42 
    43  submenu "Cameras"
    44  PearlMenuEnableFunc("ad_display_profiles") + "Exit Slit Camera", /Q, PearlLiveDisplay("X03DA-OP-PS1:", "OP", "(65280,54528,48896)")
    45  help = {"Display preview panel with latest image from Scienta", "Requires ARPES package and EPICS XOP"}
    46  PearlMenuEnableFunc("ad_display_profiles") + "Manipulator Camera", /Q, PearlCameraDisplay("X03DA-ES-PS1:", "ES", "(32767,32767,32767)")
    47  help = {"Display live panel of the exit slit camera", "Requires ARPES package and EPICS XOP"}
    48  end
    49 
    50  submenu "Display"
    51  PearlMenuEnableFunc("ad_display_profiles") + "2D Profiles", /Q, Display2dProfiles()
    52  help = {"Profiles display of 2D data", "Requires ARPES package"}
    53  PearlMenuEnableFunc("ad_display_brick") + "3D Slicer", /Q, Display3dSlicer()
    54  help = {"Slice and profiles display of 3D data", "Requires ARPES package"}
    55  PearlMenuEnableFunc("ad_display_brick") + "3D Gizmo", /Q, DisplayGizmoSlicer()
    56  help = {"Gizmo display of 3D data", "Requires ARPES package"}
    57  end
    58 
    59  submenu "Process"
    60  PearlMenuEnableFunc("asp_show_panel") + "XPD scans", /Q, asp_show_panel()
    61  help = {"Data processing of two-pi angle scans", "Requires ARPES package"}
    62  end
    63 
    64  submenu "Services"
    65  PearlMenuEnableFunc("pearl_elog") + "Open ELOG Panel", /Q, pearl_elog("")
    66  help = {"Open an ELOG panel to send entries to an ELOG logbook"}
    67  end
    68 
    69  submenu "Sample Preparation"
    70  PearlMenuEnableFunc("ramp_generator") + "Annealing Ramp", /Q, ramp_generator()
    71  help = {"Sample annealing ramp generator"}
    72  end
    73 
    74  submenu "Packages"
    75  "Load ARPES Package", /Q, LoadPearlArpes()
    76  help = {"Data processing and analysis for ARPES experiments"}
    77  "Load Preparation Package", /Q, LoadPearlPreparation()
    78  help = {"Process control for sample preparation"}
    79  "Load Optics Package", /Q, LoadPearlOptics()
    80  help = {"Data processing and analysis for beamline commissioning"}
    81  end
    82 end
    83 
    89 function /s PearlMenuEnableFunc(funcname)
    90  string funcname
    91  if (exists(funcname) >= 3)
    92  return ""
    93  else
    94  return "("
    95  endif
    96 end
    97 
    98 function LoadPearlOptics()
    99  execute /p/q/z "INSERTINCLUDE \"pearl-optics\""
    100  execute /p/q/z "COMPILEPROCEDURES "
    101  execute /p/q/z "BuildMenu \"PEARL\""
    102 end
    103 
    104 function LoadPearlArpes()
    105  execute /p/q/z "INSERTINCLUDE \"pearl-arpes\""
    106  execute /p/q/z "COMPILEPROCEDURES "
    107  execute /p/q/z "BuildMenu \"PEARL\""
    108 end
    109 
    111  execute /p/q/z "INSERTINCLUDE \"pearl-preparation\""
    112  execute /p/q/z "COMPILEPROCEDURES "
    113  execute /p/q/z "BuildMenu \"PEARL\""
    114 end
    115 
    117  dfref dfBefore = GetDataFolderDFR()
    118  Execute /q/z "CreateBrowser prompt=\"Select 2D wave\", showWaves=1, showVars=0, showStrs=0"
    119  dfref dfAfter = GetDataFolderDFR()
    120  SetDataFolder dfBefore
    121 
    122  SVAR list = S_BrowserList
    123  NVAR flag = V_Flag
    124 
    125  if ((flag != 0) && (ItemsInList(list) >= 1))
    126  string brickname = StringFromList(0, list)
    127  string cmd
    128  sprintf cmd, "ad_display_profiles(%s)", brickname
    129  execute /q/z cmd
    130  endif
    131 end
    132 
    133 function Display3dSlicer()
    134  dfref dfBefore = GetDataFolderDFR()
    135  Execute /q/z "CreateBrowser prompt=\"Select 3D wave\", showWaves=1, showVars=0, showStrs=0"
    136  dfref dfAfter = GetDataFolderDFR()
    137  SetDataFolder dfBefore
    138 
    139  SVAR list = S_BrowserList
    140  NVAR flag = V_Flag
    141 
    142  if ((flag != 0) && (ItemsInList(list) >= 1))
    143  string brickname = StringFromList(0, list)
    144  string cmd
    145  sprintf cmd, "ad_display_slice(%s)", brickname
    146  execute /q/z cmd
    147  sprintf cmd, "ad_brick_slicer(%s)", brickname
    148  execute /q/z cmd
    149  endif
    150 end
    151 
    153  dfref dfBefore = GetDataFolderDFR()
    154  Execute /q/z "CreateBrowser prompt=\"Select 3D wave\", showWaves=1, showVars=0, showStrs=0"
    155  dfref dfAfter = GetDataFolderDFR()
    156  SetDataFolder dfBefore
    157 
    158  SVAR list = S_BrowserList
    159  NVAR flag = V_Flag
    160 
    161  if ((flag != 0) && (ItemsInList(list) >= 1))
    162  string brickname = StringFromList(0, list)
    163  string cmd
    164  sprintf cmd, "ad_display_brick(%s)", brickname
    165  execute /q/z cmd
    166  sprintf cmd, "ad_brick_slicer(%s)", brickname
    167  execute /q/z cmd
    168  endif
    169 end
    170 
    185 function PearlLiveDisplay(epicsname, nickname, wbRGB)
    186  string epicsname
    187  string nickname
    188  string wbRGB
    189 
    190  string cmd
    191  sprintf cmd, "ad_connect(\"%s\", \"%s\")", epicsname, nickname
    192  execute /q/z cmd
    193  sprintf cmd, "ad_display_profiles(root:pearl_epics:%s:image)", nickname
    194  execute /q/z cmd
    195  //sprintf cmd, "ad_add_overlay(root:pearl_epics:%s:image)", nickname
    196  //execute /q/z cmd
    197  sprintf cmd, "ModifyGraph wbRGB=%s", wbRGB
    198  execute /q/z cmd
    199  sprintf cmd, "add_roi_controls()"
    200  execute /q/z cmd
    201 end
    202 
    218 function PearlCameraDisplay(epicsname, nickname, wbRGB)
    219  string epicsname
    220  string nickname
    221  string wbRGB
    222 
    223  string cmd
    224  sprintf cmd, "ad_connect(\"%s\", \"%s\")", epicsname, nickname
    225  execute /q/z cmd
    226  sprintf cmd, "display; appendimage root:pearl_epics:%s:image", nickname
    227  execute /q/z cmd
    228  sprintf cmd, "ModifyGraph wbRGB=%s", wbRGB
    229  execute /q/z cmd
    230  cmd = "ModifyGraph height={Plan,1,left,bottom}"
    231  execute /q/z cmd
    232 end
    233 
    242 function PearlAnglescanTracker(epicsname, wbRGB)
    243  string epicsname
    244  string wbRGB
    245 
    246  string cmd
    247  sprintf cmd, "ast_setup()"
    248  execute /q/z cmd
    249  sprintf cmd, "ModifyGraph wbRGB=%s", wbRGB
    250  execute /q/z cmd
    251 end
    252 
    261 function PearlSampleTracker(action)
    262  variable action
    263  string cmd
    264  sprintf cmd, "sample_tracker(%u)", action
    265  execute /q/z cmd
    266 end
    267 
    variable PearlLiveDisplay(string epicsname, string nickname, string wbRGB)
    area detector live display
    Definition: pearl-menu.ipf:185
    -
    variable DisplayGizmoSlicer()
    Definition: pearl-menu.ipf:152
    -
    variable ad_load_dialog(string APathName)
    load area detector data files selected in a file dialog window
    -
    variable ad_brick_slicer(wave data)
    open a slicer panel for 3D data.
    -
    variable ast_setup()
    set up data structures, display graph, and try to connect to analyser.
    -
    variable LoadPearlPreparation()
    Definition: pearl-menu.ipf:110
    -
    variable PearlAnglescanTracker(string epicsname, string wbRGB)
    display the angle scan tracker window
    Definition: pearl-menu.ipf:242
    -
    variable LoadPearlArpes()
    Definition: pearl-menu.ipf:104
    -
    variable LoadPearlOptics()
    Definition: pearl-menu.ipf:98
    -
    variable PearlSampleTracker(variable action)
    display the sample tracker window
    Definition: pearl-menu.ipf:261
    -
    variable PearlCameraDisplay(string epicsname, string nickname, string wbRGB)
    area detector surveillance camera display
    Definition: pearl-menu.ipf:218
    -
    variable Display3dSlicer()
    Definition: pearl-menu.ipf:133
    -
    variable otf_gather_batch(string ywavematch, string xwavematch, string destfolder)
    -
    variable asp_show_panel()
    create the angle scan processing panel
    -
    variable otf_rename_folders(string pattern, variable unique_index=defaultValue, string new_suffix=defaultValue, string match_str=defaultValue)
    -
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    -
    variable pearl_data_explorer()
    -
    string PearlMenuEnableFunc(string funcname)
    check whether a function name exists
    Definition: pearl-menu.ipf:89
    -
    string ad_display_slice(wave data)
    display three-dimensional data by 2D slice.
    -
    variable pearl_elog(string logbook)
    main function to initialize ELOG and to open an ELOG panel.
    Definition: pearl-elog.ipf:97
    -
    string ad_display_brick(wave data)
    open a new "gizmo" window with three-dimensional data.
    -
    variable Display2dProfiles()
    Definition: pearl-menu.ipf:116
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=1 // Use modern global access method.
    +
    3 #pragma ModuleName = PearlMenu
    +
    4 #pragma version = 1.02
    +
    5 
    +
    6 // main menu for PEARL data acquisition and analysis packages
    +
    7 
    +
    8 // $Id$
    +
    9 // author: matthias.muntwiler@psi.ch
    +
    10 // Copyright (c) 2013-14 Paul Scherrer Institut
    +
    11 
    +
    12 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    13 // you may not use this file except in compliance with the License.
    +
    14 // You may obtain a copy of the License at
    +
    15 // http://www.apache.org/licenses/LICENSE-2.0
    +
    16 
    +
    17 menu "PEARL"
    +
    18 
    +
    19  submenu "Data Files"
    +
    20  PearlMenuEnableFunc("pearl_data_explorer") + "Data Explorer", /Q, pearl_data_explorer()
    +
    21  help = {"Data explorer panel with file import and preview", "Requires ARPES package and HDF5 XOP"}
    +
    22  PearlMenuEnableFunc("ad_load_dialog") + "AD HDF5", /Q, ad_load_dialog("")
    +
    23  help = {"Import area detector HDF5 data file", "Requires ARPES package and HDF5 XOP"}
    +
    24  end
    +
    25 
    +
    26  submenu "On-the-Fly Data"
    +
    27  PearlMenuEnableFunc("otf_rename_folders") + "Shorten OTF Folder Names", /Q, otf_rename_folders("010")
    +
    28  help = {"Renames otf_xxxxxx_yyyyyy_zzzz data folders to otf_yyyyyy (removing date and suffix)", "Requires Optics package"}
    +
    29  PearlMenuEnableFunc("otf_gather_batch") + "Gather OTF Batch", /Q, otf_gather_batch("current_ch1", "photonenergy", "otf_batch")
    +
    30  help = {"Copies data from all otf_* folders into otf_batch folder", "Requires Optics package"}
    +
    31  PearlMenuEnableFunc("PearlOpticsPreviewPanel") + "OTF Preview", /Q, PearlOpticsPreviewPanel()
    +
    32  help = {"Opens a preview panel for OTF data in otf_* folders", "Requires Optics package"}
    +
    33  end
    +
    34 
    +
    35  submenu "Scienta Analyser"
    +
    36  PearlMenuEnableFunc("ad_display_profiles") + "Scienta Live View", /Q, PearlLiveDisplay("X03DA-SCIENTA:", "EA", "(65280,54528,48896)")
    +
    37  help = {"Display preview panel with latest image from Scienta", "Requires ARPES package and EPICS XOP"}
    +
    38  PearlMenuEnableFunc("ast_setup") + "Angle Scan Tracker", /Q, PearlAnglescanTracker("X03DA-SCIENTA:", "(65280,54528,48896)")
    +
    39  help = {"Preview of acquired angle scan data and current detection angles.", "Requires ARPES package and EPICS XOP"}
    +
    40  PearlMenuEnableFunc("sample_tracker") + "Sample Tracker", /Q, PearlSampleTracker(1)
    +
    41  help = {"Live tracking and adjustment of sample position.", "Requires ARPES package and EPICS XOP"}
    +
    42  end
    +
    43 
    +
    44  submenu "Cameras"
    +
    45  PearlMenuEnableFunc("ad_display_profiles") + "Exit Slit Camera", /Q, PearlLiveDisplay("X03DA-OP-PS1:", "OP", "(65280,54528,48896)")
    +
    46  help = {"Display preview panel with latest image from Scienta", "Requires ARPES package and EPICS XOP"}
    +
    47  PearlMenuEnableFunc("ad_display_profiles") + "Manipulator Camera", /Q, PearlCameraDisplay("X03DA-ES-PS1:", "ES", "(32767,32767,32767)")
    +
    48  help = {"Display live panel of the exit slit camera", "Requires ARPES package and EPICS XOP"}
    +
    49  end
    +
    50 
    +
    51  submenu "Display"
    +
    52  PearlMenuEnableFunc("ad_display_profiles") + "2D Profiles", /Q, Display2dProfiles()
    +
    53  help = {"Profiles display of 2D data", "Requires ARPES package"}
    +
    54  PearlMenuEnableFunc("ad_display_brick") + "3D Slicer", /Q, Display3dSlicer()
    +
    55  help = {"Slice and profiles display of 3D data", "Requires ARPES package"}
    +
    56  PearlMenuEnableFunc("ad_display_brick") + "3D Gizmo", /Q, DisplayGizmoSlicer()
    +
    57  help = {"Gizmo display of 3D data", "Requires ARPES package"}
    +
    58  end
    +
    59 
    +
    60  submenu "Process"
    +
    61  PearlMenuEnableFunc("asp_show_panel") + "XPD scans", /Q, asp_show_panel()
    +
    62  help = {"Data processing of two-pi angle scans", "Requires ARPES package"}
    +
    63  end
    +
    64 
    +
    65  submenu "Services"
    +
    66  PearlMenuEnableFunc("pearl_elog") + "Open ELOG Panel", /Q, pearl_elog("")
    +
    67  help = {"Open an ELOG panel to send entries to an ELOG logbook"}
    +
    68  end
    +
    69 
    +
    70  submenu "Sample Preparation"
    +
    71  PearlMenuEnableFunc("ramp_generator") + "Annealing Ramp", /Q, ramp_generator()
    +
    72  help = {"Sample annealing ramp generator"}
    +
    73  end
    +
    74 
    +
    75  submenu "Packages"
    +
    76  "Load ARPES Package", /Q, LoadPearlArpes()
    +
    77  help = {"Data processing and analysis for ARPES experiments"}
    +
    78  "Load Preparation Package", /Q, LoadPearlPreparation()
    +
    79  help = {"Process control for sample preparation"}
    +
    80  "Load Optics Package", /Q, LoadPearlOptics()
    +
    81  help = {"Data processing and analysis for beamline commissioning"}
    +
    82  end
    +
    83 end
    +
    84 
    +
    90 function /s PearlMenuEnableFunc(funcname)
    +
    91  string funcname
    +
    92  if (exists(funcname) >= 3)
    +
    93  return ""
    +
    94  else
    +
    95  return "("
    +
    96  endif
    +
    97 end
    +
    98 
    +
    99 function LoadPearlOptics()
    +
    100  execute /p/q/z "INSERTINCLUDE \"pearl-optics\""
    +
    101  execute /p/q/z "COMPILEPROCEDURES "
    +
    102  execute /p/q/z "BuildMenu \"PEARL\""
    +
    103 end
    +
    104 
    +
    105 function LoadPearlArpes()
    +
    106  execute /p/q/z "INSERTINCLUDE \"pearl-arpes\""
    +
    107  execute /p/q/z "COMPILEPROCEDURES "
    +
    108  execute /p/q/z "BuildMenu \"PEARL\""
    +
    109 end
    +
    110 
    + +
    112  execute /p/q/z "INSERTINCLUDE \"pearl-preparation\""
    +
    113  execute /p/q/z "COMPILEPROCEDURES "
    +
    114  execute /p/q/z "BuildMenu \"PEARL\""
    +
    115 end
    +
    116 
    + +
    118  dfref dfBefore = GetDataFolderDFR()
    +
    119  Execute /q/z "CreateBrowser prompt=\"Select 2D wave\", showWaves=1, showVars=0, showStrs=0"
    +
    120  dfref dfAfter = GetDataFolderDFR()
    +
    121  SetDataFolder dfBefore
    +
    122 
    +
    123  SVAR list = S_BrowserList
    +
    124  NVAR flag = V_Flag
    +
    125 
    +
    126  if ((flag != 0) && (ItemsInList(list) >= 1))
    +
    127  string brickname = StringFromList(0, list)
    +
    128  string cmd
    +
    129  sprintf cmd, "ad_display_profiles(%s)", brickname
    +
    130  execute /q/z cmd
    +
    131  endif
    +
    132 end
    +
    133 
    +
    134 function Display3dSlicer()
    +
    135  dfref dfBefore = GetDataFolderDFR()
    +
    136  Execute /q/z "CreateBrowser prompt=\"Select 3D wave\", showWaves=1, showVars=0, showStrs=0"
    +
    137  dfref dfAfter = GetDataFolderDFR()
    +
    138  SetDataFolder dfBefore
    +
    139 
    +
    140  SVAR list = S_BrowserList
    +
    141  NVAR flag = V_Flag
    +
    142 
    +
    143  if ((flag != 0) && (ItemsInList(list) >= 1))
    +
    144  string brickname = StringFromList(0, list)
    +
    145  string cmd
    +
    146  sprintf cmd, "ad_display_slice(%s)", brickname
    +
    147  execute /q/z cmd
    +
    148  sprintf cmd, "ad_brick_slicer(%s)", brickname
    +
    149  execute /q/z cmd
    +
    150  endif
    +
    151 end
    +
    152 
    + +
    154  dfref dfBefore = GetDataFolderDFR()
    +
    155  Execute /q/z "CreateBrowser prompt=\"Select 3D wave\", showWaves=1, showVars=0, showStrs=0"
    +
    156  dfref dfAfter = GetDataFolderDFR()
    +
    157  SetDataFolder dfBefore
    +
    158 
    +
    159  SVAR list = S_BrowserList
    +
    160  NVAR flag = V_Flag
    +
    161 
    +
    162  if ((flag != 0) && (ItemsInList(list) >= 1))
    +
    163  string brickname = StringFromList(0, list)
    +
    164  string cmd
    +
    165  sprintf cmd, "ad_display_brick(%s)", brickname
    +
    166  execute /q/z cmd
    +
    167  sprintf cmd, "ad_brick_slicer(%s)", brickname
    +
    168  execute /q/z cmd
    +
    169  endif
    +
    170 end
    +
    171 
    +
    186 function PearlLiveDisplay(epicsname, nickname, wbRGB)
    +
    187  string epicsname
    +
    188  string nickname
    +
    189  string wbRGB
    +
    190 
    +
    191  string cmd
    +
    192  sprintf cmd, "ad_connect(\"%s\", \"%s\")", epicsname, nickname
    +
    193  execute /q/z cmd
    +
    194  sprintf cmd, "ad_display_profiles(root:pearl_epics:%s:image)", nickname
    +
    195  execute /q/z cmd
    +
    196  //sprintf cmd, "ad_add_overlay(root:pearl_epics:%s:image)", nickname
    +
    197  //execute /q/z cmd
    +
    198  sprintf cmd, "ModifyGraph wbRGB=%s", wbRGB
    +
    199  execute /q/z cmd
    +
    200  sprintf cmd, "add_roi_controls()"
    +
    201  execute /q/z cmd
    +
    202 end
    +
    203 
    +
    219 function PearlCameraDisplay(epicsname, nickname, wbRGB)
    +
    220  string epicsname
    +
    221  string nickname
    +
    222  string wbRGB
    +
    223 
    +
    224  string cmd
    +
    225  sprintf cmd, "ad_connect(\"%s\", \"%s\")", epicsname, nickname
    +
    226  execute /q/z cmd
    +
    227  sprintf cmd, "display; appendimage root:pearl_epics:%s:image", nickname
    +
    228  execute /q/z cmd
    +
    229  sprintf cmd, "ModifyGraph wbRGB=%s", wbRGB
    +
    230  execute /q/z cmd
    +
    231  cmd = "ModifyGraph height={Plan,1,left,bottom}"
    +
    232  execute /q/z cmd
    +
    233 end
    +
    234 
    +
    243 function PearlAnglescanTracker(epicsname, wbRGB)
    +
    244  string epicsname
    +
    245  string wbRGB
    +
    246 
    +
    247  string cmd
    +
    248  sprintf cmd, "ast_setup()"
    +
    249  execute /q/z cmd
    +
    250  sprintf cmd, "ModifyGraph wbRGB=%s", wbRGB
    +
    251  execute /q/z cmd
    +
    252 end
    +
    253 
    +
    262 function PearlSampleTracker(action)
    +
    263  variable action
    +
    264  string cmd
    +
    265  sprintf cmd, "sample_tracker(%u)", action
    +
    266  execute /q/z cmd
    +
    267 end
    +
    268 
    +
    variable pearl_data_explorer()
    show the pearl data explorer window
    +
    string ad_display_slice(wave data)
    display three-dimensional data by 2D slice.
    +
    variable PearlCameraDisplay(string epicsname, string nickname, string wbRGB)
    area detector surveillance camera display
    Definition: pearl-menu.ipf:219
    +
    variable otf_gather_batch(string ywavematch, string xwavematch, string destfolder)
    +
    variable PearlSampleTracker(variable action)
    display the sample tracker window
    Definition: pearl-menu.ipf:262
    +
    variable ad_load_dialog(string APathName)
    load area detector data files selected in a file dialog window
    +
    variable LoadPearlPreparation()
    Definition: pearl-menu.ipf:111
    +
    string ad_display_brick(wave data)
    open a new "gizmo" window with three-dimensional data.
    +
    variable DisplayGizmoSlicer()
    Definition: pearl-menu.ipf:153
    +
    variable pearl_elog(string logbook)
    main function to initialize ELOG and to open an ELOG panel.
    Definition: pearl-elog.ipf:98
    +
    variable asp_show_panel()
    create the angle scan processing panel
    +
    variable Display3dSlicer()
    Definition: pearl-menu.ipf:134
    +
    variable LoadPearlOptics()
    Definition: pearl-menu.ipf:99
    +
    variable PearlAnglescanTracker(string epicsname, string wbRGB)
    display the angle scan tracker window
    Definition: pearl-menu.ipf:243
    +
    variable ast_setup()
    set up data structures, display graph, and try to connect to analyser.
    +
    variable Display2dProfiles()
    Definition: pearl-menu.ipf:117
    +
    variable PearlLiveDisplay(string epicsname, string nickname, string wbRGB)
    area detector live display
    Definition: pearl-menu.ipf:186
    +
    string PearlMenuEnableFunc(string funcname)
    check whether a function name exists
    Definition: pearl-menu.ipf:90
    +
    string ad_display_profiles(wave image, string filter=defaultValue)
    open a new profiles graph window.
    +
    variable ad_brick_slicer(wave data)
    open a slicer panel for 3D data.
    +
    variable otf_rename_folders(string pattern, variable unique_index=defaultValue, string new_suffix=defaultValue, string match_str=defaultValue)
    +
    variable LoadPearlArpes()
    Definition: pearl-menu.ipf:105
    diff --git a/doc/html/pearl-otf-import_8ipf.html b/doc/html/pearl-otf-import_8ipf.html index 2624645..4d19606 100644 --- a/doc/html/pearl-otf-import_8ipf.html +++ b/doc/html/pearl-otf-import_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-otf-import.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -464,9 +466,9 @@ Functions diff --git a/doc/html/pearl-otf-import_8ipf_source.html b/doc/html/pearl-otf-import_8ipf_source.html index ac78ca0..d1bba61 100644 --- a/doc/html/pearl-otf-import_8ipf_source.html +++ b/doc/html/pearl-otf-import_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-otf-import.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,26 +87,340 @@ $(document).ready(function(){initNavTree('pearl-otf-import_8ipf_source.html','')
    pearl-otf-import.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=1 // Use modern global access method.
    2 #pragma IgorVersion = 6.1
    3 #pragma ModuleName = PearlOtfImport
    4 #pragma version = 1.01
    5 
    6 // procedures for importing on-the-fly (OTF) scans
    7 // OTF scans are saved as ITX files
    8 // matthias muntwiler, 2013-02-22
    9 // $Id$
    10 
    11 // introduction
    12 // the latest version of the PEARL OTF server saves data in igor text (ITX)
    13 // the files contain code which saves all data from one file into one data folder with a unique name
    14 // multiple files can be selected in the explorer and loaded by a double click
    15 
    16 // description
    17 // OTF data folder names have the format otf_date_time_suffix, where only suffix is user-defined
    18 // thus, raw data folder names are unique
    19 // data folder names can be converted to a shorter format
    20 // an OTF data folder contains a wave for each measured quantity (detector)
    21 // and the IN, ID, IV, and IU waves for additional beamline parameters
    22 // detector waves must have a wave note containing the following key=value pairs:
    23 // PV=name of EPICS process variable
    24 // PhysicalType=physical type of the quantity in the same way as used by pearl-optics-import
    25 // Axis1=wave name of principal X axis
    26 
    27 // convergence
    28 // while the file formats may be different, data files generated by the OTF and EPICS scan tools
    29 // shall ultimately produce the same data structures in an Igor experiment
    30 
    31 function otf_load_itx_all(pathname)
    32  // loads all OTF files from a given path
    33  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
    34  // newer files can be loaded by double click from the explorer
    35  // without the danger of overwriting data from other files
    36  string pathname
    37  string filename
    38 
    39  if (strlen(pathname) <= 0)
    40  newpath /o/q otf_load_itx
    41  pathname = "otf_load_itx"
    42  endif
    43  string filelist = IndexedFile($pathname, -1, ".itx")
    44  filelist = ListMatch(filelist, "otf*.itx", ";")
    45  variable nfile = ItemsInList(filelist, ";")
    46  variable ifile
    47  for (ifile = 0; ifile < nfile; ifile += 1)
    48  filename = StringFromList(ifile, filelist, ";")
    49  otf_load_itx(pathname, filename)
    50  endfor
    51 end
    52 
    53 function otf_load_itx_match(pathname, matchstr)
    54  // loads all OTF files from a given path whose names match a given string
    55  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
    56  // newer files can be loaded by double click from the explorer
    57  // without the danger of overwriting data from other files
    58  string pathname
    59  string matchstr
    60  string filename
    61 
    62  if (strlen(pathname) <= 0)
    63  newpath /o/q otf_load_itx
    64  pathname = "otf_load_itx"
    65  endif
    66  string filelist = IndexedFile($pathname, -1, ".itx")
    67  filelist = ListMatch(filelist, matchstr, ";")
    68  variable nfile = ItemsInList(filelist, ";")
    69  variable ifile
    70  for (ifile = 0; ifile < nfile; ifile += 1)
    71  filename = StringFromList(ifile, filelist, ";")
    72  otf_load_itx(pathname, filename)
    73  endfor
    74 end
    75 
    76 function otf_load_itx(pathname, filename)
    77  // loads a specific OTF file
    78  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
    79  // newer files can be loaded by double click from the explorer
    80  // without the danger of overwriting data from other files
    81  string pathname
    82  string filename
    83 
    84  dfref savedf = GetDataFolderDFR()
    85  setdatafolder root:
    86 
    87  newdatafolder /s/o otf_load_itx_temp
    88  if (strlen(pathname) > 0)
    89  LoadWave /O/P=$pathname/Q/T filename
    90  else
    91  LoadWave /O/Q/T filename
    92  endif
    93  if (v_flag)
    94  string foldername
    95  foldername = ParseFilePath(3, s_filename, "/", 0, 0)
    96  foldername = foldername[0,16]
    97  foldername = CleanupName(foldername, 0)
    98  //foldername = UniqueName(foldername, 11, 0)
    99  renamedatafolder root:otf_load_itx_temp, $foldername
    100  printf "loaded otf data from file %s into folder %s\r", s_filename, foldername
    101  endif
    102 
    103  setdatafolder savedf
    104 end
    105 
    106 function otf_gather_iterator(df, sdata)
    107  // data folder iterator used by otf_gather_batch
    108  dfref df
    109  string &sdata // key=value list of parameters
    110  // xwavematch
    111  // ywavematch
    112  // destfolder
    113 
    114  string src_name
    115  string dst_name
    116  string src_folder
    117  string dst_folder
    118  string df_id
    119  string prefix, sdate, stime
    120 
    121  setdatafolder df
    122  src_folder = GetDataFolder(0, df)
    123  sscanf src_folder, "%[^_]_%[0-9]_%[0-9]", prefix, sdate, stime
    124  df_id = ""
    125  if (strlen(sdate) > 0)
    126  df_id += "_" + sdate
    127  endif
    128  if (strlen(stime) > 0)
    129  df_id += "_" + stime
    130  endif
    131  dst_folder = StringByKey("destfolder", sdata)
    132 
    133  src_name = StringByKey("xwavematch", sdata)
    134  src_name = WaveList(src_name, "", "")
    135  if (ItemsInList(src_name) >= 1)
    136  src_name = StringFromList(0, src_name)
    137  dst_name = dst_folder + src_name + df_id
    138  //print src_name, dst_name
    139  duplicate $src_name, $dst_name
    140  endif
    141 
    142  src_name = StringByKey("ywavematch", sdata)
    143  src_name = WaveList(src_name, "", "")
    144  if (ItemsInList(src_name) >= 1)
    145  src_name = StringFromList(0, src_name)
    146  dst_name = dst_folder + src_name + df_id
    147  //print src_name, dst_name
    148  duplicate $src_name, $dst_name
    149  endif
    150 end
    151 
    152 function otf_gather_batch(ywavematch, xwavematch, destfolder)
    153  // gathers (copies) OTF datasets in one data folder
    154  // can be used for example for the Igor batch curve fitting tool
    155  string ywavematch // match string identifies the y wave to be copied
    156  string xwavematch // match string identifies the x wave to be copied
    157  string destfolder // name of the destination data folder. folder does not have to exist.
    158 
    159  return gather_batch("otf*", ywavematch, xwavematch, destfolder)
    160 end
    161 
    162 function gather_batch(foldermatch, ywavematch, xwavematch, destfolder)
    163  // gathers (copies) OTF datasets in one data folder
    164  // can be used for example for the Igor batch curve fitting tool
    165  string foldermatch // match string to select data folders, e.g. "otf*"
    166  string ywavematch // match string identifies the y wave to be copied
    167  string xwavematch // match string identifies the x wave to be copied
    168  string destfolder // name of the destination data folder. folder does not have to exist.
    169 
    170  dfref savedf = GetDataFolderDFR()
    171  newdatafolder /o/s $destfolder
    172  destfolder = GetDataFolder(1)
    173 
    174  string iteratordata = ""
    175  iteratordata = ReplaceStringByKey("xwavematch", iteratordata, xwavematch)
    176  iteratordata = ReplaceStringByKey("ywavematch", iteratordata, ywavematch)
    177  iteratordata = ReplaceStringByKey("destfolder", iteratordata, destfolder)
    178 
    179  setdatafolder savedf
    180  iteratordata = IterateDataFolders(foldermatch, otf_gather_iterator, iteratordata)
    181 
    182  setdatafolder savedf
    183 end
    184 
    185 function otf_rename_folders_iterator(df, sdata)
    186  // data folder iterator used by otf_rename_folders
    187  dfref df
    188  string &sdata // key=value list of parameters
    189 
    190  string pattern = StringByKey("pattern", sdata)
    191  variable unique_index = NumberByKey("unique_index", sdata)
    192  string new_suffix = StringByKey("new_suffix", sdata)
    193 
    194  string src_folder
    195  string dst_folder
    196  string sprefix, sdate, stime, ssuffix
    197 
    198  setdatafolder df
    199  src_folder = GetDataFolder(0, df)
    200  sprefix = "otf"
    201  sscanf src_folder, "otf_%[0-9]_%[0-9]%s", sdate, stime, ssuffix
    202  // return early if folder name does not match the expected pattern
    203  if ((strlen(sdate) == 0) || (strlen(stime) == 0))
    204  return 1
    205  endif
    206 
    207  dst_folder = sprefix
    208  if (cmpstr(pattern[0], "0") != 0)
    209  dst_folder += "_" + sdate
    210  endif
    211  if (cmpstr(pattern[1], "0") != 0)
    212  dst_folder += "_" + stime
    213  endif
    214  if (cmpstr(pattern[2], "0") != 0)
    215  if (strlen(new_suffix) > 0)
    216  ssuffix = "_" + new_suffix
    217  endif
    218  dst_folder += ssuffix
    219  endif
    220 
    221  if ((unique_index > 0) || (CheckName(dst_folder, 11) != 0))
    222  dst_folder = UniqueName(dst_folder + "_", 11, unique_index)
    223  endif
    224 
    225  setdatafolder ::
    226  print src_folder + " -> " + dst_folder
    227  RenameDataFolder $src_folder, $dst_folder
    228  return 0
    229 end
    230 
    231 function otf_rename_folders(pattern, [unique_index, new_suffix, match_str])
    232  // renames OTF data folders by omitting parts of the file name
    233  string pattern // string of zeros and ones indicates which name parts to keep
    234  // pos 1: date
    235  // pos 2: time
    236  // pos 3: custom suffix
    237  variable unique_index // if you remove date and time,
    238  // this start index will be used to make names unique
    239  // if non-zero, new names will be forced to include a unique index
    240  // if zero (default), new names will get a unique index only in case of a conflict
    241  // optional, defaults to 0
    242  string new_suffix
    243  // replace old suffix by this one
    244  // if empty (default), the old suffix will be kept
    245  // optional, defaults to empty string
    246  string match_str // match folder name to rename
    247  // optional, defaults to "otf*" (matches all OTF folders)
    248 
    249  dfref savedf = GetDataFolderDFR()
    250 
    251  if (ParamIsDefault(unique_index))
    252  unique_index = 0
    253  endif
    254  if (ParamIsDefault(new_suffix))
    255  new_suffix = ""
    256  endif
    257  if (ParamIsDefault(match_str))
    258  match_str = "otf*"
    259  endif
    260 
    261  string iteratordata = ""
    262  iteratordata = ReplaceStringByKey("pattern", iteratordata, pattern)
    263  iteratordata = ReplaceNumberByKey("unique_index", iteratordata, unique_index)
    264  iteratordata = ReplaceStringByKey("new_suffix", iteratordata, new_suffix)
    265 
    266  iteratordata = IterateDataFolders(match_str, otf_rename_folders_iterator, iteratordata)
    267 
    268  setdatafolder savedf
    269 end
    270 
    271 function otf_interp(e1, e2, npts, smo)
    272  variable e1
    273  variable e2
    274  variable npts
    275  variable smo
    276 
    277  wave ch1 = current_ch1
    278  wave ch2 = current_ch2
    279  wave pe = photonenergy
    280  wave cff
    281  wave rc = ringcurrent
    282 
    283  duplicate /o ch1, current_ch1_int
    284  wave ch1i = current_ch1_int
    285  duplicate /o ch2, current_ch2_int
    286  wave ch2i = current_ch2_int
    287  duplicate /o pe, photonenergy_int
    288  wave pei = photonenergy_int
    289  duplicate /o cff, cff_int
    290  wave cffi = cff_int
    291  duplicate /o rc, ringcurrent_int
    292  wave rci = ringcurrent_int
    293 
    294  redimension /n=(npts) ch1i, ch2i, pei, cffi, rci
    295  setscale /i x e1, e2, "eV", ch1i, ch2i, pei, cffi, rci
    296 
    297  otf_smo_int(ch1, ch1i, pe, smo)
    298  otf_smo_int(ch2, ch2i, pe, smo)
    299  otf_smo_int(pe, pei, pe, smo)
    300  otf_smo_int(cff, cffi, pe, smo)
    301  otf_smo_int(rc, rci, pe, smo)
    302 end
    303 
    304 function otf_smo_int(win, wout, wpe, smo)
    305  wave win
    306  wave wout
    307  wave wpe
    308  variable smo
    309 
    310  //duplicate /o win, wtmp
    311  duplicate /free win, wtmp
    312  smooth /b /e=3 smo, wtmp
    313  wout = interp(x, wpe, wtmp)
    314 end
    variable otf_gather_iterator(dfref df, string *sdata)
    -
    string IterateDataFolders(string matchStr, funcref iterator, string sdata, string progress_title=defaultValue)
    Definition: pearl-tools.ipf:79
    -
    variable otf_load_itx(string pathname, string filename)
    -
    variable otf_interp(variable e1, variable e2, variable npts, variable smo)
    -
    variable gather_batch(string foldermatch, string ywavematch, string xwavematch, string destfolder)
    -
    variable otf_load_itx_match(string pathname, string matchstr)
    -
    variable otf_gather_batch(string ywavematch, string xwavematch, string destfolder)
    -
    variable otf_rename_folders(string pattern, variable unique_index=defaultValue, string new_suffix=defaultValue, string match_str=defaultValue)
    -
    variable otf_rename_folders_iterator(dfref df, string *sdata)
    -
    variable otf_load_itx_all(string pathname)
    -
    variable otf_smo_int(wave win, wave wout, wave wpe, variable smo)
    +Go to the documentation of this file.
    1 #pragma rtGlobals=1 // Use modern global access method.
    +
    2 #pragma IgorVersion = 6.1
    +
    3 #pragma ModuleName = PearlOtfImport
    +
    4 #pragma version = 1.01
    +
    5 
    +
    6 // procedures for importing on-the-fly (OTF) scans
    +
    7 // OTF scans are saved as ITX files
    +
    8 // matthias muntwiler, 2013-02-22
    +
    9 // $Id$
    +
    10 
    +
    11 // introduction
    +
    12 // the latest version of the PEARL OTF server saves data in igor text (ITX)
    +
    13 // the files contain code which saves all data from one file into one data folder with a unique name
    +
    14 // multiple files can be selected in the explorer and loaded by a double click
    +
    15 
    +
    16 // description
    +
    17 // OTF data folder names have the format otf_date_time_suffix, where only suffix is user-defined
    +
    18 // thus, raw data folder names are unique
    +
    19 // data folder names can be converted to a shorter format
    +
    20 // an OTF data folder contains a wave for each measured quantity (detector)
    +
    21 // and the IN, ID, IV, and IU waves for additional beamline parameters
    +
    22 // detector waves must have a wave note containing the following key=value pairs:
    +
    23 // PV=name of EPICS process variable
    +
    24 // PhysicalType=physical type of the quantity in the same way as used by pearl-optics-import
    +
    25 // Axis1=wave name of principal X axis
    +
    26 
    +
    27 // convergence
    +
    28 // while the file formats may be different, data files generated by the OTF and EPICS scan tools
    +
    29 // shall ultimately produce the same data structures in an Igor experiment
    +
    30 
    +
    31 function otf_load_itx_all(pathname)
    +
    32  // loads all OTF files from a given path
    +
    33  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
    +
    34  // newer files can be loaded by double click from the explorer
    +
    35  // without the danger of overwriting data from other files
    +
    36  string pathname
    +
    37  string filename
    +
    38 
    +
    39  if (strlen(pathname) <= 0)
    +
    40  newpath /o/q otf_load_itx
    +
    41  pathname = "otf_load_itx"
    +
    42  endif
    +
    43  string filelist = IndexedFile($pathname, -1, ".itx")
    +
    44  filelist = ListMatch(filelist, "otf*.itx", ";")
    +
    45  variable nfile = ItemsInList(filelist, ";")
    +
    46  variable ifile
    +
    47  for (ifile = 0; ifile < nfile; ifile += 1)
    +
    48  filename = StringFromList(ifile, filelist, ";")
    +
    49  otf_load_itx(pathname, filename)
    +
    50  endfor
    +
    51 end
    +
    52 
    +
    53 function otf_load_itx_match(pathname, matchstr)
    +
    54  // loads all OTF files from a given path whose names match a given string
    +
    55  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
    +
    56  // newer files can be loaded by double click from the explorer
    +
    57  // without the danger of overwriting data from other files
    +
    58  string pathname
    +
    59  string matchstr
    +
    60  string filename
    +
    61 
    +
    62  if (strlen(pathname) <= 0)
    +
    63  newpath /o/q otf_load_itx
    +
    64  pathname = "otf_load_itx"
    +
    65  endif
    +
    66  string filelist = IndexedFile($pathname, -1, ".itx")
    +
    67  filelist = ListMatch(filelist, matchstr, ";")
    +
    68  variable nfile = ItemsInList(filelist, ";")
    +
    69  variable ifile
    +
    70  for (ifile = 0; ifile < nfile; ifile += 1)
    +
    71  filename = StringFromList(ifile, filelist, ";")
    +
    72  otf_load_itx(pathname, filename)
    +
    73  endfor
    +
    74 end
    +
    75 
    +
    76 function otf_load_itx(pathname, filename)
    +
    77  // loads a specific OTF file
    +
    78  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
    +
    79  // newer files can be loaded by double click from the explorer
    +
    80  // without the danger of overwriting data from other files
    +
    81  string pathname
    +
    82  string filename
    +
    83 
    +
    84  dfref savedf = GetDataFolderDFR()
    +
    85  setdatafolder root:
    +
    86 
    +
    87  newdatafolder /s/o otf_load_itx_temp
    +
    88  if (strlen(pathname) > 0)
    +
    89  LoadWave /O/P=$pathname/Q/T filename
    +
    90  else
    +
    91  LoadWave /O/Q/T filename
    +
    92  endif
    +
    93  if (v_flag)
    +
    94  string foldername
    +
    95  foldername = ParseFilePath(3, s_filename, "/", 0, 0)
    +
    96  foldername = foldername[0,16]
    +
    97  foldername = CleanupName(foldername, 0)
    +
    98  //foldername = UniqueName(foldername, 11, 0)
    +
    99  renamedatafolder root:otf_load_itx_temp, $foldername
    +
    100  printf "loaded otf data from file %s into folder %s\r", s_filename, foldername
    +
    101  endif
    +
    102 
    +
    103  setdatafolder savedf
    +
    104 end
    +
    105 
    +
    106 function otf_gather_iterator(df, sdata)
    +
    107  // data folder iterator used by otf_gather_batch
    +
    108  dfref df
    +
    109  string &sdata // key=value list of parameters
    +
    110  // xwavematch
    +
    111  // ywavematch
    +
    112  // destfolder
    +
    113 
    +
    114  string src_name
    +
    115  string dst_name
    +
    116  string src_folder
    +
    117  string dst_folder
    +
    118  string df_id
    +
    119  string prefix, sdate, stime
    +
    120 
    +
    121  setdatafolder df
    +
    122  src_folder = GetDataFolder(0, df)
    +
    123  sscanf src_folder, "%[^_]_%[0-9]_%[0-9]", prefix, sdate, stime
    +
    124  df_id = ""
    +
    125  if (strlen(sdate) > 0)
    +
    126  df_id += "_" + sdate
    +
    127  endif
    +
    128  if (strlen(stime) > 0)
    +
    129  df_id += "_" + stime
    +
    130  endif
    +
    131  dst_folder = StringByKey("destfolder", sdata)
    +
    132 
    +
    133  src_name = StringByKey("xwavematch", sdata)
    +
    134  src_name = WaveList(src_name, "", "")
    +
    135  if (ItemsInList(src_name) >= 1)
    +
    136  src_name = StringFromList(0, src_name)
    +
    137  dst_name = dst_folder + src_name + df_id
    +
    138  //print src_name, dst_name
    +
    139  duplicate $src_name, $dst_name
    +
    140  endif
    +
    141 
    +
    142  src_name = StringByKey("ywavematch", sdata)
    +
    143  src_name = WaveList(src_name, "", "")
    +
    144  if (ItemsInList(src_name) >= 1)
    +
    145  src_name = StringFromList(0, src_name)
    +
    146  dst_name = dst_folder + src_name + df_id
    +
    147  //print src_name, dst_name
    +
    148  duplicate $src_name, $dst_name
    +
    149  endif
    +
    150 end
    +
    151 
    +
    152 function otf_gather_batch(ywavematch, xwavematch, destfolder)
    +
    153  // gathers (copies) OTF datasets in one data folder
    +
    154  // can be used for example for the Igor batch curve fitting tool
    +
    155  string ywavematch // match string identifies the y wave to be copied
    +
    156  string xwavematch // match string identifies the x wave to be copied
    +
    157  string destfolder // name of the destination data folder. folder does not have to exist.
    +
    158 
    +
    159  return gather_batch("otf*", ywavematch, xwavematch, destfolder)
    +
    160 end
    +
    161 
    +
    162 function gather_batch(foldermatch, ywavematch, xwavematch, destfolder)
    +
    163  // gathers (copies) OTF datasets in one data folder
    +
    164  // can be used for example for the Igor batch curve fitting tool
    +
    165  string foldermatch // match string to select data folders, e.g. "otf*"
    +
    166  string ywavematch // match string identifies the y wave to be copied
    +
    167  string xwavematch // match string identifies the x wave to be copied
    +
    168  string destfolder // name of the destination data folder. folder does not have to exist.
    +
    169 
    +
    170  dfref savedf = GetDataFolderDFR()
    +
    171  newdatafolder /o/s $destfolder
    +
    172  destfolder = GetDataFolder(1)
    +
    173 
    +
    174  string iteratordata = ""
    +
    175  iteratordata = ReplaceStringByKey("xwavematch", iteratordata, xwavematch)
    +
    176  iteratordata = ReplaceStringByKey("ywavematch", iteratordata, ywavematch)
    +
    177  iteratordata = ReplaceStringByKey("destfolder", iteratordata, destfolder)
    +
    178 
    +
    179  setdatafolder savedf
    +
    180  iteratordata = IterateDataFolders(foldermatch, otf_gather_iterator, iteratordata)
    +
    181 
    +
    182  setdatafolder savedf
    +
    183 end
    +
    184 
    +
    185 function otf_rename_folders_iterator(df, sdata)
    +
    186  // data folder iterator used by otf_rename_folders
    +
    187  dfref df
    +
    188  string &sdata // key=value list of parameters
    +
    189 
    +
    190  string pattern = StringByKey("pattern", sdata)
    +
    191  variable unique_index = NumberByKey("unique_index", sdata)
    +
    192  string new_suffix = StringByKey("new_suffix", sdata)
    +
    193 
    +
    194  string src_folder
    +
    195  string dst_folder
    +
    196  string sprefix, sdate, stime, ssuffix
    +
    197 
    +
    198  setdatafolder df
    +
    199  src_folder = GetDataFolder(0, df)
    +
    200  sprefix = "otf"
    +
    201  sscanf src_folder, "otf_%[0-9]_%[0-9]%s", sdate, stime, ssuffix
    +
    202  // return early if folder name does not match the expected pattern
    +
    203  if ((strlen(sdate) == 0) || (strlen(stime) == 0))
    +
    204  return 1
    +
    205  endif
    +
    206 
    +
    207  dst_folder = sprefix
    +
    208  if (cmpstr(pattern[0], "0") != 0)
    +
    209  dst_folder += "_" + sdate
    +
    210  endif
    +
    211  if (cmpstr(pattern[1], "0") != 0)
    +
    212  dst_folder += "_" + stime
    +
    213  endif
    +
    214  if (cmpstr(pattern[2], "0") != 0)
    +
    215  if (strlen(new_suffix) > 0)
    +
    216  ssuffix = "_" + new_suffix
    +
    217  endif
    +
    218  dst_folder += ssuffix
    +
    219  endif
    +
    220 
    +
    221  if ((unique_index > 0) || (CheckName(dst_folder, 11) != 0))
    +
    222  dst_folder = UniqueName(dst_folder + "_", 11, unique_index)
    +
    223  endif
    +
    224 
    +
    225  setdatafolder ::
    +
    226  print src_folder + " -> " + dst_folder
    +
    227  RenameDataFolder $src_folder, $dst_folder
    +
    228  return 0
    +
    229 end
    +
    230 
    +
    231 function otf_rename_folders(pattern, [unique_index, new_suffix, match_str])
    +
    232  // renames OTF data folders by omitting parts of the file name
    +
    233  string pattern // string of zeros and ones indicates which name parts to keep
    +
    234  // pos 1: date
    +
    235  // pos 2: time
    +
    236  // pos 3: custom suffix
    +
    237  variable unique_index // if you remove date and time,
    +
    238  // this start index will be used to make names unique
    +
    239  // if non-zero, new names will be forced to include a unique index
    +
    240  // if zero (default), new names will get a unique index only in case of a conflict
    +
    241  // optional, defaults to 0
    +
    242  string new_suffix
    +
    243  // replace old suffix by this one
    +
    244  // if empty (default), the old suffix will be kept
    +
    245  // optional, defaults to empty string
    +
    246  string match_str // match folder name to rename
    +
    247  // optional, defaults to "otf*" (matches all OTF folders)
    +
    248 
    +
    249  dfref savedf = GetDataFolderDFR()
    +
    250 
    +
    251  if (ParamIsDefault(unique_index))
    +
    252  unique_index = 0
    +
    253  endif
    +
    254  if (ParamIsDefault(new_suffix))
    +
    255  new_suffix = ""
    +
    256  endif
    +
    257  if (ParamIsDefault(match_str))
    +
    258  match_str = "otf*"
    +
    259  endif
    +
    260 
    +
    261  string iteratordata = ""
    +
    262  iteratordata = ReplaceStringByKey("pattern", iteratordata, pattern)
    +
    263  iteratordata = ReplaceNumberByKey("unique_index", iteratordata, unique_index)
    +
    264  iteratordata = ReplaceStringByKey("new_suffix", iteratordata, new_suffix)
    +
    265 
    +
    266  iteratordata = IterateDataFolders(match_str, otf_rename_folders_iterator, iteratordata)
    +
    267 
    +
    268  setdatafolder savedf
    +
    269 end
    +
    270 
    +
    271 function otf_interp(e1, e2, npts, smo)
    +
    272  variable e1
    +
    273  variable e2
    +
    274  variable npts
    +
    275  variable smo
    +
    276 
    +
    277  wave ch1 = current_ch1
    +
    278  wave ch2 = current_ch2
    +
    279  wave pe = photonenergy
    +
    280  wave cff
    +
    281  wave rc = ringcurrent
    +
    282 
    +
    283  duplicate /o ch1, current_ch1_int
    +
    284  wave ch1i = current_ch1_int
    +
    285  duplicate /o ch2, current_ch2_int
    +
    286  wave ch2i = current_ch2_int
    +
    287  duplicate /o pe, photonenergy_int
    +
    288  wave pei = photonenergy_int
    +
    289  duplicate /o cff, cff_int
    +
    290  wave cffi = cff_int
    +
    291  duplicate /o rc, ringcurrent_int
    +
    292  wave rci = ringcurrent_int
    +
    293 
    +
    294  redimension /n=(npts) ch1i, ch2i, pei, cffi, rci
    +
    295  setscale /i x e1, e2, "eV", ch1i, ch2i, pei, cffi, rci
    +
    296 
    +
    297  otf_smo_int(ch1, ch1i, pe, smo)
    +
    298  otf_smo_int(ch2, ch2i, pe, smo)
    +
    299  otf_smo_int(pe, pei, pe, smo)
    +
    300  otf_smo_int(cff, cffi, pe, smo)
    +
    301  otf_smo_int(rc, rci, pe, smo)
    +
    302 end
    +
    303 
    +
    304 function otf_smo_int(win, wout, wpe, smo)
    +
    305  wave win
    +
    306  wave wout
    +
    307  wave wpe
    +
    308  variable smo
    +
    309 
    +
    310  //duplicate /o win, wtmp
    +
    311  duplicate /free win, wtmp
    +
    312  smooth /b /e=3 smo, wtmp
    +
    313  wout = interp(x, wpe, wtmp)
    +
    314 end
    +
    variable gather_batch(string foldermatch, string ywavematch, string xwavematch, string destfolder)
    +
    variable otf_gather_batch(string ywavematch, string xwavematch, string destfolder)
    +
    string IterateDataFolders(string matchStr, funcref iterator, string sdata, string progress_title=defaultValue)
    Definition: pearl-tools.ipf:80
    +
    variable otf_rename_folders_iterator(dfref df, string *sdata)
    +
    variable otf_gather_iterator(dfref df, string *sdata)
    +
    variable otf_load_itx_all(string pathname)
    +
    variable otf_interp(variable e1, variable e2, variable npts, variable smo)
    +
    variable otf_smo_int(wave win, wave wout, wave wpe, variable smo)
    +
    variable otf_load_itx_match(string pathname, string matchstr)
    +
    variable otf_load_itx(string pathname, string filename)
    +
    variable otf_rename_folders(string pattern, variable unique_index=defaultValue, string new_suffix=defaultValue, string match_str=defaultValue)
    diff --git a/doc/html/pearl-pmsco-import_8ipf.html b/doc/html/pearl-pmsco-import_8ipf.html index 66b1682..d491ed4 100644 --- a/doc/html/pearl-pmsco-import_8ipf.html +++ b/doc/html/pearl-pmsco-import_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-pmsco-import.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -103,25 +105,146 @@ Namespaces

    Functions

    string pmsco_save_scan (string pathname, string filename, string energy, string theta, string phi, string alpha, string intensity, string sigma, dfref sdfr=defaultValue) - save waves in a PMSCO scan data file. More...
    + save waves in a PMSCO scan data file. More...
      static string save_scan_helper (string destname, string value, wave template, dfref destdfr, string wavenames) - helper function for save_pmsco_scan() More...
    + helper function for save_pmsco_scan() More...
      +string load_pmsco_scan (string pathname, string filename, variable is_modulation=defaultValue, variable quiet=defaultValue) + load a PMSCO scan file into the current data folder. More...
    +  +string load_pmsco_result (string pathname, string filename, variable quiet=defaultValue) + load a PMSCO result file into the current data folder. More...
    +  string pmsco_load_xyz (string pathname, string filename) - load an xyz cluster file More...
    + load an xyz cluster file More...
     

    Detailed Description

    data import/export procedures for multiple scattering calculations.

    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -

    Function Documentation

    + +

    ◆ load_pmsco_result()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    string load_pmsco_result (string pathname,
    string filename,
    variable quiet = defaultValue 
    )
    +
    + +

    load a PMSCO result file into the current data folder.

    +

    result files have the extension dat or tasks.dat. this will overwrite existing waves. the function loads all columns.

    +
    Parameters
    + + + + +
    pathnamename of a symbolic path
    filenamefile name
    quiet(optional)
      +
    • 0 (default) print the file name and wave names to the history.
    • +
    • 1 do not print messages to the history.
    • +
    +
    +
    +
    + +

    Definition at line 286 of file pearl-pmsco-import.ipf.

    + +
    +
    + +

    ◆ load_pmsco_scan()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    string load_pmsco_scan (string pathname,
    string filename,
    variable is_modulation = defaultValue,
    variable quiet = defaultValue 
    )
    +
    + +

    load a PMSCO scan file into the current data folder.

    +

    the function loads all columns from the file. the waves are named with two-letter names according to the file extension. existing waves are overwritten.

    +

    the file extension must be etpais or a subset of it, e.g., etpi. the wave names will be en (energy), th (theta), ph (phi), al (alpha), in (intensity) or mo (modulation), and si (sigma).

    +
    Parameters
    + + + + + +
    pathnamename of igor symbolic path to destination folder. prompt user if empty.
    filenamerequested file name. prompt user if empty. the extension must be a string of characters indicating the data of each column. it must be "etpais" or any substring of it, and the columns must be ordered accordingly. if the name contains .modf, the intensity wave is named as mo rather than in. this behaviour can be overridden by the is_modulation flag.
    is_modulationselect whether the intensity column is named mo rather than in.
      +
    • 0 (default) decide based on existens of .modf in the file name.
    • +
    • > 0 use mo regardless of file name.
    • +
    • < 0 use in regardless of file name.
    • +
    +
    quiet(optional)
      +
    • 0 (default) print the file name and wave names to the history.
    • +
    • 1 do not print messages to the history.
    • +
    +
    +
    +
    + +

    Definition at line 207 of file pearl-pmsco-import.ipf.

    + +
    +

    ◆ pmsco_load_xyz()

    @@ -158,7 +281,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 188 of file pearl-pmsco-import.ipf.

    +

    Definition at line 320 of file pearl-pmsco-import.ipf.

    @@ -269,7 +392,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    file name
    -

    Definition at line 88 of file pearl-pmsco-import.ipf.

    +

    Definition at line 89 of file pearl-pmsco-import.ipf.

    @@ -327,7 +450,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    helper function for save_pmsco_scan()

    -

    Definition at line 126 of file pearl-pmsco-import.ipf.

    +

    Definition at line 127 of file pearl-pmsco-import.ipf.

    @@ -337,9 +460,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
    diff --git a/doc/html/pearl-pmsco-import_8ipf.js b/doc/html/pearl-pmsco-import_8ipf.js index 03bfb34..f7bad92 100644 --- a/doc/html/pearl-pmsco-import_8ipf.js +++ b/doc/html/pearl-pmsco-import_8ipf.js @@ -1,5 +1,7 @@ var pearl_pmsco_import_8ipf = [ + [ "load_pmsco_result", "pearl-pmsco-import_8ipf.html#afae0650a37e89f18c9c54f8adc9eafb2", null ], + [ "load_pmsco_scan", "pearl-pmsco-import_8ipf.html#a98bbe8db14dba5aea9588a1b433baca7", null ], [ "pmsco_load_xyz", "pearl-pmsco-import_8ipf.html#ab3421c7f54aa64e5e493b267d700c0c8", null ], [ "pmsco_save_scan", "pearl-pmsco-import_8ipf.html#aa31bbaa2fc77b447e6c6f386b23abdd9", null ], [ "save_scan_helper", "pearl-pmsco-import_8ipf.html#a0a53a4686b482d62fe1797932a1708db", null ] diff --git a/doc/html/pearl-pmsco-import_8ipf_source.html b/doc/html/pearl-pmsco-import_8ipf_source.html index 80eb518..6db0861 100644 --- a/doc/html/pearl-pmsco-import_8ipf_source.html +++ b/doc/html/pearl-pmsco-import_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-pmsco-import.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,18 +87,224 @@ $(document).ready(function(){initNavTree('pearl-pmsco-import_8ipf_source.html','
    pearl-pmsco-import.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.2
    3 #pragma ModuleName = PearlPmscoImport
    4 
    5 // copyright (c) 2018 Paul Scherrer Institut
    6 //
    7 // Licensed under the Apache License, Version 2.0 (the "License");
    8 // you may not use this file except in compliance with the License.
    9 // You may obtain a copy of the License at
    10 // http:///www.apache.org/licenses/LICENSE-2.0
    11 //
    12 // Please acknowledge the use of this code.
    13 
    28 
    33 
    34 
    88 function /s pmsco_save_scan(pathname, filename, energy, theta, phi, alpha, intensity, sigma, [sdfr])
    89  string pathname
    90  string filename
    91  string energy
    92  string theta
    93  string phi
    94  string alpha
    95  string intensity
    96  string sigma
    97  dfref sdfr
    98 
    99  //string fileext
    100  //fileext = StringFromList(ItemsInList(filename, ".") - 1, filename, ".")
    101 
    102  dfref savedf = GetDataFolderDFR()
    103  dfref tempdf = NewFreeDataFolder()
    104 
    105  if (ParamIsDefault(sdfr))
    106  dfref sdfr = savedf
    107  endif
    108  SetDataFolder sdfr
    109  wave w_intensity = $intensity
    110  string wavenames = ""
    111 
    112  wavenames = save_scan_helper("w_energy", energy, w_intensity, tempdf, wavenames)
    113  wavenames = save_scan_helper("w_theta", theta, w_intensity, tempdf, wavenames)
    114  wavenames = save_scan_helper("w_phi", phi, w_intensity, tempdf, wavenames)
    115  wavenames = save_scan_helper("w_alpha", alpha, w_intensity, tempdf, wavenames)
    116  wavenames = save_scan_helper("w_intensity", intensity, w_intensity, tempdf, wavenames)
    117  wavenames = save_scan_helper("w_sigma", sigma, w_intensity, tempdf, wavenames)
    118 
    119  setdatafolder tempdf
    120  save /b /g /m="\n" /p=$pathname wavenames as filename
    121  setdatafolder savedf
    122 end
    123 
    126 static function /s save_scan_helper(destname, value, template, destdfr, wavenames)
    127  string destname
    128  string value
    129  wave template
    130  dfref destdfr
    131  string wavenames
    132 
    133  variable err = 0
    134  if (strlen(value) > 0)
    135  if (exists(value) == 1)
    136  duplicate $value, destdfr:$destname
    137  wave /sdfr=destdfr w=$destname
    138  else
    139  duplicate template, destdfr:$destname
    140  wave /sdfr=destdfr w=$destname
    141  variable numval = str2num(value)
    142  string msg
    143  if (numtype(numval) == 0)
    144  w = numval
    145  //elseif (cmpstr(value[0,0], "%") == 0)
    146  else
    147  strswitch(value)
    148  case "x":
    149  w = DimOffset(template, 0) + DimDelta(template, 0) * p
    150  break
    151  case "y":
    152  w = DimOffset(template, 1) + DimDelta(template, 1) * q
    153  break
    154  case "z":
    155  w = DimOffset(template, 2) + DimDelta(template, 2) * r
    156  break
    157  case "t":
    158  w = DimOffset(template, 3) + DimDelta(template, 3) * s
    159  break
    160  default:
    161  err = 1
    162  sprintf msg, "invalid %s argument", StringFromList(1, destname, "_")
    163  endswitch
    164  endif
    165  endif
    166  if (err == 0)
    167  wavenames = AddListItem(destname, wavenames, ";", inf)
    168  variable npts = DimSize(w, 0) * max(DimSize(w, 1), 1) * max(DimSize(w, 2), 1) * max(DimSize(w, 3), 1)
    169  Redimension /n=(npts) w
    170  else
    171  abort msg
    172  endif
    173  endif
    174  return wavenames
    175 end
    176 
    188 function /s pmsco_load_xyz(pathname, filename)
    189  string pathname
    190  string filename
    191 
    192  string cis = "N=at;N=xx;N=yy;N=zz;"
    193  LoadWave /A /B=cis /J /K=0 /L={0, 2, 0, 0, 0} /V={" ", " ", 0, 0} /O /P=$pathname filename
    194  wave /t at
    195  at = unpadstring(at, 32)
    196 end
    string pmsco_save_scan(string pathname, string filename, string energy, string theta, string phi, string alpha, string intensity, string sigma, dfref sdfr=defaultValue)
    save waves in a PMSCO scan data file.
    -
    static string save_scan_helper(string destname, string value, wave template, dfref destdfr, string wavenames)
    helper function for save_pmsco_scan()
    -
    string pmsco_load_xyz(string pathname, string filename)
    load an xyz cluster file
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.2
    +
    4 #pragma ModuleName = PearlPmscoImport
    +
    5 
    +
    6 // copyright (c) 2018 Paul Scherrer Institut
    +
    7 //
    +
    8 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    9 // you may not use this file except in compliance with the License.
    +
    10 // You may obtain a copy of the License at
    +
    11 // http:///www.apache.org/licenses/LICENSE-2.0
    +
    12 //
    +
    13 // Please acknowledge the use of this code.
    +
    14 
    +
    29 
    +
    34 
    +
    35 
    +
    89 function /s pmsco_save_scan(pathname, filename, energy, theta, phi, alpha, intensity, sigma, [sdfr])
    +
    90  string pathname
    +
    91  string filename
    +
    92  string energy
    +
    93  string theta
    +
    94  string phi
    +
    95  string alpha
    +
    96  string intensity
    +
    97  string sigma
    +
    98  dfref sdfr
    +
    99 
    +
    100  //string fileext
    +
    101  //fileext = StringFromList(ItemsInList(filename, ".") - 1, filename, ".")
    +
    102 
    +
    103  dfref savedf = GetDataFolderDFR()
    +
    104  dfref tempdf = NewFreeDataFolder()
    +
    105 
    +
    106  if (ParamIsDefault(sdfr))
    +
    107  dfref sdfr = savedf
    +
    108  endif
    +
    109  SetDataFolder sdfr
    +
    110  wave w_intensity = $intensity
    +
    111  string wavenames = ""
    +
    112 
    +
    113  wavenames = save_scan_helper("w_energy", energy, w_intensity, tempdf, wavenames)
    +
    114  wavenames = save_scan_helper("w_theta", theta, w_intensity, tempdf, wavenames)
    +
    115  wavenames = save_scan_helper("w_phi", phi, w_intensity, tempdf, wavenames)
    +
    116  wavenames = save_scan_helper("w_alpha", alpha, w_intensity, tempdf, wavenames)
    +
    117  wavenames = save_scan_helper("w_intensity", intensity, w_intensity, tempdf, wavenames)
    +
    118  wavenames = save_scan_helper("w_sigma", sigma, w_intensity, tempdf, wavenames)
    +
    119 
    +
    120  setdatafolder tempdf
    +
    121  save /b /g /m="\n" /p=$pathname wavenames as filename
    +
    122  setdatafolder savedf
    +
    123 end
    +
    124 
    +
    127 static function /s save_scan_helper(destname, value, template, destdfr, wavenames)
    +
    128  string destname
    +
    129  string value
    +
    130  wave template
    +
    131  dfref destdfr
    +
    132  string wavenames
    +
    133 
    +
    134  variable err = 0
    +
    135  if (strlen(value) > 0)
    +
    136  if (exists(value) == 1)
    +
    137  duplicate $value, destdfr:$destname
    +
    138  wave /sdfr=destdfr w=$destname
    +
    139  else
    +
    140  duplicate template, destdfr:$destname
    +
    141  wave /sdfr=destdfr w=$destname
    +
    142  variable numval = str2num(value)
    +
    143  string msg
    +
    144  if (numtype(numval) == 0)
    +
    145  w = numval
    +
    146  //elseif (cmpstr(value[0,0], "%") == 0)
    +
    147  else
    +
    148  strswitch(value)
    +
    149  case "x":
    +
    150  w = DimOffset(template, 0) + DimDelta(template, 0) * p
    +
    151  break
    +
    152  case "y":
    +
    153  w = DimOffset(template, 1) + DimDelta(template, 1) * q
    +
    154  break
    +
    155  case "z":
    +
    156  w = DimOffset(template, 2) + DimDelta(template, 2) * r
    +
    157  break
    +
    158  case "t":
    +
    159  w = DimOffset(template, 3) + DimDelta(template, 3) * s
    +
    160  break
    +
    161  default:
    +
    162  err = 1
    +
    163  sprintf msg, "invalid %s argument", StringFromList(1, destname, "_")
    +
    164  endswitch
    +
    165  endif
    +
    166  endif
    +
    167  if (err == 0)
    +
    168  wavenames = AddListItem(destname, wavenames, ";", inf)
    +
    169  variable npts = DimSize(w, 0) * max(DimSize(w, 1), 1) * max(DimSize(w, 2), 1) * max(DimSize(w, 3), 1)
    +
    170  Redimension /n=(npts) w
    +
    171  else
    +
    172  abort msg
    +
    173  endif
    +
    174  endif
    +
    175  return wavenames
    +
    176 end
    +
    177 
    +
    207 function /s load_pmsco_scan(pathname, filename, [is_modulation, quiet])
    +
    208  string pathname // name of a symbolic path
    +
    209  string filename
    +
    210  variable is_modulation
    +
    211  variable quiet
    +
    212 
    +
    213  if (ParamIsDefault(quiet))
    +
    214  quiet = 0
    +
    215  endif
    +
    216 
    +
    217  loadwave /p=$pathname /a /g /o /q filename
    +
    218 
    +
    219  if (ParamIsDefault(is_modulation))
    +
    220  is_modulation = StringMatch(s_filename, "*.modf.*")
    +
    221  else
    +
    222  is_modulation = is_modulation > 0
    +
    223  endif
    +
    224 
    +
    225  string fileext
    +
    226  string waves = ""
    +
    227  if (v_flag > 0)
    +
    228  fileext = StringFromList(ItemsInList(s_filename, ".") - 1, s_filename, ".")
    +
    229  variable nw = ItemsInList(s_wavenames)
    +
    230  variable iw
    +
    231  string sw1, sw2
    +
    232  for (iw = 0; iw < nw; iw += 1)
    +
    233  sw1 = StringFromlist(iw, s_wavenames)
    +
    234  strswitch(fileext[iw])
    +
    235  case "e":
    +
    236  sw2 = "en"
    +
    237  break
    +
    238  case "t":
    +
    239  sw2 = "th"
    +
    240  break
    +
    241  case "p":
    +
    242  sw2 = "ph"
    +
    243  break
    +
    244  case "a":
    +
    245  sw2 = "al"
    +
    246  break
    +
    247  case "i":
    +
    248  if (is_modulation)
    +
    249  sw2 = "mo"
    +
    250  else
    +
    251  sw2 = "in"
    +
    252  endif
    +
    253  break
    +
    254  case "s":
    +
    255  sw2 = "si"
    +
    256  break
    +
    257  endswitch
    +
    258  duplicate /o $sw1, $sw2
    +
    259  killwaves /z $sw1
    +
    260  waves = AddListItem(sw2, waves, ",", inf)
    +
    261  endfor
    +
    262 
    +
    263  // Sort {en,th,ph, al} en,th,ph,al,int,sig
    +
    264 
    +
    265  if (!quiet)
    +
    266  print "load_pmsco_scan ", s_filename, ": ", waves
    +
    267  endif
    +
    268 
    +
    269  return s_filename
    +
    270  else
    +
    271  return ""
    +
    272  endif
    +
    273 end
    +
    274 
    +
    286 function /s load_pmsco_result(pathname, filename, [quiet])
    +
    287  string pathname // name of a symbolic path
    +
    288  string filename
    +
    289  variable quiet
    +
    290 
    +
    291  if (ParamIsDefault(quiet))
    +
    292  quiet = 0
    +
    293  endif
    +
    294 
    +
    295  if (quiet)
    +
    296  loadwave /p=$pathname /a /w /g /o /q filename
    +
    297  else
    +
    298  loadwave /p=$pathname /a /w /g /o filename
    +
    299  endif
    +
    300 
    +
    301  if (v_flag > 0)
    +
    302  return s_filename
    +
    303  else
    +
    304  return ""
    +
    305  endif
    +
    306 end
    +
    307 
    +
    308 
    +
    320 function /s pmsco_load_xyz(pathname, filename)
    +
    321  string pathname
    +
    322  string filename
    +
    323 
    +
    324  string cis = "N=at;N=xx;N=yy;N=zz;"
    +
    325  LoadWave /A /B=cis /J /K=0 /L={0, 2, 0, 0, 0} /V={" ", " ", 0, 0} /O /P=$pathname filename
    +
    326  wave /t at
    +
    327  at = unpadstring(at, 32)
    +
    328 end
    +
    static string save_scan_helper(string destname, string value, wave template, dfref destdfr, string wavenames)
    helper function for save_pmsco_scan()
    +
    string load_pmsco_result(string pathname, string filename, variable quiet=defaultValue)
    load a PMSCO result file into the current data folder.
    +
    string pmsco_save_scan(string pathname, string filename, string energy, string theta, string phi, string alpha, string intensity, string sigma, dfref sdfr=defaultValue)
    save waves in a PMSCO scan data file.
    +
    string load_pmsco_scan(string pathname, string filename, variable is_modulation=defaultValue, variable quiet=defaultValue)
    load a PMSCO scan file into the current data folder.
    +
    string pmsco_load_xyz(string pathname, string filename)
    load an xyz cluster file
    diff --git a/doc/html/pearl-polar-coordinates_8ipf.html b/doc/html/pearl-polar-coordinates_8ipf.html index 3c366c3..d44f351 100644 --- a/doc/html/pearl-polar-coordinates_8ipf.html +++ b/doc/html/pearl-polar-coordinates_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-polar-coordinates.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -154,7 +156,7 @@ Functions
    -

    Definition at line 10 of file pearl-polar-coordinates.ipf.

    +

    Definition at line 11 of file pearl-polar-coordinates.ipf.

    @@ -184,7 +186,7 @@ Functions
    -

    Definition at line 36 of file pearl-polar-coordinates.ipf.

    +

    Definition at line 37 of file pearl-polar-coordinates.ipf.

    @@ -238,7 +240,7 @@ Functions
    -

    Definition at line 48 of file pearl-polar-coordinates.ipf.

    +

    Definition at line 49 of file pearl-polar-coordinates.ipf.

    @@ -268,7 +270,7 @@ Functions
    -

    Definition at line 58 of file pearl-polar-coordinates.ipf.

    +

    Definition at line 59 of file pearl-polar-coordinates.ipf.

    @@ -310,7 +312,7 @@ Functions
    -

    Definition at line 69 of file pearl-polar-coordinates.ipf.

    +

    Definition at line 70 of file pearl-polar-coordinates.ipf.

    @@ -320,9 +322,9 @@ Functions diff --git a/doc/html/pearl-polar-coordinates_8ipf_source.html b/doc/html/pearl-polar-coordinates_8ipf_source.html index 4a80f72..90d2379 100644 --- a/doc/html/pearl-polar-coordinates_8ipf_source.html +++ b/doc/html/pearl-polar-coordinates_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-polar-coordinates.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,20 +87,106 @@ $(document).ready(function(){initNavTree('pearl-polar-coordinates_8ipf_source.ht
    pearl-polar-coordinates.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3
    2 #pragma version = 1.1
    3 #pragma IgorVersion = 6.1
    4 #pragma ModuleName = PearlPolarCoordinates
    5 
    6 // author: matthias.muntwiler@psi.ch
    7 // Copyright (c) 2011-13 Paul Scherrer Institut
    8 // $Id$
    9 
    10 function cart2polar(xx, yy, zz, radius, theta, phi)
    11  // converts a 3-vector from Cartesian to polar coordinates
    12  variable xx, yy, zz
    13  variable &radius, &theta, &phi // angles in degrees
    14 
    15  radius = sqrt(xx^2 + yy^2 + zz^2)
    16 
    17  if (radius > 0)
    18  theta = acos(zz / radius) * 180 / pi
    19  else
    20  theta = 0
    21  endif
    22 
    23  if (xx > 0)
    24  phi = atan(yy / xx) * 180 / pi
    25  elseif (xx < 0)
    26  phi = atan(yy / xx) * 180 / pi + 180
    27  else
    28  if (yy > 0)
    29  phi = 90
    30  else
    31  phi = 270
    32  endif
    33  endif
    34 end
    35 
    36 function cart2polar_wave(in, out)
    37  // converts a wave of 3-vectors from Cartesian to polar coordinates
    38  wave in // wave with dimensions (3, N), N >= 1, (x, y, z)
    39  wave out // wave same dimensions as in, (radius, theta, phi)
    40  // angles in degrees
    41 
    42  out[0][] = sqrt(in[0][q]^2 + in[1][q]^2 + in[2][q]^2)
    43  out[1][] = acos(in[2][q] / out[0][q]) * 180 / pi
    44  out[2][] = atan(in[1][q] / in[0][q]) * 180 / pi + 180 * (in[0][q] < 0)
    45  out[2][] = numtype(out[2][q]) == 0 ? out[2][q] : 90 + 180 * (in[1][q] < 0)
    46 end
    47 
    48 function polar2cart(radius, theta, phi, xx, yy, zz)
    49  // converts a 3-vector from Cartesian to polar coordinates
    50  variable radius, theta, phi // angles in degrees
    51  variable &xx, &yy, &zz
    52 
    53  xx = radius * sin(theta * pi / 180) * cos(phi * pi / 180)
    54  yy = radius * sin(theta * pi / 180) * sin(phi * pi / 180)
    55  zz = radius * cos(theta * pi / 180)
    56 end
    57 
    58 function polar2cart_wave(in, out)
    59  // converts a wave of 3-vectors from polar to Cartesian coordinates
    60  wave in // wave with dimensions (3, N), N >= 1, (radius, theta, phi)
    61  // angles in degrees
    62  wave out // wave same dimensions as in, (x, y, z)
    63 
    64  out[0][] = in[0][q] * sin(in[1][q] * pi / 180) * cos(in[2][q] * pi / 180)
    65  out[1][] = in[0][q] * sin(in[1][q] * pi / 180) * sin(in[2][q] * pi / 180)
    66  out[2][] = in[0][q] * cos(in[1][q] * pi / 180)
    67 end
    68 
    69 function polar_distance(polar1, azim1, polar2, azim2)
    70  // returns the angle between two spherical coordinates
    71  variable polar1, azim1
    72  // angles in degrees
    73  variable polar2, azim2
    74  // angles in degrees
    75 
    76  variable xx1, yy1, zz1
    77  variable xx2, yy2, zz2
    78 
    79  polar2cart(1, polar1, azim1, xx1, yy1, zz1)
    80  polar2cart(1, polar2, azim2, xx2, yy2, zz2)
    81 
    82  variable vv
    83  vv = (xx1 * xx2 + yy1 * yy2 + zz1 * zz2) / sqrt(xx1^2 + yy1^2 + zz1^2) / sqrt(xx2^2 + yy2^2 + zz2^2)
    84  return acos(vv) * 180 / pi
    85 end
    variable polar2cart_wave(wave in, wave out)
    -
    variable cart2polar(variable xx, variable yy, variable zz, variable *radius, variable *theta, variable *phi)
    -
    variable cart2polar_wave(wave in, wave out)
    -
    variable polar_distance(variable polar1, variable azim1, variable polar2, variable azim2)
    -
    variable polar2cart(variable radius, variable theta, variable phi, variable *xx, variable *yy, variable *zz)
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3
    +
    3 #pragma version = 1.1
    +
    4 #pragma IgorVersion = 6.1
    +
    5 #pragma ModuleName = PearlPolarCoordinates
    +
    6 
    +
    7 // author: matthias.muntwiler@psi.ch
    +
    8 // Copyright (c) 2011-13 Paul Scherrer Institut
    +
    9 // $Id$
    +
    10 
    +
    11 function cart2polar(xx, yy, zz, radius, theta, phi)
    +
    12  // converts a 3-vector from Cartesian to polar coordinates
    +
    13  variable xx, yy, zz
    +
    14  variable &radius, &theta, &phi // angles in degrees
    +
    15 
    +
    16  radius = sqrt(xx^2 + yy^2 + zz^2)
    +
    17 
    +
    18  if (radius > 0)
    +
    19  theta = acos(zz / radius) * 180 / pi
    +
    20  else
    +
    21  theta = 0
    +
    22  endif
    +
    23 
    +
    24  if (xx > 0)
    +
    25  phi = atan(yy / xx) * 180 / pi
    +
    26  elseif (xx < 0)
    +
    27  phi = atan(yy / xx) * 180 / pi + 180
    +
    28  else
    +
    29  if (yy > 0)
    +
    30  phi = 90
    +
    31  else
    +
    32  phi = 270
    +
    33  endif
    +
    34  endif
    +
    35 end
    +
    36 
    +
    37 function cart2polar_wave(in, out)
    +
    38  // converts a wave of 3-vectors from Cartesian to polar coordinates
    +
    39  wave in // wave with dimensions (3, N), N >= 1, (x, y, z)
    +
    40  wave out // wave same dimensions as in, (radius, theta, phi)
    +
    41  // angles in degrees
    +
    42 
    +
    43  out[0][] = sqrt(in[0][q]^2 + in[1][q]^2 + in[2][q]^2)
    +
    44  out[1][] = acos(in[2][q] / out[0][q]) * 180 / pi
    +
    45  out[2][] = atan(in[1][q] / in[0][q]) * 180 / pi + 180 * (in[0][q] < 0)
    +
    46  out[2][] = numtype(out[2][q]) == 0 ? out[2][q] : 90 + 180 * (in[1][q] < 0)
    +
    47 end
    +
    48 
    +
    49 function polar2cart(radius, theta, phi, xx, yy, zz)
    +
    50  // converts a 3-vector from Cartesian to polar coordinates
    +
    51  variable radius, theta, phi // angles in degrees
    +
    52  variable &xx, &yy, &zz
    +
    53 
    +
    54  xx = radius * sin(theta * pi / 180) * cos(phi * pi / 180)
    +
    55  yy = radius * sin(theta * pi / 180) * sin(phi * pi / 180)
    +
    56  zz = radius * cos(theta * pi / 180)
    +
    57 end
    +
    58 
    +
    59 function polar2cart_wave(in, out)
    +
    60  // converts a wave of 3-vectors from polar to Cartesian coordinates
    +
    61  wave in // wave with dimensions (3, N), N >= 1, (radius, theta, phi)
    +
    62  // angles in degrees
    +
    63  wave out // wave same dimensions as in, (x, y, z)
    +
    64 
    +
    65  out[0][] = in[0][q] * sin(in[1][q] * pi / 180) * cos(in[2][q] * pi / 180)
    +
    66  out[1][] = in[0][q] * sin(in[1][q] * pi / 180) * sin(in[2][q] * pi / 180)
    +
    67  out[2][] = in[0][q] * cos(in[1][q] * pi / 180)
    +
    68 end
    +
    69 
    +
    70 function polar_distance(polar1, azim1, polar2, azim2)
    +
    71  // returns the angle between two spherical coordinates
    +
    72  variable polar1, azim1
    +
    73  // angles in degrees
    +
    74  variable polar2, azim2
    +
    75  // angles in degrees
    +
    76 
    +
    77  variable xx1, yy1, zz1
    +
    78  variable xx2, yy2, zz2
    +
    79 
    +
    80  polar2cart(1, polar1, azim1, xx1, yy1, zz1)
    +
    81  polar2cart(1, polar2, azim2, xx2, yy2, zz2)
    +
    82 
    +
    83  variable vv
    +
    84  vv = (xx1 * xx2 + yy1 * yy2 + zz1 * zz2) / sqrt(xx1^2 + yy1^2 + zz1^2) / sqrt(xx2^2 + yy2^2 + zz2^2)
    +
    85  return acos(vv) * 180 / pi
    +
    86 end
    +
    variable polar2cart(variable radius, variable theta, variable phi, variable *xx, variable *yy, variable *zz)
    +
    variable cart2polar(variable xx, variable yy, variable zz, variable *radius, variable *theta, variable *phi)
    +
    variable cart2polar_wave(wave in, wave out)
    +
    variable polar_distance(variable polar1, variable azim1, variable polar2, variable azim2)
    +
    variable polar2cart_wave(wave in, wave out)
    diff --git a/doc/html/pearl-pshell-import_8ipf.html b/doc/html/pearl-pshell-import_8ipf.html index 27d5ba5..7df936a 100644 --- a/doc/html/pearl-pshell-import_8ipf.html +++ b/doc/html/pearl-pshell-import_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-pshell-import.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -107,227 +109,217 @@ Namespaces - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Functions

    variable psh5_open_file (string ANickName, string APathName, string AFileName)
     open a HDF5 file created by the PShell data acquisition program and prepare the data folder. More...
     
    variable psh5_close_file (variable fileID)
     close a HDF5 file opened by psh5_open_file. More...
     
    string psh5_load_complete (string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
     load everything from a PShell data file. More...
     
    string psh5_load_preview (string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue, string pref_scans=defaultValue, string pref_datasets=defaultValue)
     load a preview image from a PShell data file. More...
     
    string psh5_load_scan_complete (variable fileID, string scanpath, variable load_data=defaultValue, variable load_attr=defaultValue)
     load all data of a selected scan from a PShell data file. More...
     
    string psh5_list_scans (variable fileID)
     list scan groups of a PShell data file. More...
     
    string psh5_list_scan_datasets (variable fileID, string scanpath, variable include_regions=defaultValue)
     list datasets of a PShell scan group. More...
     
    string psh5_list_scan_regions (variable fileID, string scanpath)
     list regions of a PShell scan group. More...
     
    string psh5_load_scan_data (variable fileID, string scanpath)
     load all datasets of a PShell scan group. More...
     
    string psh5_load_scan_attrs (variable fileID, string scanpath, variable attr_sets=defaultValue)
     load attributes of a PShell scan group. More...
     
    string psh5_load_scan_meta (variable fileID, string scanpath)
     load metadata of a PShell scan group. More...
     
    string psh5_load_dataset (variable fileID, string scanpath, string datasetname, variable set_scale=defaultValue)
     load a dataset from an open PShell HDF5 file. More...
     
    static string select_dataset (string file_datasets, string pref_datasets)
     select the preferred dataset from a list of available datasets. More...
     
    string psh5_load_scan_preview (variable fileID, string scanpath, variable set_scale=defaultValue, string pref_datasets=defaultValue)
     load a preview dataset from an open PShell HDF5 file. More...
     
    string psh5_load_scan_section (variable fileID, string scanpath, variable dim, variable set_scale=defaultValue, string pref_datasets=defaultValue)
     load a longitudinal section of a scan from an open PShell HDF5 file. More...
     
    variable psh5_load_dataset_meta (variable fileID, string datapath, string datasetname, wave datawave)
     load metadata of a PShell dataset. More...
     
    string psh5_load_dataset_slabs (variable fileID, string datapath, string datasetname, variable progress=defaultValue)
     load a dataset slab-wise from the open PShell HDF5 file. More...
     
    string psh5_load_dataset_slab (variable fileID, string datapath, string datasetname, variable dim2start, variable dim2count, variable dim3start, variable dim3count)
     load a single image from the open PShell data file. More...
     
    variable ps_set_dimlabels (wave data)
     set dimension labels according to the axis type More...
     
    variable ps_set_dimlabels2 (wave data, string name)
     set dimension labels according to the axis type More...
     
    static dfr find_scan_folder (dfref dataDF)
     find the scan folder More...
     
    static dfr find_attr_folder (dfref dataDF)
     find the attributes data folder More...
     
    variable ps_scale_datasets ()
     set the dimension scales of loaded PShell Scienta datasets according to attributes. More...
     
    variable ps_scale_dataset (wave data)
     set the dimension scales of a loaded PShell Scienta dataset according to attributes. More...
     
    static wave find_scale_wave (string name, dfref dataDF, dfref scanDF, dfref attrDF)
     
    variable ps_detect_scale (wave ax, wave lo, wave hi, wave un)
     detect the dimension scales from attributes. More...
     
    variable ps_scale_dataset_2 (wave data, wave ax, wave lo, wave hi, wave un)
     set the dimension scales of a dataset. More...
     
    string psh5_load_reduced (string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue)
     load and reduce the ScientaImage dataset of the first scan of a PShell data file. More...
     
    string psh5_load_dataset_reduced (variable fileID, string scanpath, string datasetname, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue)
     load a reduced dataset from the open PShell HDF5 file. More...
     
    static threadsafe variable reduce_slab_worker (funcref reduction_func)
     
    static threadsafe wave reduce_slab_image (wave slabdata, wave image, funcref reduction_func, string reduction_param)
     
    string psh5_load_info (string APathName, string AFileName)
     load descriptive info from a PShell data file. More...
     
    string psh5_load_scan_info (variable fileID, string scanpath)
     load descriptive info from a PShell scan. More...
     
    dfr psh5_load (string path_name, string file_name, string scans, string regions, string datasets, variable classes=defaultValue, variable max_rank=defaultValue, string reduction_func=defaultValue, string reduction_params=defaultValue, dfref dest_df=defaultValue)
     main data loading function More...
     
    dfr psh5_preview (string path_name, string file_name, dfref dest_df=defaultValue, string preview_datasets=defaultValue)
     load preview More...
     
    dfr psh5_open_file (string path_name, string file_name, dfref dest_df=defaultValue)
     open a HDF5 file created by the PShell data acquisition program and prepare the data folder. More...
     
    variable psh5_close_file (dfref file_df)
     close a HDF5 file opened by psh5_open_file. More...
     
    static string twave2list (wave wt, string sep)
     convert text wave to list. More...
     convert text wave to list. More...
     
    static string wave2list (wave w, string format, string sep)
     convert numeric wave to list. More...
     convert numeric wave to list. More...
     
    string psh5_list_scans (variable file_id)
     list scan groups of a PShell data file. More...
     
    string psh5_list_all_datasets (variable file_id)
     list all datasets in a file More...
     
    variable[string datatypes, string ranks, string dimensions] psh5_list_dataset_info (string variable, string file_id, variable string, sds datasets)
     list data types and dimensions of datasets More...
     
    string psh5_filter_datasets_rank (string datasets, string ranks, variable min_rank, variable max_rank)
     filter datasets by rank More...
     
    static string unique_strings (string list)
     remove duplicate items from list More...
     
    string psh5_extract_scan_paths (string datasets)
     trim dataset paths to the scan part More...
     
    string psh5_extract_region_paths (string datasets)
     trim dataset paths to the scan/region part More...
     
    string psh5_match_dataset_classes (string datasets, variable classes, string positioners=defaultValue, string detectors=defaultValue)
     filter a list of datasets by classification More...
     
    dfr psh5_create_folders (string datasetpath)
     create all data folders along a dataset path More...
     
    dfr psh5_dataset_to_folder (dfref parent_df, string datasetpath)
     map dataset path to datafolder path More...
     
    string ps_fix_folder_name (string group_name)
     convert HDF5 group name to data folder name and fix compatibility issues More...
     
    string psh5_load_datasets (dfref file_df, string datasets, variable create_folders=defaultValue, string reduction_func=defaultValue, string reduction_params=defaultValue)
     load multiple datasets from open file More...
     
    string psh5_load_dataset (dfref file_df, string datasetpath, variable create_folders=defaultValue, string reduction_func=defaultValue, string reduction_params=defaultValue)
     load a dataset from an open PShell HDF5 file. More...
     
    string psh5_load_dataset_slabs (dfref file_df, string datasetpath, variable create_folders=defaultValue, variable progress=defaultValue)
     load a dataset slab-wise from the open PShell HDF5 file. More...
     
    string psh5_load_dataset_reduced (dfref file_df, string datasetpath, funcref reduction_func, string reduction_params, variable create_folders=defaultValue, variable progress=defaultValue, variable nthreads=defaultValue)
     load a dataset with reduced dimensionality More...
     
    static threadsafe variable reduce_slab_worker (funcref reduction_func)
     
    static threadsafe wave reduce_slab_image (wave slabdata, wave image, funcref reduction_func, string reduction_params)
     
    string psh5_load_general_group (dfref file_df)
     load organizational metadata from the general group. More...
     
    string psh_load_general_string (dfref file_df, string name)
     load a string from the general group. More...
     
    variable psh5_load_dataset_meta (dfref file_df, string datasetpath, wave datawave)
     load metadata of a PShell dataset. More...
     
    string psh5_load_scan_meta (dfref file_df, string scanpath)
     load metadata of a PShell scan group. More...
     
    variable ps_set_dimlabels (wave data)
     set dimension labels according to the axis type More...
     
    variable ps_set_dimlabels2 (wave data, string name)
     set dimension labels according to the axis type More...
     
    dfr ps_find_scan_folder (dfref data_df)
     find the scan folder of current data More...
     
    dfr ps_find_attr_folder (dfref scan_df)
     find the attributes data folder More...
     
    wave ps_find_scale_wave (string name, dfref df1, dfref df2, dfref df3)
     find a wave in scan and attr data folders More...
     
    variable ps_detect_scale (dfref data_df, wave ax, wave lo, wave hi, wave un)
     detect the dimension scales from attributes. More...
     
    variable ps_scale_dataset_2 (wave data, wave ax, wave lo, wave hi, wave un)
     set the dimension scales of a dataset. More...
     
    variable ps_scale_datasets (dfref scan_df)
     set the dimension scales of loaded PShell Scienta datasets according to attributes. More...
     
    variable ps_scale_dataset (wave data)
     set the dimension scales of a loaded PShell Scienta dataset according to attributes. More...
     
    string kill_matching_waves (dfref dfr, string pattern, variable recurse, string killed=defaultValue)
     kill any waves matching a pattern in the experiment More...
     
    - + - + - + - + - - + + - - + + + + + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + +

    Variables

    const string kEnergyDimLabel = "energy"
     Dimension label for the energy dispersive dimension of multi-dimensional datasets. More...
     Dimension label for the energy dispersive dimension of multi-dimensional datasets. More...
     
    const string kAngleDimLabel = "angle"
     Dimension label for the angle dispersive dimension of multi-dimensional datasets. More...
     Dimension label for the angle dispersive dimension of multi-dimensional datasets. More...
     
    const string kScanDimLabel = "scan"
     Dimension label for the scan dimension of multi-dimensional datasets. More...
     Dimension label for the scan dimension of multi-dimensional datasets. More...
     
    const string kDataDimLabel = "data"
     Dimension label for the data dimension. More...
     Dimension label for the data dimension. More...
     
    const string kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;"
     List of preferred datasets to load for preview. More...
    const string kPreviewDatasets = "ImageEnergyDistribution;ScientaSpectrum;ScientaImage;Counts;SampleCurrent;"
     List of preferred datasets to load for preview. More...
     
    const string kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;"
     List of datasets that must be loaded to determine the axis scaling of a Scienta image. More...
    const string kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;Eph;"
     List of datasets that must be loaded to determine the axis scaling of a Scienta image. More...
     
    const string kEssentialDiagnostics = "ManipulatorX;ManipulatorY;ManipulatorZ;ManipulatorTheta;ManipulatorTilt;ManipulatorPhi;MonoEnergy;"
     List of diagnostic datasets that are normally loaded with a scan. More...
     
    const string kTransposedDatasets = "ScientaImage;"
     List of datasets that should be transposed upon loading. More...
     List of datasets that must be transposed upon loading. More...
     
    const variable kDetectorSensitivity = 1
     multiply scienta detector intensity by this value to get actual counts. More...
     
    const variable kDSCPositioners = 0x0001
     
    const variable kDSCDetectors = 0x0002
     
    const variable kDSCScientaScaling = 0x0004
     
    const variable kDSCPreview = 0x0008
     
    const variable kDSCEssentialDiags = 0x0010
     
    const variable kDSCAttrs = 0x0020
     
    const variable kDSCDiags = 0x0040
     
    const variable kDSCSnaps = 0x0080
     
    const variable kDSCMeta = 0x0100
     
    const variable kDSCMonitors = 0x0200
     
    const variable kDSCRegions = 0x0400
     
    const variable kDSCOther = 0x8000
     
    const variable kDSCAll = 0xffff
     

    Detailed Description

    import data from PShell

    -

    HDF5 file import from the PShell data acquisition program. the main import functions are:

    +

    HDF5 file import from the PShell data acquisition program.

    +

    the module provides two main entry functions:

    -

    the following helper functions are also needed:

    - +
    Version
    up to igor 8, this module requires the HDF5 XOP which must be enabled manually. as of igor 9 and later, HDF5 is built in.
    +
    +in version 2.0, the interface has changed significantly.
    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -

    Function Documentation

    - -

    ◆ find_attr_folder()

    + +

    ◆ kill_matching_waves()

    - - - - - -
    - + - - + -
    static dfr find_attr_folder string kill_matching_waves ( dfref dataDF)dfr,
    -
    -static
    -
    - -

    find the attributes data folder

    -

    this is the :attr folder.

    - -

    Definition at line 1476 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ find_scale_wave()

    - -
    -
    - - - - - -
    - - - + + - + - - + + - - - - - - - - + + @@ -335,50 +327,18 @@ Licensed under the Apache License, Version 2.0 (the "License");
    static wave find_scale_wave ( string name, pattern,
    dfref dataDF, variable recurse,
    dfref scanDF,
    dfref attrDF string killed = defaultValue 
    -
    -static
    -

    Definition at line 1564 of file pearl-pshell-import.ipf.

    +

    kill any waves matching a pattern in the experiment

    +

    this may be used to kill big waves of original data before saving.

    +

    example: to kill all ScientaImage waves:

    kill_matching_waves($"root:", "ScientaImage", 1)
    +
    +

    Definition at line 2554 of file pearl-pshell-import.ipf.

    - -

    ◆ find_scan_folder()

    - -
    -
    - - - - - -
    - - - - - - - - -
    static dfr find_scan_folder (dfref dataDF)
    -
    -static
    -
    - -

    find the scan folder

    -

    the scan folder is the one that contains the :attr folder the data and scan folders may refer to the same folder.

    - -

    Definition at line 1459 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ ps_detect_scale()

    + +

    ◆ ps_detect_scale()

    @@ -386,6 +346,12 @@ Licensed under the Apache License, Version 2.0 (the "License");
    variable ps_detect_scale ( + dfref  + data_df, + + + + wave  ax, @@ -416,15 +382,15 @@ Licensed under the Apache License, Version 2.0 (the "License");

    detect the dimension scales from attributes.

    -

    the function checks the data , scan and attributes folders for scan parameters. the results are written to the provided waves. the function is normally called by ps_scale_datasets() but can also be used independently.

    -

    the current datafolder must be the data or the scan folder. the data folder contains the waves that are to be scaled. the scan folder contains the scan positions and the :attr folder.

    +

    the function checks the data , scan and attributes folders for scan parameters. the results are written to the provided waves. the function is normally called by ps_scale_datasets() but can also be used independently.

    +

    the data folder contains the waves that are to be scaled. the function looks for the scan positions and diagnostics as necessary. if the scaling data is not found, the scales are not changed. the kEssentialDiags flag can be used with psh5_load() to select the necessary datasets.

    the provided waves are redimensioned by the function, and dimension labels are set. the scale parameters can then be extracted by keyword, e.g.,

    • lo[%energy] analyser energy dimension.
    • lo[%angle] analyser angle dimension.
    • lo[%scan] scan dimension.
    • lo[%data] data dimension.
    -

    the function tries to read the following waves, in the data, scan, and attributes folders, where the first folder in the list takes precedence. it may fall back to more or less reasonable default values if no data is not found.

      +

      the function tries to read the following waves, in the data, scan, and attributes/diagnostics folders, where the first folder in the list takes precedence. it may fall back to more or less reasonable default values if no data is not found.

      • LensMode
      • ScientaChannelBegin
      • ScientaChannelEnd
      • @@ -435,6 +401,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
      Parameters
      + @@ -442,10 +409,133 @@ Licensed under the Apache License, Version 2.0 (the "License");
      data_dfdata folder which contains the waves to be scaled. this is usually the "scan" or "region" folder.
      axtext wave to receive the axis labels.
      lowave to receive the lower limits.
      hiwave to receive the upper limits.
      -
      Returns
      the function results are written to the lo, hi, un, and ax waves.
      -
      Version
      this function supports regions from version 1.03. check that you're in the correct data folder!
      +
      Returns
      the function results are written to the lo, hi, un, and ax waves.
      -

      Definition at line 1621 of file pearl-pshell-import.ipf.

      +

      Definition at line 2225 of file pearl-pshell-import.ipf.

      + +
    +
    + +

    ◆ ps_find_attr_folder()

    + +
    +
    + + + + + + + + +
    dfr ps_find_attr_folder (dfref scan_df)
    +
    + +

    find the attributes data folder

    +

    the attributes folder contains diagnostic beamline data at each scan point. the folder can have one of several names due to different pshell versions: "attr", "attrs", or "diags" (from 2022 on). historically, the folder was named "attr" due to the area detector software.

    +

    assuming we are in the scan folder (where the ScanWritables, etc.) are, find the associated attributes folder.

    + +

    Definition at line 2134 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ ps_find_scale_wave()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    wave ps_find_scale_wave (string name,
    dfref df1,
    dfref df2,
    dfref df3 
    )
    +
    + +

    find a wave in scan and attr data folders

    +

    look up a wave by name in the given three data folders. return the first one found.

    +
    Parameters
    + + + + +
    df1first data folder to check
    df2second data folder to check
    df3third data folder to check
    +
    +
    +
    Returns
    wave reference, empty reference if not found
    + +

    Definition at line 2161 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ ps_find_scan_folder()

    + +
    +
    + + + + + + + + +
    dfr ps_find_scan_folder (dfref data_df)
    +
    + +

    find the scan folder of current data

    +

    assuming we are in the data folder (where the scan results, ScientaSpectrum, etc.) are, find the associated scan folder. this can either be the same (usually) or the parent folder (multi-region scans).

    +

    the scan folder is the one that contains the ScanWritables wave. the data and scan folders may refer to the same folder.

    + +

    Definition at line 2111 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ ps_fix_folder_name()

    + +
    +
    + + + + + + + + +
    string ps_fix_folder_name (string group_name)
    +
    + +

    convert HDF5 group name to data folder name and fix compatibility issues

    + +

    Definition at line 1065 of file pearl-pshell-import.ipf.

    @@ -467,17 +557,17 @@ Licensed under the Apache License, Version 2.0 (the "License");

    set the dimension scales of a loaded PShell Scienta dataset according to attributes.

    the current datafolder must contain the :attr folder. the data wave can be in the current folder or a sub-folder.

    -

    the dimension labels of the dataset waves must have been set correctly, e.g. by ps_set_dimlabels(). this is implicitly done by the high-level load functions.

    -

    the function is useful if a single dataset is loaded and scaled. if multiple datasets are loaded, ps_scale_datasets() is slightly more efficient.

    +

    the dimension labels of the dataset waves must have been set correctly, e.g. by ps_set_dimlabels(). this is implicitly done by the high-level load functions.

    +

    the function is useful if a single dataset is loaded and scaled. if multiple datasets are loaded, ps_scale_datasets() is slightly more efficient.

    Parameters
    - +
    datadata wave to be scaled. dimension labels (index -1) must be set correctly, cf. ps_set_dimlabels().
    datadata wave to be scaled. dimension labels (index -1) must be set correctly, cf. ps_set_dimlabels().
    Version
    this function supports regions from version 1.03.
    -

    Definition at line 1550 of file pearl-pshell-import.ipf.

    +

    Definition at line 2528 of file pearl-pshell-import.ipf.

    @@ -526,8 +616,8 @@ Licensed under the Apache License, Version 2.0 (the "License");

    set the dimension scales of a dataset.

    -

    the function is normally called by ps_scale_datasets() but can also be used independently. the limits and units must be given as function arguments with proper dimension labels.

    -

    the provided limit and unit waves must have dimension labels matching the -1 index dimension labels of the data wave, such as set by the ps_detect_scale() function. the scale parameters are extracted by keyword, e.g.,

      +

      the function is normally called by ps_scale_datasets() but can also be used independently. the limits and units must be given as function arguments with proper dimension labels.

      +

      the provided limit and unit waves must have dimension labels matching the -1 index dimension labels of the data wave, such as set by the ps_detect_scale() function. the scale parameters are extracted by keyword, e.g.,

      • lo[%energy] analyser energy dimension.
      • lo[%angle] analyser angle dimension.
      • lo[%scan] scan dimension.
      • @@ -546,12 +636,12 @@ Licensed under the Apache License, Version 2.0 (the "License");
        Version
        this function supports regions from version 1.03.
        -

        Definition at line 1781 of file pearl-pshell-import.ipf.

        +

        Definition at line 2389 of file pearl-pshell-import.ipf.

    - -

    ◆ ps_scale_datasets()

    + +

    ◆ ps_scale_datasets()

    @@ -559,7 +649,8 @@ Licensed under the Apache License, Version 2.0 (the "License");
    variable ps_scale_datasets ( - ) + dfref  + scan_df) @@ -567,11 +658,16 @@ Licensed under the Apache License, Version 2.0 (the "License");

    set the dimension scales of loaded PShell Scienta datasets according to attributes.

    datasets listed in the ScanReadables waves are scaled according to the attribute waves in the data, scan, and attributes folders, whichever is found first.

    -

    the current datafolder must contain the ScanReadables wave and the :attr folder. the ScanReadables text wave contains names of the waves to scale. wave names can include a relative path to a sub-folder. the path separator is "/".

    -

    the dimension labels of the dataset waves must have been set correctly, e.g. by ps_set_dimlabels(). this is implicitly done by the high-level load functions.

    -
    Version
    this function supports regions from version 1.03. check that you're in the correct data folder!
    +

    the specified datafolder must contain the ScanReadables wave and the :attr folder. the ScanReadables text wave contains names of the waves to scale. wave names can include a relative path to a sub-folder. the path separator is "/".

    +

    the dimension labels of the dataset waves must have been set correctly, e.g. by ps_set_dimlabels(). this is implicitly done by the high-level load functions.

    +
    Parameters
    + + +
    scan_dfscan data folder. must contain the ScanReadables wave.
    +
    +
    -

    Definition at line 1504 of file pearl-pshell-import.ipf.

    +

    Definition at line 2483 of file pearl-pshell-import.ipf.

    @@ -607,7 +703,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1383 of file pearl-pshell-import.ipf.

    +

    Definition at line 2031 of file pearl-pshell-import.ipf.

    @@ -638,7 +734,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    set dimension labels according to the axis type

    -

    same as ps_set_dimlabels() except that the dimension labels are set according to a separate name argument instead of the wave name.

    +

    same as ps_set_dimlabels() except that the dimension labels are set according to a separate name argument instead of the wave name.

    Parameters
    @@ -653,12 +749,12 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 1402 of file pearl-pshell-import.ipf.

    +

    Definition at line 2050 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_close_file()

    + +

    ◆ psh5_close_file()

    @@ -666,8 +762,8 @@ Licensed under the Apache License, Version 2.0 (the "License");
    - - + +
    datadata wave as loaded from PShell file.
    variable psh5_close_file (variable fileID)dfref file_df)
    @@ -675,40 +771,70 @@ Licensed under the Apache License, Version 2.0 (the "License");

    close a HDF5 file opened by psh5_open_file.

    this function just closes the HDF5 file. no change is made to the loaded data.

    +

    the function requires the specified data folder to contain a variable named file_id that specifies the HDF5 file ID. the variable may also be in a parent folder. the variable is killed after the file has been closed. if the folder or variable can't be found, the function does nothing.

    Parameters
    - +
    fileIDID of open HDF5 file from psh5_open_file().
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). the reference may also point to a child folder, the function will look for a file_id variable in all parent folders.
    +
    Note
    on the command line, data folder references can be specified using the $-notation like $"foldername". the current folder is written as $":".
    -

    Definition at line 140 of file pearl-pshell-import.ipf.

    +

    Definition at line 509 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_list_scan_datasets()

    + +

    ◆ psh5_create_folders()

    - + - - + + + + +
    string psh5_list_scan_datasets dfr psh5_create_folders (variable fileID, string datasetpath)
    +
    + +

    create all data folders along a dataset path

    +

    if the path ends with a slash, the path is interpreted as a group path, and each part is mapped to a data folder. else, the last part of the path is the name of a dataset and will not produce a folder.

    +

    the path will always be interpreted as starting from the root, regardless whether it starts with a slash or not.

    +

    spaces are removed from folder names, and the names are cleaned up to produce simple names.

    +

    a string variable named "s_hdf5_group" is added to each created folder and contains the incremental path.

    +

    the first child folder is created in the current data folder. at the end, the lowest child folder is selected and returned as the function result.

    +
    Parameters
    + + +
    datasetpathhdf5 group path to dataset, e.g. "/scan 1/region 1/ScientaImage".
    +
    +
    +
    Returns
    data folder reference of the lowest child folder.
    + +

    Definition at line 990 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ psh5_dataset_to_folder()

    + +
    +
    + + + + + + - - - - - - - + @@ -718,40 +844,116 @@ Licensed under the Apache License, Version 2.0 (the "License");
    dfr psh5_dataset_to_folder (dfref parent_df,
    string scanpath,
    variable include_regions = defaultValue datasetpath 
    -

    list datasets of a PShell scan group.

    -

    the function returns a list of all datasets of the selected scan. this does not include datasets from the attributes sub-group.

    -
    Note
    in a future version, an option may be introduced to filter datasets by function (Readable and/or Writable).
    +

    map dataset path to datafolder path

    +

    if the path ends with a slash, the path is interpreted as a group path, and each part maps to a data folder. if the last part of the path is the name of a dataset, it is discarded.

    +

    spaces are removed from folder names, and the names are cleaned up to produce simple names.

    +

    the path is interpreted as relative to the specified parent data folder. regardless whether it starts with a slash or not.

    Parameters
    - - + +
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    datasetpathhdf5 group path to dataset, e.g. "/scan 1/region 1/ScientaImage".
    parent_dfparent data folder
    -
    Returns
    semicolon-separated list of dataset paths.
    -
    Version
    since version 1.03 this function returns paths relative to scanpath.
    +
    Returns
    data folder reference
    -

    Definition at line 440 of file pearl-pshell-import.ipf.

    +

    Definition at line 1034 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_list_scan_regions()

    + +

    ◆ psh5_extract_region_paths()

    - + - - + + + + +
    string psh5_list_scan_regions string psh5_extract_region_paths (variable fileID, string datasets)
    +
    + +

    trim dataset paths to the scan/region part

    +

    return dataset paths stripped to the form /scan*‍/region*‍/.

    +

    the function matches each path for scan and region tokens in the first two path elements and strips off the remainder. if there are no region-based datasets, the function returns an empty string.

    +

    the function operates on a single path or a semicolon-separated list of paths. the items of the returned list are unique.

    +
    Parameters
    + + +
    datasetssemicolon separated list of dataset paths
    +
    +
    +
    Returns
    list of scan/region paths (no duplicates)
    + +

    Definition at line 853 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ psh5_extract_scan_paths()

    + +
    +
    + + + + + + + + +
    string psh5_extract_scan_paths (string datasets)
    +
    + +

    trim dataset paths to the scan part

    +

    return dataset paths stripped to the form /scan*‍/.

    +

    the function matches each path for a scan token in the first path element and strips off the remaining path. if there are no scan-based datasets, the function returns an empty string.

    +

    the function operates on a single path or a semicolon-separated list of paths. the items of the returned list are unique.

    +
    Parameters
    + + +
    datasetssemicolon separated list of dataset paths
    +
    +
    +
    Returns
    list of scan paths (no duplicates)
    + +

    Definition at line 803 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ psh5_filter_datasets_rank()

    + +
    +
    + + + + + + - + + + + + + + + + + + + + @@ -761,23 +963,123 @@ Licensed under the Apache License, Version 2.0 (the "License");
    string psh5_filter_datasets_rank (string datasets,
    string scanpath ranks,
    variable min_rank,
    variable max_rank 
    -

    list regions of a PShell scan group.

    -

    the function returns a list of all region groups of the selected scan.

    +

    filter datasets by rank

    Parameters
    - - + +
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    datasetssemicolon-separated list of datasets to be checked.
    rankssemicolon-separated list of ranks of each dataset.
    -
    Returns
    semicolon-separated list of datagroup paths.
    +
    Returns
    filtered dataset list.
    -

    Definition at line 481 of file pearl-pshell-import.ipf.

    +

    Definition at line 728 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_list_scans()

    + +

    ◆ psh5_list_all_datasets()

    + +
    +
    + + + + + + + + +
    string psh5_list_all_datasets (variable file_id)
    +
    + +

    list all datasets in a file

    +

    the function returns a list of all datasets in a file. each dataset is listed by its full path like, e.g., "/scan 1/region 1/dataset 1".

    +

    this function wraps a one-line HDF5 operation and is provided just to be more memorable.

    +
    Parameters
    + + +
    file_idID of open HDF5 file from psh5_open_file().
    +
    +
    +
    Returns
    semicolon-separated list of absolute dataset paths.
    + +

    Definition at line 605 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ psh5_list_dataset_info()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    variable [string datatypes, string ranks, string dimensions] psh5_list_dataset_info (string variable,
    string file_id,
    variable string,
    sds datasets 
    )
    +
    + +

    list data types and dimensions of datasets

    +

    this function has multiple returns.

    +
    Parameters
    + + +
    file_idID of open HDF5 file from psh5_open_file().
    +
    +
    +
    Returns
    semicolon-separated list of (simplified) datatypes. datatypes are marked as "i" (integer), "f" (float), "s" (string) or "?" (unknown).
    +
    +semicolon-separated list of ranks (number of dimensions).
    +
    +semicolon-separated list of dimensions. each item is a comma-separated list of dimension sizes. items do not contain trailing commas.
    +

    filter a list of datasets by string matching

    +

    this function can be used to extract certain dataset paths from a list of all datasets in a file. the matching is insensitive to spaces and case.

    +

    examples match strings:

      +
    • "*&zwj;/scan1/region1/*" match all datasets in scan 1, region 1
    • +
    • "!*&zwj;/diags/*" remove diagnostics from list
    • +
    +
    Parameters
    + + + +
    datasetssemicolon separated list of dataset paths
    matchmatch string for igor's StringMatch function
    +
    +
    +
    Returns
    list of matching datasets
    + +

    Definition at line 631 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ psh5_list_scans()

    @@ -786,7 +1088,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    string psh5_list_scans ( variable  - fileID) + file_id) @@ -796,51 +1098,81 @@ Licensed under the Apache License, Version 2.0 (the "License");

    the function returns a list of all top-level groups whose name starts with "scan".

    Parameters
    - +
    fileIDID of open HDF5 file from psh5_open_file().
    file_idID of open HDF5 file from psh5_open_file().
    Returns
    semicolon-separated list of group paths.
    -

    Definition at line 405 of file pearl-pshell-import.ipf.

    +

    Definition at line 574 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_complete()

    + +

    ◆ psh5_load()

    - + - + - + - + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + @@ -850,37 +1182,39 @@ Licensed under the Apache License, Version 2.0 (the "License");
    string psh5_load_complete dfr psh5_load ( string ANickName, path_name,
    string APathName, file_name,
    string AFileName, scans,
    string regions,
    string datasets,
    variable load_data = defaultValue, classes = defaultValue,
    variable load_attr = defaultValue max_rank = defaultValue,
    string reduction_func = defaultValue,
    string reduction_params = defaultValue,
    dfref dest_df = defaultValue 
    -

    load everything from a PShell data file.

    +

    main data loading function

    +

    load the requested elements from the given file.

    +

    scans, regions and datasets are additive. wildcards can be used to select multiple or all datasets.

    +

    classes are subtractive: only datasets of specified classes are loaded. by default, only positioners, detectors, scaling and essential diagnostics are loaded.

    +

    essential diags, scaling, positioners related to requested detectors are always loaded

    +

    data reduction (if specified) applies to 3d data, see psh5_load_dataset_reduced() for details.

    Parameters
    - - - - - + + + + + + + +
    ANickNamedestination folder name (top level under root)
    APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
    AFileNameif empty a dialog box shows up
    load_dataselect whether datasets (positioners and detectors) are loaded.
      -
    • 1 (default) load data.
    • -
    • 0 do not load data.
    • -
    -
    load_attrselect whether attributes (auxiliary device readbacks) are loaded. for proper wave scaling, the attributes must be loaded.
      -
    • 1 (default) load attributes.
    • -
    • 0 do not load attributes.
    • -
    -
    path_nameigor symbolic path name. can be empty if the path is specified in file_name or a dialog box should be displayed
    file_nameif empty a dialog box shows up
    dest_dfdestination folder reference. if dest_df is specified, data is loaded into this folder. else, a new folder derived from the file name is created under root:
    scanssemicolon-separated list of scan paths to load. scan groups are at the top level, their name consists of "scan", an optional space and a number. all datasets in the group and sub-groups are considered for loading unless excluded by other arguments. if empty, no datasets are loaded based on their relation to a scan. names are matched by Igor's StringMatch function. the matching is insensitive to case and spaces. to load all scans, pass "/scan*". the leading slash before "scan" can be omitted.
    regionssemicolon-separated list of region paths to load. region groups are children of scan groups, their name consists of "region", an optional space and a number. all datasets in the group and sub-groups are considered for loading unless excluded by other arguments. if empty, no datasets are loaded based on their relation to a region. names are matched by Igor's StringMatch function. the matching is insensitive to case and spaces. to load all regions of scan 1, pass "/scan1/region*". to load regions 1 of all scans, pass "/scan*&zwj;/region1". the leading slash before "scan" can be omitted.
    datasetssemicolon-separated list of dataset paths to load. this allows to load individual datasets. names are matched by Igor's StringMatch function against full dataset paths. to load all datasets named "SampleCurrent", pass "*&zwj;/SampleCurrent". the matching is insensitive to case and spaces. additional datasets may be loaded for scaling.
    classesfilter datasets (that were selected by the scans, regions and datasets arguments) by class. this allows, for example, to exclude the diagnostics. note that scaling datasets are always loaded. the value is a bit-wise switch, typically the arithmetic disjunction of kDSCXxxx constants. by default, only positioners, detectors, scaling and essential diagnostics are loaded. to completely load all datasets, specify kDSCAll.
    max_rankload only datasets with lower or equal rank.
    -
    Returns
    complete path of the loaded file if successful. empty string otherwise.
    +
    Returns
    data folder reference of the file-level data folder. same as dest_df if specified.
    global string s_filepath in new data folder contains the full file path on disk.
    -global string s_scanpaths in new data folder contains a list of scan groups inside the file.
    +global string s_scanpaths in new data folder contains a list of scan groups inside the file. +
    +global string s_loaded_datasets in new data folder contains a list of loaded datasets. the items are full group paths of the HDF5 file. dataset paths can be mapped to loaded data folders using the psh5_dataset_to_folder function.
    -

    Definition at line 170 of file pearl-pshell-import.ipf.

    +

    Definition at line 158 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_dataset()

    + +

    ◆ psh5_load_dataset()

    @@ -888,26 +1222,32 @@ global string s_scanpaths in new data folder contains a list of scan groups insi string psh5_load_dataset ( - variable  - fileID, + dfref  + file_df, string  - scanpath, - - - - - string  - datasetname, + datasetpath, variable  - set_scale = defaultValue  + create_folders = defaultValue, + + + + + string  + reduction_func = defaultValue, + + + + + string  + reduction_params = defaultValue  @@ -918,35 +1258,31 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    load a dataset from an open PShell HDF5 file.

    -

    if the dataset has a maximum of two dimensions, the function loads it at once. if it has more than two dimension, the function calls psh5_load_dataset_slabs() to load the data slab by slab.

    +

    if the dataset has a maximum of two dimensions, the function loads it at once. if it has more than two dimension, the function calls psh5_load_dataset_slabs() to load the data slab by slab.

    -

    the dataset is loaded into the current data folder unless datasetname contains a region specifier. in the latter case, the dataset is loaded into sub-folder with the name of the region. the function returns from the original data folder.

    +

    the dataset is loaded into the current data folder or a tree based on the group path given in the datasetpath argument. the function returns from the original data folder.

    +

    only numeric and string data types are supported, string datasets must have rank 1.

    Parameters
    - - - - + + + + +
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    datasetnamename of the dataset. the name of the loaded wave is a cleaned up version of the dataset name. the name can include the region name as a relative path, e.g. "region1/ScientaSpectrum". in this case, the dataset is loaded into a sub-folder named "region1".
    set_scaleby default, the function tries to set the wave scaling if the attributes have been loaded. if multiple datasets are loaded from a file, it is more efficient to set the scaling of all loaded datasets at the end by calling ps_scale_datasets().
      -
    • 1 (default) set the wave scaling.
    • -
    • 0 do not set the wave scaling.
    • -
    -
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). if undefined, the current datafolder is assumed.
    datasetpathgroup path and name of the dataset, e.g. "/scan 1/ScientaImage". HDF5 groups map to igor data folders below the current data folder, the wave is placed into the leaf folder. the names of groups and waves are cleaned up to produce simple names, in particular, spaces and other illegal characters are removed.
    create_foldersif 1 (default), data folders according to the group path are created. if 0, the dataset is loaded into the current folder.
    reduction_funcdata reduction function. three-dimensional datasets can be reduced in dimensionality by on-the-fly data reduction. by default (or if empty string), no reduction is applied. see psh5_load_dataset_reduced().
    reduction_paramsparameter string for the reduction function.
    -
    Returns
    name of loaded wave if successful. empty string otherwise.
    -
    Version
    this function supports regions as of version 1.03.
    +
    Returns
    semicolon-separated list of loaded wave names. multiple waves are loaded if the dataset has a compound data type. in that case the wave name is a concatenation of the dataset and field names (see HDF5LoadData).
    -

    Definition at line 706 of file pearl-pshell-import.ipf.

    +

    Definition at line 1176 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_dataset_meta()

    + +

    ◆ psh5_load_dataset_meta()

    @@ -954,20 +1290,14 @@ global string s_scanpaths in new data folder contains a list of scan groups insi variable psh5_load_dataset_meta ( - variable  - fileID, + dfref  + file_df, string  - datapath, - - - - - string  - datasetname, + datasetpath, @@ -984,25 +1314,28 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    load metadata of a PShell dataset.

    -

    "metadata" are the HDF5 attributes attached to the scan dataset.

    -

    data is added to the wave note.

    +

    metadata are the HDF5 attributes attached to a dataset. they are mapped to "key=value" pairs and added to the wave note in separate lines. the following attributes are loaded. names and mappings are hard-coded.

    +
      +
    • "Writable Dimension" -> "ScanDimension"
    • +
    • "Writable Index" -> "WriteableIndex"
    • +
    • "Readable Index" -> "ReadableIndex"
    • +
    Parameters
    - - - + +
    fileIDID of open HDF5 file from psh5_open_file().
    datapathpath to the containing group in the HDF5 file. path separator is the slash "/".
    datasetnamename of the dataset. may include relative path.
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). if undefined, the current datafolder is assumed.
    datasetpathgroup path and name of the dataset. path separator is the slash "/".
    datawavemetadata is added to the wave note of this wave.
    Returns
    0 if successful, non-zero if an error occurred.
    -

    Definition at line 1091 of file pearl-pshell-import.ipf.

    +

    Definition at line 1887 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_dataset_reduced()

    + +

    ◆ psh5_load_dataset_reduced()

    @@ -1010,20 +1343,14 @@ global string s_scanpaths in new data folder contains a list of scan groups insi string psh5_load_dataset_reduced ( - variable  - fileID, + dfref  + file_df, string  - scanpath, - - - - - string  - datasetname, + datasetpath, @@ -1035,7 +1362,13 @@ global string s_scanpaths in new data folder contains a list of scan groups insi string  - reduction_param, + reduction_params, + + + + + variable  + create_folders = defaultValue, @@ -1057,17 +1390,20 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    -

    load a reduced dataset from the open PShell HDF5 file.

    -

    the function loads the dataset image by image using the hyperslab option and applies a custom reduction function to each image. the results from the reduction function are written to the ReducedData1, ReducedData2, etc. waves. the raw data are discarded.

    -

    by default, the reduction function is called in separate threads to reduce the total loading time. (see the global variable psh5_perf_secs which reports the total run time of the function.) the effect varies depending on the balance between file loading (image size) and data processing (complexity of the reduction function). for debugging the reduction function, multi-threading can be disabled.

    -

    if the reduction function requires the image waves to be scaled properly, the attributes must have been loaded by psh5_load_scan_attrs() before. in this case, the scales of the result waves are also set by the function. otherwise, the results can also be scaled by ps_scale_dataset() later.

    +

    load a dataset with reduced dimensionality

    +

    the function loads the dataset image by image using the hyperslab option and applies a custom reduction function like numeric integration, curve fitting, etc. to each image. the results from the reduction function are written to the ReducedData1, ReducedData2, etc. waves. the raw data are discarded.

    +

    example reduction functions can be found in the PearlScientaPreprocess module. they must implement the adh5_default_reduction() interface.

    +

    by default, the reduction function is called in separate threads to reduce the total loading time. (psh5_load() reports the total run time in the global variable psh5_perf_secs.) the effect varies depending on the balance between file loading (image size) and data processing (complexity of the reduction function).

    +

    the function loads images (as hyperslabs) one by one and passes them to the reduction function. only a limited number of images are held in the queue at a time to limit memory use. for debugging the reduction function, multi-threading can be disabled (also remove threadsafe attributes from reduce_slab_image() and the reduction function!)

    +

    if the reduction function requires the image waves to be scaled properly, the attributes must have been loaded by psh5_load_scan_attrs() before. in this case, the scales of the result waves are also set by the function. otherwise, the results can also be scaled by ps_scale_dataset() later.

    Parameters
    - + - + +
    fileIDID of open HDF5 file from psh5_open_file().
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). if undefined, the current datafolder is assumed.
    scanpathpath to scan group in the HDF5 file.
    datasetnamename of the dataset. this must currently be "ScientaImage", other data is not supported. the name of the loaded wave is a cleaned up version of the dataset name. the name can include the region name as a relative path, e.g. "region1/ScientaImage". in this case, the dataset is loaded into a sub-folder named "region1".
    reduction_funccustom data reduction function. this can be any user-defined function which has the same parameters as adh5_default_reduction. some reduction functions are predefined in the PearlScientaPreprocess module.
    reduction_paramparameter string for the reduction function.
    reduction_paramsparameter string for the reduction function.
    create_foldersif 1 (default), data folders according to the group path are created. if 0, the dataset is loaded into the current folder.
    progressprogress window.
    • 1 (default) show progress window
    • 0 do not show progress window
    • @@ -1082,91 +1418,14 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    -
    Returns
    semicolon-separated list of the loaded dataset ReducedData1, ReducedData2, etc. if successful. auxiliary waves, scan positions, attributes are loaded but not listed in the string. empty string if an error occurred. error messages are printed to the history.
    -
    Version
    this function supports regions as of version 1.03.
    +
    Returns
    semicolon-separated list of the loaded dataset ReducedData1, ReducedData2, etc. if successful. auxiliary waves, scan positions, attributes are loaded but not listed in the string. empty string if an error occurred. error messages are printed to the history.
    -

    Definition at line 2040 of file pearl-pshell-import.ipf.

    +

    Definition at line 1472 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_dataset_slab()

    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    string psh5_load_dataset_slab (variable fileID,
    string datapath,
    string datasetname,
    variable dim2start,
    variable dim2count,
    variable dim3start,
    variable dim3count 
    )
    -
    - -

    load a single image from the open PShell data file.

    -

    the function can average over a region in the extra dimensions.

    -
    Parameters
    - - - - - - - - -
    fileIDID of open HDF5 file from psh5_open_file().
    datapathpath to the containing group in the HDF5 file. path separator is the slash "/".
    datasetname of the dataset. also defines the name of the loaded wave.
    dim2start2nd dimension coordinate of the first image set to 0 if dimension may not be present
    dim2countnumber of subsequent images to average set to 1 if dimension may not be present
    dim3start3rd dimension coordinate of the first image set to 0 if dimension may not be present
    dim3countnumber of subsequent images to average set to 1 if dimension may not be present
    -
    -
    -
    Returns
    name of loaded wave if successful. empty string otherwise.
    - -

    Definition at line 1284 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ psh5_load_dataset_slabs()

    + +

    ◆ psh5_load_dataset_slabs()

    @@ -1174,20 +1433,20 @@ global string s_scanpaths in new data folder contains a list of scan groups insi string psh5_load_dataset_slabs ( + dfref  + file_df, + + + + + string  + datasetpath, + + + + variable  - fileID, - - - - - string  - datapath, - - - - - string  - datasetname, + create_folders = defaultValue, @@ -1204,43 +1463,61 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    load a dataset slab-wise from the open PShell HDF5 file.

    -

    the function loads the dataset image by image using the hyperslab option.

    +

    the function loads the dataset image by image using the hyperslab option. the wave is loaded into the current data folder.

    Parameters
    - - - + + +
    fileIDID of open HDF5 file from psh5_open_file().
    datapathpath to the containing group in the HDF5 file. path separator is the slash "/".
    datasetname of the dataset. also defines the name of the loaded wave.
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). if undefined, the current datafolder is assumed.
    datasetpathgroup path and name of the dataset. the dataset name defines the name of the loaded wave (after cleaning up).
    progressselect whether a progress window is displayed during the process.
    • 1 (default) show progress window.
    • 0 do not show progress window.
    create_foldersif 1 (default), data folders according to the group path are created. if 0, the dataset is loaded into the current folder.
    -
    Returns
    name of loaded wave if successful. empty string otherwise.
    +
    Returns
    semicolon-separated list of loaded wave names. in the current version, the function returns zero or one wave, as it does not support compound types.
    -

    Definition at line 1148 of file pearl-pshell-import.ipf.

    +

    Definition at line 1289 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_info()

    + +

    ◆ psh5_load_datasets()

    - + - - + + - + + + + + + + + + + + + + + + + + + + @@ -1250,393 +1527,55 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    string psh5_load_info string psh5_load_datasets (string APathName, dfref file_df,
    string AFileName datasets,
    variable create_folders = defaultValue,
    string reduction_func = defaultValue,
    string reduction_params = defaultValue 
    -

    load descriptive info from a PShell data file.

    -

    the info string lists the following information for each scan contained in the file:

      -
    • path of the scan group inside the file.
    • -
    • number of scan positions.
    • -
    • dataset names of scan positioners.
    • -
    • dataset names of detectors.
    • -
    +

    load multiple datasets from open file

    Parameters
    - - + + + +
    APathNameigor symbolic path name. can be empty if the path is specified in AFileName or a dialog box should be displayed
    AFileNameif empty a dialog box shows up
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). if undefined, the current datafolder is assumed.
    create_foldersif 1 (default), data folders according to the group path are created. if 0, the dataset is loaded into the current folder. the latter option should be used with care because datasets with same names may be overwritten.
    reduction_funcdata reduction function. three-dimensional datasets can be reduced in dimensionality by on-the-fly data reduction. by default (or if empty string), no reduction is applied. see psh5_load_dataset_reduced().
    reduction_paramsparameter string for the reduction function.
    -
    Returns
    newline terminated string.
    +
    Returns
    (string) semicolon-separated list of loaded datasets
    -

    Definition at line 2367 of file pearl-pshell-import.ipf.

    +

    Definition at line 1098 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_preview()

    + +

    ◆ psh5_load_general_group()

    - + - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    string psh5_load_preview string psh5_load_general_group (string APathName,
    dfref file_df) string AFileName,
    variable load_data = defaultValue,
    variable load_attr = defaultValue,
    string pref_scans = defaultValue,
    string pref_datasets = defaultValue 
    )
    -

    load a preview image from a PShell data file.

    -

    the data wave is loaded into the current data folder. attributes are loaded into the attr subfolder. existing waves in attr are deleted.

    +

    load organizational metadata from the general group.

    +

    the general group contains the following datasets: authors, pgroup, proposal, proposer, sample.

    +

    data is loaded into the current data folder. all items are loaded into strings, authors is a comma-separated list. missing items default to empty strings.

    Parameters
    - - - - - - +
    APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
    AFileNameif empty a dialog box shows up
    load_data1 (default): load data; 0: do not load data
    load_attr1 (default): load attributes; 0: do not load attributes note: for correct scaling of the image, the attributes need to be loaded
    pref_scanssemicolon-separated list of preferred scans. the items of the list are match strings for the Igor StringMatch function. the first matching scan (i.e. top-level HDF5 group with a matching name) is loaded from the file. if no match is found, the first scan is loaded.
    pref_datasetssemicolon-separated list of preferred datasets. the items of the list are match strings for the Igor StringMatch function. the first matching dataset is loaded from the file. if no match is found, the first dataset listed in the file is loaded.
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). if undefined, the current datafolder is assumed.
    -
    Returns
    name of loaded preview wave.
    +
    Returns
    semicolon-separated list of the objects.
    -

    Definition at line 251 of file pearl-pshell-import.ipf.

    +

    Definition at line 1803 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_reduced()

    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    string psh5_load_reduced (string ANickName,
    string APathName,
    string AFileName,
    funcref reduction_func,
    string reduction_param,
    variable progress = defaultValue,
    variable nthreads = defaultValue 
    )
    -
    - -

    load and reduce the ScientaImage dataset of the first scan of a PShell data file.

    -

    the resulting dataset is reduced in one image dimension by a user-defined reduction function, e.g. by region-of-interest integration, curve fitting, etc. cf. adh5_default_reduction for further details.

    -

    the function loads the dataset image by image using the hyperslab option and applies a custom reduction function to each image. the results from the reduction function are composed into one result wave. the raw data are discarded.

    -

    if the data is from the electron analyser driver and some special attributes are included, the function will set the scales of the image dimensions.

    -

    by default, the reduction function is called in separate threads to reduce the total loading time. (see the global variable psh5_perf_secs which reports the total run time of the function.) the effect varies depending on the balance between file loading (image size) and data processing (complexity of the reduction function). for debugging the reduction function, multi-threading can be disabled.

    -
    Parameters
    - - - - - - - - -
    ANickNamedestination folder name (top level under root).
    APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed.
    AFileNameif empty a dialog box shows up.
    reduction_funccustom data reduction function. this can be any user-defined function which has the same parameters as adh5_default_reduction. some reduction functions are predefined in the PearlScientaPreprocess module.
    reduction_paramparameter string for the reduction function.
    progressprogress window.
      -
    • 1 (default) show progress window
    • -
    • 0 do not show progress window
    • -
    -
    nthreads
      -
    • -1 (default) use as many threads as there are processor cores (in addition to main thread).
    • -
    • 0 use main thread only (for debugging and profiling).
    • -
    • >= 1 use a fixed number of (additional) threads.
    • -
    -
    -
    -
    -
    Returns
    semicolon-separated list of the loaded dataset ReducedData1, ReducedData2, etc. if successful. auxiliary waves, scan positions, attributes are loaded but not listed in the string. empty string if an error occurred. error messages are printed to the history.
    -
    -global string s_filepath in new data folder contains the full file path on disk.
    -
    -global string s_scanpaths in new data folder contains a list of scan groups inside the file.
    - -

    Definition at line 1911 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ psh5_load_scan_attrs()

    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - -
    string psh5_load_scan_attrs (variable fileID,
    string scanpath,
    variable attr_sets = defaultValue 
    )
    -
    - -

    load attributes of a PShell scan group.

    -

    "attributes" are the auxiliary data inside the attrs group. do not confuse with HDF5 attributes! HDF5 attributes are loaded by the psh5_load_scan_meta() function.

    -

    data is loaded into the current data folder. this should normally be the :attr folder inside the respective scan folder.

    -
    Parameters
    - - - - -
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    attr_setsspecify the attribute sets to be loaded. this value can be an arithmetic OR of the following constants. by default, all attributes are loaded.
      -
    • 1 all datasets that are present in the file.
    • -
    • 2 datasets relevant for wave scaling of Scienta data.
    • -
    -
    -
    -
    -
    Returns
    semicolon-separated list of the loaded waves.
    - -

    Definition at line 554 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ psh5_load_scan_complete()

    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    string psh5_load_scan_complete (variable fileID,
    string scanpath,
    variable load_data = defaultValue,
    variable load_attr = defaultValue 
    )
    -
    - -

    load all data of a selected scan from a PShell data file.

    -

    data is loaded into the current data folder. attribute datasets are loaded into sub-folder attr. region datasets are loaded into region sub-folders. existing data, if present, is overwritten.

    -
    Parameters
    - - - - - -
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    load_dataselect whether datasets (positioners and detectors) are loaded.
      -
    • 1 (default) load data.
    • -
    • 0 do not load data.
    • -
    -
    load_attrselect whether attributes (auxiliary device readbacks) are loaded. for proper wave scaling, the attributes must be loaded.
      -
    • 1 (default) load attributes.
    • -
    • 0 do not load attributes.
    • -
    -
    -
    -
    -
    Returns
    semicolon-separated list of the loaded data waves (excluding attributes).
    - -

    Definition at line 361 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ psh5_load_scan_data()

    - -
    -
    - - - - - - - - - - - - - - - - - - -
    string psh5_load_scan_data (variable fileID,
    string scanpath 
    )
    -
    - -

    load all datasets of a PShell scan group.

    -

    data is loaded into the current data folder. region datasets are loaded into the respective region sub-folders.

    -

    this function does not scale the datasets. call ps_scale_datasets() separately.

    -
    Parameters
    - - - -
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    -
    -
    -
    Returns
    semicolon-separated list of the loaded waves.
    - -

    Definition at line 514 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ psh5_load_scan_info()

    - -
    -
    - - - - - - - - - - - - - - - - - - -
    string psh5_load_scan_info (variable fileID,
    string scanpath 
    )
    -
    - -

    load descriptive info from a PShell scan.

    -

    the info string contains up to three lines which are made up of the following information:

      -
    • number of scan positions.
    • -
    • dataset names of scan positioners.
    • -
    • dataset names of detectors (without region names).
    • -
    • region names
    • -
    -
    Parameters
    - - - -
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to scan group in the HDF5 file.
    -
    -
    -
    Returns
    newline terminated string.
    - -

    Definition at line 2414 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ psh5_load_scan_meta()

    + +

    ◆ psh5_load_scan_meta()

    @@ -1644,8 +1583,8 @@ global string s_scanpaths in new data folder contains a list of scan groups insi string psh5_load_scan_meta ( - variable  - fileID, + dfref  + file_df, @@ -1676,46 +1615,46 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    data is loaded into the current data folder.

    Parameters
    - +
    fileIDID of open HDF5 file from psh5_open_file().
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). if undefined, the current datafolder is assumed.
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    Returns
    semicolon-separated list of the loaded waves.
    -

    Definition at line 625 of file pearl-pshell-import.ipf.

    +

    Definition at line 1954 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_scan_preview()

    + +

    ◆ psh5_match_dataset_classes()

    - + - - - - - - - + - + - + + + + + + + @@ -1725,117 +1664,43 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    string psh5_load_scan_preview string psh5_match_dataset_classes (variable fileID,
    string scanpath, datasets,
    variable set_scale = defaultValue, classes,
    string pref_datasets = defaultValue positioners = defaultValue,
    string detectors = defaultValue 
    -

    load a preview dataset from an open PShell HDF5 file.

    -

    if the dataset has a maximum of two dimensions, the function loads it at once. if it has more than two dimension, the function selects and loads one two-dimensional slab.

    +

    filter a list of datasets by classification

    Parameters
    - - - - + +
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    set_scaleby default, the function tries to set the wave scaling if the attributes have been loaded. if multiple datasets are loaded from a file, it is more efficient to set the scaling of all loaded datasets at the end by calling ps_scale_datasets().
      -
    • 1 (default) set the wave scaling.
    • -
    • 0 do not set the wave scaling.
    • -
    -
    pref_datasetssemicolon-separated list of preferred datasets. the items of the list are match strings for the Igor StringMatch function. the first matching dataset is loaded from the file. if no match is found, the first dataset listed in the file is loaded. if empty, a hard-coded default preference list is used.
    datasetssemicolon separated list of dataset paths
    classesdataset classes. arithmetic OR of the kDSCXxxx constants.
    -
    Returns
    name of loaded wave if successful. empty string otherwise.
    +
    Returns
    list of scan/region paths (no duplicates)
    -

    Definition at line 840 of file pearl-pshell-import.ipf.

    +

    Definition at line 899 of file pearl-pshell-import.ipf.

    - -

    ◆ psh5_load_scan_section()

    + +

    ◆ psh5_open_file()

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    string psh5_load_scan_section (variable fileID,
    string scanpath,
    variable dim,
    variable set_scale = defaultValue,
    string pref_datasets = defaultValue 
    )
    -
    - -

    load a longitudinal section of a scan from an open PShell HDF5 file.

    -

    the dataset must have three dimensions.

    -
    Parameters
    - - - - - - -
    fileIDID of open HDF5 file from psh5_open_file().
    scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
    dimreserved, must be 0.
    set_scaleby default, the function tries to set the wave scaling if the attributes have been loaded. if multiple datasets are loaded from a file, it is more efficient to set the scaling of all loaded datasets at the end by calling ps_scale_datasets().
      -
    • 1 (default) set the wave scaling.
    • -
    • 0 do not set the wave scaling.
    • -
    -
    pref_datasetssemicolon-separated list of preferred datasets. the items of the list are match strings for the Igor StringMatch function. the first matching dataset is loaded from the file. if no match is found, the first dataset listed in the file is loaded. if empty, a hard-coded default preference list is used.
    -
    -
    -
    Returns
    name of loaded wave if successful. empty string otherwise.
    -
    Warning
    EXPERIMENTAL: this function is under development.
    - -

    Definition at line 953 of file pearl-pshell-import.ipf.

    - -
    -
    - -

    ◆ psh5_open_file()

    - -
    -
    - - - + - + - + - - + + @@ -1846,28 +1711,117 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    open a HDF5 file created by the PShell data acquisition program and prepare the data folder.

    -

    the function opens a specified or interactively selected HDF5 file, creates a data folder $ANickName under root, and changes to the new data folder.

    -

    the file must be closed by psh5_close_file() after use.

    +

    the function opens a specified or interactively selected HDF5 file, and loads general information about the file including a list of contained datasets.

    +

    data can be loaded into an existing or new data folder under root.

    +

    the file must be closed by psh5_close_file() after use. the HDF5 file ID is stored in the global variable file_id until the file is closed.

    Parameters
    variable psh5_open_file dfr psh5_open_file ( string ANickName, path_name,
    string APathName, file_name,
    string AFileName dfref dest_df = defaultValue 
    - - - + + +
    ANickNamedestination folder name (top level under root).
    APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
    AFileNameif empty a dialog box shows up
    path_nameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
    file_nameif empty a dialog box shows up
    dest_dfdestination folder reference. if dest_df is specified, data is loaded into this folder. else, by default, a new folder derived from the file name is created in root:
    -
    Returns
    ID of open HDF5 file from HDF5OpenFile. zero if an error occurred.
    +
    Returns
    the return value of the function is a data folder reference of the created data folder.
    +
    +global variable file_id contains ID number of open HDF5 file from HDF5OpenFile. zero if an error occurred.
    global string s_filepath in new data folder contains the full file path on disk.
    global string s_scanpaths in new data folder contains a list of scan groups inside the file.
    -

    Definition at line 110 of file pearl-pshell-import.ipf.

    +

    Definition at line 450 of file pearl-pshell-import.ipf.

    - -

    ◆ reduce_slab_image()

    + +

    ◆ psh5_preview()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    dfr psh5_preview (string path_name,
    string file_name,
    dfref dest_df = defaultValue,
    string preview_datasets = defaultValue 
    )
    +
    + +

    load preview

    +

    load information about the file structure and a preview dataset

    + +

    Definition at line 345 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ psh_load_general_string()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    string psh_load_general_string (dfref file_df,
    string name 
    )
    +
    + +

    load a string from the general group.

    +

    the general group contains the following datasets: authors, pgroup, proposal, proposer, sample.

    +

    data is loaded into a global string in the current data folder. arrays with multiple items are loaded into a comma-separated list. a missing item defaults to the empty string.

    +
    Parameters
    + + +
    file_dfdata folder reference of open HDF5 file from psh5_open_file(). if undefined, the current datafolder is assumed.
    +
    +
    +
    Returns
    comma-separated list of values.
    + +

    Definition at line 1838 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ reduce_slab_image()

    @@ -1897,7 +1851,7 @@ global string s_scanpaths in new data folder contains a list of scan groups insi string  - reduction_param  + reduction_params  @@ -1912,7 +1866,7 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    -

    Definition at line 2341 of file pearl-pshell-import.ipf.

    +

    Definition at line 1776 of file pearl-pshell-import.ipf.

    @@ -1940,55 +1894,7 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    -

    Definition at line 2302 of file pearl-pshell-import.ipf.

    - -
    - - -

    ◆ select_dataset()

    - -
    -
    - - - - - -
    - - - - - - - - - - - - - - - - - - -
    static string select_dataset (string file_datasets,
    string pref_datasets 
    )
    -
    -static
    -
    - -

    select the preferred dataset from a list of available datasets.

    -
    Parameters
    - - - -
    file_datasetssemicolon-separated list of datasets that are available in the file. the items may include a path separated by slashes "/". only the last component of the path is checked.
    pref_datasetssemicolon-separated list of preferred datasets. the items of the list are match strings for the Igor StringMatch function. the first matching dataset is loaded from the file. if no match is found, the first file dataset is selected.
    -
    -
    -
    Returns
    selected dataset.
    - -

    Definition at line 778 of file pearl-pshell-import.ipf.

    +

    Definition at line 1737 of file pearl-pshell-import.ipf.

    @@ -2028,7 +1934,44 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    convert text wave to list.

    -

    Definition at line 2473 of file pearl-pshell-import.ipf.

    +

    Definition at line 532 of file pearl-pshell-import.ipf.

    + + + + +

    ◆ unique_strings()

    + +
    +
    + + + + + +
    + + + + + + + + +
    static string unique_strings (string list)
    +
    +static
    +
    + +

    remove duplicate items from list

    +
    Parameters
    + + +
    listsemicolon-separated list of strings. strings can contain any printable character except the semicolon.
    +
    +
    +
    Returns
    list of strings with duplicates (second and further instances) removed. all remaining items retain the position of their first occurrence in the original list. the function uses Igor's FindDuplicates operation.
    + +

    Definition at line 764 of file pearl-pshell-import.ipf.

    @@ -2074,7 +2017,7 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    convert numeric wave to list.

    -

    Definition at line 2490 of file pearl-pshell-import.ipf.

    +

    Definition at line 549 of file pearl-pshell-import.ipf.

    @@ -2093,7 +2036,7 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    Dimension label for the angle dispersive dimension of multi-dimensional datasets.

    -

    Definition at line 68 of file pearl-pshell-import.ipf.

    +

    Definition at line 53 of file pearl-pshell-import.ipf.

    @@ -2112,25 +2055,215 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    Dimension label for the data dimension.

    This label may be used to store the parameters for the setscale d operation.

    -

    Definition at line 75 of file pearl-pshell-import.ipf.

    +

    Definition at line 60 of file pearl-pshell-import.ipf.

    - -

    ◆ kDetectorSensitivity

    + +

    ◆ kDSCAll

    - +
    const variable kDetectorSensitivity = 1const variable kDSCAll = 0xffff
    -

    multiply scienta detector intensity by this value to get actual counts.

    +

    Definition at line 86 of file pearl-pshell-import.ipf.

    -

    Definition at line 87 of file pearl-pshell-import.ipf.

    +
    +
    + +

    ◆ kDSCAttrs

    + +
    +
    + + + + +
    const variable kDSCAttrs = 0x0020
    +
    + +

    Definition at line 79 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCDetectors

    + +
    +
    + + + + +
    const variable kDSCDetectors = 0x0002
    +
    + +

    Definition at line 75 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCDiags

    + +
    +
    + + + + +
    const variable kDSCDiags = 0x0040
    +
    + +

    Definition at line 80 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCEssentialDiags

    + +
    +
    + + + + +
    const variable kDSCEssentialDiags = 0x0010
    +
    + +

    Definition at line 78 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCMeta

    + +
    +
    + + + + +
    const variable kDSCMeta = 0x0100
    +
    + +

    Definition at line 82 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCMonitors

    + +
    +
    + + + + +
    const variable kDSCMonitors = 0x0200
    +
    + +

    Definition at line 83 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCOther

    + +
    +
    + + + + +
    const variable kDSCOther = 0x8000
    +
    + +

    Definition at line 85 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCPositioners

    + +
    +
    + + + + +
    const variable kDSCPositioners = 0x0001
    +
    + +

    Definition at line 74 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCPreview

    + +
    +
    + + + + +
    const variable kDSCPreview = 0x0008
    +
    + +

    Definition at line 77 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCRegions

    + +
    +
    + + + + +
    const variable kDSCRegions = 0x0400
    +
    + +

    Definition at line 84 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCScientaScaling

    + +
    +
    + + + + +
    const variable kDSCScientaScaling = 0x0004
    +
    + +

    Definition at line 76 of file pearl-pshell-import.ipf.

    + +
    +
    + +

    ◆ kDSCSnaps

    + +
    +
    + + + + +
    const variable kDSCSnaps = 0x0080
    +
    + +

    Definition at line 81 of file pearl-pshell-import.ipf.

    @@ -2148,7 +2281,25 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    Dimension label for the energy dispersive dimension of multi-dimensional datasets.

    -

    Definition at line 65 of file pearl-pshell-import.ipf.

    +

    Definition at line 50 of file pearl-pshell-import.ipf.

    + + + + +

    ◆ kEssentialDiagnostics

    + +
    +
    + + + + +
    const string kEssentialDiagnostics = "ManipulatorX;ManipulatorY;ManipulatorZ;ManipulatorTheta;ManipulatorTilt;ManipulatorPhi;MonoEnergy;"
    +
    + +

    List of diagnostic datasets that are normally loaded with a scan.

    + +

    Definition at line 69 of file pearl-pshell-import.ipf.

    @@ -2159,14 +2310,14 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    - +
    const string kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;"const string kPreviewDatasets = "ImageEnergyDistribution;ScientaSpectrum;ScientaImage;Counts;SampleCurrent;"

    List of preferred datasets to load for preview.

    -

    Definition at line 78 of file pearl-pshell-import.ipf.

    +

    Definition at line 63 of file pearl-pshell-import.ipf.

    @@ -2184,7 +2335,7 @@ global string s_scanpaths in new data folder contains a list of scan groups insi

    Dimension label for the scan dimension of multi-dimensional datasets.

    -

    Definition at line 71 of file pearl-pshell-import.ipf.

    +

    Definition at line 56 of file pearl-pshell-import.ipf.

    @@ -2195,14 +2346,14 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    - +
    const string kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;"const string kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;Eph;"

    List of datasets that must be loaded to determine the axis scaling of a Scienta image.

    -

    Definition at line 81 of file pearl-pshell-import.ipf.

    +

    Definition at line 66 of file pearl-pshell-import.ipf.

    @@ -2218,21 +2369,22 @@ global string s_scanpaths in new data folder contains a list of scan groups insi
    -

    List of datasets that should be transposed upon loading.

    +

    List of datasets that must be transposed upon loading.

    -

    Definition at line 84 of file pearl-pshell-import.ipf.

    +

    Definition at line 72 of file pearl-pshell-import.ipf.

    +
    string kill_matching_waves(dfref dfr, string pattern, variable recurse, string killed=defaultValue)
    kill any waves matching a pattern in the experiment
    diff --git a/doc/html/pearl-pshell-import_8ipf.js b/doc/html/pearl-pshell-import_8ipf.js index 83c74c5..08cb23c 100644 --- a/doc/html/pearl-pshell-import_8ipf.js +++ b/doc/html/pearl-pshell-import_8ipf.js @@ -1,44 +1,59 @@ var pearl_pshell_import_8ipf = [ - [ "find_attr_folder", "pearl-pshell-import_8ipf.html#a41bf534983b0662ec2609b136c395f14", null ], - [ "find_scale_wave", "pearl-pshell-import_8ipf.html#acfb01ee360b66f286225f6e9c7220ba2", null ], - [ "find_scan_folder", "pearl-pshell-import_8ipf.html#a79b968d7439dfbfbc38c05f933071489", null ], - [ "ps_detect_scale", "pearl-pshell-import_8ipf.html#acba7f4b98f67cc112c02dfeefe3e5acd", null ], + [ "kill_matching_waves", "pearl-pshell-import_8ipf.html#a972bf23d6da0bb33e9f12e50c9d7f5e5", null ], + [ "ps_detect_scale", "pearl-pshell-import_8ipf.html#ad2275b0b8a0a1ed05afc50ef50564243", null ], + [ "ps_find_attr_folder", "pearl-pshell-import_8ipf.html#a476f19c72d6e54787535ab6989ee778d", null ], + [ "ps_find_scale_wave", "pearl-pshell-import_8ipf.html#a2f39f9379e66ead0d25c33adfbe05ee9", null ], + [ "ps_find_scan_folder", "pearl-pshell-import_8ipf.html#a513091ea9a4e23f76765aa37f1d34055", null ], + [ "ps_fix_folder_name", "pearl-pshell-import_8ipf.html#a7d7b67c9f983d3446c5c6f274284b82a", null ], [ "ps_scale_dataset", "pearl-pshell-import_8ipf.html#adc11ea797562b3d99c247f4866618d39", null ], [ "ps_scale_dataset_2", "pearl-pshell-import_8ipf.html#a2c456397c36d4116bfddca452eff5954", null ], - [ "ps_scale_datasets", "pearl-pshell-import_8ipf.html#af08a467036c64f70ca3dfe644fcc457c", null ], + [ "ps_scale_datasets", "pearl-pshell-import_8ipf.html#a5a1961e05ea900e72d6a886ac5744f2d", null ], [ "ps_set_dimlabels", "pearl-pshell-import_8ipf.html#aba25eb98e4c6cc9066c46ef6be1cde15", null ], [ "ps_set_dimlabels2", "pearl-pshell-import_8ipf.html#a8704627410409bcd27a1adeda4082c47", null ], - [ "psh5_close_file", "pearl-pshell-import_8ipf.html#a2fc497747287d6fe40c6de997ed4a90d", null ], - [ "psh5_list_scan_datasets", "pearl-pshell-import_8ipf.html#a4508bd507c4c935bd8463d9b2b84c6fc", null ], - [ "psh5_list_scan_regions", "pearl-pshell-import_8ipf.html#acb317b57ef137d4d5da5938013dbe442", null ], - [ "psh5_list_scans", "pearl-pshell-import_8ipf.html#a2152f7c39a187b740cf9890767ffac3f", null ], - [ "psh5_load_complete", "pearl-pshell-import_8ipf.html#a8a5ce6c2767607de194b4c148ee98c27", null ], - [ "psh5_load_dataset", "pearl-pshell-import_8ipf.html#ac4dfb90b951d29b56501e904f5cc38aa", null ], - [ "psh5_load_dataset_meta", "pearl-pshell-import_8ipf.html#afde787a00a18dc8c63b100d8ac7d992f", null ], - [ "psh5_load_dataset_reduced", "pearl-pshell-import_8ipf.html#a13a45e8618c1ab7406e1aa5e608e21fe", null ], - [ "psh5_load_dataset_slab", "pearl-pshell-import_8ipf.html#a035a4df9f4508144149abdb0b46c87d1", null ], - [ "psh5_load_dataset_slabs", "pearl-pshell-import_8ipf.html#a2972587ec82cc2a261b8119a582b4215", null ], - [ "psh5_load_info", "pearl-pshell-import_8ipf.html#aa14b28120a07a8213e5a692930704a4b", null ], - [ "psh5_load_preview", "pearl-pshell-import_8ipf.html#a1dc6c971120749b378014f1f63cb6668", null ], - [ "psh5_load_reduced", "pearl-pshell-import_8ipf.html#a3eefc2f84a09f2ce29893c71ef44ae32", null ], - [ "psh5_load_scan_attrs", "pearl-pshell-import_8ipf.html#aec191d0167bbf606d24396f4658104b5", null ], - [ "psh5_load_scan_complete", "pearl-pshell-import_8ipf.html#a0a02f87e19e825964aa17c46ed51df8c", null ], - [ "psh5_load_scan_data", "pearl-pshell-import_8ipf.html#ad26b0b56d7ccd23547535091c9430569", null ], - [ "psh5_load_scan_info", "pearl-pshell-import_8ipf.html#a79ac37bb666b42c3332e9984196ccfe7", null ], - [ "psh5_load_scan_meta", "pearl-pshell-import_8ipf.html#aa56c25d64b3e59f74d6dd92a599cce4f", null ], - [ "psh5_load_scan_preview", "pearl-pshell-import_8ipf.html#ad3b9354b137ba4f1bc3ed2e74f24dc88", null ], - [ "psh5_load_scan_section", "pearl-pshell-import_8ipf.html#a83804ba9637debed6ef8b13e7b9b19e0", null ], - [ "psh5_open_file", "pearl-pshell-import_8ipf.html#accc20b0fc6bda95ba0cd0aea6633086f", null ], - [ "reduce_slab_image", "pearl-pshell-import_8ipf.html#a44d495fba0dd2b82dec13760a07fd226", null ], + [ "psh5_close_file", "pearl-pshell-import_8ipf.html#a47513a1db5693f88d64739a5b28926b2", null ], + [ "psh5_create_folders", "pearl-pshell-import_8ipf.html#aa7a48b65e465abde9aad80377605ae59", null ], + [ "psh5_dataset_to_folder", "pearl-pshell-import_8ipf.html#acda8bf0493a2e8ba1955f12de08e28f2", null ], + [ "psh5_extract_region_paths", "pearl-pshell-import_8ipf.html#a4f5d11063bd50ded36ca013a2656b539", null ], + [ "psh5_extract_scan_paths", "pearl-pshell-import_8ipf.html#ab86e42bb6f9ff20f685ad5627b446b77", null ], + [ "psh5_filter_datasets_rank", "pearl-pshell-import_8ipf.html#a7c191ea7367f2f328333b9986c7dd538", null ], + [ "psh5_list_all_datasets", "pearl-pshell-import_8ipf.html#a113622ae05611e5051a97d223fae59d0", null ], + [ "psh5_list_dataset_info", "pearl-pshell-import_8ipf.html#ad811542ccfc7c73156c2a107faa93d87", null ], + [ "psh5_list_scans", "pearl-pshell-import_8ipf.html#a85c1fbd2aefff2028e084ea61314dc67", null ], + [ "psh5_load", "pearl-pshell-import_8ipf.html#ab41e955a4ff70f9c78571faad1b43d7b", null ], + [ "psh5_load_dataset", "pearl-pshell-import_8ipf.html#af7a6eefbda58d31336c81a3dda6e9a2d", null ], + [ "psh5_load_dataset_meta", "pearl-pshell-import_8ipf.html#abcf01e205858a512aa713da914eaf966", null ], + [ "psh5_load_dataset_reduced", "pearl-pshell-import_8ipf.html#af662500c4f992ef7b956f37ed463513d", null ], + [ "psh5_load_dataset_slabs", "pearl-pshell-import_8ipf.html#afc4fa60c5fbfdb08c2a9d3072d3e16ce", null ], + [ "psh5_load_datasets", "pearl-pshell-import_8ipf.html#ae539a7501119cb2349707e2027f0f759", null ], + [ "psh5_load_general_group", "pearl-pshell-import_8ipf.html#ac782084655d44d222742e3397051619d", null ], + [ "psh5_load_scan_meta", "pearl-pshell-import_8ipf.html#a23a2e4cb2dc5364bfdbab4367ed6f234", null ], + [ "psh5_match_dataset_classes", "pearl-pshell-import_8ipf.html#af3b5005859915f410ec27a31ac9519ca", null ], + [ "psh5_open_file", "pearl-pshell-import_8ipf.html#ab684c44d5f0668631e42d9c9c9dfea9e", null ], + [ "psh5_preview", "pearl-pshell-import_8ipf.html#a24afba76ed5323d8cd0abc3c7b0d9912", null ], + [ "psh_load_general_string", "pearl-pshell-import_8ipf.html#a72465006d4e8379fad08d1a1064de2a3", null ], + [ "reduce_slab_image", "pearl-pshell-import_8ipf.html#a8089a75744ffc3626305406e925d320a", null ], [ "reduce_slab_worker", "pearl-pshell-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6", null ], - [ "select_dataset", "pearl-pshell-import_8ipf.html#abb4afdef6ae4476c25a1ff77b17266c3", null ], [ "twave2list", "pearl-pshell-import_8ipf.html#a92a18d6e81c3f521ba3bb240eaf578a9", null ], + [ "unique_strings", "pearl-pshell-import_8ipf.html#ae2aedcb7028cccdb683c43411cc8f1e2", null ], [ "wave2list", "pearl-pshell-import_8ipf.html#aa6dc3e3f7dc1ca4346132635a90fc447", null ], [ "kAngleDimLabel", "pearl-pshell-import_8ipf.html#a83930d4384b0238fc8416ba03dbc0386", null ], [ "kDataDimLabel", "pearl-pshell-import_8ipf.html#a277cd450cca7832aa44f8097934e6acb", null ], - [ "kDetectorSensitivity", "pearl-pshell-import_8ipf.html#a5745428740b64cd66394a7fcd78b86f1", null ], + [ "kDSCAll", "pearl-pshell-import_8ipf.html#a237e95f14b988f58e2d4c37659f17347", null ], + [ "kDSCAttrs", "pearl-pshell-import_8ipf.html#a10224f615973777a43fefae8eb1a39f2", null ], + [ "kDSCDetectors", "pearl-pshell-import_8ipf.html#a7c5aaa2f133862ae16ddd735df1ab73d", null ], + [ "kDSCDiags", "pearl-pshell-import_8ipf.html#adf778206fa825ab5006bd553c64a8760", null ], + [ "kDSCEssentialDiags", "pearl-pshell-import_8ipf.html#aebf53e3de392d631b340ee0747b8bbbf", null ], + [ "kDSCMeta", "pearl-pshell-import_8ipf.html#a712ea7a6f18ce4178fd06b07d2d05a9f", null ], + [ "kDSCMonitors", "pearl-pshell-import_8ipf.html#a300847a8e08161a64a199a6e7ef165c8", null ], + [ "kDSCOther", "pearl-pshell-import_8ipf.html#ac81d8f4276cf7bb86a74796cc7199e42", null ], + [ "kDSCPositioners", "pearl-pshell-import_8ipf.html#aeb9a7f56922ff3c862e8b29b5090c01a", null ], + [ "kDSCPreview", "pearl-pshell-import_8ipf.html#a654f0b9fe8770a8bd09a6da4182ca3bc", null ], + [ "kDSCRegions", "pearl-pshell-import_8ipf.html#a48f07030482af8315447ac2c598edd0d", null ], + [ "kDSCScientaScaling", "pearl-pshell-import_8ipf.html#ab7c2cc8687f6d4550ef90c538b938dad", null ], + [ "kDSCSnaps", "pearl-pshell-import_8ipf.html#a3236744797a780eb144a684b0bd41d4a", null ], [ "kEnergyDimLabel", "pearl-pshell-import_8ipf.html#a5ad52cb10171572c454f9426d3a9be21", null ], + [ "kEssentialDiagnostics", "pearl-pshell-import_8ipf.html#ab0bc752ab76659b492cf88c75935336b", null ], [ "kPreviewDatasets", "pearl-pshell-import_8ipf.html#a3c72087695969f42ea91c000de47b26e", null ], [ "kScanDimLabel", "pearl-pshell-import_8ipf.html#a412b4753ceb753d705a113a26c018b22", null ], [ "kScientaScalingDatasets", "pearl-pshell-import_8ipf.html#a03f00b3299bc3df671fcc239f7dd5418", null ], diff --git a/doc/html/pearl-pshell-import_8ipf_source.html b/doc/html/pearl-pshell-import_8ipf_source.html index 4f67627..95006c7 100644 --- a/doc/html/pearl-pshell-import_8ipf_source.html +++ b/doc/html/pearl-pshell-import_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-pshell-import.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,36 +87,1981 @@ $(document).ready(function(){initNavTree('pearl-pshell-import_8ipf_source.html',
    pearl-pshell-import.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.36
    3 #pragma ModuleName = PearlPShellImport
    4 #include <HDF5 Browser>
    5 #include "pearl-compat"
    6 #include "pearl-gui-tools"
    7 #include "pearl-area-import"
    8 
    9 // copyright (c) 2013-18 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 
    58 
    63 
    65 strconstant kEnergyDimLabel = "energy"
    66 
    68 strconstant kAngleDimLabel = "angle"
    69 
    71 strconstant kScanDimLabel = "scan"
    72 
    75 strconstant kDataDimLabel = "data"
    76 
    78 strconstant kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;"
    79 
    81 strconstant kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;"
    82 
    84 strconstant kTransposedDatasets = "ScientaImage;"
    85 
    88 
    110 function psh5_open_file(ANickName, APathName, AFileName)
    111  string ANickName
    112  string APathName
    113  string AFileName
    114 
    115  setdatafolder root:
    116  newdatafolder /s /o $("root:" + ANickName)
    117  dfref fileDF = GetDataFolderDFR()
    118 
    119  variable fileID
    120  HDF5OpenFile /P=$APathName /R fileID as AFileName
    121  if (v_flag == 0)
    122  string /g s_filepath
    123  string /g s_scanpaths
    124  s_filepath = s_path + s_filename
    125  s_scanpaths = psh5_list_scans(fileID)
    126  else
    127  fileID = 0
    128  endif
    129 
    130  return fileID
    131 end
    132 
    140 function psh5_close_file(fileID)
    141  variable fileID
    142 
    143  HDF5CloseFile fileID
    144 end
    145 
    170 function /s psh5_load_complete(ANickName, APathName, AFileName, [load_data, load_attr])
    171  string ANickName
    172  string APathName
    173  string AFileName
    174  variable load_data
    175  variable load_attr
    176 
    177  if (ParamIsDefault(load_data))
    178  load_data = 1
    179  endif
    180  if (ParamIsDefault(load_attr))
    181  load_attr = 1
    182  endif
    183 
    184  dfref saveDF = GetDataFolderDFR()
    185 
    186  // performance monitoring
    187  variable timerRefNum
    188  variable /g psh5_perf_secs
    189  timerRefNum = startMSTimer
    190 
    191  variable fileID = psh5_open_file(ANickName, APathName, AFileName)
    192  if (fileID)
    193  dfref fileDF = GetDataFolderDFR()
    194  svar s_filepath
    195  svar s_scanpaths
    196  AFileName = s_filepath
    197  print "loading " + s_filepath + "\r"
    198 
    199  variable ig
    200  variable ng = ItemsInList(s_scanpaths, ";")
    201  string sg
    202  string folder
    203 
    204  for (ig = 0; ig < ng; ig += 1)
    205  sg = StringFromList(ig, s_scanpaths, ";")
    206  folder = ReplaceString("/", sg, "")
    207  folder = ReplaceString(" ", folder, "")
    208  folder = PearlCleanupName(folder)
    209  setdatafolder fileDF
    210  newdatafolder /s /o $folder
    211  psh5_load_scan_complete(fileID, sg, load_data=load_data, load_attr=load_attr)
    212  endfor
    213 
    214  psh5_close_file(fileID)
    215  else
    216  AFileName = ""
    217  endif
    218 
    219  psh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    220 
    221  setdatafolder saveDF
    222  return AFileName
    223 end
    224 
    251 function /s psh5_load_preview(APathName, AFileName, [load_data, load_attr, pref_scans, pref_datasets])
    252  string APathName
    253  string AFileName
    254  variable load_data
    255  variable load_attr
    256  string pref_scans
    257  string pref_datasets
    258 
    259  if (ParamIsDefault(load_data))
    260  load_data = 1
    261  endif
    262  if (ParamIsDefault(load_attr))
    263  load_attr = 1
    264  endif
    265  if (ParamIsDefault(pref_scans))
    266  pref_scans = "*scan1*;"
    267  endif
    268  if (ParamIsDefault(pref_datasets))
    269  pref_datasets = ""
    270  endif
    271 
    272  dfref saveDF = GetDataFolderDFR()
    273 
    274  variable fileID
    275  string scanpaths = ""
    276  string dataname = ""
    277 
    278  // performance monitoring
    279  variable timerRefNum
    280  variable /g adh5_perf_secs
    281  timerRefNum = startMSTimer
    282 
    283  HDF5OpenFile /P=$APathName /R /Z fileID as AFileName
    284  if (v_flag == 0)
    285  AFileName = s_path + s_filename
    286  dfref fileDF = GetDataFolderDFR()
    287 
    288  scanpaths = psh5_list_scans(fileID)
    289  variable ng = ItemsInList(scanpaths)
    290  variable ig
    291  string sg
    292  variable np = ItemsInList(pref_scans)
    293  variable ip
    294  string sp
    295  variable found = 0
    296  if (ng > 0)
    297  for (ip = 0; ip < np; ip += 1)
    298  for (ig = 0; ig < ng; ig += 1)
    299  sg = StringFromList(ig, scanpaths)
    300  sp = StringFromList(ip, pref_scans)
    301  if (StringMatch(sg, sp))
    302  found = 1
    303  break
    304  endif
    305  endfor
    306  if (found)
    307  break
    308  endif
    309  endfor
    310  if (!found)
    311  ig = 0
    312  endif
    313  sg = StringFromList(ig, scanpaths)
    314 
    315  if (load_attr)
    316  setdatafolder fileDF
    317  newdatafolder /o/s attr
    318  killwaves /a/z
    319  psh5_load_scan_attrs(fileID, sg)
    320  endif
    321 
    322  setdatafolder fileDF
    323  dataname = psh5_load_scan_preview(fileID, sg, set_scale=load_attr, pref_datasets=pref_datasets)
    324  else
    325  print "no scans found in file " + AFileName
    326  endif
    327 
    328  HDF5CloseFile fileID
    329  endif
    330 
    331  if (timerRefNum >= 0)
    332  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    333  endif
    334 
    335  setdatafolder saveDF
    336  return dataname
    337 end
    338 
    361 function /s psh5_load_scan_complete(fileID, scanpath, [load_data, load_attr])
    362  variable fileID
    363  string scanpath
    364  variable load_data
    365  variable load_attr
    366 
    367  if (ParamIsDefault(load_data))
    368  load_data = 1
    369  endif
    370  if (ParamIsDefault(load_attr))
    371  load_attr = 1
    372  endif
    373 
    374  dfref saveDF = GetDataFolderDFR()
    375 
    376  dfref dataDF = GetDataFolderDFR()
    377  string wavenames
    378  string attrnames
    379  psh5_load_scan_meta(fileID, scanpath)
    380  if (load_attr)
    381  newdatafolder /s /o attr
    382  attrnames = psh5_load_scan_attrs(fileID, scanpath)
    383  endif
    384  if (load_data)
    385  setdatafolder dataDF
    386  wavenames = psh5_load_scan_data(fileID, scanpath)
    387  endif
    388  if (load_data && load_attr)
    389  setdatafolder dataDF
    391  endif
    392 
    393  setdatafolder saveDF
    394  return wavenames
    395 end
    396 
    405 function /s psh5_list_scans(fileID)
    406  variable fileID
    407 
    408  HDF5ListGroup /F /TYPE=1 fileID, "/"
    409 
    410  variable ig
    411  variable ng = ItemsInList(S_HDF5ListGroup, ";")
    412  string sg
    413  string scans = ""
    414 
    415  for (ig = 0; ig < ng; ig += 1)
    416  sg = StringFromList(ig, S_HDF5ListGroup, ";")
    417  if (cmpstr(sg[1,4], "scan") == 0)
    418  scans = AddListItem(sg, scans, ";", inf)
    419  endif
    420  endfor
    421 
    422  return scans
    423 end
    424 
    440 function /s psh5_list_scan_datasets(fileID, scanpath, [include_regions])
    441  variable fileID
    442  string scanpath
    443  variable include_regions
    444 
    445  if (ParamIsDefault(include_regions))
    446  include_regions = 0
    447  endif
    448  string result
    449 
    450  HDF5ListGroup /TYPE=2 /Z fileID, scanpath
    451  result = S_HDF5ListGroup
    452 
    453  if (include_regions)
    454  HDF5ListGroup /R /TYPE=2 /Z fileID, scanpath
    455  variable n = ItemsInList(S_HDF5ListGroup)
    456  variable i
    457  string ds
    458  string region_datasets
    459  for (i = 0; i < n; i += 1)
    460  ds = StringFromList(i, S_HDF5ListGroup)
    461  if (StringMatch(ds, "region*/*"))
    462  //region_datasets = psh5_list_scan_datasets(fileID, ReplaceString("//", scanpath + "/" + region, "/"), include_regions=0)
    463  result = AddListItem(ds, result, ";", inf)
    464  endif
    465  endfor
    466  endif
    467 
    468  return result
    469 end
    470 
    481 function /s psh5_list_scan_regions(fileID, scanpath)
    482  variable fileID
    483  string scanpath
    484 
    485  HDF5ListGroup /TYPE=1 /Z fileID, scanpath
    486  variable n = ItemsInList(S_HDF5ListGroup)
    487  variable i
    488  string result = ""
    489  string s
    490  for (i = 0; i < n; i += 1)
    491  s = StringFromList(i, S_HDF5ListGroup)
    492  if (StringMatch(s, "region*"))
    493  result = AddListItem(s, result, ";", inf)
    494  endif
    495  endfor
    496 
    497  return result
    498 end
    499 
    514 function /s psh5_load_scan_data(fileID, scanpath)
    515  variable fileID
    516  string scanpath
    517 
    518  string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
    519  variable nds = ItemsInList(datasets)
    520  variable ids
    521  string sds
    522  string sw
    523  string wavenames = ""
    524  for (ids = 0; ids < nds; ids += 1)
    525  sds = StringFromList(ids, datasets)
    526  sw = psh5_load_dataset(fileID, scanpath, sds, set_scale=0)
    527  wavenames = AddListItem(sw, wavenames, ";", inf)
    528  endfor
    529 
    530  return wavenames
    531 end
    532 
    554 function /s psh5_load_scan_attrs(fileID, scanpath, [attr_sets])
    555  variable fileID
    556  string scanpath
    557  variable attr_sets
    558 
    559  if (ParamIsDefault(attr_sets))
    560  attr_sets = 1
    561  endif
    562 
    563  string attr_path = ReplaceString("//", scanpath + "/attrs", "/")
    564  string attr_list = ""
    565  if (attr_sets & 1)
    566  HDF5ListGroup /TYPE=2 /Z fileID, attr_path
    567  if (!v_flag)
    568  attr_list = S_HDF5ListGroup
    569  endif
    570  endif
    571 
    572  variable ids
    573  variable nds
    574  string sds
    575 
    576  if (attr_sets & 2)
    577  nds = ItemsInList(kScientaScalingDatasets, ";")
    578  for (ids = 0; ids < nds; ids += 1)
    579  sds = StringFromList(ids, kScientaScalingDatasets)
    580  if (WhichListItem(sds, attr_list) < 0)
    581  attr_list = AddListItem(sds, attr_list, ";", inf)
    582  endif
    583  endfor
    584  endif
    585 
    586  nds = ItemsInList(attr_list, ";")
    587  string wavenames = ""
    588  for (ids = 0; ids < nds; ids += 1)
    589  sds = StringFromList(ids, attr_list, ";")
    590  HDF5LoadData /O /Q /Z fileID, attr_path + "/" + sds
    591  if (!v_flag)
    592  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    593  endif
    594  endfor
    595  wavenames = ReplaceString(";;", wavenames, ";")
    596 
    597  return wavenames
    598 end
    599 
    625 function /s psh5_load_scan_meta(fileID, scanpath)
    626  variable fileID
    627  string scanpath
    628  string wavenames = ""
    629 
    630  HDF5LoadData /O /Q /Z /A="Dimensions" /N=ScanDimensions /TYPE=1 fileID, scanpath
    631  if (!v_flag)
    632  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    633  else
    634  make /n=1 /o ScanDimensions
    635  ScanDimensions = 0
    636  wavenames = AddListItem("ScanDimensions", wavenames, ";", inf)
    637  endif
    638  HDF5LoadData /O /Q /Z /A="Readables" /N=ScanReadables /TYPE=1 fileID, scanpath
    639  if (!v_flag)
    640  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    641  else
    642  make /n=1 /o /t ScanReadables
    643  ScanReadables[0] = "ScientaSpectrum"
    644  wavenames = AddListItem("ScanReadables", wavenames, ";", inf)
    645  endif
    646  HDF5LoadData /O /Q /Z /A="Writables" /N=ScanWritables /TYPE=1 fileID, scanpath
    647  if (!v_flag)
    648  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    649  endif
    650  HDF5LoadData /O /Q /Z /A="Steps" /N=ScanSteps /TYPE=1 fileID, scanpath
    651  if (!v_flag)
    652  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    653  endif
    654  wavenames = ReplaceString(";;", wavenames, ";")
    655 
    656  // additional attributes from XPSSpectrum.py
    657  HDF5LoadData /O /Q /Z /A="Iterations" /N=ScanIterations /TYPE=1 fileID, scanpath
    658  if (!v_flag)
    659  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    660  endif
    661  HDF5LoadData /O /Q /Z /A="Step Size" /N=ScanStepSize /TYPE=1 fileID, scanpath
    662  if (!v_flag)
    663  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    664  endif
    665  HDF5LoadData /O /Q /Z /A="Step Time" /N=ScanStepTime /TYPE=1 fileID, scanpath
    666  if (!v_flag)
    667  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    668  endif
    669 
    670  return wavenames
    671 end
    672 
    706 function /s psh5_load_dataset(fileID, scanpath, datasetname, [set_scale])
    707  variable fileID
    708  string scanpath
    709  string datasetname
    710  variable set_scale
    711 
    712  if (ParamIsDefault(set_scale))
    713  set_scale = 1
    714  endif
    715 
    716  dfref base_df = GetDataFolderDFR()
    717 
    718  string datasetpath
    719  datasetpath = scanpath + "/" + datasetname
    720  datasetpath = ReplaceString("//", datasetpath, "/")
    721 
    722  string regionname
    723  string regionpath
    724  if (ItemsInList(datasetname, "/") >= 2)
    725  regionname = StringFromList(0, datasetname, "/")
    726  regionpath = ReplaceString("//", scanpath + "/" + regionname, "/")
    727  datasetname = RemoveListItem(0, datasetname, "/")
    728  NewDataFolder /o/s $regionname
    729  else
    730  regionname = ""
    731  regionpath = scanpath
    732  endif
    733 
    734  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    735  InitHDF5DataInfo(di)
    736  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
    737  if (err != 0)
    738  print "error accessing detector/data"
    739  return ""
    740  endif
    741 
    742  string dataname
    743  if (di.ndims < 2)
    744  HDF5LoadData /O /Q /Z fileID, datasetpath
    745  dataname = StringFromList(0, S_waveNames)
    746  else
    747  dataname = psh5_load_dataset_slabs(fileID, regionpath, datasetname)
    748  endif
    749 
    750  wave /z data = $dataname
    751  if (waveexists(data))
    752  psh5_load_dataset_meta(fileID, regionpath, datasetname, data)
    753  ps_set_dimlabels(data)
    754  if (set_scale)
    755  ps_scale_dataset(data)
    756  endif
    757  else
    758  dataname = ""
    759  endif
    760 
    761  setdatafolder base_df
    762  return dataname
    763 end
    764 
    778 static function /s select_dataset(file_datasets, pref_datasets)
    779  string file_datasets
    780  string pref_datasets
    781 
    782  variable index
    783  variable nds = ItemsInList(file_datasets)
    784  variable ids
    785  string sds = ""
    786  string mds = ""
    787  variable np = ItemsInList(pref_datasets)
    788  variable ip
    789  string sp
    790  variable found = 0
    791  if (nds > 0)
    792  for (ip = 0; ip < np; ip += 1)
    793  for (ids = 0; ids < nds; ids += 1)
    794  sds = StringFromList(ids, file_datasets)
    795  index = ItemsInList(sds, "/") - 1
    796  mds = StringFromList(index, sds, "/")
    797  sp = StringFromList(ip, pref_datasets)
    798  if (StringMatch(mds, sp))
    799  found = 1
    800  break
    801  endif
    802  endfor
    803  if (found)
    804  break
    805  endif
    806  endfor
    807  if (!found)
    808  ids = 0
    809  sds = StringFromList(ids, file_datasets)
    810  endif
    811  endif
    812 
    813  return sds
    814 end
    815 
    840 function /s psh5_load_scan_preview(fileID, scanpath, [set_scale, pref_datasets])
    841  variable fileID
    842  string scanpath
    843  variable set_scale
    844  string pref_datasets
    845 
    846  if (ParamIsDefault(set_scale))
    847  set_scale = 1
    848  endif
    849  if (ParamIsDefault(pref_datasets) || (strlen(pref_datasets) == 0))
    850  pref_datasets = kPreviewDatasets
    851  endif
    852 
    853  dfref saveDF = GetDataFolderDFR()
    854  dfref dataDF = saveDF
    855 
    856  string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
    857  string datasetname = select_dataset(datasets, pref_datasets)
    858  string datasetpath
    859  datasetpath = scanpath + "/" + datasetname
    860  datasetpath = ReplaceString("//", datasetpath, "/")
    861 
    862  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    863  InitHDF5DataInfo(di)
    864  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
    865  if (err != 0)
    866  print "error accessing detector/data"
    867  return ""
    868  endif
    869 
    870  string dataname
    871  if (di.ndims < 2)
    872  HDF5LoadData /O /Q /Z fileID, datasetpath
    873  dataname = StringFromList(0, S_waveNames)
    874  wave /z data = $dataname
    875  if (waveexists(data))
    876  ps_set_dimlabels(data)
    877  endif
    878  else
    879  variable dim2start = 0
    880  variable dim2count = 1
    881  variable dim3start = 0
    882  variable dim3count = 1
    883  if (di.ndims >= 3)
    884  dim2start = floor(di.dims[2] / 2)
    885  dim2count = 1
    886  endif
    887  if (di.ndims >= 4)
    888  dim3start = floor(di.dims[3] / 2)
    889  dim3count = 1
    890  endif
    891 
    892  dataname = psh5_load_dataset_slab(fileID, scanpath, datasetname, dim2start, dim2count, dim3start, dim3count)
    893  endif
    894 
    895  wave /z data = $dataname
    896  if (waveexists(data))
    897  if (set_scale)
    898  setdatafolder dataDF
    899  string positioners
    900  string positioner
    901  string positionerpath
    902  positioners = psh5_load_scan_meta(fileID, scanpath)
    903  wave /t /z ScanWritables
    904  if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
    905  positioner = ScanWritables[0]
    906  if (strlen(positioner) > 0)
    907  positionerpath = scanpath + "/" + positioner
    908  positionerpath = ReplaceString("//", positionerpath, "/")
    909  HDF5LoadData /O /Q /Z fileID, positionerpath
    910  endif
    911  endif
    912 
    913  setdatafolder dataDF
    914  newdatafolder /o/s attr
    915  psh5_load_scan_attrs(fileID, scanpath, attr_sets=2)
    916  setdatafolder dataDF
    917  ps_scale_dataset(data)
    918  endif
    919  else
    920  dataname = ""
    921  endif
    922 
    923  return dataname
    924 end
    925 
    953 function /s psh5_load_scan_section(fileID, scanpath, dim, [set_scale, pref_datasets])
    954  variable fileID
    955  string scanpath
    956  variable dim
    957  variable set_scale
    958  string pref_datasets
    959 
    960  // select first dimension (future argument)
    961  // 0 = first dimension is x axis (energy of scienta image)
    962  dim = 0
    963 
    964  if (ParamIsDefault(set_scale))
    965  set_scale = 1
    966  endif
    967  if (ParamIsDefault(pref_datasets) || (strlen(pref_datasets) == 0))
    968  pref_datasets = kPreviewDatasets
    969  endif
    970 
    971  dfref saveDF = GetDataFolderDFR()
    972  dfref dataDF = saveDF
    973 
    974  string datasets = psh5_list_scan_datasets(fileID, scanpath)
    975  string datasetname = select_dataset(datasets, pref_datasets)
    976  string datasetpath
    977  datasetpath = scanpath + "/" + datasetname
    978  datasetpath = ReplaceString("//", datasetpath, "/")
    979  string dataname = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
    980  string destname = dataname[0,29] + num2str(dim)
    981 
    982  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    983  InitHDF5DataInfo(di)
    984  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
    985  if (err != 0)
    986  print "error accessing detector/data"
    987  return ""
    988  elseif (di.ndims != 3)
    989  print "error: rank of dataset != 3"
    990  return ""
    991  endif
    992 
    993  variable idx, idy, idz, idt
    994  variable transpose = WhichListItem(dataname, kTransposedDatasets) >= 0
    995  if (transpose)
    996  idx = 1
    997  idy = 0
    998  else
    999  idx = 0
    1000  idy = 1
    1001  endif
    1002  idz = 2
    1003  idt = 3
    1004 
    1005  variable nx, ny, nz
    1006  nx = di.dims[idx]
    1007  ny = di.dims[idy]
    1008  nz = di.dims[idz]
    1009 
    1010  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
    1011  wave slab
    1012  slab[][%Start] = 0
    1013  slab[][%Stride] = 1
    1014  slab[][%Count] = 1
    1015  slab[][%Block] = 1
    1016 
    1017  if (dim == 0)
    1018  slab[idy][%Start] = floor(ny / 2)
    1019  slab[idx][%Block] = nx
    1020  make /n=(nx,nz) /o $destname
    1021  else
    1022  slab[idx][%Start] = floor(nx / 2)
    1023  slab[idy][%Block] = ny
    1024  make /n=(ny,nz) /o $destname
    1025  endif
    1026  slab[idz][%Block] = nz
    1027  wave data = $destname
    1028  data = 0
    1029 
    1030  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
    1031  if (!v_flag)
    1032  wave slabdata
    1033  if (transpose)
    1034  data += slabdata[0][p][q][0]
    1035  else
    1036  data += slabdata[p][0][q][0]
    1037  endif
    1038  endif
    1039  killwaves /z slab, slabdata
    1040 
    1041  if (set_scale)
    1042  make /n=(1,1,1) /free dummy
    1043  ps_set_dimlabels2(dummy, dataname)
    1044  setdimlabel 0, -1, $GetDimLabel(dummy, dim, -1), data
    1045  setdimlabel 1, -1, $kScanDimLabel, data
    1046 
    1047  setdatafolder dataDF
    1048  string positioners
    1049  string positioner
    1050  string positionerpath
    1051  positioners = psh5_load_scan_meta(fileID, scanpath)
    1052  wave /t /z ScanWritables
    1053  if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
    1054  positioner = ScanWritables[0]
    1055  if (strlen(positioner) > 0)
    1056  positionerpath = scanpath + "/" + positioner
    1057  positionerpath = ReplaceString("//", positionerpath, "/")
    1058  HDF5LoadData /O /Q /Z fileID, positionerpath
    1059  endif
    1060  endif
    1061 
    1062  setdatafolder dataDF
    1063  newdatafolder /o/s attr
    1064  killwaves /a/z
    1065  psh5_load_scan_attrs(fileID, scanpath, attr_sets=2)
    1066  setdatafolder dataDF
    1067  ps_scale_dataset(data)
    1068  endif
    1069 
    1070  return destname
    1071 end
    1072 
    1091 function psh5_load_dataset_meta(fileID, datapath, datasetname, datawave)
    1092  variable fileID
    1093  string datapath
    1094  string datasetname
    1095  wave datawave
    1096 
    1097  dfref saveDF = GetDataFolderDFR()
    1098  SetDataFolder NewFreeDataFolder()
    1099 
    1100  string datasetpath = datapath + "/" + datasetname
    1101  datasetpath = ReplaceString("//", datasetpath, "/")
    1102  string wnote
    1103 
    1104  HDF5LoadData /O /Q /Z /A="Writable Dimension" /N=WriteDim fileID, datasetpath
    1105  if (!v_flag)
    1106  wave WriteDim
    1107  // scan dimension starts at 1
    1108  sprintf wnote, "ScanDimension=%u", WriteDim[0]
    1109  Note datawave, wnote
    1110  endif
    1111 
    1112  HDF5LoadData /O /Q /Z /A="Writable Index" /N=WriteIndex fileID, datasetpath
    1113  if (!v_flag)
    1114  wave WriteIndex
    1115  sprintf wnote, "WriteableIndex=%u", WriteIndex[0]
    1116  Note datawave, wnote
    1117  endif
    1118 
    1119  HDF5LoadData /O /Q /Z /A="Readable Index" /N=ReadIndex fileID, datasetpath
    1120  if (!v_flag)
    1121  wave ReadIndex
    1122  sprintf wnote, "ReadableIndex=%u", ReadIndex[0]
    1123  Note datawave, wnote
    1124  endif
    1125 
    1126  setdatafolder saveDF
    1127  return 0
    1128 end
    1129 
    1148 function /s psh5_load_dataset_slabs(fileID, datapath, datasetname, [progress])
    1149  variable fileID
    1150  string datapath
    1151  string datasetname
    1152  variable progress
    1153 
    1154  if (ParamIsDefault(progress))
    1155  progress = 1
    1156  endif
    1157 
    1158  variable result = 0
    1159  string datasetpath
    1160  string datawavename
    1161  datasetpath = datapath + "/" + datasetname
    1162  datasetpath = ReplaceString("//", datasetpath, "/")
    1163  datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
    1164 
    1165  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    1166  InitHDF5DataInfo(di)
    1167  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
    1168  if (err != 0)
    1169  print "error accessing detector/data"
    1170  return ""
    1171  endif
    1172  if (di.ndims < 2)
    1173  print "error: rank of dataset < 2"
    1174  return ""
    1175  elseif (di.ndims < 3)
    1176  progress = 0
    1177  endif
    1178 
    1179  variable idx, idy, idz, idt, izt
    1180  variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
    1181  if (transpose)
    1182  idx = 1
    1183  idy = 0
    1184  else
    1185  idx = 0
    1186  idy = 1
    1187  endif
    1188  idz = 2
    1189  idt = 3
    1190 
    1191  variable nx, ny, nz, nt, nzt
    1192  nx = di.dims[idx]
    1193  ny = di.dims[idy]
    1194  nz = di.dims[idz]
    1195  nt = di.dims[idt]
    1196  make /n=(nx,ny,nz,nt) /o $datawavename
    1197  wave data = $datawavename
    1198 
    1199  nz = max(nz, 1)
    1200  nt = max(nt, 1)
    1201  nzt = nz * nt
    1202  izt = 0
    1203  if (progress)
    1204  display_progress_panel("HDF5 Import", "Loading data...", nzt)
    1205  endif
    1206 
    1207  // load data image by image
    1208  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
    1209  wave slab
    1210  slab[][%Start] = 0
    1211  slab[][%Stride] = 1
    1212  slab[][%Count] = 1
    1213  slab[][%Block] = 1
    1214  slab[idx][%Block] = nx
    1215  slab[idy][%Block] = ny
    1216 
    1217  variable iz, it
    1218  for (iz = 0; iz < nz; iz += 1)
    1219  for (it = 0; it < nt; it += 1)
    1220  slab[idz][%Start] = iz
    1221  slab[idt][%Start] = it
    1222  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
    1223  wave slabdata // 2D, 3D, or 4D with singletons
    1224  if (transpose)
    1225  data[][][iz][it] = slabdata[q][p][0][0]
    1226  else
    1227  data[][][iz][it] = slabdata[p][q][0][0]
    1228  endif
    1229 
    1230  // progress window
    1231  izt += 1
    1232  if (progress)
    1233  if (update_progress_panel(izt))
    1234  result = -4 // user abort
    1235  break
    1236  endif
    1237  endif
    1238  endfor
    1239  if (result < 0)
    1240  break
    1241  endif
    1242  endfor
    1243 
    1244  if (progress)
    1245  kill_progress_panel()
    1246  endif
    1247 
    1248  killwaves /z slab, slabdata
    1249  if (!result)
    1250  ps_set_dimlabels(data)
    1251  return datawavename
    1252  else
    1253  killwaves /z data
    1254  return ""
    1255  endif
    1256 end
    1257 
    1284 function /s psh5_load_dataset_slab(fileID, datapath, datasetname, dim2start, dim2count, dim3start, dim3count)
    1285  variable fileID
    1286  string datapath
    1287  string datasetname
    1288  variable dim2start
    1289  variable dim2count
    1290  variable dim3start
    1291  variable dim3count
    1292 
    1293  string datasetpath
    1294  string datawavename
    1295  datasetpath = datapath + "/" + datasetname
    1296  datasetpath = ReplaceString("//", datasetpath, "/")
    1297  datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
    1298 
    1299  STRUCT HDF5DataInfo di
    1300  InitHDF5DataInfo(di)
    1301  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
    1302  if (err != 0)
    1303  print "error accessing detector/data"
    1304  return ""
    1305  endif
    1306  if (di.ndims < 2)
    1307  print "error: rank of dataset < 2"
    1308  return ""
    1309  endif
    1310 
    1311  variable idx, idy, idz, idt
    1312  variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
    1313  if (transpose)
    1314  idx = 1
    1315  idy = 0
    1316  else
    1317  idx = 0
    1318  idy = 1
    1319  endif
    1320  idz = 2
    1321  idt = 3
    1322 
    1323  variable nx, ny
    1324  nx = di.dims[idx]
    1325  ny = di.dims[idy]
    1326  make /n=(nx,ny) /o $datawavename
    1327  wave data = $datawavename
    1328  data = 0
    1329 
    1330  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
    1331  wave slab
    1332  slab[][%Start] = 0
    1333  slab[][%Stride] = 1
    1334  slab[][%Count] = 1
    1335  slab[][%Block] = 1
    1336  slab[idx][%Block] = nx
    1337  slab[idy][%Block] = ny
    1338 
    1339  variable iz, it
    1340  variable navg = 0
    1341  variable dim2end = dim2start + dim2count - 1
    1342  variable dim3end = dim3start + dim3count - 1
    1343  for (iz = dim2start; iz <= dim2end; iz += 1)
    1344  for (it = dim3start; it <= dim3end; it += 1)
    1345  slab[idz][%Start] = iz
    1346  slab[idt][%Start] = it
    1347  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
    1348  if (!v_flag)
    1349  wave slabdata
    1350  if (transpose)
    1351  data += slabdata[q][p][0][0]
    1352  else
    1353  data += slabdata[p][q][0][0]
    1354  endif
    1355  navg += 1
    1356  endif
    1357  endfor
    1358  endfor
    1359  if (navg)
    1360  data /= navg
    1361  endif
    1362 
    1363  killwaves /z slab, slabdata
    1364  ps_set_dimlabels(data)
    1365  return datawavename
    1366 end
    1367 
    1383 function ps_set_dimlabels(data)
    1384  wave data
    1385 
    1386  ps_set_dimlabels2(data, NameOfWave(data))
    1387 end
    1388 
    1402 function ps_set_dimlabels2(data, name)
    1403  wave data
    1404  string name
    1405 
    1406  variable dummy
    1407  try
    1408  // intrinsic dimensions
    1409  strswitch(name)
    1410  case "ScientaImage":
    1411  setdimlabel 0, -1, $kEnergyDimLabel, data
    1412  setdimlabel 1, -1, $kAngleDimLabel, data
    1413  if (WaveDims(data) >= 3)
    1414  setdimlabel 2, -1, $kScanDimLabel, data
    1415  endif
    1416  AbortOnRTE
    1417  break
    1418  case "ImageAngleDistribution":
    1419  case "ScientaAngleDistribution":
    1420  if (WaveDims(data) >= 2)
    1421  setdimlabel 0, -1, $kScanDimLabel, data
    1422  setdimlabel 1, -1, $kAngleDimLabel, data
    1423  else
    1424  setdimlabel 0, -1, $kAngleDimLabel, data
    1425  endif
    1426  AbortOnRTE
    1427  break
    1428  case "ScientaSpectrum":
    1429  case "ImageEnergyDistribution":
    1430  case "ScientaEnergyDistribution":
    1431  if (WaveDims(data) >= 2)
    1432  setdimlabel 0, -1, $kScanDimLabel, data
    1433  setdimlabel 1, -1, $kEnergyDimLabel, data
    1434  else
    1435  setdimlabel 0, -1, $kEnergyDimLabel, data
    1436  endif
    1437  AbortOnRTE
    1438  break
    1439  default:
    1440  if (WaveDims(data) == 1)
    1441  setdimlabel 0, -1, $kScanDimLabel, data
    1442  AbortOnRTE
    1443  else
    1444  return 1
    1445  endif
    1446  endswitch
    1447  catch
    1448  dummy = GetRTError(1)
    1449  return 2
    1450  endtry
    1451  return 0
    1452 end
    1453 
    1459 static function /df find_scan_folder(dataDF)
    1460  dfref dataDF
    1461 
    1462  dfref attrDF = dataDF:attr
    1463  if (!DataFolderRefStatus(attrDF))
    1464  string df = GetDataFolder(1, dataDF) + ":"
    1465  dfref scanDF = $df
    1466  else
    1467  dfref scanDF = dataDF
    1468  endif
    1469  return scanDF
    1470 end
    1471 
    1476 static function /df find_attr_folder(dataDF)
    1477  dfref dataDF
    1478 
    1479  dfref attrDF = dataDF:attr
    1480  if (!DataFolderRefStatus(attrDF))
    1481  string df = GetDataFolder(1, dataDF) + ":"
    1482  dfref scanDF = $df
    1483  dfref attrDF = scanDF:attr
    1484  endif
    1485  return attrDF
    1486 end
    1487 
    1504 function ps_scale_datasets()
    1505  dfref scanDF = GetDataFolderDFR()
    1506  dfref attrDF = find_attr_folder(scanDF)
    1507 
    1508  make /n=3 /free lo, hi
    1509  make /n=3 /t /free ax, un
    1510  wave /t /z /SDFR=scanDF ScanReadables
    1511  if (WaveExists(ScanReadables))
    1512  variable isr
    1513  variable nsr = numpnts(ScanReadables)
    1514  string ssr
    1515  string sdf
    1516  for (isr = 0; isr < nsr; isr += 1)
    1517  setdatafolder scanDF
    1518  ssr = ScanReadables[isr]
    1519  if (ItemsInList(ssr, "/") >= 2)
    1520  sdf = StringFromList(0, ssr, "/")
    1521  ssr = RemoveListItem(0, ssr, "/")
    1522  setdatafolder $sdf
    1523  endif
    1524  wave /z wsr=$ssr
    1525  if (WaveExists(wsr))
    1526  ps_detect_scale(ax, lo, hi, un)
    1527  ps_scale_dataset_2(wsr, ax, lo, hi, un)
    1528  endif
    1529  endfor
    1530  endif
    1531  setdatafolder scanDF
    1532 end
    1533 
    1550 function ps_scale_dataset(data)
    1551  wave data
    1552 
    1553  dfref saveDF = GetDataFolderDFR()
    1554  dfref dataDF = GetWavesDataFolderDFR(data)
    1555 
    1556  setdatafolder dataDF
    1557  make /n=3 /free lo, hi
    1558  make /n=3 /t /free ax, un
    1559  ps_detect_scale(ax, lo, hi, un)
    1560  ps_scale_dataset_2(data, ax, lo, hi, un)
    1561  setdatafolder saveDF
    1562 end
    1563 
    1564 static function /wave find_scale_wave(name, dataDF, scanDF, attrDF)
    1565  string name
    1566  dfref dataDF
    1567  dfref scanDF
    1568  dfref attrDF
    1569 
    1570  wave /SDFR=dataDF /Z w = $name
    1571  if (!WaveExists(w))
    1572  wave /SDFR=scanDF /Z w = $name
    1573  if (!WaveExists(w))
    1574  wave /SDFR=attrDF /Z w = $name
    1575  endif
    1576  endif
    1577  return w
    1578 end
    1579 
    1621 function ps_detect_scale(ax, lo, hi, un)
    1622  wave /t ax
    1623  wave lo
    1624  wave hi
    1625  wave /t un
    1626 
    1627  dfref dataDF = GetDataFolderDFR()
    1628  dfref scanDF = find_scan_folder(dataDF)
    1629  dfref attrDF = find_attr_folder(dataDF)
    1630 
    1631  redimension /n=4 lo, hi, un, ax
    1632  setdimlabel 0, 0, $kEnergyDimLabel, lo, hi, un, ax
    1633  setdimlabel 0, 1, $kAngleDimLabel, lo, hi, un, ax
    1634  setdimlabel 0, 2, $kScanDimLabel, lo, hi, un, ax
    1635  setdimlabel 0, 3, $kDataDimLabel, lo, hi, un, ax
    1636 
    1637  // default values
    1638  lo[%$kEnergyDimLabel] = 0
    1639  hi[%$kEnergyDimLabel] = 1
    1640  un[%$kEnergyDimLabel] = "eV"
    1641  ax[%$kEnergyDimLabel] = "Ekin"
    1642 
    1643  lo[%$kAngleDimLabel] = -1
    1644  hi[%$kAngleDimLabel] = 1
    1645  un[%$kAngleDimLabel] = "arb."
    1646  un[%$kAngleDimLabel] = "slice"
    1647 
    1648  lo[%$kScanDimLabel] = 0
    1649  hi[%$kScanDimLabel] = 1
    1650  un[%$kScanDimLabel] = "arb."
    1651  ax[%$kScanDimLabel] = "scan"
    1652 
    1653  lo[%$kDataDimLabel] = 0
    1654  hi[%$kDataDimLabel] = 0
    1655  un[%$kDataDimLabel] = "arb."
    1656  ax[%$kDataDimLabel] = "value"
    1657 
    1658  wave /SDFR=attrDF /T /Z LensMode
    1659  wave /Z ChannelBegin = find_scale_wave("ScientaChannelBegin", dataDF, scanDF, attrDF)
    1660  wave /Z ChannelEnd = find_scale_wave("ScientaChannelEnd", dataDF, scanDF, attrDF)
    1661  wave /Z SliceBegin = find_scale_wave("ScientaSliceBegin", dataDF, scanDF, attrDF)
    1662  wave /Z SliceEnd = find_scale_wave("ScientaSliceEnd", dataDF, scanDF, attrDF)
    1663 
    1664  // lens mode can give more detail
    1665  if (waveexists(LensMode) && (numpnts(LensMode) >= 1))
    1666  strswitch(LensMode[0])
    1667  case "Angular45":
    1668  lo[%$kAngleDimLabel] = -45/2
    1669  hi[%$kAngleDimLabel] = +45/2
    1670  un[%$kAngleDimLabel] = "°"
    1671  ax[%$kAngleDimLabel] = "angle"
    1672  break
    1673  case "Angular60":
    1674  lo[%$kAngleDimLabel] = -60/2
    1675  hi[%$kAngleDimLabel] = +60/2
    1676  un[%$kAngleDimLabel] = "°"
    1677  ax[%$kAngleDimLabel] = "angle"
    1678  break
    1679  case "Transmission":
    1680  un[%$kAngleDimLabel] = "arb."
    1681  ax[%$kAngleDimLabel] = "offset"
    1682  break
    1683  endswitch
    1684  endif
    1685 
    1686  // best option if scales are explicit in separate waves
    1687  if (waveexists(ChannelBegin) && waveexists(ChannelEnd) && (numpnts(ChannelBegin) >= 1) && (numpnts(ChannelEnd) >= 1))
    1688  lo[%$kEnergyDimLabel] = ChannelBegin[0]
    1689  hi[%$kEnergyDimLabel] = ChannelEnd[0]
    1690  endif
    1691  if (waveexists(SliceBegin) && waveexists(SliceEnd) && (numpnts(SliceBegin) >= 1) && (numpnts(SliceEnd) >= 1))
    1692  lo[%$kAngleDimLabel] = SliceBegin[0]
    1693  hi[%$kAngleDimLabel] = SliceEnd[0]
    1694  endif
    1695 
    1696  wave /z /t /SDFR=scanDF ScanWritables
    1697  if (WaveExists(ScanWritables))
    1698  wave /z /SDFR=scanDF scanner = $ScanWritables[0]
    1699  if (!WaveExists(scanner))
    1700  wave /z /SDFR=attrDF scanner = $ScanWritables[0]
    1701  endif
    1702  if (WaveExists(scanner) && (numpnts(scanner) >= 1))
    1703  lo[%$kScanDimLabel] = scanner[0]
    1704  hi[%$kScanDimLabel] = scanner[numpnts(scanner)-1]
    1705  ax[%$kScanDimLabel] = NameOfWave(scanner)
    1706  strswitch(NameOfWave(scanner))
    1707  case "Eph":
    1708  ax[%$kScanDimLabel] = "photon energy"
    1709  un[%$kScanDimLabel] = "eV"
    1710  break
    1711  case "ManipulatorX":
    1712  case "ManipulatorY":
    1713  case "ManipulatorZ":
    1714  case "FocusYTrans":
    1715  case "FocusZTrans":
    1716  case "RefocusYTrans":
    1717  case "RefocusZTrans":
    1718  case "ExitSlitY":
    1719  un[%$kScanDimLabel] = "mm"
    1720  break
    1721  case "ExitSlit":
    1722  un[%$kScanDimLabel] = "µm"
    1723  break
    1724  case "ManipulatorTheta":
    1725  case "ManipulatorTilt":
    1726  case "ManipulatorPhi":
    1727  un[%$kScanDimLabel] = "°"
    1728  break
    1729  case "FocusXRot":
    1730  case "FocusYRot":
    1731  case "FocusZRot":
    1732  case "RefocusXRot":
    1733  case "RefocusYRot":
    1734  case "RefocusZRot":
    1735  un[%$kScanDimLabel] = "mrad"
    1736  break
    1737  endswitch
    1738  endif
    1739  endif
    1740 end
    1741 
    1781 function ps_scale_dataset_2(data, ax, lo, hi, un)
    1782  wave data
    1783  wave /t ax
    1784  wave lo
    1785  wave hi
    1786  wave /t un
    1787 
    1788  string snote = note(data)
    1789  string sdim
    1790  sdim = GetDimLabel(data, 0, -1)
    1791  if (strlen(sdim))
    1792  setscale /i x lo[%$sdim], hi[%$sdim], un[%$sdim], data
    1793  snote = ReplaceStringByKey("AxisLabelX", snote, ax[%$sdim], "=", "\r")
    1794  endif
    1795 
    1796  sdim = GetDimLabel(data, 1, -1)
    1797  if (strlen(sdim))
    1798  setscale /i y lo[%$sdim], hi[%$sdim], un[%$sdim], data
    1799  snote = ReplaceStringByKey("AxisLabelY", snote, ax[%$sdim], "=", "\r")
    1800  endif
    1801 
    1802  sdim = GetDimLabel(data, 2, -1)
    1803  if (strlen(sdim))
    1804  setscale /i z lo[%$sdim], hi[%$sdim], un[%$sdim], data
    1805  snote = ReplaceStringByKey("AxisLabelZ", snote, ax[%$sdim], "=", "\r")
    1806  endif
    1807 
    1808  string data_unit = un[%$kDataDimLabel]
    1809  string data_label = ax[%$kDataDimLabel]
    1810  string s
    1811  variable def = (cmpstr(data_unit, "arb.") == 0) && (cmpstr(data_label, "value") == 0)
    1812 
    1813  if (def)
    1814  s = StringByKey("AxisLabelD", snote, "=", "\r")
    1815  if (strlen(s) > 0)
    1816  data_label = s
    1817  def = 0
    1818  endif
    1819  s = StringByKey("AxisUnitD", snote, "=", "\r")
    1820  if (strlen(s) > 0)
    1821  data_unit = s
    1822  def = 0
    1823  endif
    1824  endif
    1825 
    1826  if (def)
    1827  strswitch(NameOfWave(data))
    1828  case "ScientaImage":
    1829  case "ImageAngleDistribution":
    1830  case "ScientaAngleDistribution":
    1831  case "ScientaSpectrum":
    1832  case "ImageEnergyDistribution":
    1833  case "ScientaEnergyDistribution":
    1834  data *= kDetectorSensitivity
    1835  data_unit = "counts"
    1836  data_label = "intensity"
    1837  def = 0
    1838  break
    1839  case "SampleCurrent":
    1840  case "RefCurrent":
    1841  case "AuxCurrent":
    1842  data_unit = "A"
    1843  data_label = "current"
    1844  def = 0
    1845  break
    1846  case "MachineCurrent":
    1847  data_unit = "mA"
    1848  data_label = "current"
    1849  def = 0
    1850  break
    1851  endswitch
    1852  endif
    1853 
    1854  setscale d 0, 0, data_unit, data
    1855  snote = ReplaceStringByKey("AxisLabelD", snote, data_label, "=", "\r")
    1856  snote = ReplaceStringByKey("AxisUnitD", snote, data_unit, "=", "\r")
    1857  snote = ReplaceStringByKey("Dataset", snote, NameOfWave(data), "=", "\r")
    1858  note /k data, snote
    1859 end
    1860 
    1911 function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [progress, nthreads])
    1912  string ANickName
    1913  string APathName
    1914  string AFileName
    1915  funcref adh5_default_reduction reduction_func
    1916  string reduction_param
    1917  variable progress
    1918  variable nthreads
    1919 
    1920  if (ParamIsDefault(progress))
    1921  progress = 1
    1922  endif
    1923  if (ParamIsDefault(nthreads))
    1924  nthreads = -1
    1925  endif
    1926 
    1927  dfref saveDF = GetDataFolderDFR()
    1928 
    1929  // performance monitoring
    1930  variable timerRefNum
    1931  variable /g psh5_perf_secs
    1932  timerRefNum = startMSTimer
    1933 
    1934  variable fileID = psh5_open_file(ANickName, APathName, AFileName)
    1935  string wavenames = ""
    1936  if (fileID)
    1937  dfref fileDF = GetDataFolderDFR()
    1938  svar s_filepath
    1939  svar s_scanpaths
    1940  AFileName = s_filepath
    1941  print "loading " + s_filepath + "\r"
    1942 
    1943  variable ig = 0
    1944  variable ng = ItemsInList(s_scanpaths)
    1945  string scanpath
    1946  string folder
    1947  string positioners
    1948  string positioner
    1949  string positionerpath
    1950 
    1951  scanpath = StringFromList(ig, s_scanpaths)
    1952  folder = ReplaceString("/", scanpath, "")
    1953  folder = ReplaceString(" ", folder, "")
    1954  folder = PearlCleanupName(folder)
    1955  setdatafolder fileDF
    1956  newdatafolder /s /o $folder
    1957  dfref dataDF = GetDataFolderDFR()
    1958  positioners = psh5_load_scan_meta(fileID, scanpath)
    1959  newdatafolder /s /o attr
    1960  killwaves /a/z
    1961  psh5_load_scan_attrs(fileID, scanpath)
    1962  setdatafolder dataDF
    1963  wave /t /z ScanWritables
    1964  if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
    1965  positioner = ScanWritables[0]
    1966  if (strlen(positioner) > 0)
    1967  positionerpath = scanpath + "/" + positioner
    1968  positionerpath = ReplaceString("//", positionerpath, "/")
    1969  HDF5LoadData /O /Q /Z fileID, positionerpath
    1970  endif
    1971  endif
    1972 
    1973  setdatafolder dataDF
    1974  string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
    1975  string dataset = select_dataset(datasets, "ScientaImage")
    1976  wavenames = psh5_load_dataset_reduced(fileID, scanpath, dataset, reduction_func, reduction_param, progress=progress, nthreads=nthreads)
    1977 
    1978  psh5_close_file(fileID)
    1979  endif
    1980 
    1981  if (timerRefNum >= 0)
    1982  psh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    1983  endif
    1984 
    1985  setdatafolder saveDF
    1986  return wavenames
    1987 end
    1988 
    1989 
    2040 function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_func, reduction_param, [progress, nthreads])
    2041  variable fileID
    2042  string scanpath
    2043  string datasetname
    2044  funcref adh5_default_reduction reduction_func
    2045  string reduction_param
    2046  variable progress
    2047  variable nthreads
    2048 
    2049  if (ParamIsDefault(progress))
    2050  progress = 1
    2051  endif
    2052  if (ParamIsDefault(nthreads))
    2053  nthreads = -1
    2054  endif
    2055 
    2056  dfref base_df = GetDataFolderDFR()
    2057  variable result = 0
    2058  string datasetpath
    2059  string datawavename
    2060  string wavenames = ""
    2061 
    2062  datasetpath = scanpath + "/" + datasetname
    2063  datasetpath = ReplaceString("//", datasetpath, "/")
    2064  datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
    2065 
    2066  string regionname
    2067  string regionpath
    2068  if (ItemsInList(datasetname, "/") >= 2)
    2069  regionname = StringFromList(0, datasetname, "/")
    2070  regionpath = ReplaceString("//", scanpath + "/" + regionname, "/")
    2071  datasetname = RemoveListItem(0, datasetname, "/")
    2072  NewDataFolder /o/s $regionname
    2073  else
    2074  regionname = ""
    2075  regionpath = scanpath
    2076  endif
    2077 
    2078  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    2079  InitHDF5DataInfo(di)
    2080  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
    2081  if (err != 0)
    2082  print "error accessing detector/data"
    2083  result = -1
    2084  return wavenames
    2085  endif
    2086  if (di.ndims < 2)
    2087  print "error: rank of dataset < 2"
    2088  result = -2
    2089  return wavenames
    2090  elseif (di.ndims < 3)
    2091  progress = 0
    2092  endif
    2093 
    2094  variable idx, idy, idz, idt
    2095  variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
    2096  if (transpose)
    2097  idx = 1
    2098  idy = 0
    2099  else
    2100  idx = 0
    2101  idy = 1
    2102  endif
    2103  idz = 2
    2104  idt = 3
    2105 
    2106  variable nx, ny, nz, nt, nzt
    2107  nx = di.dims[idx]
    2108  ny = di.dims[idy]
    2109  nz = di.dims[idz]
    2110  nt = di.dims[idt]
    2111  // adjust singleton dimensions
    2112  nz = max(nz, 1)
    2113  nt = max(nt, 1)
    2114  nzt = nz * nt
    2115 
    2116  // load data image by image
    2117  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
    2118  wave slab
    2119  slab[][%Start] = 0
    2120  slab[][%Stride] = 1
    2121  slab[][%Count] = 1
    2122  slab[][%Block] = 1
    2123  slab[idx][%Block] = nx
    2124  slab[idy][%Block] = ny
    2125 
    2126  // set up multi threading
    2127  if (nthreads < 0)
    2128  nthreads = ThreadProcessorCount
    2129  endif
    2130  if (nthreads > 0)
    2131  variable threadGroupID = ThreadGroupCreate(nthreads)
    2132  variable ithread
    2133  for (ithread = 0; ithread < nthreads; ithread += 1)
    2134  ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
    2135  endfor
    2136  else
    2137  make /n=(nzt) /df /free processing_folders
    2138  endif
    2139 
    2140  if (progress)
    2141  display_progress_panel("HDF5 Import", "Loading data (step 1 of 2)...", nzt)
    2142  endif
    2143 
    2144  // create a template wave with the correct scales and labels
    2145  make /n=(nx,ny) /d /o $datawavename
    2146  wave template = $datawavename
    2147  ps_set_dimlabels2(template, datawavename)
    2148  ps_scale_dataset(template)
    2149 
    2150  variable iz, it, izt
    2151  string dfname
    2152  variable iw, nw
    2153  string sw
    2154  make /n=0 /free /wave result_waves
    2155 
    2156  izt = 0
    2157  for (iz = 0; iz < nz; iz += 1)
    2158  for (it = 0; it < nt; it += 1)
    2159  // load hyperslab
    2160  slab[idz][%Start] = iz
    2161  slab[idt][%Start] = it
    2162  dfname = "processing_" + num2str(izt)
    2163  newdatafolder /s $dfname
    2164  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
    2165 
    2166  // send to processing queue
    2167  duplicate template, image
    2168  variable /g r_index = iz
    2169  variable /g s_index = it
    2170  string /g func_param = reduction_param
    2171 
    2172  if (nthreads > 0)
    2173  WaveClear image
    2174  ThreadGroupPutDF threadGroupID, :
    2175  else
    2176  processing_folders[izt] = GetDataFolderDFR()
    2177  make /n=1/d profile1, profile2
    2178  wave slabdata
    2179  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
    2180  variable /g func_result = numpnts(reduced_waves)
    2181  adh5_get_result_waves(reduced_waves, "redw_", 0)
    2182  WaveClear slabdata, image, reduced_waves
    2183  setdatafolder ::
    2184  endif
    2185 
    2186  izt += 1
    2187  // progress window
    2188  if (progress)
    2189  if (update_progress_panel(izt))
    2190  print "user abort"
    2191  result = -4
    2192  break
    2193  endif
    2194  endif
    2195  endfor
    2196  endfor
    2197 
    2198  killwaves /z slab, slabdata, template
    2199  if (progress)
    2200  update_progress_panel(0, message="Processing data (step 2 of 2)...")
    2201  endif
    2202 
    2203  dfref dfr
    2204  for (izt = 0; (izt < nzt) && (result == 0); izt += 1)
    2205  if (nthreads > 0)
    2206  do
    2207  if (progress)
    2208  if (update_progress_panel(izt))
    2209  print "user abort"
    2210  result = -4
    2211  break
    2212  endif
    2213  endif
    2214  dfr = ThreadGroupGetDFR(threadGroupID, 1000)
    2215  if (DatafolderRefStatus(dfr) != 0)
    2216  break
    2217  endif
    2218  while (1)
    2219  else
    2220  if (progress)
    2221  if (update_progress_panel(izt))
    2222  print "user abort"
    2223  result = -4
    2224  break
    2225  endif
    2226  endif
    2227  dfr = processing_folders[izt]
    2228  endif
    2229 
    2230  if (result != 0)
    2231  break
    2232  endif
    2233 
    2234  nvar rr = dfr:r_index
    2235  nvar ss = dfr:s_index
    2236  nvar func_result = dfr:func_result
    2237 
    2238  if (func_result < 1)
    2239  print "error during data reduction."
    2240  result = -3
    2241  break
    2242  endif
    2243 
    2244  if (numpnts(result_waves) == 0)
    2245  redimension /n=(func_result) result_waves
    2246  for (iw = 0; iw < func_result; iw += 1)
    2247  sw = "redw_" + num2str(iw)
    2248  wave profile = dfr:$sw
    2249  sw = "ReducedData" + num2str(iw+1)
    2250  make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
    2251  wave data = $sw
    2252  setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
    2253  setdimlabel 1, -1, $kScanDimLabel, data
    2254  note data, note(profile)
    2255  ps_scale_dataset(data)
    2256  setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
    2257  setscale d 0, 0, waveunits(profile, -1), data
    2258  result_waves[iw] = data
    2259  endfor
    2260  endif
    2261  for (iw = 0; iw < func_result; iw += 1)
    2262  sw = "redw_" + num2str(iw)
    2263  wave profile = dfr:$sw
    2264  wave data = result_waves[iw]
    2265  data[][rr][ss] = profile[p]
    2266  endfor
    2267  endfor
    2268 
    2269  if (nthreads > 0)
    2270  variable tstatus = ThreadGroupRelease(threadGroupID)
    2271  if (tstatus == -2)
    2272  print "error: thread did not terminate properly."
    2273  result = -5
    2274  endif
    2275  else
    2276  for (izt = 0; izt < nzt; izt += 1)
    2277  KillDataFolder /Z processing_folders[izt]
    2278  endfor
    2279  endif
    2280 
    2281  if (result == 0)
    2282  nw = numpnts(result_waves)
    2283  wavenames = ""
    2284  for (iw = 0; iw < nw; iw += 1)
    2285  wave data = result_waves[iw]
    2286  if (nz == 1)
    2287  redimension /n=(-1, 0, 0) data
    2288  elseif (nt == 1)
    2289  redimension /n=(-1, nz, 0) data
    2290  endif
    2291  wavenames += nameofwave(data) + ";"
    2292  endfor
    2293  endif
    2294  if (progress)
    2295  kill_progress_panel()
    2296  endif
    2297 
    2298  setdatafolder base_df
    2299  return wavenames
    2300 end
    2301 
    2302 threadsafe static function reduce_slab_worker(reduction_func)
    2303  funcref adh5_default_reduction reduction_func
    2304  do
    2305  // wait for job from main thread
    2306  do
    2307  dfref dfr = ThreadGroupGetDFR(0, 1000)
    2308  if (DataFolderRefStatus(dfr) == 0)
    2309  if (GetRTError(2))
    2310  return 0 // no more jobs
    2311  endif
    2312  else
    2313  break
    2314  endif
    2315  while (1)
    2316 
    2317  // get input data
    2318  wave slabdata = dfr:slabdata
    2319  wave image = dfr:image
    2320  svar func_param = dfr:func_param
    2321  nvar rr = dfr:r_index
    2322  nvar ss = dfr:s_index
    2323 
    2324  // do the work
    2325  newdatafolder /s outDF
    2326  variable /g r_index = rr
    2327  variable /g s_index = ss
    2328  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
    2329  variable /g func_result = numpnts(reduced_waves)
    2330 
    2331  // send output to queue and clean up
    2332  adh5_get_result_waves(reduced_waves, "redw_", 0)
    2333  WaveClear slabdata, image, reduced_waves
    2334  ThreadGroupPutDF 0, :
    2335  KillDataFolder dfr
    2336  while (1)
    2337 
    2338  return 0
    2339 end
    2340 
    2341 threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_param)
    2342  wave slabdata
    2343  wave image
    2344  funcref adh5_default_reduction reduction_func
    2345  string reduction_param
    2346 
    2347  // the multiplication by detector sensitivity assumes that we are loading a ScientaImage.
    2348  image = slabdata[q][p][0][0] * kDetectorSensitivity
    2349 
    2350  return reduction_func(image, reduction_param)
    2351 end
    2352 
    2367 function /s psh5_load_info(APathName, AFileName)
    2368  string APathName
    2369  string AFileName
    2370 
    2371  dfref saveDF = GetDataFolderDFR()
    2372  dfref fileDF = NewFreeDataFolder()
    2373  setdatafolder fileDF
    2374 
    2375  variable fileID
    2376  string filepath
    2377  string scanpaths
    2378  variable nscans
    2379  variable iscan
    2380  string scanpath
    2381  string info = ""
    2382 
    2383  HDF5OpenFile /P=$APathName /R fileID as AFileName
    2384  if (v_flag == 0)
    2385  filepath = s_path + s_filename
    2386  scanpaths = psh5_list_scans(fileID)
    2387  nscans = ItemsInList(scanpaths)
    2388  for (iscan = 0; iscan < nscans; iscan += 1)
    2389  scanpath = StringFromList(iscan, scanpaths)
    2390  info = info + scanpath + "\r"
    2391  info = info + psh5_load_scan_info(fileID, scanpath)
    2392  endfor
    2393  HDF5CloseFile fileID
    2394  endif
    2395 
    2396  setdatafolder saveDF
    2397  return info
    2398 end
    2399 
    2414 function /s psh5_load_scan_info(fileID, scanpath)
    2415  variable fileID
    2416  string scanpath
    2417 
    2418  string info = ""
    2419  string positions = ""
    2420  string positioners = ""
    2421  string readables = ""
    2422  string detectors = ""
    2423  string regions = ""
    2424 
    2425  psh5_load_scan_meta(fileID, scanpath)
    2426 
    2427  wave /z ScanDimensions
    2428  wave /t /z ScanWritables
    2429  wave /t /z ScanReadables
    2430  wave /z ScanSteps
    2431 
    2432  if (WaveExists(ScanSteps) && (numpnts(ScanSteps) >= 1))
    2433  ScanSteps += 1
    2434  positions = "positions = (" + wave2list(ScanSteps, "%u", ",") + ")"
    2435  info = AddListItem(positions, info, "\r", inf)
    2436  endif
    2437  if (WaveExists(ScanWritables) && (numpnts(ScanWritables) >= 1))
    2438  positioners = "positioners = " + twave2list(ScanWritables, ",")
    2439  info = AddListItem(positioners, info, "\r", inf)
    2440  endif
    2441 
    2442  variable i, m, n
    2443  string s
    2444  if (WaveExists(ScanReadables) && (numpnts(ScanReadables) >= 1))
    2445  readables = twave2list(ScanReadables, ",")
    2446  n = ItemsInList(readables, ",")
    2447  for (i = 0; i < n; i += 1)
    2448  s = StringFromList(i, readables, ",")
    2449  m = ItemsInList(s, "/")
    2450  if (m > 1)
    2451  s = StringFromList(m - 1, s, "/")
    2452  endif
    2453  if (WhichListItem(s, detectors, ",") < 0)
    2454  detectors = AddListItem(s, detectors, ",", inf)
    2455  endif
    2456  endfor
    2457  detectors = "detectors = " + detectors
    2458  info = AddListItem(detectors, info, "\r", inf)
    2459  endif
    2460 
    2461  regions = psh5_list_scan_regions(fileID, scanpath)
    2462  if (strlen(regions) > 0)
    2463  regions = "regions = " + regions
    2464  info = AddListItem(regions, info, "\r", inf)
    2465  endif
    2466 
    2467  return info
    2468 end
    2469 
    2473 static function /s twave2list(wt, sep)
    2474  wave /t wt
    2475  string sep
    2476 
    2477  string list = ""
    2478  variable n = numpnts(wt)
    2479  variable i
    2480  for (i = 0; i < n; i += 1)
    2481  list = AddListItem(wt[i], list, sep, inf)
    2482  endfor
    2483 
    2484  return list
    2485 end
    2486 
    2490 static function /s wave2list(w, format, sep)
    2491  wave w
    2492  string format
    2493  string sep
    2494 
    2495  string list = ""
    2496  variable n = numpnts(w)
    2497  variable i
    2498  string s
    2499  for (i = 0; i < n; i += 1)
    2500  sprintf s, format, w[i]
    2501  list = AddListItem(s, list, sep, inf)
    2502  endfor
    2503 
    2504  return list
    2505 end
    const string kEnergyDimLabel
    Dimension label for the energy dispersive dimension of multi-dimensional datasets.
    -
    string psh5_load_scan_preview(variable fileID, string scanpath, variable set_scale=defaultValue, string pref_datasets=defaultValue)
    load a preview dataset from an open PShell HDF5 file.
    -
    string psh5_load_scan_attrs(variable fileID, string scanpath, variable attr_sets=defaultValue)
    load attributes of a PShell scan group.
    -
    const string kTransposedDatasets
    List of datasets that should be transposed upon loading.
    -
    string psh5_load_scan_complete(variable fileID, string scanpath, variable load_data=defaultValue, variable load_attr=defaultValue)
    load all data of a selected scan from a PShell data file.
    -
    const string kScanDimLabel
    Dimension label for the scan dimension of multi-dimensional datasets.
    -
    string PearlCleanupName(string name)
    -
    const string kAngleDimLabel
    Dimension label for the angle dispersive dimension of multi-dimensional datasets. ...
    -
    const string kDataDimLabel
    Dimension label for the data dimension.
    -
    string psh5_load_preview(string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue, string pref_scans=defaultValue, string pref_datasets=defaultValue)
    load a preview image from a PShell data file.
    -
    variable psh5_open_file(string ANickName, string APathName, string AFileName)
    open a HDF5 file created by the PShell data acquisition program and prepare the data folder...
    -
    variable ps_scale_datasets()
    set the dimension scales of loaded PShell Scienta datasets according to attributes.
    -
    string psh5_load_scan_meta(variable fileID, string scanpath)
    load metadata of a PShell scan group.
    -
    const string kScientaScalingDatasets
    List of datasets that must be loaded to determine the axis scaling of a Scienta image.
    -
    string psh5_list_scan_datasets(variable fileID, string scanpath, variable include_regions=defaultValue)
    list datasets of a PShell scan group.
    -
    string psh5_load_scan_data(variable fileID, string scanpath)
    load all datasets of a PShell scan group.
    -
    const variable kDetectorSensitivity
    multiply scienta detector intensity by this value to get actual counts.
    -
    string psh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
    load everything from a PShell data file.
    -
    string psh5_list_scans(variable fileID)
    list scan groups of a PShell data file.
    -
    variable psh5_close_file(variable fileID)
    close a HDF5 file opened by psh5_open_file.
    -
    const string kPreviewDatasets
    List of preferred datasets to load for preview.
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 8.00
    +
    4 #pragma ModuleName = PearlPShellImport
    +
    5 #pragma version = 2.1
    +
    6 #if IgorVersion() < 9.00
    +
    7 #include <HDF5 Browser>
    +
    8 #endif
    +
    9 #include "pearl-compat"
    +
    10 #include "pearl-gui-tools"
    +
    11 #include "pearl-area-import"
    +
    12 
    +
    13 // copyright (c) 2013-22 Paul Scherrer Institut
    +
    14 //
    +
    15 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    16 // you may not use this file except in compliance with the License.
    +
    17 // You may obtain a copy of the License at
    +
    18 // http:///www.apache.org/licenses/LICENSE-2.0
    +
    19 
    +
    43 
    +
    48 
    +
    50 strconstant kEnergyDimLabel = "energy"
    +
    51 
    +
    53 strconstant kAngleDimLabel = "angle"
    +
    54 
    +
    56 strconstant kScanDimLabel = "scan"
    +
    57 
    +
    60 strconstant kDataDimLabel = "data"
    +
    61 
    +
    63 strconstant kPreviewDatasets = "ImageEnergyDistribution;ScientaSpectrum;ScientaImage;Counts;SampleCurrent;"
    +
    64 
    +
    66 strconstant kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;Eph;"
    +
    67 
    +
    69 strconstant kEssentialDiagnostics = "ManipulatorX;ManipulatorY;ManipulatorZ;ManipulatorTheta;ManipulatorTilt;ManipulatorPhi;MonoEnergy;"
    +
    70 
    +
    72 strconstant kTransposedDatasets = "ScientaImage;"
    +
    73 
    +
    74 constant kDSCPositioners = 0x0001
    +
    75 constant kDSCDetectors = 0x0002
    +
    76 constant kDSCScientaScaling = 0x0004
    +
    77 constant kDSCPreview = 0x0008
    +
    78 constant kDSCEssentialDiags = 0x0010
    +
    79 constant kDSCAttrs = 0x0020
    +
    80 constant kDSCDiags = 0x0040
    +
    81 constant kDSCSnaps = 0x0080
    +
    82 constant kDSCMeta = 0x0100
    +
    83 constant kDSCMonitors = 0x0200
    +
    84 constant kDSCRegions = 0x0400
    +
    85 constant kDSCOther = 0x8000
    +
    86 constant kDSCAll = 0xffff
    +
    87 
    +
    88 
    +
    89 // ====== main import functions ======
    +
    90 
    +
    158 function /df psh5_load(path_name, file_name, scans, regions, datasets, [classes, max_rank, reduction_func, reduction_params, dest_df])
    +
    159  string path_name
    +
    160  string file_name
    +
    161  string scans
    +
    162  string regions
    +
    163  string datasets
    +
    164  variable classes
    +
    165  variable max_rank
    +
    166  string reduction_func
    +
    167  string reduction_params
    +
    168  dfref dest_df
    +
    169 
    +
    170  dfref save_df = GetDataFolderDFR()
    +
    171  variable timerRefNum = startMSTimer
    +
    172 
    +
    173  if (ParamIsDefault(classes) || (classes == 0))
    + +
    175  endif
    +
    176  variable essential_classes = kDSCPositioners | kDSCScientaScaling | kDSCEssentialDiags
    +
    177 
    +
    178  if (ParamIsDefault(dest_df) || !DataFolderRefStatus(dest_df))
    +
    179  dest_df = psh5_open_file(path_name, file_name)
    +
    180  else
    +
    181  dest_df = psh5_open_file(path_name, file_name, dest_df=dest_df)
    +
    182  endif
    +
    183  if (ParamIsDefault(reduction_func))
    +
    184  reduction_func = ""
    +
    185  endif
    +
    186  if (ParamIsDefault(reduction_params))
    +
    187  reduction_params = ""
    +
    188  endif
    +
    189 
    +
    190  if (DataFolderRefStatus(dest_df))
    +
    191  setdatafolder dest_df
    +
    192  psh5_load_general_group(dest_df)
    +
    193 
    +
    194  // datasets contained in file
    +
    195  svar /sdfr=dest_df file_datasets = s_datasets
    +
    196 
    +
    197  // datasets contained in file up to allowed rank
    +
    198  string ranked_datasets = ""
    +
    199  if (ParamIsDefault(max_rank))
    +
    200  ranked_datasets = file_datasets
    +
    201  else
    +
    202  svar /sdfr=dest_df file_ranks = s_datasets_ranks
    +
    203  ranked_datasets = psh5_filter_datasets_rank(file_datasets, file_ranks, 0, max_rank)
    +
    204  endif
    +
    205 
    +
    206  string matching_datasets = ""
    +
    207  string matching_essentials = ""
    +
    208  string scan_datasets = ""
    +
    209  string region_datasets = ""
    +
    210  string free_datasets = ""
    +
    211  string selected_datasets = ""
    +
    212  string essential_datasets = ""
    +
    213 
    +
    214  variable i_item
    +
    215  variable n_items
    +
    216  string item
    +
    217 
    +
    218  // select datasets belonging to selected scans
    +
    219  n_items = ItemsInList(scans, ";")
    +
    220  for (i_item = 0; i_item < n_items; i_item += 1)
    +
    221  item = StringFromList(i_item, scans, ";")
    +
    222  if (cmpstr(item[0,3], "scan") == 0)
    +
    223  item = "/" + item
    +
    224  endif
    +
    225  item = ReplaceString("//", item + "/*", "/")
    +
    226  matching_datasets = psh5_match_datasets(ranked_datasets, item)
    +
    227  scan_datasets = scan_datasets + matching_datasets
    +
    228  endfor
    +
    229 
    +
    230  // select datasets belonging to selected regions
    +
    231  n_items = ItemsInList(regions, ";")
    +
    232  for (i_item = 0; i_item < n_items; i_item += 1)
    +
    233  item = StringFromList(i_item, regions, ";")
    +
    234  if (cmpstr(item[0,3], "scan") == 0)
    +
    235  item = "/" + item
    +
    236  endif
    +
    237  item = ReplaceString("//", item + "/*", "/")
    +
    238  matching_datasets = psh5_match_datasets(ranked_datasets, item)
    +
    239  region_datasets = region_datasets + matching_datasets
    +
    240  endfor
    +
    241 
    +
    242  // free select datasets
    +
    243  n_items = ItemsInList(datasets, ";")
    +
    244  for (i_item = 0; i_item < n_items; i_item += 1)
    +
    245  item = StringFromList(i_item, datasets, ";")
    +
    246  if (cmpstr(item[0,3], "scan") == 0)
    +
    247  item = "/" + item
    +
    248  endif
    +
    249  matching_datasets = psh5_match_datasets(ranked_datasets, item)
    +
    250  free_datasets = free_datasets + matching_datasets
    +
    251  endfor
    +
    252 
    +
    253  selected_datasets = scan_datasets + region_datasets + free_datasets
    +
    254 
    +
    255  string filtered_datasets = ""
    +
    256  string diag_datasets = ""
    +
    257  string selected_scans = psh5_extract_scan_paths(selected_datasets)
    +
    258  variable i_scan
    +
    259  variable n_scans = ItemsInList(selected_scans)
    +
    260  string scan
    +
    261  string selected_regions = psh5_extract_region_paths(selected_datasets)
    +
    262  variable i_region
    +
    263  variable n_regions = ItemsInList(selected_regions)
    +
    264  string region
    +
    265  string positioners
    +
    266  string detectors
    +
    267 
    +
    268  // datasets directly under one of the selected regions
    +
    269  region_datasets = ""
    +
    270  for (i_region = 0; i_region < n_regions; i_region += 1)
    +
    271  region = StringFromList(i_region, selected_regions, ";")
    +
    272  region_datasets = region_datasets + GrepList(file_datasets, "(?i)^" + region + "[[:alpha:]]+$")
    +
    273  endfor
    +
    274 
    +
    275  // filter selected datasets by class and add essential dependencies
    +
    276  // each scan may have specific positioners and detectors
    +
    277  for (i_scan = 0; i_scan < n_scans; i_scan += 1)
    +
    278  scan = StringFromList(i_scan, selected_scans, ";")
    +
    279 
    +
    280  // potentially interesting diagnostics of current scan and selected regions
    +
    281  diag_datasets = psh5_match_datasets(file_datasets, scan + "*")
    +
    282  diag_datasets = psh5_match_dataset_classes(diag_datasets, kDSCAttrs | kDSCDiags | kDSCSnaps)
    +
    283  diag_datasets = diag_datasets + GrepList(file_datasets, "(?i)^" + scan + "[[:alpha:]]+$")
    +
    284  diag_datasets = diag_datasets + psh5_match_datasets(region_datasets, scan + "*")
    +
    285 
    +
    286  // explicit positioners and detectors set by pshell
    +
    287  setdatafolder dest_df
    +
    288  dfref scan_df = psh5_create_folders(scan)
    +
    289  setdatafolder scan_df
    +
    290  psh5_load_scan_meta(dest_df, scan)
    +
    291  wave /t /z ScanWritables
    +
    292  wave /t /z ScanReadables
    +
    293  if (WaveExists(ScanWritables))
    +
    294  positioners = twave2list(ScanWritables, ";")
    +
    295  else
    +
    296  positioners = ""
    +
    297  endif
    +
    298  if (WaveExists(ScanReadables))
    +
    299  detectors = twave2list(ScanReadables, ";")
    +
    300  else
    +
    301  detectors = ""
    +
    302  endif
    +
    303 
    +
    304  // filtering by classes
    +
    305  matching_datasets = psh5_match_dataset_classes(selected_datasets, classes, positioners=positioners, detectors=detectors)
    +
    306 
    +
    307  // add essential diags
    +
    308  if (strlen(matching_datasets) > 1)
    +
    309  essential_datasets = psh5_match_dataset_classes(diag_datasets, essential_classes, positioners=positioners, detectors=detectors)
    +
    310  endif
    +
    311 
    +
    312  // scaling datasets before detectors because data reduction needs the scales
    +
    313  filtered_datasets = essential_datasets + filtered_datasets + matching_datasets
    +
    314  endfor
    +
    315 
    +
    316  // load the datasets
    +
    317  setdatafolder dest_df
    +
    318  string /g s_loaded_datasets = ""
    +
    319  s_loaded_datasets = psh5_load_datasets(dest_df, filtered_datasets, reduction_func=reduction_func, reduction_params=reduction_params)
    +
    320 
    +
    321  // apply scaling by scan
    +
    322  for (i_scan = 0; i_scan < n_scans; i_scan += 1)
    +
    323  scan = StringFromList(i_scan, selected_scans, ";")
    + +
    325  endfor
    +
    326 
    +
    327  psh5_close_file(dest_df)
    +
    328 
    +
    329  // performance reporting
    +
    330  if (timerRefNum >= 0)
    +
    331  setdatafolder dest_df
    +
    332  variable /g psh5_perf_secs
    +
    333  psh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
    +
    334  endif
    +
    335  endif
    +
    336 
    +
    337  setdatafolder save_df
    +
    338  return dest_df
    +
    339 end
    +
    340 
    +
    345 function /df psh5_preview(path_name, file_name, [dest_df, preview_datasets])
    +
    346  string path_name
    +
    347  string file_name
    +
    348  dfref dest_df
    +
    349  string preview_datasets
    +
    350 
    +
    351  dfref save_df = GetDataFolderDFR()
    +
    352 
    +
    353  if (ParamIsDefault(dest_df))
    +
    354  dest_df = psh5_open_file(path_name, file_name)
    +
    355  else
    +
    356  dest_df = psh5_open_file(path_name, file_name, dest_df=dest_df)
    +
    357  endif
    +
    358  if (ParamIsDefault(preview_datasets))
    +
    359  preview_datasets = kPreviewDatasets
    +
    360  endif
    +
    361  variable essential_classes = kDSCPositioners | kDSCScientaScaling
    +
    362 
    +
    363  if (DataFolderRefStatus(dest_df))
    +
    364  setdatafolder dest_df
    +
    365  psh5_load_general_group(dest_df)
    +
    366 
    +
    367  // select dataset based on preference
    +
    368  svar /sdfr=dest_df file_datasets = s_datasets
    +
    369  svar /sdfr=dest_df file_datasets_ranks = s_datasets_ranks
    +
    370  string selected_datasets = ""
    +
    371  string essential_datasets = ""
    +
    372  string scan_datasets = ""
    +
    373  string filtered_datasets = ""
    +
    374 
    +
    375  variable nds = ItemsInList(preview_datasets, ";")
    +
    376  variable ids
    +
    377  string ds
    +
    378  for (ids = 0; ids < nds; ids += 1)
    +
    379  ds = StringFromList(ids, preview_datasets, ";")
    +
    380  selected_datasets = psh5_filter_datasets_rank(file_datasets, file_datasets_ranks, 1, 2)
    +
    381  selected_datasets = psh5_match_datasets(selected_datasets, "/scan*" + ds)
    +
    382  if (strlen(selected_datasets) > 1)
    +
    383  selected_datasets = StringFromList(0, selected_datasets, ";")
    +
    384  break
    +
    385  endif
    +
    386  endfor
    +
    387 
    +
    388  // add essential dependencies
    +
    389  if (strlen(selected_datasets) > 1)
    +
    390  string selected_scans = psh5_extract_scan_paths(selected_datasets)
    +
    391  string scan
    +
    392  string positioners
    +
    393 
    +
    394  scan = StringFromList(0, selected_scans, ";")
    +
    395  scan_datasets = psh5_match_datasets(file_datasets, scan + "*")
    +
    396 
    +
    397  psh5_load_scan_meta(dest_df, scan)
    +
    398  wave /t /z ScanWritables
    +
    399  if (WaveExists(ScanWritables))
    +
    400  positioners = twave2list(ScanWritables, ";")
    +
    401  else
    +
    402  positioners = ""
    +
    403  endif
    +
    404 
    +
    405  essential_datasets = psh5_match_dataset_classes(scan_datasets, essential_classes, positioners=positioners)
    +
    406  filtered_datasets = essential_datasets + selected_datasets
    +
    407 
    +
    408  // load the datasets
    +
    409  psh5_load_datasets(dest_df, filtered_datasets, create_folders=0)
    +
    410  ps_scale_datasets(dest_df)
    +
    411  string /g s_preview_dataset = StringFromList(0, selected_datasets, ";")
    +
    412  string /g s_preview_wave = StringFromList(ItemsInList(s_preview_dataset, "/") - 1, s_preview_dataset, "/")
    +
    413  endif
    +
    414 
    +
    415  psh5_close_file(dest_df)
    +
    416  endif
    +
    417 
    +
    418  setdatafolder save_df
    +
    419  return dest_df
    +
    420 end
    +
    421 
    +
    450 function /df psh5_open_file(path_name, file_name, [dest_df])
    +
    451  string path_name
    +
    452  string file_name
    +
    453  dfref dest_df
    +
    454 
    +
    455  dfref save_df = GetDataFolderDFR()
    +
    456 
    +
    457  variable fid
    +
    458  HDF5OpenFile /P=$path_name /R fid as file_name
    +
    459  if (v_flag == 0)
    +
    460  if (!ParamIsDefault(dest_df))
    +
    461  setdatafolder dest_df
    +
    462  else
    +
    463  string dest_name = ad_suggest_foldername(s_filename, sourcename="psh")
    +
    464  setdatafolder root:
    +
    465  newdatafolder /s /o $("root:" + dest_name)
    +
    466  endif
    +
    467  dfref file_df = GetDataFolderDFR()
    +
    468 
    +
    469  variable /g file_id = fid
    +
    470  string /g s_filepath
    +
    471  string /g s_scanpaths
    +
    472  string /g s_datasets
    +
    473  string datatypes
    +
    474  string ranks
    +
    475  string dimensions
    +
    476  s_filepath = s_path + s_filename
    +
    477  s_scanpaths = psh5_list_scans(file_id)
    +
    478  s_datasets = psh5_list_all_datasets(file_id)
    +
    479  [datatypes, ranks, dimensions] = psh5_list_dataset_info(file_id, s_datasets)
    +
    480  string /g s_datasets_datatypes = datatypes
    +
    481  string /g s_datasets_ranks = ranks
    +
    482  string /g s_datasets_dimensions = dimensions
    +
    483  else
    +
    484  dfref file_df = $""
    +
    485  endif
    +
    486 
    +
    487  setdatafolder save_df
    +
    488  return file_df
    +
    489 end
    +
    490 
    +
    509 function psh5_close_file(file_df)
    +
    510  dfref file_df
    +
    511 
    +
    512  if (DataFolderRefStatus(file_df))
    +
    513  nvar /sdfr=file_df /z file_id
    +
    514  if (nvar_Exists(file_id))
    +
    515  HDF5CloseFile /z file_id
    +
    516  file_id = 0
    +
    517  KillVariables /z file_id
    +
    518  else
    +
    519  dfref parent_df = $(GetDataFolder(1, file_df) + ":")
    +
    520  if (DataFolderRefStatus(parent_df))
    +
    521  psh5_close_file(parent_df)
    +
    522  endif
    +
    523  endif
    +
    524  endif
    +
    525 end
    +
    526 
    +
    527 // === datasets and paths ===
    +
    528 
    +
    532 static function /s twave2list(wt, sep)
    +
    533  wave /t wt
    +
    534  string sep
    +
    535 
    +
    536  string list = ""
    +
    537  variable n = numpnts(wt)
    +
    538  variable i
    +
    539  for (i = 0; i < n; i += 1)
    +
    540  list = AddListItem(wt[i], list, sep, inf)
    +
    541  endfor
    +
    542 
    +
    543  return list
    +
    544 end
    +
    545 
    +
    549 static function /s wave2list(w, format, sep)
    +
    550  wave w
    +
    551  string format
    +
    552  string sep
    +
    553 
    +
    554  string list = ""
    +
    555  variable n = numpnts(w)
    +
    556  variable i
    +
    557  string s
    +
    558  for (i = 0; i < n; i += 1)
    +
    559  sprintf s, format, w[i]
    +
    560  list = AddListItem(s, list, sep, inf)
    +
    561  endfor
    +
    562 
    +
    563  return list
    +
    564 end
    +
    565 
    +
    574 function /s psh5_list_scans(file_id)
    +
    575  variable file_id
    +
    576 
    +
    577  HDF5ListGroup /F /TYPE=1 file_id, "/"
    +
    578 
    +
    579  variable ig
    +
    580  variable ng = ItemsInList(S_HDF5ListGroup, ";")
    +
    581  string sg
    +
    582  string scans = ""
    +
    583 
    +
    584  for (ig = 0; ig < ng; ig += 1)
    +
    585  sg = StringFromList(ig, S_HDF5ListGroup, ";")
    +
    586  if (cmpstr(sg[1,4], "scan") == 0)
    +
    587  scans = AddListItem(sg, scans, ";", inf)
    +
    588  endif
    +
    589  endfor
    +
    590 
    +
    591  return scans
    +
    592 end
    +
    593 
    +
    605 function /s psh5_list_all_datasets(file_id)
    +
    606  variable file_id
    +
    607 
    +
    608  HDF5ListGroup /F /R /TYPE=2 /Z file_id, "/"
    +
    609  if (!v_flag)
    +
    610  return S_HDF5ListGroup
    +
    611  else
    +
    612  return ""
    +
    613  endif
    +
    614 end
    +
    615 
    +
    631 function [string datatypes, string ranks, string dimensions] psh5_list_dataset_info(variable file_id, string datasets)
    +
    632  variable nds = ItemsInList(datasets, ";")
    +
    633  variable ids
    +
    634  string sds
    +
    635  STRUCT HDF5DataInfo di
    +
    636  InitHDF5DataInfo(di)
    +
    637  variable err
    +
    638  variable idim
    +
    639  string sdims
    +
    640  datatypes = ""
    +
    641  ranks = ""
    +
    642  dimensions = ""
    +
    643 
    +
    644  for (ids = 0; ids < nds; ids += 1)
    +
    645  sds = StringFromList(ids, datasets, ";")
    +
    646  err = HDF5DatasetInfo(file_id, sds, 0, di)
    +
    647  if (err == 0)
    +
    648  switch (di.datatype_class)
    +
    649  case H5T_INTEGER:
    +
    650  datatypes = AddListItem("i", datatypes, ";", ids)
    +
    651  break
    +
    652  case H5T_FLOAT:
    +
    653  datatypes = AddListItem("f", datatypes, ";", ids)
    +
    654  break
    +
    655  case H5T_STRING:
    +
    656  datatypes = AddListItem("s", datatypes, ";", ids)
    +
    657  break
    +
    658  default:
    +
    659  datatypes = AddListItem("?", datatypes, ";", ids)
    +
    660  break
    +
    661  endswitch
    +
    662 
    +
    663  ranks = AddListItem(num2str(di.ndims), ranks, ";", ids)
    +
    664 
    +
    665  sdims = ""
    +
    666  for (idim = 0; idim < di.ndims; idim += 1)
    +
    667  sdims = AddListItem(num2str(di.dims[idim]), sdims, ",", idim)
    +
    668  endfor
    +
    669  if (strlen(sdims) > 1)
    +
    670  sdims = sdims[0, strlen(sdims)-2]
    +
    671  endif
    +
    672  dimensions = AddListItem(sdims, dimensions, ";", ids)
    +
    673  endif
    +
    674  endfor
    +
    675 end
    +
    676 
    +
    692 function /s psh5_match_datasets(datasets, match)
    +
    693  string datasets
    +
    694  string match
    +
    695 
    +
    696  string result = ""
    +
    697 
    +
    698  string spaceless_datasets = ReplaceString(" ", datasets, "")
    +
    699  string spaceless_match = ReplaceString(" ", match, "")
    +
    700 
    +
    701  string sep = ";"
    +
    702  variable seplen = strlen(sep)
    +
    703  variable nds = ItemsInList(spaceless_datasets, sep)
    +
    704  variable ids
    +
    705  string ds
    +
    706  variable offset = 0
    +
    707 
    +
    708  for (ids = 0; ids < nds; ids += 1)
    +
    709  ds = StringFromList(0, spaceless_datasets, sep, offset)
    +
    710  offset += strlen(ds) + seplen
    +
    711  if (StringMatch(ds, spaceless_match))
    +
    712  ds = StringFromList(ids, datasets, sep, 0)
    +
    713  result = AddListItem(ds, result, sep, inf)
    +
    714  endif
    +
    715  endfor
    +
    716 
    +
    717  return result
    +
    718 end
    +
    719 
    +
    728 function /s psh5_filter_datasets_rank(datasets, ranks, min_rank, max_rank)
    +
    729  string datasets
    +
    730  string ranks
    +
    731  variable min_rank
    +
    732  variable max_rank
    +
    733 
    +
    734  string result = ""
    +
    735  string sep = ";"
    +
    736  variable seplen = strlen(sep)
    +
    737  variable nds = ItemsInList(datasets, sep)
    +
    738  variable ids
    +
    739  string ds
    +
    740  variable offset = 0
    +
    741  variable rank
    +
    742 
    +
    743  for (ids = 0; ids < nds; ids += 1)
    +
    744  ds = StringFromList(0, datasets, sep, offset)
    +
    745  offset += strlen(ds) + seplen
    +
    746  rank = str2num(StringFromList(ids, ranks, sep))
    +
    747  if ((rank >= min_rank) && (rank <= max_rank))
    +
    748  result = AddListItem(ds, result, sep, inf)
    +
    749  endif
    +
    750  endfor
    +
    751 
    +
    752  return result
    +
    753 end
    +
    754 
    +
    764 static function /s unique_strings(list)
    +
    765  string list
    +
    766 
    +
    767  string result = ""
    +
    768 
    +
    769  string sep = ";"
    +
    770  variable seplen = strlen(sep)
    +
    771  variable nn = ItemsInList(list, sep)
    +
    772  variable ii
    +
    773  string item
    +
    774  variable offset = 0
    +
    775 
    +
    776  make /n=(nn) /t /free wt_in
    +
    777  for (ii = 0; ii < nn; ii += 1)
    +
    778  item = StringFromList(0, list, sep, offset)
    +
    779  offset += strlen(item) + seplen
    +
    780  wt_in[ii] = item
    +
    781  endfor
    +
    782 
    +
    783  FindDuplicates /Z /FREE /RT=wt_out wt_in
    +
    784 
    +
    785  return twave2list(wt_out, ";")
    +
    786 end
    +
    787 
    +
    803 function /s psh5_extract_scan_paths(datasets)
    +
    804  string datasets
    +
    805 
    +
    806  string result = ""
    +
    807  string sep = ";"
    +
    808  variable seplen = strlen(sep)
    +
    809  variable nds = ItemsInList(datasets, sep)
    +
    810  variable ids
    +
    811  string ds
    +
    812  string scan
    +
    813  string item
    +
    814  variable offset = 0
    +
    815 
    +
    816  for (ids = 0; ids < nds; ids += 1)
    +
    817  ds = StringFromList(0, datasets, sep, offset)
    +
    818  offset += strlen(ds) + seplen
    +
    819  if (cmpstr(ds[0], "/") != 0)
    +
    820  ds = "/" + ds
    +
    821  endif
    +
    822 
    +
    823  scan = StringFromList(1, ds, "/")
    +
    824  if (StringMatch(scan, "scan*"))
    +
    825  item = "/" + scan + "/"
    +
    826  else
    +
    827  item = ""
    +
    828  endif
    +
    829 
    +
    830  if ((strlen(item) > 0) && (WhichListItem(item, result, ";", 0, 0) < 0))
    +
    831  result = AddListItem(item, result, ";", inf)
    +
    832  endif
    +
    833  endfor
    +
    834 
    +
    835  return result
    +
    836 end
    +
    837 
    +
    853 function /s psh5_extract_region_paths(datasets)
    +
    854  string datasets
    +
    855 
    +
    856  string result = ""
    +
    857  string sep = ";"
    +
    858  variable seplen = strlen(sep)
    +
    859  variable nds = ItemsInList(datasets, sep)
    +
    860  variable ids
    +
    861  string ds
    +
    862  string scan
    +
    863  string region
    +
    864  string item
    +
    865  variable offset = 0
    +
    866 
    +
    867  for (ids = 0; ids < nds; ids += 1)
    +
    868  ds = StringFromList(0, datasets, sep, offset)
    +
    869  offset += strlen(ds) + seplen
    +
    870  if (cmpstr(ds[0], "/") != 0)
    +
    871  ds = "/" + ds
    +
    872  endif
    +
    873 
    +
    874  scan = StringFromList(1, ds, "/")
    +
    875  region = StringFromList(2, ds, "/")
    +
    876  if (StringMatch(scan, "scan*") && StringMatch(region, "region*"))
    +
    877  item = "/" + scan + "/" + region + "/"
    +
    878  else
    +
    879  item = ""
    +
    880  endif
    +
    881 
    +
    882  if ((strlen(item) > 0) && (WhichListItem(item, result, ";", 0, 0) < 0))
    +
    883  result = AddListItem(item, result, ";", inf)
    +
    884  endif
    +
    885  endfor
    +
    886 
    +
    887  return result
    +
    888 end
    +
    889 
    +
    899 function /s psh5_match_dataset_classes(datasets, classes, [positioners, detectors])
    +
    900  string datasets
    +
    901  variable classes
    +
    902  string positioners
    +
    903  string detectors
    +
    904 
    +
    905  if (ParamIsDefault(positioners))
    +
    906  positioners = ""
    +
    907  endif
    +
    908  if (ParamIsDefault(detectors) || (strlen(detectors) == 0))
    +
    909  detectors = kPreviewDatasets
    +
    910  endif
    +
    911 
    +
    912  string result = ""
    +
    913  string sep = ";"
    +
    914  variable seplen = strlen(sep)
    +
    915  variable nds = ItemsInList(datasets, sep)
    +
    916  variable ids
    +
    917  variable offset = 0
    +
    918  string ds
    +
    919  variable nparts
    +
    920  string ds_parent
    +
    921  string ds_name
    +
    922  string ds_scan_rel
    +
    923  variable ds_class
    +
    924 
    +
    925  for (ids = 0; ids < nds; ids += 1)
    +
    926  ds = StringFromList(0, datasets, sep, offset)
    +
    927  offset += strlen(ds) + seplen
    +
    928  nparts = ItemsInList(ds, "/")
    +
    929  ds_parent = StringFromList(nparts - 2, ds, "/")
    +
    930  ds_name = StringFromList(nparts - 1, ds, "/")
    +
    931  if (cmpstr(ds[0,4], "/scan") == 0)
    +
    932  ds_scan_rel = RemoveListItem(0, ds[1, strlen(ds) - 1], "/")
    +
    933  else
    +
    934  ds_scan_rel = ds
    +
    935  endif
    +
    936  ds_class = 0
    +
    937 
    +
    938  if (strlen(ds_parent) > 0)
    +
    939  ds_class = ds_class | (cmpstr(ds_parent, "attr") == 0 ? kDSCAttrs : 0)
    +
    940  ds_class = ds_class | (cmpstr(ds_parent, "attrs") == 0 ? kDSCAttrs : 0)
    +
    941  ds_class = ds_class | (cmpstr(ds_parent, "diags") == 0 ? kDSCDiags : 0)
    +
    942  ds_class = ds_class | (cmpstr(ds_parent, "snaps") == 0 ? kDSCSnaps : 0)
    +
    943  ds_class = ds_class | (cmpstr(ds_parent, "meta") == 0 ? kDSCMeta : 0)
    +
    944  ds_class = ds_class | (cmpstr(ds_parent, "monitors") == 0 ? kDSCMonitors : 0)
    +
    945  ds_class = ds_class | (cmpstr(ds_parent[0,5], "region") == 0 ? kDSCRegions : 0)
    +
    946  endif
    +
    947 
    +
    948  if (strlen(ds_name) > 0)
    +
    949  ds_class = ds_class | (WhichListItem(ds_scan_rel, positioners, sep, 0, 0) >= 0 ? kDSCPositioners : 0)
    +
    950  ds_class = ds_class | (WhichListItem(ds_scan_rel, detectors, sep, 0, 0) >= 0 ? kDSCDetectors : 0)
    +
    951  ds_class = ds_class | (WhichListItem(ds_name, kPreviewDatasets, sep, 0, 0) >= 0 ? kDSCPreview : 0)
    +
    952  ds_class = ds_class | (WhichListItem(ds_name, kScientaScalingDatasets, sep, 0, 0) >= 0 ? kDSCScientaScaling : 0)
    +
    953  ds_class = ds_class | (WhichListItem(ds_name, kEssentialDiagnostics, sep, 0, 0) >= 0 ? kDSCEssentialDiags : 0)
    +
    954  endif
    +
    955 
    +
    956  if (ds_class == 0)
    +
    957  ds_class = kDSCOther
    +
    958  endif
    +
    959 
    +
    960  if (ds_class & classes)
    +
    961  result = AddListItem(ds, result, sep, inf)
    +
    962  endif
    +
    963  endfor
    +
    964 
    +
    965  return result
    +
    966 end
    +
    967 
    +
    990 function /df psh5_create_folders(datasetpath)
    +
    991  string datasetpath
    +
    992 
    +
    993  if (cmpstr(datasetpath[0], "/") == 0)
    +
    994  datasetpath = datasetpath[1, strlen(datasetpath)-1]
    +
    995  endif
    +
    996  if (cmpstr(datasetpath[strlen(datasetpath)-1], "/") == 0)
    +
    997  datasetpath += "dummy"
    +
    998  endif
    +
    999 
    +
    1000  variable nfolders = ItemsInList(datasetpath, "/") - 1
    +
    1001  variable ifolder
    +
    1002  string folder
    +
    1003  string inc_path = "/"
    +
    1004 
    +
    1005  for (ifolder = 0; ifolder < nfolders; ifolder += 1)
    +
    1006  folder = StringFromList(ifolder, datasetpath, "/")
    +
    1007  folder = ps_fix_folder_name(folder)
    +
    1008  NewDataFolder /o/s $folder
    +
    1009  inc_path += folder
    +
    1010  inc_path += "/"
    +
    1011  string /g s_hdf5_group = inc_path
    +
    1012  endfor
    +
    1013 
    +
    1014  return GetDataFolderDFR()
    +
    1015 end
    +
    1016 
    +
    1034 function /df psh5_dataset_to_folder(parent_df, datasetpath)
    +
    1035  dfref parent_df
    +
    1036  string datasetpath
    +
    1037 
    +
    1038  if (cmpstr(datasetpath[0], "/") == 0)
    +
    1039  datasetpath = datasetpath[1, strlen(datasetpath)-1]
    +
    1040  endif
    +
    1041  if (cmpstr(datasetpath[strlen(datasetpath)-1], "/") == 0)
    +
    1042  datasetpath += "dummy"
    +
    1043  endif
    +
    1044 
    +
    1045  variable nfolders = ItemsInList(datasetpath, "/") - 1
    +
    1046  variable ifolder
    +
    1047  string folder
    +
    1048  string inc_path = ""
    +
    1049 
    +
    1050  for (ifolder = 0; ifolder < nfolders; ifolder += 1)
    +
    1051  folder = StringFromList(ifolder, datasetpath, "/")
    +
    1052  folder = ps_fix_folder_name(folder)
    +
    1053  if (ifolder)
    +
    1054  inc_path += ":"
    +
    1055  endif
    +
    1056  inc_path += folder
    +
    1057  endfor
    +
    1058 
    +
    1059  dfref out_df = parent_df:$inc_path
    +
    1060  return out_df
    +
    1061 end
    +
    1062 
    +
    1065 function /s ps_fix_folder_name(group_name)
    +
    1066  string group_name
    +
    1067  string folder_name
    +
    1068 
    +
    1069  folder_name = ReplaceString(" ", group_name, "")
    +
    1070  if (cmpstr(folder_name, "attrs") == 0)
    +
    1071  folder_name = "attr"
    +
    1072  endif
    +
    1073  folder_name = PearlCleanupName(folder_name)
    +
    1074 
    +
    1075  return folder_name
    +
    1076 end
    +
    1077 
    +
    1078 // ====== import functions ======
    +
    1079 
    +
    1098 function /s psh5_load_datasets(file_df, datasets, [create_folders, reduction_func, reduction_params])
    +
    1099  dfref file_df
    +
    1100  string datasets
    +
    1101  variable create_folders
    +
    1102  string reduction_func
    +
    1103  string reduction_params
    +
    1104 
    +
    1105  if (!DataFolderRefStatus(file_df))
    +
    1106  dfref file_df = GetDataFolderDFR()
    +
    1107  endif
    +
    1108  if (ParamIsDefault(create_folders))
    +
    1109  create_folders = 1
    +
    1110  endif
    +
    1111  if (ParamIsDefault(reduction_func))
    +
    1112  reduction_func = ""
    +
    1113  endif
    +
    1114  if (ParamIsDefault(reduction_params))
    +
    1115  reduction_params = ""
    +
    1116  endif
    +
    1117 
    +
    1118  dfref save_df = GetdataFolderDFR()
    +
    1119 
    +
    1120  datasets = unique_strings(datasets)
    +
    1121  variable nds = ItemsInList(datasets, ";")
    +
    1122  variable ids
    +
    1123  string ds
    +
    1124  string loaded_datasets = ""
    +
    1125  string loaded_waves = ""
    +
    1126 
    +
    1127  for (ids = 0; ids < nds; ids += 1)
    +
    1128  SetDataFolder file_df
    +
    1129  ds = StringFromList(ids, datasets, ";")
    +
    1130  loaded_waves = psh5_load_dataset(file_df, ds, create_folders=create_folders, reduction_func=reduction_func, reduction_params=reduction_params)
    +
    1131  if (strlen(loaded_waves) > 1)
    +
    1132  loaded_datasets = loaded_datasets + ds + ";"
    +
    1133  endif
    +
    1134  endfor
    +
    1135 
    +
    1136  setdatafolder save_df
    +
    1137  return loaded_datasets
    +
    1138 end
    +
    1139 
    +
    1176 function /s psh5_load_dataset(file_df, datasetpath, [create_folders, reduction_func, reduction_params])
    +
    1177  dfref file_df
    +
    1178  string datasetpath
    +
    1179  variable create_folders
    +
    1180  string reduction_func
    +
    1181  string reduction_params
    +
    1182 
    +
    1183  dfref base_df = GetDataFolderDFR()
    +
    1184  if (!DataFolderRefStatus(file_df))
    +
    1185  dfref file_df = GetDataFolderDFR()
    +
    1186  endif
    +
    1187  nvar /sdfr=file_df file_id
    +
    1188 
    +
    1189  if (ParamIsDefault(create_folders))
    +
    1190  create_folders = 1
    +
    1191  endif
    +
    1192  if (create_folders)
    +
    1193  psh5_create_folders(datasetpath)
    +
    1194  endif
    +
    1195  if (ParamIsDefault(reduction_func))
    +
    1196  reduction_func = ""
    +
    1197  endif
    +
    1198  if (ParamIsDefault(reduction_params))
    +
    1199  reduction_params = ""
    +
    1200  endif
    +
    1201 
    +
    1202  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    1203  InitHDF5DataInfo(di)
    +
    1204  variable err = HDF5DatasetInfo(file_id, datasetpath, 0, di)
    +
    1205  if (err != 0)
    +
    1206  // error accessing data
    +
    1207  return ""
    +
    1208  endif
    +
    1209 
    +
    1210  variable numeric = 0
    +
    1211  variable compound = 0
    +
    1212 
    +
    1213  switch (di.datatype_class)
    +
    1214  case H5T_INTEGER:
    +
    1215  case H5T_FLOAT:
    +
    1216  numeric = 1
    +
    1217  break
    +
    1218  case H5T_STRING:
    +
    1219  numeric = 0
    +
    1220  break
    +
    1221  case H5T_COMPOUND:
    +
    1222  compound = 1
    +
    1223  break
    +
    1224  case H5T_TIME:
    +
    1225  case H5T_BITFIELD:
    +
    1226  case H5T_OPAQUE:
    +
    1227  case H5T_REFERENCE:
    +
    1228  case H5T_ENUM:
    +
    1229  case H5T_VLEN:
    +
    1230  case H5T_ARRAY:
    +
    1231  default:
    +
    1232  // unsupported data type
    +
    1233  return ""
    +
    1234  endswitch
    +
    1235 
    +
    1236  string wave_names = ""
    +
    1237  if (di.ndims <= 2)
    +
    1238  string datasetname = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
    +
    1239  variable transpose = WhichListItem(datasetname, kTransposedDatasets) >= 0
    +
    1240  HDF5LoadData /O /Q /Z /TRAN=(transpose) file_id, datasetpath
    +
    1241  wave_names = S_waveNames
    +
    1242  elseif (numeric)
    +
    1243  if (exists(reduction_func) == 6)
    +
    1244  wave_names = psh5_load_dataset_reduced(file_df, datasetpath, $reduction_func, reduction_params, create_folders=0)
    +
    1245  else
    +
    1246  wave_names = psh5_load_dataset_slabs(file_df, datasetpath, create_folders=0)
    +
    1247  endif
    +
    1248  endif
    +
    1249 
    +
    1250  variable nw = ItemsInList(wave_names, ";")
    +
    1251  variable iw
    +
    1252  string sw
    +
    1253  string loaded_waves = ""
    +
    1254  for (iw = 0; iw < nw; iw += 1)
    +
    1255  sw = StringFromList(iw, wave_names)
    +
    1256  wave /z w = $sw
    +
    1257  if (WaveExists(w))
    +
    1258  loaded_waves = loaded_waves + sw + ";"
    +
    1259  ps_set_dimlabels(w)
    +
    1260  psh5_load_dataset_meta(file_df, datasetpath, w)
    +
    1261  endif
    +
    1262  endfor
    +
    1263 
    +
    1264  setdatafolder base_df
    +
    1265  return loaded_waves
    +
    1266 end
    +
    1267 
    +
    1289 function /s psh5_load_dataset_slabs(file_df, datasetpath, [create_folders, progress])
    +
    1290  dfref file_df
    +
    1291  string datasetpath
    +
    1292  variable create_folders
    +
    1293  variable progress
    +
    1294 
    +
    1295  if (ParamIsDefault(create_folders))
    +
    1296  create_folders = 1
    +
    1297  endif
    +
    1298  if (ParamIsDefault(progress))
    +
    1299  progress = 1
    +
    1300  endif
    +
    1301 
    +
    1302  if (!DataFolderRefStatus(file_df))
    +
    1303  dfref file_df = GetDataFolderDFR()
    +
    1304  endif
    +
    1305  nvar /sdfr=file_df file_id
    +
    1306 
    +
    1307  variable result = 0
    +
    1308  string datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
    +
    1309 
    +
    1310  if (create_folders)
    +
    1311  psh5_create_folders(datasetpath)
    +
    1312  endif
    +
    1313 
    +
    1314  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    1315  InitHDF5DataInfo(di)
    +
    1316  variable err = HDF5DatasetInfo(file_id, datasetpath, 0, di)
    +
    1317  if (err != 0)
    +
    1318  print "error accessing dataset", datasetpath
    +
    1319  return ""
    +
    1320  endif
    +
    1321  if (di.ndims < 2)
    +
    1322  print "error: rank of dataset < 2", datasetpath
    +
    1323  return ""
    +
    1324  elseif (di.ndims < 3)
    +
    1325  progress = 0
    +
    1326  endif
    +
    1327  if ((di.datatype_class != H5T_INTEGER) && (di.datatype_class != H5T_FLOAT))
    +
    1328  print "error: unsupported datatype", datasetpath
    +
    1329  return ""
    +
    1330  endif
    +
    1331 
    +
    1332  variable idx, idy, idz, idt, izt
    +
    1333  variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
    +
    1334  if (transpose)
    +
    1335  idx = 1
    +
    1336  idy = 0
    +
    1337  else
    +
    1338  idx = 0
    +
    1339  idy = 1
    +
    1340  endif
    +
    1341  idz = 2
    +
    1342  idt = 3
    +
    1343 
    +
    1344  variable nx, ny, nz, nt, nzt
    +
    1345  nx = di.dims[idx]
    +
    1346  ny = di.dims[idy]
    +
    1347  nz = di.dims[idz]
    +
    1348  nt = di.dims[idt]
    +
    1349  make /n=(nx,ny,nz,nt) /o $datawavename
    +
    1350  wave data = $datawavename
    +
    1351 
    +
    1352  nz = max(nz, 1)
    +
    1353  nt = max(nt, 1)
    +
    1354  nzt = nz * nt
    +
    1355  izt = 0
    +
    1356  if (progress)
    +
    1357  display_progress_panel("HDF5 Import", "Loading " + datasetpath + "...", nzt)
    +
    1358  endif
    +
    1359 
    +
    1360  // load data image by image
    +
    1361  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
    +
    1362  wave slab
    +
    1363  slab[][%Start] = 0
    +
    1364  slab[][%Stride] = 1
    +
    1365  slab[][%Count] = 1
    +
    1366  slab[][%Block] = 1
    +
    1367  slab[idx][%Block] = nx
    +
    1368  slab[idy][%Block] = ny
    +
    1369 
    +
    1370  variable iz, it
    +
    1371  for (iz = 0; iz < nz; iz += 1)
    +
    1372  for (it = 0; it < nt; it += 1)
    +
    1373  slab[idz][%Start] = iz
    +
    1374  slab[idt][%Start] = it
    +
    1375  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata file_id, datasetpath
    +
    1376  wave slabdata // 2D, 3D, or 4D with singletons
    +
    1377  if (transpose)
    +
    1378  data[][][iz][it] = slabdata[q][p][0][0]
    +
    1379  else
    +
    1380  data[][][iz][it] = slabdata[p][q][0][0]
    +
    1381  endif
    +
    1382 
    +
    1383  // progress window
    +
    1384  izt += 1
    +
    1385  if (progress)
    +
    1386  if (update_progress_panel(izt))
    +
    1387  result = -4 // user abort
    +
    1388  break
    +
    1389  endif
    +
    1390  endif
    +
    1391  endfor
    +
    1392  if (result < 0)
    +
    1393  break
    +
    1394  endif
    +
    1395  endfor
    +
    1396 
    +
    1397  if (progress)
    + +
    1399  endif
    +
    1400 
    +
    1401  killwaves /z slab, slabdata
    +
    1402  if (!result)
    +
    1403  ps_set_dimlabels(data)
    +
    1404  return NameOfWave(data) + ";"
    +
    1405  else
    +
    1406  killwaves /z data
    +
    1407  return ""
    +
    1408  endif
    +
    1409 end
    +
    1410 
    +
    1411 // ====== data reduction ======
    +
    1412 
    +
    1472 function /s psh5_load_dataset_reduced(file_df, datasetpath, reduction_func, reduction_params, [create_folders, progress, nthreads])
    +
    1473  dfref file_df
    +
    1474  string datasetpath
    +
    1475  funcref adh5_default_reduction reduction_func
    +
    1476  string reduction_params
    +
    1477  variable create_folders
    +
    1478  variable progress
    +
    1479  variable nthreads
    +
    1480 
    +
    1481  if (ParamIsDefault(create_folders))
    +
    1482  create_folders = 1
    +
    1483  endif
    +
    1484  if (ParamIsDefault(progress))
    +
    1485  progress = 1
    +
    1486  endif
    +
    1487  if (ParamIsDefault(nthreads))
    +
    1488  nthreads = -1
    +
    1489  endif
    +
    1490 
    +
    1491  dfref base_df = GetDataFolderDFR()
    +
    1492  if (!DataFolderRefStatus(file_df))
    +
    1493  dfref file_df = GetDataFolderDFR()
    +
    1494  endif
    +
    1495  nvar /sdfr=file_df file_id
    +
    1496 
    +
    1497  variable result = 0
    +
    1498  string datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
    +
    1499  string wavenames = ""
    +
    1500 
    +
    1501  if (create_folders)
    +
    1502  psh5_create_folders(datasetpath)
    +
    1503  endif
    +
    1504 
    +
    1505  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
    +
    1506  InitHDF5DataInfo(di)
    +
    1507  variable err = HDF5DatasetInfo(file_id, datasetpath, 0, di)
    +
    1508  if (err != 0)
    +
    1509  print "error accessing detector/data"
    +
    1510  result = -1
    +
    1511  return wavenames
    +
    1512  endif
    +
    1513  if (di.ndims < 2)
    +
    1514  print "error: rank of dataset < 2"
    +
    1515  result = -2
    +
    1516  return wavenames
    +
    1517  elseif (di.ndims < 3)
    +
    1518  progress = 0
    +
    1519  endif
    +
    1520 
    +
    1521  variable idx, idy, idz, idt
    +
    1522  variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
    +
    1523  if (transpose)
    +
    1524  idx = 1
    +
    1525  idy = 0
    +
    1526  else
    +
    1527  idx = 0
    +
    1528  idy = 1
    +
    1529  endif
    +
    1530  idz = 2
    +
    1531  idt = 3
    +
    1532 
    +
    1533  variable nx, ny, nz, nt, nzt
    +
    1534  nx = di.dims[idx]
    +
    1535  ny = di.dims[idy]
    +
    1536  nz = di.dims[idz]
    +
    1537  nt = di.dims[idt]
    +
    1538  // adjust singleton dimensions
    +
    1539  nz = max(nz, 1)
    +
    1540  nt = max(nt, 1)
    +
    1541  nzt = nz * nt
    +
    1542 
    +
    1543  // load data image by image
    +
    1544  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
    +
    1545  wave slab
    +
    1546  slab[][%Start] = 0
    +
    1547  slab[][%Stride] = 1
    +
    1548  slab[][%Count] = 1
    +
    1549  slab[][%Block] = 1
    +
    1550  slab[idx][%Block] = nx
    +
    1551  slab[idy][%Block] = ny
    +
    1552 
    +
    1553  // set up multi threading
    +
    1554  if (nthreads < 0)
    +
    1555  nthreads = ThreadProcessorCount
    +
    1556  endif
    +
    1557  if (nthreads > 0)
    +
    1558  variable threadGroupID = ThreadGroupCreate(nthreads)
    +
    1559  variable ithread
    +
    1560  for (ithread = 0; ithread < nthreads; ithread += 1)
    +
    1561  ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
    +
    1562  endfor
    +
    1563  else
    +
    1564  make /n=(nzt) /df /free processing_folders
    +
    1565  endif
    +
    1566 
    +
    1567  if (progress)
    +
    1568  display_progress_panel("PShell Import", "Reducing " + datasetpath + "...", nzt)
    +
    1569  endif
    +
    1570 
    +
    1571  // create a template wave with the correct scales and labels
    +
    1572  make /n=(nx,ny) /d /o $datawavename
    +
    1573  wave template = $datawavename
    +
    1574  ps_set_dimlabels2(template, datawavename)
    +
    1575  ps_scale_dataset(template)
    +
    1576 
    +
    1577  variable iz, it, izt
    +
    1578  variable n_sent = 0
    +
    1579  variable n_recvd = 0
    +
    1580  variable tmo = 0
    +
    1581  string dfname
    +
    1582  dfref dfr
    +
    1583  variable iw, nw
    +
    1584  string sw
    +
    1585  make /n=0 /free /wave result_waves
    +
    1586 
    +
    1587  iz = 0
    +
    1588  it = 0
    +
    1589 
    +
    1590  do
    +
    1591  // fill the processing queue up to a maximum number of folders
    +
    1592  if (n_sent < max(1, nthreads) * 10 + n_recvd)
    +
    1593  if (iz < nz)
    +
    1594  if (it < nt)
    +
    1595  // load a slab into a temporary folder
    +
    1596  slab[idz][%Start] = iz
    +
    1597  slab[idt][%Start] = it
    +
    1598  dfname = "processing_" + num2str(n_sent)
    +
    1599  NewDataFolder /s $dfname
    +
    1600  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata file_id, datasetpath
    +
    1601 
    +
    1602  duplicate template, image
    +
    1603  variable /g r_index = iz
    +
    1604  variable /g s_index = it
    +
    1605  string /g func_param = reduction_params
    +
    1606 
    +
    1607  if (nthreads > 0)
    +
    1608  // send to thread group
    +
    1609  WaveClear image
    +
    1610  ThreadGroupPutDF threadGroupID, :
    +
    1611  else
    +
    1612  // process immediately in single-thread mode
    +
    1613  processing_folders[n_sent] = GetDataFolderDFR()
    +
    1614  make /n=1/d profile1, profile2
    +
    1615  wave slabdata
    +
    1616  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
    +
    1617  variable /g func_result = numpnts(reduced_waves)
    +
    1618  adh5_get_result_waves(reduced_waves, "redw_", 0)
    +
    1619  WaveClear slabdata, image, reduced_waves
    +
    1620  setdatafolder ::
    +
    1621  endif
    +
    1622 
    +
    1623  iz += 1
    +
    1624  n_sent += 1
    +
    1625  tmo = 0
    +
    1626  else
    +
    1627  iz += 1
    +
    1628  it = 0
    +
    1629  endif
    +
    1630  endif
    +
    1631  else
    +
    1632  // throttle the loop if processing is slow
    +
    1633  tmo = min(100, tmo + 10)
    +
    1634  endif
    +
    1635 
    +
    1636  // receive a slab from the processing queue
    +
    1637  if (n_recvd < nzt)
    +
    1638  if (nthreads > 0)
    +
    1639  dfr = ThreadGroupGetDFR(threadGroupID, tmo)
    +
    1640  else
    +
    1641  dfr = processing_folders[n_recvd]
    +
    1642  processing_folders[n_recvd] = $""
    +
    1643  endif
    +
    1644 
    +
    1645  if (DatafolderRefStatus(dfr) != 0)
    +
    1646  // access results folder
    +
    1647  nvar rr = dfr:r_index
    +
    1648  nvar ss = dfr:s_index
    +
    1649  nvar func_result = dfr:func_result
    +
    1650 
    +
    1651  if (func_result < 1)
    +
    1652  print "error during data reduction."
    +
    1653  result = -3
    +
    1654  break
    +
    1655  endif
    +
    1656 
    +
    1657  // initialize result waves just once
    +
    1658  if (numpnts(result_waves) == 0)
    +
    1659  redimension /n=(func_result) result_waves
    +
    1660  for (iw = 0; iw < func_result; iw += 1)
    +
    1661  sw = "redw_" + num2str(iw)
    +
    1662  wave profile = dfr:$sw
    +
    1663  sw = "ReducedData" + num2str(iw+1)
    +
    1664  make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
    +
    1665  wave data = $sw
    +
    1666  setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
    +
    1667  setdimlabel 1, -1, $kScanDimLabel, data
    +
    1668  note data, note(profile)
    +
    1669  ps_scale_dataset(data)
    +
    1670  setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
    +
    1671  setscale d 0, 0, waveunits(profile, -1), data
    +
    1672  result_waves[iw] = data
    +
    1673  endfor
    +
    1674  endif
    +
    1675 
    +
    1676  // copy results
    +
    1677  for (iw = 0; iw < func_result; iw += 1)
    +
    1678  sw = "redw_" + num2str(iw)
    +
    1679  wave profile = dfr:$sw
    +
    1680  wave data = result_waves[iw]
    +
    1681  data[][rr][ss] = profile[p]
    +
    1682  endfor
    +
    1683 
    +
    1684  n_recvd += 1
    +
    1685  KillDataFolder /Z dfr
    +
    1686  endif
    +
    1687  else
    +
    1688  // processing complete
    +
    1689  break
    +
    1690  endif
    +
    1691 
    +
    1692  // update progress window
    +
    1693  if (progress)
    +
    1694  if (update_progress_panel(n_recvd))
    +
    1695  print "user abort"
    +
    1696  result = -4
    +
    1697  break
    +
    1698  endif
    +
    1699  endif
    +
    1700  while ((n_recvd < nzt) && (result == 0))
    +
    1701 
    +
    1702  // clean up
    +
    1703  killwaves /z slab, slabdata, template
    +
    1704 
    +
    1705  if (nthreads > 0)
    +
    1706  variable tstatus = ThreadGroupRelease(threadGroupID)
    +
    1707  if (tstatus == -2)
    +
    1708  print "error: thread did not terminate properly."
    +
    1709  result = -5
    +
    1710  endif
    +
    1711  endif
    +
    1712 
    +
    1713  // finalize results
    +
    1714  nw = numpnts(result_waves)
    +
    1715  wavenames = ""
    +
    1716  for (iw = 0; iw < nw; iw += 1)
    +
    1717  wave /z data = result_waves[iw]
    +
    1718  if (WaveExists(data))
    +
    1719  if (nz == 1)
    +
    1720  redimension /n=(-1, 0, 0) data
    +
    1721  elseif (nt == 1)
    +
    1722  redimension /n=(-1, nz, 0) data
    +
    1723  endif
    +
    1724  wavenames += nameofwave(data) + ";"
    +
    1725  endif
    +
    1726  endfor
    +
    1727 
    +
    1728  if (progress)
    + +
    1730  endif
    +
    1731 
    +
    1732  setdatafolder base_df
    +
    1733  return wavenames
    +
    1734 end
    +
    1735 
    +
    1736 
    +
    1737 threadsafe static function reduce_slab_worker(reduction_func)
    +
    1738  funcref adh5_default_reduction reduction_func
    +
    1739  do
    +
    1740  // wait for job from main thread
    +
    1741  do
    +
    1742  dfref dfr = ThreadGroupGetDFR(0, 1000)
    +
    1743  if (DataFolderRefStatus(dfr) == 0)
    +
    1744  if (GetRTError(2))
    +
    1745  return 0 // no more jobs
    +
    1746  endif
    +
    1747  else
    +
    1748  break
    +
    1749  endif
    +
    1750  while (1)
    +
    1751 
    +
    1752  // get input data
    +
    1753  wave slabdata = dfr:slabdata
    +
    1754  wave image = dfr:image
    +
    1755  svar func_param = dfr:func_param
    +
    1756  nvar rr = dfr:r_index
    +
    1757  nvar ss = dfr:s_index
    +
    1758 
    +
    1759  // do the work
    +
    1760  newdatafolder /s out_df
    +
    1761  variable /g r_index = rr
    +
    1762  variable /g s_index = ss
    +
    1763  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
    +
    1764  variable /g func_result = numpnts(reduced_waves)
    +
    1765 
    +
    1766  // send output to queue and clean up
    +
    1767  adh5_get_result_waves(reduced_waves, "redw_", 0)
    +
    1768  WaveClear slabdata, image, reduced_waves
    +
    1769  ThreadGroupPutDF 0, :
    +
    1770  KillDataFolder dfr
    +
    1771  while (1)
    +
    1772 
    +
    1773  return 0
    +
    1774 end
    +
    1775 
    +
    1776 threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_params)
    +
    1777  wave slabdata
    +
    1778  wave image
    +
    1779  funcref adh5_default_reduction reduction_func
    +
    1780  string reduction_params
    +
    1781 
    +
    1782  image = slabdata[q][p][0][0]
    +
    1783 
    +
    1784  return reduction_func(image, reduction_params)
    +
    1785 end
    +
    1786 
    +
    1787 // ====== meta and auxiliary data ======
    +
    1788 
    +
    1803 function /s psh5_load_general_group(file_df)
    +
    1804  dfref file_df
    +
    1805 
    +
    1806  if (!DataFolderRefStatus(file_df))
    +
    1807  dfref file_df = GetDataFolderDFR()
    +
    1808  endif
    +
    1809  nvar /sdfr=file_df file_id
    +
    1810 
    +
    1811  string obj_names = "authors;pgroup;proposal;proposer;sample;"
    +
    1812  variable nn = ItemsInList(obj_names, ";")
    +
    1813  variable ii
    +
    1814  string name
    +
    1815 
    +
    1816  for (ii = 0; ii < nn; ii += 1)
    +
    1817  name = StringFromList(ii, obj_names, ";")
    +
    1818  psh_load_general_string(file_df, name)
    +
    1819  endfor
    +
    1820 
    +
    1821  return obj_names
    +
    1822 end
    +
    1823 
    +
    1838 function /s psh_load_general_string(file_df, name)
    +
    1839  dfref file_df
    +
    1840  string name
    +
    1841 
    +
    1842  if (!DataFolderRefStatus(file_df))
    +
    1843  dfref file_df = GetDataFolderDFR()
    +
    1844  endif
    +
    1845  nvar /sdfr=file_df file_id
    +
    1846 
    +
    1847  string path = "/general/" + name
    +
    1848  HDF5LoadData /O /Q /Z /N=wt_load_general /TYPE=1 file_id, path
    +
    1849  string values = ""
    +
    1850  if (!v_flag)
    +
    1851  wave /t wt_load_general
    +
    1852  variable nn = numpnts(wt_load_general)
    +
    1853  variable ii
    +
    1854  for (ii = 0; ii < nn; ii += 1)
    +
    1855  values = AddListItem(wt_load_general[ii], values, ",", inf)
    +
    1856  endfor
    +
    1857  killwaves /z wt_load_general
    +
    1858  if (strlen(values) >= 1)
    +
    1859  values = values[0,strlen(values)-2]
    +
    1860  endif
    +
    1861  endif
    +
    1862  string /g $name = values
    +
    1863  return values
    +
    1864 end
    +
    1865 
    +
    1887 function psh5_load_dataset_meta(file_df, datasetpath, datawave)
    +
    1888  dfref file_df
    +
    1889  string datasetpath
    +
    1890  wave datawave
    +
    1891 
    +
    1892  if (!DataFolderRefStatus(file_df))
    +
    1893  dfref file_df = GetDataFolderDFR()
    +
    1894  endif
    +
    1895  nvar /sdfr=file_df file_id
    +
    1896 
    +
    1897  dfref save_df = GetDataFolderDFR()
    +
    1898  SetDataFolder NewFreeDataFolder()
    +
    1899 
    +
    1900  string wnote
    +
    1901 
    +
    1902  HDF5LoadData /O /Q /Z /A="Writable Dimension" /N=WriteDim file_id, datasetpath
    +
    1903  if (!v_flag)
    +
    1904  wave WriteDim
    +
    1905  // scan dimension starts at 1
    +
    1906  sprintf wnote, "ScanDimension=%u", WriteDim[0]
    +
    1907  Note datawave, wnote
    +
    1908  endif
    +
    1909 
    +
    1910  HDF5LoadData /O /Q /Z /A="Writable Index" /N=WriteIndex file_id, datasetpath
    +
    1911  if (!v_flag)
    +
    1912  wave WriteIndex
    +
    1913  sprintf wnote, "WriteableIndex=%u", WriteIndex[0]
    +
    1914  Note datawave, wnote
    +
    1915  endif
    +
    1916 
    +
    1917  HDF5LoadData /O /Q /Z /A="Readable Index" /N=ReadIndex file_id, datasetpath
    +
    1918  if (!v_flag)
    +
    1919  wave ReadIndex
    +
    1920  sprintf wnote, "ReadableIndex=%u", ReadIndex[0]
    +
    1921  Note datawave, wnote
    +
    1922  endif
    +
    1923 
    +
    1924  setdatafolder save_df
    +
    1925  return 0
    +
    1926 end
    +
    1927 
    +
    1954 function /s psh5_load_scan_meta(file_df, scanpath)
    +
    1955  // todo: convert to variables/strings
    +
    1956  dfref file_df
    +
    1957  string scanpath
    +
    1958  string wavenames = ""
    +
    1959 
    +
    1960  if (!DataFolderRefStatus(file_df))
    +
    1961  dfref file_df = GetDataFolderDFR()
    +
    1962  endif
    +
    1963  nvar /sdfr=file_df file_id
    +
    1964 
    +
    1965  HDF5LoadData /O /Q /Z /A="Dimensions" /N=ScanDimensions /TYPE=1 file_id, scanpath
    +
    1966  if (!v_flag)
    +
    1967  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    +
    1968  else
    +
    1969  make /n=1 /o ScanDimensions
    +
    1970  ScanDimensions = 0
    +
    1971  wavenames = AddListItem("ScanDimensions", wavenames, ";", inf)
    +
    1972  endif
    +
    1973  HDF5LoadData /O /Q /Z /A="Readables" /N=ScanReadables /TYPE=1 file_id, scanpath
    +
    1974  if (!v_flag)
    +
    1975  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    +
    1976  else
    +
    1977  make /n=1 /o /t ScanReadables
    +
    1978  ScanReadables[0] = "ScientaSpectrum"
    +
    1979  wavenames = AddListItem("ScanReadables", wavenames, ";", inf)
    +
    1980  endif
    +
    1981  HDF5LoadData /O /Q /Z /A="Writables" /N=ScanWritables /TYPE=1 file_id, scanpath
    +
    1982  if (!v_flag)
    +
    1983  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    +
    1984  else
    +
    1985  // OTF script
    +
    1986  HDF5LoadData /O /Q /Z /A="PlotDomain" /N=ScanWritables /TYPE=1 file_id, scanpath
    +
    1987  if (!v_flag)
    +
    1988  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    +
    1989  endif
    +
    1990  endif
    +
    1991  HDF5LoadData /O /Q /Z /A="Steps" /N=ScanSteps /TYPE=1 file_id, scanpath
    +
    1992  if (!v_flag)
    +
    1993  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    +
    1994  endif
    +
    1995  wavenames = ReplaceString(";;", wavenames, ";")
    +
    1996 
    +
    1997  // additional attributes from XPSSpectrum.py
    +
    1998  HDF5LoadData /O /Q /Z /A="Iterations" /N=ScanIterations /TYPE=1 file_id, scanpath
    +
    1999  if (!v_flag)
    +
    2000  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    +
    2001  endif
    +
    2002  HDF5LoadData /O /Q /Z /A="Step Size" /N=ScanStepSize /TYPE=1 file_id, scanpath
    +
    2003  if (!v_flag)
    +
    2004  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    +
    2005  endif
    +
    2006  HDF5LoadData /O /Q /Z /A="Step Time" /N=ScanStepTime /TYPE=1 file_id, scanpath
    +
    2007  if (!v_flag)
    +
    2008  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
    +
    2009  endif
    +
    2010 
    +
    2011  return wavenames
    +
    2012 end
    +
    2013 
    +
    2014 // ====== dimension scaling ======
    +
    2015 
    +
    2031 function ps_set_dimlabels(data)
    +
    2032  wave data
    +
    2033 
    +
    2034  ps_set_dimlabels2(data, NameOfWave(data))
    +
    2035 end
    +
    2036 
    +
    2050 function ps_set_dimlabels2(data, name)
    +
    2051  wave data
    +
    2052  string name
    +
    2053 
    +
    2054  variable dummy
    +
    2055  try
    +
    2056  // intrinsic dimensions
    +
    2057  strswitch(name)
    +
    2058  case "ScientaImage":
    +
    2059  setdimlabel 0, -1, $kEnergyDimLabel, data
    +
    2060  setdimlabel 1, -1, $kAngleDimLabel, data
    +
    2061  if (WaveDims(data) >= 3)
    +
    2062  setdimlabel 2, -1, $kScanDimLabel, data
    +
    2063  endif
    +
    2064  AbortOnRTE
    +
    2065  break
    +
    2066  case "ImageAngleDistribution":
    +
    2067  case "ScientaAngleDistribution":
    +
    2068  if (WaveDims(data) >= 2)
    +
    2069  setdimlabel 0, -1, $kScanDimLabel, data
    +
    2070  setdimlabel 1, -1, $kAngleDimLabel, data
    +
    2071  else
    +
    2072  setdimlabel 0, -1, $kAngleDimLabel, data
    +
    2073  endif
    +
    2074  AbortOnRTE
    +
    2075  break
    +
    2076  case "ScientaSpectrum":
    +
    2077  case "ImageEnergyDistribution":
    +
    2078  case "ScientaEnergyDistribution":
    +
    2079  if (WaveDims(data) >= 2)
    +
    2080  setdimlabel 0, -1, $kScanDimLabel, data
    +
    2081  setdimlabel 1, -1, $kEnergyDimLabel, data
    +
    2082  else
    +
    2083  setdimlabel 0, -1, $kEnergyDimLabel, data
    +
    2084  endif
    +
    2085  AbortOnRTE
    +
    2086  break
    +
    2087  default:
    +
    2088  if (WaveDims(data) == 1)
    +
    2089  setdimlabel 0, -1, $kScanDimLabel, data
    +
    2090  AbortOnRTE
    +
    2091  else
    +
    2092  return 1
    +
    2093  endif
    +
    2094  endswitch
    +
    2095  catch
    +
    2096  dummy = GetRTError(1)
    +
    2097  return 2
    +
    2098  endtry
    +
    2099  return 0
    +
    2100 end
    +
    2101 
    +
    2111 function /df ps_find_scan_folder(data_df)
    +
    2112  dfref data_df
    +
    2113 
    +
    2114  wave /z /t /sdfr=data_df ScanWritables=::ScanWritables
    +
    2115  if (WaveExists(ScanWritables))
    +
    2116  string sdf = GetDataFolder(1, data_df)
    +
    2117  dfref parent_df = $(sdf + ":")
    +
    2118  return parent_df
    +
    2119  else
    +
    2120  return data_df
    +
    2121  endif
    +
    2122 end
    +
    2123 
    +
    2134 function /df ps_find_attr_folder(scan_df)
    +
    2135  dfref scan_df
    +
    2136 
    +
    2137  dfref diags_df = data_df:diags
    +
    2138  dfref attrs_df = scan_df:attrs
    +
    2139  dfref attr_df = scan_df:attr
    +
    2140  if (DataFolderRefStatus(diags_df))
    +
    2141  return diags_df
    +
    2142  elseif (DataFolderRefStatus(attrs_df))
    +
    2143  return attrs_df
    +
    2144  elseif (DataFolderRefStatus(attr_df))
    +
    2145  return attr_df
    +
    2146  else
    +
    2147  return $""
    +
    2148  endif
    +
    2149 end
    +
    2150 
    +
    2161 function /wave ps_find_scale_wave(name, df1, df2, df3)
    +
    2162  string name
    +
    2163  dfref df1
    +
    2164  dfref df2
    +
    2165  dfref df3
    +
    2166 
    +
    2167  variable idf
    +
    2168  variable ndf=3
    +
    2169  make /n=(ndf) /df /free dfs
    +
    2170  dfs[0] = {df1, df2, df3}
    +
    2171  for (idf = 0; idf < ndf; idf += 1)
    +
    2172  if (DataFolderRefStatus(dfs[idf]))
    +
    2173  wave /SDFR=dfs[idf] /Z w = $name
    +
    2174  if (WaveExists(w))
    +
    2175  return w
    +
    2176  endif
    +
    2177  endif
    +
    2178  endfor
    +
    2179 
    +
    2180  return $""
    +
    2181 end
    +
    2182 
    +
    2225 function ps_detect_scale(data_df, ax, lo, hi, un)
    +
    2226  dfref data_df
    +
    2227  wave /t ax
    +
    2228  wave lo
    +
    2229  wave hi
    +
    2230  wave /t un
    +
    2231 
    +
    2232  dfref scan_df = ps_find_scan_folder(data_df)
    +
    2233  dfref attr_df = ps_find_attr_folder(scan_df)
    +
    2234 
    +
    2235  redimension /n=4 lo, hi, un, ax
    +
    2236  setdimlabel 0, 0, $kEnergyDimLabel, lo, hi, un, ax
    +
    2237  setdimlabel 0, 1, $kAngleDimLabel, lo, hi, un, ax
    +
    2238  setdimlabel 0, 2, $kScanDimLabel, lo, hi, un, ax
    +
    2239  setdimlabel 0, 3, $kDataDimLabel, lo, hi, un, ax
    +
    2240 
    +
    2241  // default values
    +
    2242  lo[%$kEnergyDimLabel] = 0
    +
    2243  hi[%$kEnergyDimLabel] = 1
    +
    2244  un[%$kEnergyDimLabel] = "eV"
    +
    2245  ax[%$kEnergyDimLabel] = "Ekin"
    +
    2246 
    +
    2247  lo[%$kAngleDimLabel] = -1
    +
    2248  hi[%$kAngleDimLabel] = 1
    +
    2249  un[%$kAngleDimLabel] = "arb."
    +
    2250  un[%$kAngleDimLabel] = "slice"
    +
    2251 
    +
    2252  lo[%$kScanDimLabel] = 0
    +
    2253  hi[%$kScanDimLabel] = 1
    +
    2254  un[%$kScanDimLabel] = "arb."
    +
    2255  ax[%$kScanDimLabel] = "scan"
    +
    2256 
    +
    2257  lo[%$kDataDimLabel] = 0
    +
    2258  hi[%$kDataDimLabel] = 0
    +
    2259  un[%$kDataDimLabel] = "arb."
    +
    2260  ax[%$kDataDimLabel] = "value"
    +
    2261 
    +
    2262  wave /T /Z LensMode = ps_find_scale_wave("LensMode", data_df, scan_df, attr_df)
    +
    2263  wave /Z ChannelBegin = ps_find_scale_wave("ScientaChannelBegin", data_df, scan_df, attr_df)
    +
    2264  wave /Z ChannelEnd = ps_find_scale_wave("ScientaChannelEnd", data_df, scan_df, attr_df)
    +
    2265  wave /Z SliceBegin = ps_find_scale_wave("ScientaSliceBegin", data_df, scan_df, attr_df)
    +
    2266  wave /Z SliceEnd = ps_find_scale_wave("ScientaSliceEnd", data_df, scan_df, attr_df)
    +
    2267  wave /Z ScientaChannels = ps_find_scale_wave("ScientaChannels", data_df, scan_df, attr_df)
    +
    2268 
    +
    2269  // lens mode can give more detail
    +
    2270  if (waveexists(LensMode) && (numpnts(LensMode) >= 1))
    +
    2271  strswitch(LensMode[0])
    +
    2272  case "Angular45":
    +
    2273  lo[%$kAngleDimLabel] = -45/2
    +
    2274  hi[%$kAngleDimLabel] = +45/2
    +
    2275  un[%$kAngleDimLabel] = "°"
    +
    2276  ax[%$kAngleDimLabel] = "angle"
    +
    2277  break
    +
    2278  case "Angular60":
    +
    2279  lo[%$kAngleDimLabel] = -60/2
    +
    2280  hi[%$kAngleDimLabel] = +60/2
    +
    2281  un[%$kAngleDimLabel] = "°"
    +
    2282  ax[%$kAngleDimLabel] = "angle"
    +
    2283  break
    +
    2284  case "Transmission":
    +
    2285  un[%$kAngleDimLabel] = "arb."
    +
    2286  ax[%$kAngleDimLabel] = "offset"
    +
    2287  break
    +
    2288  endswitch
    +
    2289  endif
    +
    2290 
    +
    2291  // best option if scales are explicit in separate waves
    +
    2292  if (waveexists(ChannelBegin) && waveexists(ChannelEnd) && (numpnts(ChannelBegin) >= 1) && (numpnts(ChannelEnd) >= 1))
    +
    2293  lo[%$kEnergyDimLabel] = ChannelBegin[0]
    +
    2294  hi[%$kEnergyDimLabel] = ChannelEnd[0]
    +
    2295  elseif (waveexists(ScientaChannels) && (numpnts(ScientaChannels) >= 1))
    +
    2296  lo[%$kEnergyDimLabel] = ScientaChannels[0]
    +
    2297  hi[%$kEnergyDimLabel] = ScientaChannels[numpnts(ScientaChannels)-1]
    +
    2298  endif
    +
    2299  if (waveexists(SliceBegin) && waveexists(SliceEnd) && (numpnts(SliceBegin) >= 1) && (numpnts(SliceEnd) >= 1))
    +
    2300  lo[%$kAngleDimLabel] = SliceBegin[0]
    +
    2301  hi[%$kAngleDimLabel] = SliceEnd[0]
    +
    2302  endif
    +
    2303 
    +
    2304  wave /z /t /SDFR=scan_df ScanWritables
    +
    2305  if (WaveExists(ScanWritables))
    +
    2306  wave /z /SDFR=scan_df scanner = $ScanWritables[0]
    +
    2307  if (!WaveExists(scanner))
    +
    2308  wave /z /SDFR=attr_df scanner = $ScanWritables[0]
    +
    2309  endif
    +
    2310  if (WaveExists(scanner) && (numpnts(scanner) >= 1))
    +
    2311  lo[%$kScanDimLabel] = scanner[0]
    +
    2312  hi[%$kScanDimLabel] = scanner[numpnts(scanner)-1]
    +
    2313  ax[%$kScanDimLabel] = NameOfWave(scanner)
    +
    2314  strswitch(NameOfWave(scanner))
    +
    2315  case "Eph":
    +
    2316  ax[%$kScanDimLabel] = "photon energy"
    +
    2317  un[%$kScanDimLabel] = "eV"
    +
    2318  break
    +
    2319  case "ManipulatorX":
    +
    2320  case "ManipulatorY":
    +
    2321  case "ManipulatorZ":
    +
    2322  case "FocusYTrans":
    +
    2323  case "FocusZTrans":
    +
    2324  case "RefocusYTrans":
    +
    2325  case "RefocusZTrans":
    +
    2326  case "ExitSlitY":
    +
    2327  un[%$kScanDimLabel] = "mm"
    +
    2328  break
    +
    2329  case "ExitSlit":
    +
    2330  un[%$kScanDimLabel] = "µm"
    +
    2331  break
    +
    2332  case "ManipulatorTheta":
    +
    2333  case "ManipulatorTilt":
    +
    2334  case "ManipulatorPhi":
    +
    2335  un[%$kScanDimLabel] = "°"
    +
    2336  break
    +
    2337  case "FocusXRot":
    +
    2338  case "FocusYRot":
    +
    2339  case "FocusZRot":
    +
    2340  case "RefocusXRot":
    +
    2341  case "RefocusYRot":
    +
    2342  case "RefocusZRot":
    +
    2343  un[%$kScanDimLabel] = "mrad"
    +
    2344  break
    +
    2345  endswitch
    +
    2346  endif
    +
    2347  endif
    +
    2348 end
    +
    2349 
    +
    2389 function ps_scale_dataset_2(data, ax, lo, hi, un)
    +
    2390  wave data
    +
    2391  wave /t ax
    +
    2392  wave lo
    +
    2393  wave hi
    +
    2394  wave /t un
    +
    2395 
    +
    2396  string snote = note(data)
    +
    2397  string sdim
    +
    2398  sdim = GetDimLabel(data, 0, -1)
    +
    2399  if (strlen(sdim))
    +
    2400  setscale /i x lo[%$sdim], hi[%$sdim], un[%$sdim], data
    +
    2401  snote = ReplaceStringByKey("AxisLabelX", snote, ax[%$sdim], "=", "\r")
    +
    2402  endif
    +
    2403 
    +
    2404  sdim = GetDimLabel(data, 1, -1)
    +
    2405  if (strlen(sdim))
    +
    2406  setscale /i y lo[%$sdim], hi[%$sdim], un[%$sdim], data
    +
    2407  snote = ReplaceStringByKey("AxisLabelY", snote, ax[%$sdim], "=", "\r")
    +
    2408  endif
    +
    2409 
    +
    2410  sdim = GetDimLabel(data, 2, -1)
    +
    2411  if (strlen(sdim))
    +
    2412  setscale /i z lo[%$sdim], hi[%$sdim], un[%$sdim], data
    +
    2413  snote = ReplaceStringByKey("AxisLabelZ", snote, ax[%$sdim], "=", "\r")
    +
    2414  endif
    +
    2415 
    +
    2416  string data_unit = un[%$kDataDimLabel]
    +
    2417  string data_label = ax[%$kDataDimLabel]
    +
    2418  string s
    +
    2419  variable def = (cmpstr(data_unit, "arb.") == 0) && (cmpstr(data_label, "value") == 0)
    +
    2420 
    +
    2421  if (def)
    +
    2422  s = StringByKey("AxisLabelD", snote, "=", "\r")
    +
    2423  if (strlen(s) > 0)
    +
    2424  data_label = s
    +
    2425  def = 0
    +
    2426  endif
    +
    2427  s = StringByKey("AxisUnitD", snote, "=", "\r")
    +
    2428  if (strlen(s) > 0)
    +
    2429  data_unit = s
    +
    2430  def = 0
    +
    2431  endif
    +
    2432  endif
    +
    2433 
    +
    2434  if (def)
    +
    2435  strswitch(NameOfWave(data))
    +
    2436  case "ScientaImage":
    +
    2437  case "ImageAngleDistribution":
    +
    2438  case "ScientaAngleDistribution":
    +
    2439  case "ScientaSpectrum":
    +
    2440  case "ImageEnergyDistribution":
    +
    2441  case "ScientaEnergyDistribution":
    +
    2442  data_unit = "arb."
    +
    2443  data_label = "intensity"
    +
    2444  def = 0
    +
    2445  break
    +
    2446  case "SampleCurrent":
    +
    2447  case "RefCurrent":
    +
    2448  case "AuxCurrent":
    +
    2449  data_unit = "A"
    +
    2450  data_label = "current"
    +
    2451  def = 0
    +
    2452  break
    +
    2453  case "MachineCurrent":
    +
    2454  data_unit = "mA"
    +
    2455  data_label = "current"
    +
    2456  def = 0
    +
    2457  break
    +
    2458  endswitch
    +
    2459  endif
    +
    2460 
    +
    2461  setscale d 0, 0, data_unit, data
    +
    2462  snote = ReplaceStringByKey("AxisLabelD", snote, data_label, "=", "\r")
    +
    2463  snote = ReplaceStringByKey("AxisUnitD", snote, data_unit, "=", "\r")
    +
    2464  snote = ReplaceStringByKey("Dataset", snote, NameOfWave(data), "=", "\r")
    +
    2465  note /k data, snote
    +
    2466 end
    +
    2467 
    +
    2483 function ps_scale_datasets(scan_df)
    +
    2484  dfref scan_df
    +
    2485 
    +
    2486  make /n=3 /free lo, hi
    +
    2487  make /n=3 /t /free ax, un
    +
    2488  wave /t /z /SDFR=scan_df ScanReadables
    +
    2489  if (WaveExists(ScanReadables))
    +
    2490  variable isr
    +
    2491  variable nsr = numpnts(ScanReadables)
    +
    2492  variable nel
    +
    2493  string ssr
    +
    2494  string sds
    +
    2495  for (isr = 0; isr < nsr; isr += 1)
    +
    2496  ssr = ScanReadables[isr]
    +
    2497  dfref data_df = psh5_dataset_to_folder(scan_df, ssr)
    +
    2498  if (!DataFolderRefStatus(data_df))
    +
    2499  dfref data_df = scan_df
    +
    2500  endif
    +
    2501  nel = ItemsInList(ssr, "/")
    +
    2502  sds = StringFromList(nel - 1, ssr, "/")
    +
    2503  wave /z /sdfr=data_df wsr=$sds
    +
    2504  if (WaveExists(wsr))
    +
    2505  ps_detect_scale(data_df, ax, lo, hi, un)
    +
    2506  ps_scale_dataset_2(wsr, ax, lo, hi, un)
    +
    2507  endif
    +
    2508  endfor
    +
    2509  endif
    +
    2510 end
    +
    2511 
    +
    2528 function ps_scale_dataset(data)
    +
    2529  wave data
    +
    2530 
    +
    2531  dfref save_df = GetDataFolderDFR()
    +
    2532  dfref data_df = GetWavesDataFolderDFR(data)
    +
    2533 
    +
    2534  setdatafolder data_df
    +
    2535  make /n=3 /free lo, hi
    +
    2536  make /n=3 /t /free ax, un
    +
    2537  ps_detect_scale(data_df, ax, lo, hi, un)
    +
    2538  ps_scale_dataset_2(data, ax, lo, hi, un)
    +
    2539  setdatafolder save_df
    +
    2540 end
    +
    2541 
    +
    2542 
    +
    2543 // ====== miscellaneous functions ======
    +
    2544 
    +
    2554 function /s kill_matching_waves(dfr, pattern, recurse, [killed])
    +
    2555  DFREF dfr
    +
    2556  string pattern
    +
    2557  variable recurse
    +
    2558  string killed
    +
    2559 
    +
    2560  if (ParamIsDefault(killed))
    +
    2561  killed = ""
    +
    2562  endif
    +
    2563 
    +
    2564  string s
    +
    2565  string r
    +
    2566  variable index = 0
    +
    2567  do
    +
    2568  Wave/Z w = WaveRefIndexedDFR(dfr, index)
    +
    2569  if (!WaveExists(w))
    +
    2570  break
    +
    2571  endif
    +
    2572 
    +
    2573  s = NameOfWave(w)
    +
    2574  if (stringmatch(s, pattern))
    +
    2575  killwaves /z w
    +
    2576  killed = AddListItem(s, killed, ";", Inf)
    +
    2577  endif
    +
    2578 
    +
    2579  index += 1
    +
    2580  while(1)
    +
    2581 
    +
    2582  if (recurse)
    +
    2583  Variable numChildDataFolders = CountObjectsDFR(dfr, 4)
    +
    2584  Variable i
    +
    2585  for(i=0; i<numChildDataFolders; i+=1)
    +
    2586  String childDFName = GetIndexedObjNameDFR(dfr, 4, i)
    +
    2587  DFREF childDFR = dfr:$childDFName
    +
    2588  killed = kill_matching_waves(childDFR, pattern, 1, killed=killed)
    +
    2589  endfor
    +
    2590  endif
    +
    2591 
    +
    2592  return killed
    +
    2593 End
    +
    string psh5_load_dataset(dfref file_df, string datasetpath, variable create_folders=defaultValue, string reduction_func=defaultValue, string reduction_params=defaultValue)
    load a dataset from an open PShell HDF5 file.
    +
    string ps_fix_folder_name(string group_name)
    convert HDF5 group name to data folder name and fix compatibility issues
    +
    static threadsafe variable reduce_slab_worker(funcref reduction_func)
    +
    string psh5_filter_datasets_rank(string datasets, string ranks, variable min_rank, variable max_rank)
    filter datasets by rank
    +
    wave ps_find_scale_wave(string name, dfref df1, dfref df2, dfref df3)
    find a wave in scan and attr data folders
    +
    const variable kDSCEssentialDiags
    +
    dfr psh5_create_folders(string datasetpath)
    create all data folders along a dataset path
    +
    variable ps_set_dimlabels(wave data)
    set dimension labels according to the axis type
    +
    variable ps_set_dimlabels2(wave data, string name)
    set dimension labels according to the axis type
    +
    string psh5_load_general_group(dfref file_df)
    load organizational metadata from the general group.
    +
    string psh_load_general_string(dfref file_df, string name)
    load a string from the general group.
    +
    variable kill_progress_panel()
    +
    string psh5_load_dataset_slabs(dfref file_df, string datasetpath, variable create_folders=defaultValue, variable progress=defaultValue)
    load a dataset slab-wise from the open PShell HDF5 file.
    +
    variable display_progress_panel(string title, string message, variable progress_max)
    +
    variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
    +
    const string kScientaScalingDatasets
    List of datasets that must be loaded to determine the axis scaling of a Scienta image.
    +
    const variable kDSCMonitors
    +
    string psh5_load_dataset_reduced(dfref file_df, string datasetpath, funcref reduction_func, string reduction_params, variable create_folders=defaultValue, variable progress=defaultValue, variable nthreads=defaultValue)
    load a dataset with reduced dimensionality
    +
    const variable kDSCRegions
    +
    const variable kDSCPositioners
    +
    threadsafe variable adh5_get_result_waves(wave results, string result_prefix, variable start_index)
    copy waves from wave reference wave into current data folder
    +
    const variable kDSCPreview
    +
    string psh5_load_scan_meta(dfref file_df, string scanpath)
    load metadata of a PShell scan group.
    +
    static string twave2list(wave wt, string sep)
    convert text wave to list.
    +
    const variable kDSCScientaScaling
    +
    variable psh5_load_dataset_meta(dfref file_df, string datasetpath, wave datawave)
    load metadata of a PShell dataset.
    +
    variable ps_scale_dataset(wave data)
    set the dimension scales of a loaded PShell Scienta dataset according to attributes.
    +
    string psh5_extract_region_paths(string datasets)
    trim dataset paths to the scan/region part
    +
    const string kAngleDimLabel
    Dimension label for the angle dispersive dimension of multi-dimensional datasets.
    +
    variable ps_scale_dataset_2(wave data, wave ax, wave lo, wave hi, wave un)
    set the dimension scales of a dataset.
    +
    const string kTransposedDatasets
    List of datasets that must be transposed upon loading.
    +
    const variable kDSCSnaps
    +
    dfr psh5_dataset_to_folder(dfref parent_df, string datasetpath)
    map dataset path to datafolder path
    +
    string ad_suggest_foldername(string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
    generate the name of a data folder based on a file name.
    +
    const variable kDSCMeta
    +
    const variable kDSCDiags
    +
    const string kPreviewDatasets
    List of preferred datasets to load for preview.
    +
    const variable kDSCOther
    +
    dfr ps_find_attr_folder(dfref scan_df)
    find the attributes data folder
    +
    const variable kDSCAttrs
    +
    string psh5_list_all_datasets(variable file_id)
    list all datasets in a file
    +
    string psh5_load_datasets(dfref file_df, string datasets, variable create_folders=defaultValue, string reduction_func=defaultValue, string reduction_params=defaultValue)
    load multiple datasets from open file
    +
    const string kEssentialDiagnostics
    List of diagnostic datasets that are normally loaded with a scan.
    +
    const string kDataDimLabel
    Dimension label for the data dimension.
    +
    static string wave2list(wave w, string format, string sep)
    convert numeric wave to list.
    +
    threadsafe wave adh5_default_reduction(wave source, string *param)
    function prototype for adh5_load_reduced_detector
    +
    const variable kDSCDetectors
    +
    dfr psh5_preview(string path_name, string file_name, dfref dest_df=defaultValue, string preview_datasets=defaultValue)
    load preview
    +
    variable psh5_close_file(dfref file_df)
    close a HDF5 file opened by psh5_open_file.
    +
    string psh5_list_scans(variable file_id)
    list scan groups of a PShell data file.
    +
    string kill_matching_waves(dfref dfr, string pattern, variable recurse, string killed=defaultValue)
    kill any waves matching a pattern in the experiment
    +
    string PearlCleanupName(string name)
    +
    static string unique_strings(string list)
    remove duplicate items from list
    +
    variable ps_scale_datasets(dfref scan_df)
    set the dimension scales of loaded PShell Scienta datasets according to attributes.
    +
    dfr psh5_load(string path_name, string file_name, string scans, string regions, string datasets, variable classes=defaultValue, variable max_rank=defaultValue, string reduction_func=defaultValue, string reduction_params=defaultValue, dfref dest_df=defaultValue)
    main data loading function
    +
    const string kScanDimLabel
    Dimension label for the scan dimension of multi-dimensional datasets.
    +
    string psh5_match_dataset_classes(string datasets, variable classes, string positioners=defaultValue, string detectors=defaultValue)
    filter a list of datasets by classification
    +
    variable ps_detect_scale(dfref data_df, wave ax, wave lo, wave hi, wave un)
    detect the dimension scales from attributes.
    +
    variable[string datatypes, string ranks, string dimensions] psh5_list_dataset_info(string variable, string file_id, variable string, sds datasets)
    list data types and dimensions of datasets
    +
    const string kEnergyDimLabel
    Dimension label for the energy dispersive dimension of multi-dimensional datasets.
    +
    string psh5_extract_scan_paths(string datasets)
    trim dataset paths to the scan part
    +
    dfr psh5_open_file(string path_name, string file_name, dfref dest_df=defaultValue)
    open a HDF5 file created by the PShell data acquisition program and prepare the data folder.
    +
    static threadsafe wave reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_params)
    +
    dfr ps_find_scan_folder(dfref data_df)
    find the scan folder of current data
    +
    const variable kDSCAll
    diff --git a/doc/html/pearl-scienta-countrate_8ipf.html b/doc/html/pearl-scienta-countrate_8ipf.html deleted file mode 100644 index 260edb9..0000000 --- a/doc/html/pearl-scienta-countrate_8ipf.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - - - -PEARL Procedures: pearl-scienta-countrate.ipf File Reference - - - - - - - - - - - - - - -
    -
    - - - - - - -
    -
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty -
    -
    Igor procedures for the analysis of PEARL data
    -
    -
    - - - - - - - -
    -
    - -
    -
    -
    - -
    - -
    -
    - - -
    - -
    - -
    - -
    -
    pearl-scienta-countrate.ipf File Reference
    -
    -
    - -

    count rate functions for Scienta detector images. -More...

    -
    #include "pearl-area-display"
    -
    -

    Go to the source code of this file.

    - - - - - -

    -Namespaces

     PearlScientaCountrate
     count rate functions for Scienta detector images.
     
    - - - - - - - -

    -Functions

    variable ScientaLiveDisplay (string epicsname, string nickname, string wbRGB)
     open live display of most recent scienta measurement More...
     
    variable check_exposure_opt (wave image, wave outmask, variable dwelltime, dfref calc_df=defaultValue)
     optimized check exposure and calculate overexposure indicator mask More...
     
    -

    Detailed Description

    -

    count rate functions for Scienta detector images.

    -

    this procedure contains functions for working with true count rates.

    -
    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    - - -

    Definition in file pearl-scienta-countrate.ipf.

    -

    Function Documentation

    - -

    ◆ check_exposure_opt()

    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    variable check_exposure_opt (wave image,
    wave outmask,
    variable dwelltime,
    dfref calc_df = defaultValue 
    )
    -
    - -

    optimized check exposure and calculate overexposure indicator mask

    -

    calculate the local count rate density and return a mask to indicate where the maximum count rate is exceeded. the raw image is filtered by FFT with a gaussian kernel.

    -

    the raw image must have been acquired in fixed mode. slicing and dwell time are accounted for.

    -

    this function does the same as check_exposure() but keeps intermediate waves for time-optimized processing. moreover it is compatible with igor 6.

    -
    Parameters
    - - -
    -
    -
    - -

    Definition at line 150 of file pearl-scienta-countrate.ipf.

    - -
    -
    - -

    ◆ ScientaLiveDisplay()

    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - -
    variable ScientaLiveDisplay (string epicsname,
    string nickname,
    string wbRGB 
    )
    -
    - -

    open live display of most recent scienta measurement

    -
    Parameters
    - - - - -
    epicsnamebase name of the detector, e.g. X03DA-SCIENTA: image1: and cam1: are appended by the function. see ad_connect.
    nicknamenick name under which this detector is referred to in Igor. must be a valid data folder name. see ad_connect.
    wbRGBwindow background color, e.g. "32768,49152,55296"
    -
    -
    - -

    Definition at line 43 of file pearl-scienta-countrate.ipf.

    - -
    -
    -
    -
    - - - - diff --git a/doc/html/pearl-scienta-countrate_8ipf.js b/doc/html/pearl-scienta-countrate_8ipf.js deleted file mode 100644 index 84a0dae..0000000 --- a/doc/html/pearl-scienta-countrate_8ipf.js +++ /dev/null @@ -1,5 +0,0 @@ -var pearl_scienta_countrate_8ipf = -[ - [ "check_exposure_opt", "pearl-scienta-countrate_8ipf.html#af2879284b1d1397447a31733fddd6273", null ], - [ "ScientaLiveDisplay", "pearl-scienta-countrate_8ipf.html#a55886895329455b36b64d52ed6a4e228", null ] -]; \ No newline at end of file diff --git a/doc/html/pearl-scienta-countrate_8ipf_source.html b/doc/html/pearl-scienta-countrate_8ipf_source.html deleted file mode 100644 index c16ae9b..0000000 --- a/doc/html/pearl-scienta-countrate_8ipf_source.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - -PEARL Procedures: pearl-scienta-countrate.ipf Source File - - - - - - - - - - - - - - -
    -
    - - - - - - -
    -
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty -
    -
    Igor procedures for the analysis of PEARL data
    -
    -
    - - - - - - - -
    -
    - -
    -
    -
    - -
    - -
    -
    - - -
    - -
    - -
    -
    -
    pearl-scienta-countrate.ipf
    -
    -
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.35
    3 #pragma ModuleName = PearlScientaCountrate
    4 #include "pearl-area-display"
    5 
    6 // Copyright (c) 2019 Paul Scherrer Institut
    7 //
    8 // Licensed under the Apache License, Version 2.0 (the "License");
    9 // you may not use this file except in compliance with the License.
    10 // You may obtain a copy of the License at
    11 // http://www.apache.org/licenses/LICENSE-2.0
    12 
    26 
    31 
    43 function ScientaLiveDisplay(epicsname, nickname, wbRGB)
    44  string epicsname
    45  string nickname
    46  string wbRGB
    47 
    48  ad_connect(epicsname, nickname)
    49  string df_name
    50  sprintf df_name, "ad_display_profiles(root:pearl_epics:%s)", nickname
    51  dfref df = $df_name
    52  wave /sdfr=df img = image
    53  string graphname = ad_display(img)
    54  wbRGB = replacestring("(", wbRGB, "")
    55  wbRGB = replacestring(")", wbRGB, "")
    56  variable rr = str2num(StringFromList(0, wbRGB, ","))
    57  variable gg = str2num(StringFromList(1, wbRGB, ","))
    58  variable bb = str2num(StringFromList(2, wbRGB, ","))
    59  ModifyGraph /w=$graphname wbRGB=(rr,gg,bb)
    60  add_roi_controls()
    61  ad_add_overlay(img)
    62 end
    63 
    64 #if igorVersion() >= 8
    65 function check_exposure(image, outmask, dwelltime)
    88  wave image
    89  wave outmask
    90  variable dwelltime
    91 
    92  variable xbin = 1
    93  variable ybin = 902 / dimsize(image, 1)
    94  variable thresh = 1e5 / 900 / 900
    95 
    96  duplicate /free image, filt
    97  setscale /p x -dimsize(image, 0)/2, 1, "", filt // energy
    98  setscale /p y -dimsize(image, 1)/2, 1, "", filt // angle
    99  variable wx = sqrt(500) / xbin
    100  variable wy = sqrt(500) / ybin
    101  filt = exp(-((x/wx)^2 + (y/wy)^2))
    102  variable nfilt = sum(filt)
    103  filt /= nfilt
    104  fft /free /dest=filt_fft filt
    105 
    106  duplicate /free image, img
    107  img /= dwelltime
    108  setscale /p x -dimsize(image, 0)/2, 1, "", img
    109  setscale /p y -dimsize(image, 1)/2, 1, "", img
    110  fft /free /dest=img_fft img
    111  img_fft *= filt_fft
    112  ifft /free /dest=img_ifft img_fft
    113  imagetransform swap img_ifft
    114 
    115  outmask = (img_ifft < thresh) * 64
    116 end
    117 #endif
    118 
    150 function check_exposure_opt(image, outmask, dwelltime, [calc_df])
    151  wave image
    152  wave outmask
    153  variable dwelltime
    154  dfref calc_df
    155 
    156  variable xbin = 1
    157  variable ybin = 902 / dimsize(image, 1)
    158  variable thresh = 1e5 / 900 / 900
    159 
    160  dfref save_df = GetDataFolderDFR()
    161  if (ParamIsDefault(calc_df))
    162  dfref source_df = GetWavesDataFolderDFR(image)
    163  string calc_df_name = PearlCleanupName("psc_" + NameOfWave(image))
    164  dfref calc_df = source_df:$calc_df_name
    165  endif
    166  NewDataFolder /o /s calc_df
    167 
    168  wave /z co_filt
    169  wave /z /c co_filt_fft
    170  wave /z co_img
    171  wave /z /c co_img_fft
    172  wave /z co_img_ifft
    173  nvar /z co_img_size_x
    174  nvar /z co_img_size_y
    175 
    176  variable cache = 0
    177  if (waveexists(co_filt))
    178  cache = (dimsize(image, 0) == co_img_size_x) && (dimsize(image, 1) == co_img_size_y)
    179  if (!cache)
    180  redimension /n=(dimsize(image, 0), dimsize(image, 1)) co_filt, co_filt_fft, co_img, co_img_fft, co_img_ifft
    181  endif
    182  else
    183  duplicate /o image, co_filt, co_img, co_img_ifft
    184  make /n=(dimsize(image, 0), dimsize(image, 1)) /c co_filt_fft, co_img_fft
    185  variable /g co_img_size_x
    186  variable /g co_img_size_y
    187  endif
    188 
    189  co_img_size_x = dimsize(image, 0)
    190  co_img_size_y = dimsize(image, 1)
    191  setscale /p x -co_img_size_x/2, 1, "", co_filt, co_filt_fft, co_img, co_img_fft, co_img_ifft
    192  setscale /p y -co_img_size_y/2, 1, "", co_filt, co_filt_fft, co_img, co_img_fft, co_img_ifft
    193 
    194  if (!cache)
    195  variable wx = sqrt(500) / xbin
    196  variable wy = sqrt(500) / ybin
    197  co_filt = exp(-((x/wx)^2 + (y/wy)^2))
    198  variable nfilt = sum(co_filt)
    199  co_filt /= nfilt
    200  fft /dest=co_filt_fft co_filt
    201  endif
    202 
    203  co_img /= dwelltime
    204  fft /dest=co_img_fft co_img
    205  co_img_fft *= co_filt_fft
    206  ifft /dest=co_img_ifft co_img_fft
    207  imagetransform swap co_img_ifft
    208 
    209  redimension /n=(dimsize(co_img_ifft, 0), dimsize(co_img_ifft, 1)) outmask
    210  outmask = (co_img_ifft < thresh) * 64
    211 
    212  SetDataFolder save_df
    213 end
    variable check_exposure_opt(wave image, wave outmask, variable dwelltime, dfref calc_df=defaultValue)
    optimized check exposure and calculate overexposure indicator mask
    -
    string PearlCleanupName(string name)
    -
    string ad_display(wave image)
    open a new graph window with a 2D image.
    -
    wave ad_add_overlay(wave image, string rgba=defaultValue)
    add an overlay on top of the displayed image
    -
    variable ScientaLiveDisplay(string epicsname, string nickname, string wbRGB)
    open live display of most recent scienta measurement
    -
    -
    - - - - diff --git a/doc/html/pearl-scienta-preprocess_8ipf.html b/doc/html/pearl-scienta-preprocess_8ipf.html index 724e608..e0a0104 100644 --- a/doc/html/pearl-scienta-preprocess_8ipf.html +++ b/doc/html/pearl-scienta-preprocess_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-scienta-preprocess.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -92,6 +94,7 @@ $(document).ready(function(){initNavTree('pearl-scienta-preprocess_8ipf.html',''

    preprocessing functions for Scienta detector images. More...

    #include "pearl-fitfuncs"
    +#include "pearl-area-import"

    Go to the source code of this file.

    @@ -104,45 +107,47 @@ Namespaces - + - + - + - + - + - + - + - + - + - + + +

    Functions

    variable prompt_int_linbg_reduction (string *param)
     prompt the user for integrate on linear background reduction parameters. More...
     prompt the user for integrate on linear background reduction parameters. More...
     
    string capture_int_linbg_cursors ()
     capture linear background reduction parameters from cursors in a graph. More...
     capture linear background reduction parameters from cursors in a graph. More...
     
    string csr_int_linbg_reduction (string win)
     calculate linear background reduction parameters from cursors in a graph. More...
     calculate linear background reduction parameters from cursors in a graph. More...
     
    threadsafe wave int_linbg_reduction (wave source, string *param)
     linear-background subtracted integration reduction function. More...
     linear-background subtracted integration reduction function. More...
     
    variable prompt_int_quadbg_reduction (string *param)
     
    threadsafe wave int_quadbg_reduction (wave source, string *param)
     integrate peak area minus a quadratic background More...
     integrate peak area minus a quadratic background More...
     
    variable prompt_redim_linbg_reduction (string *param)
     parameter dialog for the redim_linbg_reduction() function More...
     parameter dialog for the redim_linbg_reduction() function More...
     
    threadsafe wave redim_linbg_reduction (wave source, string *param)
     linear background reduction function for incorrectly dimensioned scienta image More...
     linear background reduction function for incorrectly dimensioned scienta image More...
     
    variable test_gauss4_reduction (wave image)
     apply the gauss4_reduction function to a single image More...
     apply the gauss4_reduction function to a single image More...
     
    variable prompt_gauss4_reduction (string *param)
     prompt for the gauss4_reduction parameters More...
     prompt for the gauss4_reduction parameters More...
     
    threadsafe wave gauss4_reduction (wave source, string *param)
     fit horizontal cuts of an image with up to four gaussian peaks on a linear background More...
     fit horizontal cuts of an image with up to four gaussian peaks on a linear background More...
     
    threadsafe wave gauss6_reduction (wave source, string *param)
     

    Detailed Description

    preprocessing functions for Scienta detector images.

    this procedure contains functions for data reduction and instrument-specific normalization.

    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -
    @@ -211,7 +216,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    parameter string for linear background subtraction
    -

    Definition at line 133 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 135 of file pearl-scienta-preprocess.ipf.

    @@ -267,7 +272,37 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    free wave containing references of the result waves. the number of waves is two times the number of peaks that are fit. the first npeaks waves contain the peak integrals, the second npeaks waves the corresponding error estimates.
    -

    Definition at line 718 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 720 of file pearl-scienta-preprocess.ipf.

    + + + + +

    ◆ gauss6_reduction()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    threadsafe wave gauss6_reduction (wave source,
    string * param 
    )
    +
    + +

    Definition at line 856 of file pearl-scienta-preprocess.ipf.

    @@ -318,7 +353,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    free wave containing references of the two result waves. the first wave is the integral minus linear background. the second wave is the Poisson one-sigma error.
    -

    Definition at line 260 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 262 of file pearl-scienta-preprocess.ipf.

    @@ -369,7 +404,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    free wave containing references of the two result waves. the first wave is the integral minus linear background. the second wave is the Poisson one-sigma error.
    -

    Definition at line 413 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 415 of file pearl-scienta-preprocess.ipf.

    @@ -391,7 +426,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    prompt for the gauss4_reduction parameters

    -

    Definition at line 626 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 628 of file pearl-scienta-preprocess.ipf.

    @@ -413,7 +448,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    prompt the user for integrate on linear background reduction parameters.

    -

    Definition at line 35 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 37 of file pearl-scienta-preprocess.ipf.

    @@ -433,7 +468,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    Definition at line 351 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 353 of file pearl-scienta-preprocess.ipf.

    @@ -453,16 +488,16 @@ Licensed under the Apache License, Version 2.0 (the "License");
    -

    parameter dialog for the redim_linbg_reduction() function

    +

    parameter dialog for the redim_linbg_reduction() function

    Parameters
    - +
    paramparameter string in a key1=value1;key2=value2;... list. the parameter string is passed by reference. see redim_linbg_reduction() for a description of parameters.
    paramparameter string in a key1=value1;key2=value2;... list. the parameter string is passed by reference. see redim_linbg_reduction() for a description of parameters.
    Returns
    zero if the user clicked OK, non-zero if the user clicked Cancel.
    -

    Definition at line 509 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 511 of file pearl-scienta-preprocess.ipf.

    @@ -495,7 +530,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    linear background reduction function for incorrectly dimensioned scienta image

    if the energy step size does not divide the energy range to an integer number, the scienta image is exported with the wrong array size. this can be fixed by redimensioning the array.

    the current implementation works in the case where dimension 0 needs to be incremented. the function may be generalized to dimension 1 and/or decrementing by additional parameters. it is not known yet whether a generalization is needed or whether it can cover all cases.

    -

    background subtraction and peak integration is the same as by the int_linbg_reduction() function.

    +

    background subtraction and peak integration is the same as by the int_linbg_reduction() function.

    Parameters
    @@ -514,7 +549,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    typical values (peak centered on detector, FWHM ~ 20 % of image) Lcrop=0.11;Hcrop=0.11;Lsize=0.2;Hsize=0.2;Cpos=0.5;Csize=0.2

    Returns
    free wave containing references of the two result waves. the first wave is the integral minus linear background. the second wave is the Poisson one-sigma error.
    -

    Definition at line 572 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 574 of file pearl-scienta-preprocess.ipf.

    @@ -537,7 +572,7 @@ Licensed under the Apache License, Version 2.0 (the "License");

    apply the gauss4_reduction function to a single image

    useful for testing or manual processing. to debug, (temporarily) remove the threadsafe attribute from the gauss2_reduction function.

    -

    Definition at line 592 of file pearl-scienta-preprocess.ipf.

    +

    Definition at line 594 of file pearl-scienta-preprocess.ipf.

    @@ -547,9 +582,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
    diff --git a/doc/html/pearl-scienta-preprocess_8ipf.js b/doc/html/pearl-scienta-preprocess_8ipf.js index aacafc2..5ca776b 100644 --- a/doc/html/pearl-scienta-preprocess_8ipf.js +++ b/doc/html/pearl-scienta-preprocess_8ipf.js @@ -3,6 +3,7 @@ var pearl_scienta_preprocess_8ipf = [ "capture_int_linbg_cursors", "pearl-scienta-preprocess_8ipf.html#ae6877c51ad15c2ba8a69c65356cb34b8", null ], [ "csr_int_linbg_reduction", "pearl-scienta-preprocess_8ipf.html#a95fbd22f52f61d2bff0625b7b8e159d1", null ], [ "gauss4_reduction", "pearl-scienta-preprocess_8ipf.html#a83cdbd96c5b59011914d53118e5ef71c", null ], + [ "gauss6_reduction", "pearl-scienta-preprocess_8ipf.html#a11d42ef1352876666b710b7545360fce", null ], [ "int_linbg_reduction", "pearl-scienta-preprocess_8ipf.html#a1e91197cd7a3581b70bc59a194d3f43b", null ], [ "int_quadbg_reduction", "pearl-scienta-preprocess_8ipf.html#ad626526589efec3f2f72ad001702fe39", null ], [ "prompt_gauss4_reduction", "pearl-scienta-preprocess_8ipf.html#a1514250704b40aa2614d389a2e250d61", null ], diff --git a/doc/html/pearl-scienta-preprocess_8ipf_source.html b/doc/html/pearl-scienta-preprocess_8ipf_source.html index 8c915c1..7a81f64 100644 --- a/doc/html/pearl-scienta-preprocess_8ipf_source.html +++ b/doc/html/pearl-scienta-preprocess_8ipf_source.html @@ -1,9 +1,9 @@ - + - +PEARL Procedures: pearl-scienta-preprocess.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@ @@ -38,18 +35,21 @@
    sourcesource wave Scienta detector image, energy axis along X, angle axis along Y
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,31 +87,1319 @@ $(document).ready(function(){initNavTree('pearl-scienta-preprocess_8ipf_source.h
    pearl-scienta-preprocess.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    2 #pragma IgorVersion = 6.1
    3 #pragma ModuleName = PearlScientaPreprocess
    4 #include "pearl-fitfuncs"
    5 
    6 // Copyright (c) 2013-18 Paul Scherrer Institut
    7 //
    8 // Licensed under the Apache License, Version 2.0 (the "License");
    9 // you may not use this file except in compliance with the License.
    10 // You may obtain a copy of the License at
    11 // http://www.apache.org/licenses/LICENSE-2.0
    12 
    27 
    32 
    36  string &param
    37 
    38  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
    39  variable Lsize = NumberByKey("Lsize", param, "=", ";")
    40  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
    41  variable Hsize = NumberByKey("Hsize", param, "=", ";")
    42  variable Cpos = NumberByKey("Cpos", param, "=", ";")
    43  variable Csize = NumberByKey("Csize", param, "=", ";")
    44 
    45  prompt Lcrop, "Lower cropping region"
    46  prompt Hcrop, "Upper cropping region"
    47  prompt Lsize, "Lower background region"
    48  prompt Hsize, "Upper background region"
    49  prompt Cpos, "Center position"
    50  prompt Csize, "Center integration region"
    51 
    52  doprompt "int_linbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
    53  if (v_flag == 0)
    54  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
    55  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
    56  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
    57  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
    58  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
    59  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
    60  endif
    61 
    62  return v_flag
    63 end
    64 
    94  string param = csr_int_linbg_reduction("")
    95  svar /z global_params = root:packages:pearl_explorer:s_reduction_params
    96  if (svar_exists(global_params))
    97  global_params = param
    98  endif
    99  return param
    100 end
    101 
    133 function /s csr_int_linbg_reduction(win)
    134  string win
    135 
    136  // read all cursor positions
    137  variable ic
    138  string sc
    139  variable nc = 10
    140  make /n=(nc) /free positions
    141  variable np = 0
    142  wave /z image = $""
    143  string imagename = ""
    144  string tracename = ""
    145  string info
    146 
    147  for (ic = 0; ic < nc; ic += 1)
    148  sc = num2char(char2num("A") + ic)
    149  wave /z wc = CsrWaveRef($sc, win)
    150  info = CsrInfo($sc, win)
    151  tracename = StringByKey("TNAME", info, ":", ";")
    152  if (waveexists(wc) && (wavedims(wc) == 2))
    153  if (!waveexists(image))
    154  wave image = wc
    155  imagename = tracename
    156  endif
    157  if (cmpstr(tracename, imagename) == 0)
    158  positions[np] = pcsr($sc, win)
    159  np += 1
    160  endif
    161  endif
    162  endfor
    163 
    164  np = floor(np / 2) * 2 // ignore odd cursor
    165  redimension /n=(np) positions
    166  sort positions, positions
    167  // shift upper positions by one so that the rightmost pixel becomes 1.0
    168  positions = p >= np / 2 ? positions + 1 : positions
    169  positions = positions / dimsize(image, 0)
    170 
    171  // map innermost cursor pair to peak center and size
    172  variable ip2 = np / 2
    173  variable ip1 = ip2 - 1
    174  variable Cpos
    175  variable Csize
    176  if (ip1 >= 0)
    177  Cpos = (positions[ip1] + positions[ip2]) / 2
    178  Csize = positions[ip2] - positions[ip1]
    179  else
    180  // default: a small region in the center
    181  Cpos = 0.5
    182  Csize = 0.2
    183  endif
    184 
    185  // background region
    186  ip1 -= 1
    187  ip2 += 1
    188  variable Lsize
    189  variable Hsize
    190  if (ip1 >= 0)
    191  Lsize = positions[ip1]
    192  Hsize = 1 - positions[ip2]
    193  else
    194  // default: everything outside the peak region
    195  Lsize = Cpos - Csize / 2
    196  Hsize = 1 - (Cpos + Csize / 2)
    197  endif
    198 
    199  // crop region
    200  ip1 -= 1
    201  ip2 += 1
    202  variable Lcrop = 0
    203  variable Hcrop = 0
    204  if (ip1 >= 0)
    205  Lcrop = positions[ip1]
    206  Hcrop = 1 - positions[ip2]
    207  else
    208  // default: in fixed mode: dark corners of the EW4000 at PEARL, 0 otherwise
    209  if (dimsize(image, 0) >= 992)
    210  Lcrop = 0.11
    211  Hcrop = 0.11
    212  endif
    213  endif
    214  Lsize = max(Lsize - Lcrop, 0)
    215  Hsize = max(Hsize - Hcrop, 0)
    216 
    217  string param = ""
    218  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
    219  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
    220  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
    221  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
    222  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
    223  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
    224 
    225  return param
    226 end
    227 
    260 threadsafe function /wave int_linbg_reduction(source, param)
    261  wave source
    262  string &param
    263 
    264  variable nx = dimsize(source, 0)
    265  variable ny = dimsize(source, 1)
    266 
    267  // read parameters
    268  variable lcrop = NumberByKey("Lcrop", param, "=", ";")
    269  variable lsize = NumberByKey("Lsize", param, "=", ";")
    270  variable hcrop = NumberByKey("Hcrop", param, "=", ";")
    271  variable hsize = NumberByKey("Hsize", param, "=", ";")
    272  variable cpos = NumberByKey("Cpos", param, "=", ";")
    273  variable csize = NumberByKey("Csize", param, "=", ";")
    274 
    275  make /wave /free /n=2 result_waves
    276  make /free /n=0 dest1, dest2
    277  result_waves[0] = dest1
    278  result_waves[1] = dest2
    279  adh5_setup_profile(source, dest1, 1)
    280  adh5_setup_profile(source, dest2, 1)
    281 
    282  // validate parameters
    283  // background parameters are optional, center parameter is required.
    284  if (numtype(lcrop) != 0)
    285  lcrop = 0
    286  endif
    287  if (numtype(lsize) != 0)
    288  lsize = 0
    289  endif
    290  if (numtype(hcrop) != 0)
    291  hcrop = 0
    292  endif
    293  if (numtype(hsize) != 0)
    294  hsize = 0
    295  endif
    296  if (numtype(Cpos) != 0)
    297  redimension /n=0 result_waves
    298  return result_waves // Cpos parameter missing
    299  endif
    300  if (numtype(Csize) != 0)
    301  redimension /n=0 result_waves
    302  return result_waves // Csize parameter missing
    303  endif
    304 
    305  variable lpos = lcrop + lsize / 2
    306  variable hpos = 1 - (hcrop + hsize / 2)
    307 
    308  variable p0
    309  variable p1
    310 
    311  duplicate /free dest1, lbg, hbg
    312  if (lsize > 0)
    313  p0 = round(lcrop * nx)
    314  p1 = round((lcrop + lsize) * nx)
    315  ad_profile_y_w(source, p0, p1, lbg)
    316  else
    317  lbg = 0
    318  endif
    319  if (hsize > 0)
    320  p0 = round((1 - hcrop - hsize) * nx)
    321  p1 = round((1 - hcrop) * nx)
    322  ad_profile_y_w(source, p0, p1, hbg)
    323  else
    324  hbg = 0
    325  endif
    326  if (csize > 0)
    327  p0 = round((cpos - csize/2) * nx)
    328  p1 = round((cpos + csize/2) * nx)
    329  ad_profile_y_w(source, p0, p1, dest1)
    330  else
    331  dest1 = 0
    332  endif
    333 
    334  variable scale = (cpos - lpos) / (hpos - lpos)
    335  dest2 = dest1
    336  dest1 -= scale * (hbg - lbg) + lbg
    337  dest2 = sqrt(dest2 + scale^2 * (hbg + lbg))
    338 
    339  string s_note1
    340  string s_note2
    341  sprintf s_note1, "AxisLabelD=peak integral"
    342  sprintf s_note2, "KineticEnergy=%.3f", cpos * nx * dimdelta(source, 0) + dimoffset(source, 0)
    343  Note dest1, s_note1
    344  Note dest1, s_note2
    345  Note dest2, s_note1
    346  Note dest2, s_note2
    347 
    348  return result_waves
    349 end
    350 
    352  string &param
    353 
    354  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
    355  variable Lsize = NumberByKey("Lsize", param, "=", ";")
    356  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
    357  variable Hsize = NumberByKey("Hsize", param, "=", ";")
    358  variable Cpos = NumberByKey("Cpos", param, "=", ";")
    359  variable Csize = NumberByKey("Csize", param, "=", ";")
    360 
    361  prompt Lcrop, "Lower cropping region"
    362  prompt Hcrop, "Upper cropping region"
    363  prompt Lsize, "Lower background region"
    364  prompt Hsize, "Upper background region"
    365  prompt Cpos, "Center position"
    366  prompt Csize, "Center integration region"
    367 
    368  doprompt "int_quadbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
    369  if (v_flag == 0)
    370  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
    371  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
    372  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
    373  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
    374  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
    375  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
    376  endif
    377 
    378  return v_flag
    379 end
    380 
    413 threadsafe function /wave int_quadbg_reduction(source, param)
    414  wave source
    415  string &param
    416 
    417  variable nx = dimsize(source, 0)
    418  variable ny = dimsize(source, 1)
    419 
    420  // read parameters
    421  variable lcrop = NumberByKey("Lcrop", param, "=", ";")
    422  variable lsize = NumberByKey("Lsize", param, "=", ";")
    423  variable hcrop = NumberByKey("Hcrop", param, "=", ";")
    424  variable hsize = NumberByKey("Hsize", param, "=", ";")
    425  variable cpos = NumberByKey("Cpos", param, "=", ";")
    426  variable csize = NumberByKey("Csize", param, "=", ";")
    427 
    428  make /wave /free /n=2 result_waves
    429  make /free /n=0 dest1, dest2
    430  result_waves[0] = dest1
    431  result_waves[1] = dest2
    432  adh5_setup_profile(source, dest1, 1)
    433  adh5_setup_profile(source, dest2, 1)
    434 
    435  // validate parameters
    436  // background parameters are optional, center parameter is required.
    437  if (numtype(lcrop) != 0)
    438  lcrop = 0
    439  endif
    440  if (numtype(lsize) != 0)
    441  lsize = 0
    442  endif
    443  if (numtype(hcrop) != 0)
    444  hcrop = 0
    445  endif
    446  if (numtype(hsize) != 0)
    447  hsize = 0
    448  endif
    449  if (numtype(Cpos) != 0)
    450  redimension /n=0 result_waves
    451  return result_waves // Cpos parameter missing
    452  endif
    453  if (numtype(Csize) != 0)
    454  redimension /n=0 result_waves
    455  return result_waves // Csize parameter missing
    456  endif
    457 
    458  // crop boundaries
    459  variable pcl = round(lcrop * nx)
    460  variable pch = round((1 - hcrop) * nx)
    461  // fit boundaries
    462  variable pfl = round((lcrop + lsize) * nx)
    463  variable pfh = round((1 - hcrop - hsize) * nx)
    464  // integration boundaries
    465  variable pil = round((cpos - csize/2) * nx)
    466  variable pih = round((cpos + csize/2) * nx)
    467 
    468  // prepare intermediate data buffer
    469  make /n=(nx) /d /free profile, mask, fit
    470  setscale /p x dimoffset(source,0), dimdelta(source,0), waveunits(source,0), profile, mask, fit
    471  mask = ((p >= pcl) && (p < pfl)) || ((p >= pfh) && (p < pch))
    472 
    473  variable qq
    474  variable sp, sf
    475  variable xil = x2pnt(profile, pil)
    476  variable xih = x2pnt(profile, pih)
    477 
    478  make /n=3 /free /d w_coef
    479  for (qq = 0; qq < ny; qq += 1)
    480  profile = source[p][qq]
    481  curvefit /Q /NTHR=1 /W=2 poly 3, kwCWave=w_coef, profile /M=mask
    482  fit = poly(w_coef, x)
    483  sp = sum(profile, xil, xih)
    484  sf = sum(fit, xil, xih)
    485  dest1[qq] = sp - sf
    486  dest2[qq] = sqrt(sp)
    487  endfor
    488 
    489  string s_note1
    490  string s_note2
    491  sprintf s_note1, "AxisLabelD=peak integral"
    492  sprintf s_note2, "KineticEnergy=%.3f", cpos * nx * dimdelta(source, 0) + dimoffset(source, 0)
    493  Note dest1, s_note1
    494  Note dest1, s_note2
    495  Note dest2, s_note1
    496  Note dest2, s_note2
    497 
    498  return result_waves
    499 end
    500 
    510  string &param
    511 
    512  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
    513  variable Lsize = NumberByKey("Lsize", param, "=", ";")
    514  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
    515  variable Hsize = NumberByKey("Hsize", param, "=", ";")
    516  variable Cpos = NumberByKey("Cpos", param, "=", ";")
    517  variable Csize = NumberByKey("Csize", param, "=", ";")
    518 
    519  prompt Lcrop, "Lower cropping region"
    520  prompt Hcrop, "Upper cropping region"
    521  prompt Lsize, "Lower background region"
    522  prompt Hsize, "Upper background region"
    523  prompt Cpos, "Center position"
    524  prompt Csize, "Center integration region"
    525 
    526  doprompt "redim_linbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
    527  if (v_flag == 0)
    528  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
    529  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
    530  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
    531  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
    532  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
    533  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
    534  endif
    535 
    536  return v_flag
    537 end
    538 
    572 threadsafe function /wave redim_linbg_reduction(source, param)
    573  wave source
    574  string &param
    575 
    576  variable nx = dimsize(source, 0)
    577  variable ny = dimsize(source, 1)
    578 
    579  duplicate /free source, source_redim
    580  redimension /n=(nx * ny) source_redim
    581  nx += 1
    582  redimension /n=(nx, ny) source_redim
    583 
    584  return int_linbg_reduction(source_redim, param)
    585 end
    586 
    592 function test_gauss4_reduction(image)
    593  wave image
    594 
    595  string param = ""
    596 
    597  param = ReplaceNumberByKey("rngl", param, -inf, "=", ";")
    598  param = ReplaceNumberByKey("rngh", param, inf, "=", ";")
    599  param = ReplaceNumberByKey("npeaks", param, 4, "=", ";")
    600  param = ReplaceNumberByKey("ybox", param, 1, "=", ";")
    601  param = ReplaceNumberByKey("pos1", param, 11, "=", ";")
    602  param = ReplaceNumberByKey("wid1", param, 0.1, "=", ";")
    603  param = ReplaceNumberByKey("pos2", param, 12, "=", ";")
    604  param = ReplaceNumberByKey("wid2", param, 0.2, "=", ";")
    605  param = ReplaceNumberByKey("pos3", param, 13, "=", ";")
    606  param = ReplaceNumberByKey("wid3", param, 0.3, "=", ";")
    607  param = ReplaceNumberByKey("pos4", param, 14, "=", ";")
    608  param = ReplaceNumberByKey("wid4", param, 0.4, "=", ";")
    609 
    610  wave /wave results = gauss4_reduction(image, param)
    611 
    612  variable npk = numpnts(results) / 2
    613  variable ipk
    614  string sw
    615  for (ipk = 0; ipk < npk; ipk += 1)
    616  sw = "test_int_" + num2str(ipk + 1)
    617  duplicate /o results[ipk], $sw
    618  sw = "test_sig_" + num2str(ipk + 1)
    619  duplicate /o results[ipk + npk], $sw
    620  endfor
    621 end
    622 
    626 function prompt_gauss4_reduction(param)
    627  string &param
    628 
    629  variable rngl = NumberByKey("rngl", param, "=", ";")
    630  variable rngh = NumberByKey("rngh", param, "=", ";")
    631  variable pos1 = NumberByKey("pos1", param, "=", ";")
    632  variable wid1 = NumberByKey("wid1", param, "=", ";")
    633  variable pos2 = NumberByKey("pos2", param, "=", ";")
    634  variable wid2 = NumberByKey("wid2", param, "=", ";")
    635  variable pos3 = NumberByKey("pos3", param, "=", ";")
    636  variable wid3 = NumberByKey("wid3", param, "=", ";")
    637  variable pos4 = NumberByKey("pos4", param, "=", ";")
    638  variable wid4 = NumberByKey("wid4", param, "=", ";")
    639  variable npeaks = NumberByKey("npeaks", param, "=", ";")
    640  variable ybox = NumberByKey("ybox", param, "=", ";")
    641 
    642  prompt rngl, "range low"
    643  prompt rngh, "range high"
    644  prompt pos1, "position 1"
    645  prompt wid1, "width 1"
    646  prompt pos2, "position 2"
    647  prompt wid2, "width 2"
    648  prompt pos3, "position 3"
    649  prompt wid3, "width 3"
    650  prompt pos4, "position 4"
    651  prompt wid4, "width 4"
    652  prompt npeaks, "number of peaks"
    653  prompt ybox, "ybox (1 or 3)"
    654 
    655  doprompt "gauss4_reduction reduction parameters (1/2)", rngl, rngh, npeaks, ybox
    656  if (v_flag == 0)
    657  param = ReplaceNumberByKey("rngl", param, rngl, "=", ";")
    658  param = ReplaceNumberByKey("rngh", param, rngh, "=", ";")
    659  param = ReplaceNumberByKey("npeaks", param, npeaks, "=", ";")
    660  param = ReplaceNumberByKey("ybox", param, ybox, "=", ";")
    661 
    662  doprompt "gauss4_reduction reduction parameters (2/2)", pos1, wid1, pos2, wid2, pos3, wid3, pos4, wid4
    663  if (v_flag == 0)
    664  param = ReplaceNumberByKey("pos1", param, pos1, "=", ";")
    665  param = ReplaceNumberByKey("wid1", param, wid1, "=", ";")
    666  param = ReplaceNumberByKey("pos2", param, pos2, "=", ";")
    667  param = ReplaceNumberByKey("wid2", param, wid2, "=", ";")
    668  param = ReplaceNumberByKey("pos3", param, pos3, "=", ";")
    669  param = ReplaceNumberByKey("wid3", param, wid3, "=", ";")
    670  param = ReplaceNumberByKey("pos4", param, pos4, "=", ";")
    671  param = ReplaceNumberByKey("wid4", param, wid4, "=", ";")
    672  endif
    673  endif
    674 
    675  return v_flag
    676 end
    677 
    718 threadsafe function /wave gauss4_reduction(source, param)
    719  wave source
    720  string &param
    721 
    722  variable nx = dimsize(source, 0)
    723  variable ny = dimsize(source, 1)
    724 
    725  // read parameters
    726  variable rngl = NumberByKey("rngl", param, "=", ";")
    727  variable rngh = NumberByKey("rngh", param, "=", ";")
    728  variable pos1 = NumberByKey("pos1", param, "=", ";")
    729  variable wid1 = NumberByKey("wid1", param, "=", ";")
    730  variable pos2 = NumberByKey("pos2", param, "=", ";")
    731  variable wid2 = NumberByKey("wid2", param, "=", ";")
    732  variable pos3 = NumberByKey("pos3", param, "=", ";")
    733  variable wid3 = NumberByKey("wid3", param, "=", ";")
    734  variable pos4 = NumberByKey("pos4", param, "=", ";")
    735  variable wid4 = NumberByKey("wid4", param, "=", ";")
    736  variable npeaks = NumberByKey("npeaks", param, "=", ";")
    737  variable ybox = NumberByKey("ybox", param, "=", ";")
    738 
    739  // prepare curve fit
    740  variable ipk
    741  make /free xprof
    742  adh5_setup_profile(source, xprof, 0)
    743  duplicate /free xprof, xprof_sig
    744  variable pl = max(x2pnt(xprof, rngl), 0)
    745  variable ph = min(x2pnt(xprof, rngh), numpnts(xprof) - 1)
    746 
    747  make /free /n=(npeaks) peak_coef
    748  peak_coef = p * 3 + 2
    749  variable n_coef = npeaks * 3 + 2
    750  make /free /d /n=14 w_coef, W_sigma
    751  w_coef[0] = {0, 0, 1, pos1, wid1, 1, pos2, wid2, 1, pos3, wid3, 1, pos4, wid4}
    752  redimension /n=(n_coef) w_coef, w_sigma
    753 
    754  // text constraints cannot be used in threadsafe functions.
    755  // the following matrix-vector forumlation is equivalent to:
    756  // make /free /T /N=6 constraints
    757  // constraints[0] = {"K2 >= 0", "K5 >= 0", "K8 >= 0", "K11 >= 0", "K1 <= 0", "K0 => 0"}
    758  make /free /n=(npeaks + 2, numpnts(w_coef)) cmat
    759  make /free /n=(npeaks + 2) cvec
    760  cmat = 0
    761  cmat[0][0] = -1
    762  cmat[1][1] = 1
    763  cvec = 0
    764 
    765  string hold = "00"
    766  for (ipk=0; ipk < npeaks; ipk += 1)
    767  hold += "011"
    768  cmat[2 + ipk][2 + ipk*3] = -1
    769  endfor
    770 
    771  // prepare output
    772  make /free /n=(npeaks * 2) /wave result_waves
    773  string s_note
    774  for (ipk = 0; ipk < npeaks; ipk += 1)
    775  make /free /n=0 pk_int
    776  adh5_setup_profile(source, pk_int, 1)
    777  pk_int = nan
    778  sprintf s_note, "AxisLabelD=peak %u integral", ipk+1
    779  Note pk_int, s_note
    780  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * 3]
    781  Note pk_int, s_note
    782  result_waves[ipk] = pk_int
    783 
    784  make /free /n=0 pk_sig
    785  adh5_setup_profile(source, pk_sig, 1)
    786  pk_sig = nan
    787  sprintf s_note, "AxisLabelD=peak %u sigma", ipk+1
    788  Note pk_sig, s_note
    789  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * 3]
    790  Note pk_sig, s_note
    791  result_waves[ipk + npeaks] = pk_sig
    792 
    793  waveclear pk_int, pk_sig
    794  endfor
    795 
    796  // loop over angle scale
    797  variable p0 = 0
    798  variable p1 = dimsize(source, 1) - 1
    799  variable pp
    800  variable wmin
    801  variable wmax
    802  if (ybox > 1)
    803  p0 += ceil((ybox - 1) / 2)
    804  p1 -= ceil((ybox - 1) / 2)
    805  endif
    806  variable V_FitNumIters
    807 
    808  for (pp = p0; pp <= p1; pp += 1)
    809  // box average
    810  xprof = source[p][pp]
    811  if (ybox > 1)
    812  xprof += source[p][pp-1] + source[p][pp+1]
    813  endif
    814  xprof_sig = max(sqrt(xprof), 1)
    815  xprof /= ybox
    816  xprof_sig /= ybox
    817 
    818  // generate guess
    819  wmin = wavemin(xprof)
    820  wmax = wavemax(xprof)
    821  w_coef[0] = wmin
    822  w_coef[1] = 0
    823 
    824  for (ipk=0; ipk < npeaks; ipk += 1)
    825  w_coef[2 + ipk*3] = wmax - wmin
    826  endfor
    827  FuncFit /H=hold /Q /NTHR=1 /N /W=2 MultiGaussLinBG_AO w_coef xprof[pl,ph] /C={cmat, cvec} /I=1 /W=xprof_sig[pl,ph]
    828  wave w_sigma
    829 
    830  // retrieve results, leave them at nan if the fit did not converge
    831  if (V_FitNumIters < 40)
    832  for (ipk = 0; ipk < npeaks; ipk += 1)
    833  wave val = result_waves[ipk]
    834  wave sig = result_waves[ipk + npeaks]
    835  val[pp] = max(w_coef[peak_coef[ipk]], 0)
    836  sig[pp] = max(w_sigma[peak_coef[ipk]], 0)
    837  endfor
    838  endif
    839  endfor
    840 
    841  // calculate integral
    842  for (ipk = 0; ipk < npeaks; ipk += 1)
    843  wave val = result_waves[ipk]
    844  wave sig = result_waves[ipk + npeaks]
    845  val *= w_coef[peak_coef[ipk] + 2] * sqrt(pi)
    846  sig *= w_coef[peak_coef[ipk] + 2] * sqrt(pi)
    847  endfor
    848 
    849  return result_waves
    850 end
    851 
    852 
    884 function /s find_gauss4_reduction_params(spectrum, peakpos)
    885  wave spectrum
    886  wave peakpos
    887  string param = ""
    888 
    889  variable wmin = wavemin(spectrum)
    890  variable wmax = wavemax(spectrum)
    891 
    892  // read parameters
    893  variable rngl = dimoffset(spectrum, 0)
    894  variable rngh = dimoffset(spectrum, 0) + dimdelta(spectrum, 0) * (dimsize(spectrum, 0) - 1)
    895  make /n=4 /free positions, widths
    896  variable npeaks = numpnts(peakpos)
    897  variable ybox = 1
    898  positions = 0
    899  positions[0, npeaks-1] = peakpos[p]
    900  widths = 0.2
    901 
    902  variable n_coef = npeaks * 3 + 2
    903  make /free /d /n=(n_coef) w_coef
    904  w_coef = 0
    905  w_coef[0] = wmin
    906  w_coef[1] = 0
    907 
    908  make /free /n=(2+npeaks, numpnts(w_coef)) cmat
    909  make /free /n=(2+npeaks) cvec
    910  cmat = 0
    911  cmat[0][0] = -1
    912  cmat[1][1] = 1
    913  cvec = 0
    914 
    915  variable ip
    916  for (ip=0; ip < npeaks; ip += 1)
    917  cmat[2 + ip][2 + ip*3] = -1
    918  w_coef[2 + ip*3] = wmax - wmin
    919  w_coef[3 + ip*3] = peakpos[ip]
    920  w_coef[4 + ip*3] = widths[ip]
    921  endfor
    922 
    923  variable V_FitNumIters
    924  FuncFit /Q /NTHR=1 /N MultiGaussLinBG w_coef spectrum /C={cmat, cvec}
    925 
    926  for (ip=0; ip < npeaks; ip += 1)
    927  positions[ip] = w_coef[3 + ip * 3]
    928  widths[ip ] = abs(w_coef[4 + ip * 3])
    929  endfor
    930  for (ip=npeaks; ip < 4; ip += 1)
    931  positions[ip] = 0
    932  widths[ip] = 0.2
    933  endfor
    934 
    935  param = ReplaceNumberByKey("rngl", param, rngl, "=", ";")
    936  param = ReplaceNumberByKey("rngh", param, rngh, "=", ";")
    937  param = ReplaceNumberByKey("npeaks", param, npeaks, "=", ";")
    938  param = ReplaceNumberByKey("ybox", param, ybox, "=", ";")
    939  param = ReplaceNumberByKey("pos1", param, positions[0], "=", ";")
    940  param = ReplaceNumberByKey("wid1", param, widths[0], "=", ";")
    941  param = ReplaceNumberByKey("pos2", param, positions[1], "=", ";")
    942  param = ReplaceNumberByKey("wid2", param, widths[1], "=", ";")
    943  param = ReplaceNumberByKey("pos3", param, positions[2], "=", ";")
    944  param = ReplaceNumberByKey("wid3", param, widths[2], "=", ";")
    945  param = ReplaceNumberByKey("pos4", param, positions[3], "=", ";")
    946  param = ReplaceNumberByKey("wid4", param, widths[3], "=", ";")
    947 
    948  return param
    949 end
    950 
    958 function test_shockley_anglefit(image, branch)
    959  wave image
    960  variable branch
    961 
    962  string param = ""
    963  param = ReplaceStringByKey("branch", param, num2str(branch), "=", ";")
    964 
    965  string s_branch
    966  if (branch >= 0)
    967  s_branch = "p"
    968  else
    969  s_branch = "n"
    970  endif
    971  string pkpos_name = "saf_pkpos_" + s_branch
    972  string pkwid_name = "saf_pkwid_" + s_branch
    973 
    974  wave /wave results = shockley_anglefit(image, param)
    975  duplicate results[0], $pkpos_name
    976  duplicate results[1], $pkwid_name
    977 end
    978 
    979 function prompt_Shockley_anglefit(param)
    980  string &param
    981 
    982  variable branch = NumberByKey("branch", param, "=", ";")
    983 
    984  prompt branch, "Branch (-1 or +1)"
    985 
    986  doprompt "Shockley_anglefit_reduction Parameters", branch
    987  if (v_flag == 0)
    988  param = ReplaceNumberByKey("branch", param, branch, "=", ";")
    989  endif
    990 
    991  return v_flag
    992 end
    993 
    1016 threadsafe function /wave Shockley_anglefit(source, param)
    1017  wave source
    1018  string &param
    1019 
    1020  variable nx = dimsize(source, 0)
    1021  variable ny = dimsize(source, 1)
    1022 
    1023  // read parameters
    1024  variable branch = NumberByKey("branch", param, "=", ";")
    1025 
    1026  // validate parameters
    1027  if (numtype(branch) != 0)
    1028  branch = +1
    1029  endif
    1030 
    1031  // prepare output
    1032  make /wave /free /n=2 result_waves
    1033  make /free /n=0 dest1, dest2
    1034  result_waves[0] = dest1
    1035  result_waves[1] = dest2
    1036  adh5_setup_profile(source, dest1, 0)
    1037  adh5_setup_profile(source, dest2, 0)
    1038  dest1 = nan
    1039  dest2 = nan
    1040 
    1041  // select angle range
    1042  // hard-coded for a particular measurement series
    1043  variable y0
    1044  variable y1
    1045  if (branch < 0)
    1046  y0 = -5
    1047  y1 = 0
    1048  else
    1049  y0 = 0
    1050  y1 = 5
    1051  endif
    1052 
    1053  // select energy range
    1054  // start at the point of highest intensity and go up 0.45 eV
    1055  variable p0
    1056  variable p1
    1057  variable q0
    1058  variable q1
    1059  duplicate /free dest1, center
    1060  q0 = round((y0 - dimoffset(source, 1)) / dimdelta(source, 1))
    1061  q1 = round((y1 - dimoffset(source, 1)) / dimdelta(source, 1))
    1062  ad_profile_x_w(source, q0, q1, center)
    1063  wavestats /q/m=1 center
    1064  p0 = round((v_maxloc - dimoffset(source, 0)) / dimdelta(source, 0))
    1065  p1 = round((v_maxloc + 0.4 - dimoffset(source, 0)) / dimdelta(source, 0))
    1066 
    1067  // prepare intermediate data buffer
    1068  make /n=(ny)/d/free profile
    1069  setscale /p x dimoffset(source,1), dimdelta(source,1), waveunits(source,1), profile
    1070 
    1071  variable pp
    1072  for (pp = p0; pp <= p1; pp += 1)
    1073  profile = source[pp][p]
    1074  curvefit /Q /NTHR=1 /W=2 gauss profile(y0,y1)
    1075  wave w_coef
    1076  dest1[pp] = w_coef[2]
    1077  dest2[pp] = w_coef[3]
    1078  endfor
    1079 
    1080  return result_waves
    1081 end
    1082 
    1083 function scienta_norm(w, x): fitfunc
    1084  wave w
    1085  variable x
    1086 
    1087  return w[0] * (x^2 - w[1]^2)
    1088 end
    1089 
    1090 function /wave fit_scienta_ang_transm(data, params)
    1091  wave data // measured angular distribution (1D)
    1092  wave /z params
    1093 
    1094  if (!waveexists(params))
    1095  make /n=12 /o params
    1096  endif
    1097  redimension /n=12/d params
    1098 
    1099  variable h = wavemax(data) - wavemin(data)
    1100  params[0] = h / 2
    1101  params[1] = 0
    1102  params[2] = 7
    1103  params[3] = h / 4
    1104  params[4] = -23
    1105  params[5] = 4
    1106  params[6] = h / 4
    1107  params[7] = +23
    1108  params[8] = 4
    1109  params[9] = h / 2
    1110  params[10] = 0
    1111  params[11] = -0.001
    1112  FuncFit /NTHR=0 /q scienta_ang_transm params data
    1113 
    1114  return params
    1115 end
    1116 
    1117 threadsafe function scienta_ang_transm(w, x): fitfunc
    1118  // parameterized angular transmission function of the analyser
    1119  wave w // coefficients
    1120  // w[0] = amplitude gauss 1
    1121  // w[1] = position gauss 1
    1122  // w[2] = width gauss 1
    1123  // w[3] = amplitude gauss 2
    1124  // w[4] = position gauss 2
    1125  // w[5] = width gauss 2
    1126  // w[6] = amplitude gauss 3
    1127  // w[7] = position gauss 3
    1128  // w[8] = width gauss 3
    1129  // w[9] = constant background
    1130  // w[10] = linear background
    1131  // w[11] = quadratic background
    1132  variable x
    1133 
    1134  make /free /n=4 /d w_int
    1135  w_int[0] = 0
    1136  w_int[1,] = w[p - 1]
    1137  variable pk1 = gauss1d(w_int, x)
    1138  w_int[1,] = w[p + 2]
    1139  variable pk2 = gauss1d(w_int, x)
    1140  w_int[1,] = w[p + 5]
    1141  variable pk3 = gauss1d(w_int, x)
    1142  w_int[0,2] = w[9 + p]
    1143  w_int[3] = 0
    1144  variable bg = poly(w_int, x)
    1145 
    1146  return bg + pk1 + pk2 + pk3
    1147 end
    1148 
    1149 function /wave fit_scienta_poly_bg(data, params, bgterms)
    1150  wave data // measured distribution (2D)
    1151  wave /z params // wave, will be redimensioned for the correct size
    1152  variable bgterms // number of terms in the polynomial background: 2, 3, or 4
    1153 
    1154  if (!waveexists(params))
    1155  make /n=15 /o params
    1156  endif
    1157  redimension /n=15 /d params
    1158 
    1159  variable wmax = wavemax(data)
    1160  variable wmin = wavemin(data)
    1161  params[0] = 0
    1162  params[1] = 7
    1163  params[2] = 1 / 2
    1164  params[3] = -23
    1165  params[4] = 4
    1166  params[5] = 1 / 2
    1167  params[6] = +23
    1168  params[7] = 4
    1169  params[8] = 1
    1170  params[9] = 0
    1171  params[10] = -0.001
    1172  params[11] = wmin
    1173  params[12] = (wmax - wmin) / dimdelta(data,1) / dimsize(data,1)
    1174  params[13] = 0
    1175  params[14] = 0
    1176 
    1177  string h = "0000000000000"
    1178  if (bgterms < 3)
    1179  h = h + "1"
    1180  else
    1181  h = h + "0"
    1182  endif
    1183  if (bgterms < 4)
    1184  h = h + "1"
    1185  else
    1186  h = h + "0"
    1187  endif
    1188  FuncFitMD /NTHR=1 /q /h=h scienta_poly_bg params data
    1189 
    1190  return params
    1191 end
    1192 
    1193 function scienta_poly_bg(w, e, a): fitfunc
    1194  // polynomial background with
    1195  // parameterized angular transmission function of the analyser
    1196  wave w // coefficients
    1197  // angular transmission, varies with a
    1198  // amplitude of gauss 1 = 1 constant
    1199  // other peak amplitudes and linear terms are relative to gauss 1
    1200  // w[0] = position gauss 1
    1201  // w[1] = width gauss 1
    1202  // w[2] = amplitude gauss 2, relative to gauss 1
    1203  // w[3] = position gauss 2
    1204  // w[4] = width gauss 2
    1205  // w[5] = amplitude gauss 3, relative to gauss 1
    1206  // w[6] = position gauss 3
    1207  // w[7] = width gauss 3
    1208  // w[8] = constant term
    1209  // w[9] = linear term
    1210  // w[10] = quadratic term
    1211  // spectral background, varies with e
    1212  // w[11] = constant term
    1213  // w[12] = linear term
    1214  // w[13] = quadratic term
    1215  // w[14] = cubic term
    1216  variable a // detection angle
    1217  variable e // electron energy
    1218 
    1219  make /free /n=4 /d w_int
    1220  variable p0 = 0
    1221 
    1222  w_int[0] = 0
    1223  w_int[1] = 1
    1224  w_int[2,] = w[p0 + p - 2]
    1225  variable pk1 = gauss1d(w_int, a)
    1226  p0 += 2
    1227 
    1228  w_int[1,] = w[p0 + p - 1]
    1229  variable pk2 = gauss1d(w_int, a)
    1230  p0 += 3
    1231 
    1232  w_int[1,] = w[p0 + p - 1]
    1233  variable pk3 = gauss1d(w_int, a)
    1234  p0 += 3
    1235 
    1236  w_int[0,2] = w[p0 + p]
    1237  w_int[3] = 0
    1238  variable base = poly(w_int, a)
    1239  p0 += 3
    1240 
    1241  w_int[0,3] = w[p0 + p]
    1242  variable bg = poly(w_int, e)
    1243 
    1244  return bg * (base + pk1 + pk2 + pk3)
    1245 end
    threadsafe variable MultiGaussLinBG(wave w, variable x)
    multiple gaussian peaks on a linear background fit function.
    -
    threadsafe variable MultiGaussLinBG_AO(wave pw, wave yw, wave xw)
    multiple gaussian peaks on a linear background fit function (all at once).
    -
    variable prompt_gauss4_reduction(string *param)
    prompt for the gauss4_reduction parameters
    -
    threadsafe wave redim_linbg_reduction(wave source, string *param)
    linear background reduction function for incorrectly dimensioned scienta image
    -
    variable test_gauss4_reduction(wave image)
    apply the gauss4_reduction function to a single image
    -
    threadsafe wave ad_profile_x_w(wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    -
    threadsafe variable adh5_setup_profile(wave image, wave profile, variable dim)
    set up a one-dimensional wave for a line profile based on a 2D original wave.
    -
    variable prompt_int_quadbg_reduction(string *param)
    -
    threadsafe wave int_linbg_reduction(wave source, string *param)
    linear-background subtracted integration reduction function.
    -
    threadsafe wave gauss4_reduction(wave source, string *param)
    fit horizontal cuts of an image with up to four gaussian peaks on a linear background ...
    -
    variable prompt_redim_linbg_reduction(string *param)
    parameter dialog for the redim_linbg_reduction() function
    -
    threadsafe wave ad_profile_y_w(wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    -
    threadsafe wave int_quadbg_reduction(wave source, string *param)
    integrate peak area minus a quadratic background
    -
    variable prompt_int_linbg_reduction(string *param)
    prompt the user for integrate on linear background reduction parameters.
    -
    string csr_int_linbg_reduction(string win)
    calculate linear background reduction parameters from cursors in a graph.
    -
    string capture_int_linbg_cursors()
    capture linear background reduction parameters from cursors in a graph.
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma IgorVersion = 6.1
    +
    4 #pragma ModuleName = PearlScientaPreprocess
    +
    5 #include "pearl-fitfuncs"
    +
    6 #include "pearl-area-import"
    +
    7 
    +
    8 // Copyright (c) 2013-18 Paul Scherrer Institut
    +
    9 //
    +
    10 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    11 // you may not use this file except in compliance with the License.
    +
    12 // You may obtain a copy of the License at
    +
    13 // http://www.apache.org/licenses/LICENSE-2.0
    +
    14 
    +
    29 
    +
    34 
    + +
    38  string &param
    +
    39 
    +
    40  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
    +
    41  variable Lsize = NumberByKey("Lsize", param, "=", ";")
    +
    42  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
    +
    43  variable Hsize = NumberByKey("Hsize", param, "=", ";")
    +
    44  variable Cpos = NumberByKey("Cpos", param, "=", ";")
    +
    45  variable Csize = NumberByKey("Csize", param, "=", ";")
    +
    46 
    +
    47  prompt Lcrop, "Lower cropping region"
    +
    48  prompt Hcrop, "Upper cropping region"
    +
    49  prompt Lsize, "Lower background region"
    +
    50  prompt Hsize, "Upper background region"
    +
    51  prompt Cpos, "Center position"
    +
    52  prompt Csize, "Center integration region"
    +
    53 
    +
    54  doprompt "int_linbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
    +
    55  if (v_flag == 0)
    +
    56  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
    +
    57  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
    +
    58  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
    +
    59  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
    +
    60  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
    +
    61  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
    +
    62  endif
    +
    63 
    +
    64  return v_flag
    +
    65 end
    +
    66 
    + +
    96  string param = csr_int_linbg_reduction("")
    +
    97  svar /z global_params = root:packages:pearl_explorer:s_reduction_params
    +
    98  if (svar_exists(global_params))
    +
    99  global_params = param
    +
    100  endif
    +
    101  return param
    +
    102 end
    +
    103 
    +
    135 function /s csr_int_linbg_reduction(win)
    +
    136  string win
    +
    137 
    +
    138  // read all cursor positions
    +
    139  variable ic
    +
    140  string sc
    +
    141  variable nc = 10
    +
    142  make /n=(nc) /free positions
    +
    143  variable np = 0
    +
    144  wave /z image = $""
    +
    145  string imagename = ""
    +
    146  string tracename = ""
    +
    147  string info
    +
    148 
    +
    149  for (ic = 0; ic < nc; ic += 1)
    +
    150  sc = num2char(char2num("A") + ic)
    +
    151  wave /z wc = CsrWaveRef($sc, win)
    +
    152  info = CsrInfo($sc, win)
    +
    153  tracename = StringByKey("TNAME", info, ":", ";")
    +
    154  if (waveexists(wc) && (wavedims(wc) == 2))
    +
    155  if (!waveexists(image))
    +
    156  wave image = wc
    +
    157  imagename = tracename
    +
    158  endif
    +
    159  if (cmpstr(tracename, imagename) == 0)
    +
    160  positions[np] = pcsr($sc, win)
    +
    161  np += 1
    +
    162  endif
    +
    163  endif
    +
    164  endfor
    +
    165 
    +
    166  np = floor(np / 2) * 2 // ignore odd cursor
    +
    167  redimension /n=(np) positions
    +
    168  sort positions, positions
    +
    169  // shift upper positions by one so that the rightmost pixel becomes 1.0
    +
    170  positions = p >= np / 2 ? positions + 1 : positions
    +
    171  positions = positions / dimsize(image, 0)
    +
    172 
    +
    173  // map innermost cursor pair to peak center and size
    +
    174  variable ip2 = np / 2
    +
    175  variable ip1 = ip2 - 1
    +
    176  variable Cpos
    +
    177  variable Csize
    +
    178  if (ip1 >= 0)
    +
    179  Cpos = (positions[ip1] + positions[ip2]) / 2
    +
    180  Csize = positions[ip2] - positions[ip1]
    +
    181  else
    +
    182  // default: a small region in the center
    +
    183  Cpos = 0.5
    +
    184  Csize = 0.2
    +
    185  endif
    +
    186 
    +
    187  // background region
    +
    188  ip1 -= 1
    +
    189  ip2 += 1
    +
    190  variable Lsize
    +
    191  variable Hsize
    +
    192  if (ip1 >= 0)
    +
    193  Lsize = positions[ip1]
    +
    194  Hsize = 1 - positions[ip2]
    +
    195  else
    +
    196  // default: everything outside the peak region
    +
    197  Lsize = Cpos - Csize / 2
    +
    198  Hsize = 1 - (Cpos + Csize / 2)
    +
    199  endif
    +
    200 
    +
    201  // crop region
    +
    202  ip1 -= 1
    +
    203  ip2 += 1
    +
    204  variable Lcrop = 0
    +
    205  variable Hcrop = 0
    +
    206  if (ip1 >= 0)
    +
    207  Lcrop = positions[ip1]
    +
    208  Hcrop = 1 - positions[ip2]
    +
    209  else
    +
    210  // default: in fixed mode: dark corners of the EW4000 at PEARL, 0 otherwise
    +
    211  if (dimsize(image, 0) >= 992)
    +
    212  Lcrop = 0.11
    +
    213  Hcrop = 0.11
    +
    214  endif
    +
    215  endif
    +
    216  Lsize = max(Lsize - Lcrop, 0)
    +
    217  Hsize = max(Hsize - Hcrop, 0)
    +
    218 
    +
    219  string param = ""
    +
    220  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
    +
    221  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
    +
    222  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
    +
    223  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
    +
    224  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
    +
    225  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
    +
    226 
    +
    227  return param
    +
    228 end
    +
    229 
    +
    262 threadsafe function /wave int_linbg_reduction(source, param)
    +
    263  wave source
    +
    264  string &param
    +
    265 
    +
    266  variable nx = dimsize(source, 0)
    +
    267  variable ny = dimsize(source, 1)
    +
    268 
    +
    269  // read parameters
    +
    270  variable lcrop = NumberByKey("Lcrop", param, "=", ";")
    +
    271  variable lsize = NumberByKey("Lsize", param, "=", ";")
    +
    272  variable hcrop = NumberByKey("Hcrop", param, "=", ";")
    +
    273  variable hsize = NumberByKey("Hsize", param, "=", ";")
    +
    274  variable cpos = NumberByKey("Cpos", param, "=", ";")
    +
    275  variable csize = NumberByKey("Csize", param, "=", ";")
    +
    276 
    +
    277  make /wave /free /n=2 result_waves
    +
    278  make /free /n=0 dest1, dest2
    +
    279  result_waves[0] = dest1
    +
    280  result_waves[1] = dest2
    +
    281  adh5_setup_profile(source, dest1, 1)
    +
    282  adh5_setup_profile(source, dest2, 1)
    +
    283 
    +
    284  // validate parameters
    +
    285  // background parameters are optional, center parameter is required.
    +
    286  if (numtype(lcrop) != 0)
    +
    287  lcrop = 0
    +
    288  endif
    +
    289  if (numtype(lsize) != 0)
    +
    290  lsize = 0
    +
    291  endif
    +
    292  if (numtype(hcrop) != 0)
    +
    293  hcrop = 0
    +
    294  endif
    +
    295  if (numtype(hsize) != 0)
    +
    296  hsize = 0
    +
    297  endif
    +
    298  if (numtype(Cpos) != 0)
    +
    299  redimension /n=0 result_waves
    +
    300  return result_waves // Cpos parameter missing
    +
    301  endif
    +
    302  if (numtype(Csize) != 0)
    +
    303  redimension /n=0 result_waves
    +
    304  return result_waves // Csize parameter missing
    +
    305  endif
    +
    306 
    +
    307  variable lpos = lcrop + lsize / 2
    +
    308  variable hpos = 1 - (hcrop + hsize / 2)
    +
    309 
    +
    310  variable p0
    +
    311  variable p1
    +
    312 
    +
    313  duplicate /free dest1, lbg, hbg
    +
    314  if (lsize > 0)
    +
    315  p0 = round(lcrop * nx)
    +
    316  p1 = round((lcrop + lsize) * nx)
    +
    317  ad_profile_y_w(source, p0, p1, lbg)
    +
    318  else
    +
    319  lbg = 0
    +
    320  endif
    +
    321  if (hsize > 0)
    +
    322  p0 = round((1 - hcrop - hsize) * nx)
    +
    323  p1 = round((1 - hcrop) * nx)
    +
    324  ad_profile_y_w(source, p0, p1, hbg)
    +
    325  else
    +
    326  hbg = 0
    +
    327  endif
    +
    328  if (csize > 0)
    +
    329  p0 = round((cpos - csize/2) * nx)
    +
    330  p1 = round((cpos + csize/2) * nx)
    +
    331  ad_profile_y_w(source, p0, p1, dest1)
    +
    332  else
    +
    333  dest1 = 0
    +
    334  endif
    +
    335 
    +
    336  variable scale = (cpos - lpos) / (hpos - lpos)
    +
    337  dest2 = dest1
    +
    338  dest1 -= scale * (hbg - lbg) + lbg
    +
    339  dest2 = sqrt(dest2 + scale^2 * (hbg + lbg))
    +
    340 
    +
    341  string s_note1
    +
    342  string s_note2
    +
    343  sprintf s_note1, "AxisLabelD=peak integral"
    +
    344  sprintf s_note2, "KineticEnergy=%.3f", cpos * nx * dimdelta(source, 0) + dimoffset(source, 0)
    +
    345  Note dest1, s_note1
    +
    346  Note dest1, s_note2
    +
    347  Note dest2, s_note1
    +
    348  Note dest2, s_note2
    +
    349 
    +
    350  return result_waves
    +
    351 end
    +
    352 
    + +
    354  string &param
    +
    355 
    +
    356  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
    +
    357  variable Lsize = NumberByKey("Lsize", param, "=", ";")
    +
    358  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
    +
    359  variable Hsize = NumberByKey("Hsize", param, "=", ";")
    +
    360  variable Cpos = NumberByKey("Cpos", param, "=", ";")
    +
    361  variable Csize = NumberByKey("Csize", param, "=", ";")
    +
    362 
    +
    363  prompt Lcrop, "Lower cropping region"
    +
    364  prompt Hcrop, "Upper cropping region"
    +
    365  prompt Lsize, "Lower background region"
    +
    366  prompt Hsize, "Upper background region"
    +
    367  prompt Cpos, "Center position"
    +
    368  prompt Csize, "Center integration region"
    +
    369 
    +
    370  doprompt "int_quadbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
    +
    371  if (v_flag == 0)
    +
    372  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
    +
    373  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
    +
    374  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
    +
    375  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
    +
    376  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
    +
    377  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
    +
    378  endif
    +
    379 
    +
    380  return v_flag
    +
    381 end
    +
    382 
    +
    415 threadsafe function /wave int_quadbg_reduction(source, param)
    +
    416  wave source
    +
    417  string &param
    +
    418 
    +
    419  variable nx = dimsize(source, 0)
    +
    420  variable ny = dimsize(source, 1)
    +
    421 
    +
    422  // read parameters
    +
    423  variable lcrop = NumberByKey("Lcrop", param, "=", ";")
    +
    424  variable lsize = NumberByKey("Lsize", param, "=", ";")
    +
    425  variable hcrop = NumberByKey("Hcrop", param, "=", ";")
    +
    426  variable hsize = NumberByKey("Hsize", param, "=", ";")
    +
    427  variable cpos = NumberByKey("Cpos", param, "=", ";")
    +
    428  variable csize = NumberByKey("Csize", param, "=", ";")
    +
    429 
    +
    430  make /wave /free /n=2 result_waves
    +
    431  make /free /n=0 dest1, dest2
    +
    432  result_waves[0] = dest1
    +
    433  result_waves[1] = dest2
    +
    434  adh5_setup_profile(source, dest1, 1)
    +
    435  adh5_setup_profile(source, dest2, 1)
    +
    436 
    +
    437  // validate parameters
    +
    438  // background parameters are optional, center parameter is required.
    +
    439  if (numtype(lcrop) != 0)
    +
    440  lcrop = 0
    +
    441  endif
    +
    442  if (numtype(lsize) != 0)
    +
    443  lsize = 0
    +
    444  endif
    +
    445  if (numtype(hcrop) != 0)
    +
    446  hcrop = 0
    +
    447  endif
    +
    448  if (numtype(hsize) != 0)
    +
    449  hsize = 0
    +
    450  endif
    +
    451  if (numtype(Cpos) != 0)
    +
    452  redimension /n=0 result_waves
    +
    453  return result_waves // Cpos parameter missing
    +
    454  endif
    +
    455  if (numtype(Csize) != 0)
    +
    456  redimension /n=0 result_waves
    +
    457  return result_waves // Csize parameter missing
    +
    458  endif
    +
    459 
    +
    460  // crop boundaries
    +
    461  variable pcl = round(lcrop * nx)
    +
    462  variable pch = round((1 - hcrop) * nx)
    +
    463  // fit boundaries
    +
    464  variable pfl = round((lcrop + lsize) * nx)
    +
    465  variable pfh = round((1 - hcrop - hsize) * nx)
    +
    466  // integration boundaries
    +
    467  variable pil = round((cpos - csize/2) * nx)
    +
    468  variable pih = round((cpos + csize/2) * nx)
    +
    469 
    +
    470  // prepare intermediate data buffer
    +
    471  make /n=(nx) /d /free profile, mask, fit
    +
    472  setscale /p x dimoffset(source,0), dimdelta(source,0), waveunits(source,0), profile, mask, fit
    +
    473  mask = ((p >= pcl) && (p < pfl)) || ((p >= pfh) && (p < pch))
    +
    474 
    +
    475  variable qq
    +
    476  variable sp, sf
    +
    477  variable xil = x2pnt(profile, pil)
    +
    478  variable xih = x2pnt(profile, pih)
    +
    479 
    +
    480  make /n=3 /free /d w_coef
    +
    481  for (qq = 0; qq < ny; qq += 1)
    +
    482  profile = source[p][qq]
    +
    483  curvefit /Q /NTHR=1 /W=2 poly 3, kwCWave=w_coef, profile /M=mask
    +
    484  fit = poly(w_coef, x)
    +
    485  sp = sum(profile, xil, xih)
    +
    486  sf = sum(fit, xil, xih)
    +
    487  dest1[qq] = sp - sf
    +
    488  dest2[qq] = sqrt(sp)
    +
    489  endfor
    +
    490 
    +
    491  string s_note1
    +
    492  string s_note2
    +
    493  sprintf s_note1, "AxisLabelD=peak integral"
    +
    494  sprintf s_note2, "KineticEnergy=%.3f", cpos * nx * dimdelta(source, 0) + dimoffset(source, 0)
    +
    495  Note dest1, s_note1
    +
    496  Note dest1, s_note2
    +
    497  Note dest2, s_note1
    +
    498  Note dest2, s_note2
    +
    499 
    +
    500  return result_waves
    +
    501 end
    +
    502 
    + +
    512  string &param
    +
    513 
    +
    514  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
    +
    515  variable Lsize = NumberByKey("Lsize", param, "=", ";")
    +
    516  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
    +
    517  variable Hsize = NumberByKey("Hsize", param, "=", ";")
    +
    518  variable Cpos = NumberByKey("Cpos", param, "=", ";")
    +
    519  variable Csize = NumberByKey("Csize", param, "=", ";")
    +
    520 
    +
    521  prompt Lcrop, "Lower cropping region"
    +
    522  prompt Hcrop, "Upper cropping region"
    +
    523  prompt Lsize, "Lower background region"
    +
    524  prompt Hsize, "Upper background region"
    +
    525  prompt Cpos, "Center position"
    +
    526  prompt Csize, "Center integration region"
    +
    527 
    +
    528  doprompt "redim_linbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
    +
    529  if (v_flag == 0)
    +
    530  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
    +
    531  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
    +
    532  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
    +
    533  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
    +
    534  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
    +
    535  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
    +
    536  endif
    +
    537 
    +
    538  return v_flag
    +
    539 end
    +
    540 
    +
    574 threadsafe function /wave redim_linbg_reduction(source, param)
    +
    575  wave source
    +
    576  string &param
    +
    577 
    +
    578  variable nx = dimsize(source, 0)
    +
    579  variable ny = dimsize(source, 1)
    +
    580 
    +
    581  duplicate /free source, source_redim
    +
    582  redimension /n=(nx * ny) source_redim
    +
    583  nx += 1
    +
    584  redimension /n=(nx, ny) source_redim
    +
    585 
    +
    586  return int_linbg_reduction(source_redim, param)
    +
    587 end
    +
    588 
    +
    594 function test_gauss4_reduction(image)
    +
    595  wave image
    +
    596 
    +
    597  string param = ""
    +
    598 
    +
    599  param = ReplaceNumberByKey("rngl", param, -inf, "=", ";")
    +
    600  param = ReplaceNumberByKey("rngh", param, inf, "=", ";")
    +
    601  param = ReplaceNumberByKey("npeaks", param, 4, "=", ";")
    +
    602  param = ReplaceNumberByKey("ybox", param, 1, "=", ";")
    +
    603  param = ReplaceNumberByKey("pos1", param, 11, "=", ";")
    +
    604  param = ReplaceNumberByKey("wid1", param, 0.1, "=", ";")
    +
    605  param = ReplaceNumberByKey("pos2", param, 12, "=", ";")
    +
    606  param = ReplaceNumberByKey("wid2", param, 0.2, "=", ";")
    +
    607  param = ReplaceNumberByKey("pos3", param, 13, "=", ";")
    +
    608  param = ReplaceNumberByKey("wid3", param, 0.3, "=", ";")
    +
    609  param = ReplaceNumberByKey("pos4", param, 14, "=", ";")
    +
    610  param = ReplaceNumberByKey("wid4", param, 0.4, "=", ";")
    +
    611 
    +
    612  wave /wave results = gauss4_reduction(image, param)
    +
    613 
    +
    614  variable npk = numpnts(results) / 2
    +
    615  variable ipk
    +
    616  string sw
    +
    617  for (ipk = 0; ipk < npk; ipk += 1)
    +
    618  sw = "test_int_" + num2str(ipk + 1)
    +
    619  duplicate /o results[ipk], $sw
    +
    620  sw = "test_sig_" + num2str(ipk + 1)
    +
    621  duplicate /o results[ipk + npk], $sw
    +
    622  endfor
    +
    623 end
    +
    624 
    +
    628 function prompt_gauss4_reduction(param)
    +
    629  string &param
    +
    630 
    +
    631  variable rngl = NumberByKey("rngl", param, "=", ";")
    +
    632  variable rngh = NumberByKey("rngh", param, "=", ";")
    +
    633  variable pos1 = NumberByKey("pos1", param, "=", ";")
    +
    634  variable wid1 = NumberByKey("wid1", param, "=", ";")
    +
    635  variable pos2 = NumberByKey("pos2", param, "=", ";")
    +
    636  variable wid2 = NumberByKey("wid2", param, "=", ";")
    +
    637  variable pos3 = NumberByKey("pos3", param, "=", ";")
    +
    638  variable wid3 = NumberByKey("wid3", param, "=", ";")
    +
    639  variable pos4 = NumberByKey("pos4", param, "=", ";")
    +
    640  variable wid4 = NumberByKey("wid4", param, "=", ";")
    +
    641  variable npeaks = NumberByKey("npeaks", param, "=", ";")
    +
    642  variable ybox = NumberByKey("ybox", param, "=", ";")
    +
    643 
    +
    644  prompt rngl, "range low"
    +
    645  prompt rngh, "range high"
    +
    646  prompt pos1, "position 1"
    +
    647  prompt wid1, "width 1"
    +
    648  prompt pos2, "position 2"
    +
    649  prompt wid2, "width 2"
    +
    650  prompt pos3, "position 3"
    +
    651  prompt wid3, "width 3"
    +
    652  prompt pos4, "position 4"
    +
    653  prompt wid4, "width 4"
    +
    654  prompt npeaks, "number of peaks"
    +
    655  prompt ybox, "ybox (1 or 3)"
    +
    656 
    +
    657  doprompt "gauss4_reduction reduction parameters (1/2)", rngl, rngh, npeaks, ybox
    +
    658  if (v_flag == 0)
    +
    659  param = ReplaceNumberByKey("rngl", param, rngl, "=", ";")
    +
    660  param = ReplaceNumberByKey("rngh", param, rngh, "=", ";")
    +
    661  param = ReplaceNumberByKey("npeaks", param, npeaks, "=", ";")
    +
    662  param = ReplaceNumberByKey("ybox", param, ybox, "=", ";")
    +
    663 
    +
    664  doprompt "gauss4_reduction reduction parameters (2/2)", pos1, wid1, pos2, wid2, pos3, wid3, pos4, wid4
    +
    665  if (v_flag == 0)
    +
    666  param = ReplaceNumberByKey("pos1", param, pos1, "=", ";")
    +
    667  param = ReplaceNumberByKey("wid1", param, wid1, "=", ";")
    +
    668  param = ReplaceNumberByKey("pos2", param, pos2, "=", ";")
    +
    669  param = ReplaceNumberByKey("wid2", param, wid2, "=", ";")
    +
    670  param = ReplaceNumberByKey("pos3", param, pos3, "=", ";")
    +
    671  param = ReplaceNumberByKey("wid3", param, wid3, "=", ";")
    +
    672  param = ReplaceNumberByKey("pos4", param, pos4, "=", ";")
    +
    673  param = ReplaceNumberByKey("wid4", param, wid4, "=", ";")
    +
    674  endif
    +
    675  endif
    +
    676 
    +
    677  return v_flag
    +
    678 end
    +
    679 
    +
    720 threadsafe function /wave gauss4_reduction(source, param)
    +
    721  wave source
    +
    722  string &param
    +
    723 
    +
    724  variable nx = dimsize(source, 0)
    +
    725  variable ny = dimsize(source, 1)
    +
    726 
    +
    727  // read parameters
    +
    728  variable rngl = NumberByKey("rngl", param, "=", ";")
    +
    729  variable rngh = NumberByKey("rngh", param, "=", ";")
    +
    730  variable pos1 = NumberByKey("pos1", param, "=", ";")
    +
    731  variable wid1 = NumberByKey("wid1", param, "=", ";")
    +
    732  variable pos2 = NumberByKey("pos2", param, "=", ";")
    +
    733  variable wid2 = NumberByKey("wid2", param, "=", ";")
    +
    734  variable pos3 = NumberByKey("pos3", param, "=", ";")
    +
    735  variable wid3 = NumberByKey("wid3", param, "=", ";")
    +
    736  variable pos4 = NumberByKey("pos4", param, "=", ";")
    +
    737  variable wid4 = NumberByKey("wid4", param, "=", ";")
    +
    738  variable npeaks = NumberByKey("npeaks", param, "=", ";")
    +
    739  variable ybox = NumberByKey("ybox", param, "=", ";")
    +
    740 
    +
    741  // prepare curve fit
    +
    742  variable ipk
    +
    743  make /free xprof
    +
    744  adh5_setup_profile(source, xprof, 0)
    +
    745  duplicate /free xprof, xprof_sig
    +
    746  variable pl = max(x2pnt(xprof, rngl), 0)
    +
    747  variable ph = min(x2pnt(xprof, rngh), numpnts(xprof) - 1)
    +
    748 
    +
    749  make /free /n=(npeaks) peak_coef
    +
    750  peak_coef = p * 3 + 2
    +
    751  variable n_coef = npeaks * 3 + 2
    +
    752  make /free /d /n=14 w_coef, W_sigma
    +
    753  w_coef[0] = {0, 0, 1, pos1, wid1, 1, pos2, wid2, 1, pos3, wid3, 1, pos4, wid4}
    +
    754  redimension /n=(n_coef) w_coef, w_sigma
    +
    755 
    +
    756  // text constraints cannot be used in threadsafe functions.
    +
    757  // the following matrix-vector forumlation is equivalent to:
    +
    758  // make /free /T /N=6 constraints
    +
    759  // constraints[0] = {"K2 >= 0", "K5 >= 0", "K8 >= 0", "K11 >= 0", "K1 <= 0", "K0 => 0"}
    +
    760  make /free /n=(npeaks + 2, numpnts(w_coef)) cmat
    +
    761  make /free /n=(npeaks + 2) cvec
    +
    762  cmat = 0
    +
    763  cmat[0][0] = -1
    +
    764  cmat[1][1] = 1
    +
    765  cvec = 0
    +
    766 
    +
    767  string hold = "00"
    +
    768  for (ipk=0; ipk < npeaks; ipk += 1)
    +
    769  hold += "011"
    +
    770  cmat[2 + ipk][2 + ipk*3] = -1
    +
    771  endfor
    +
    772 
    +
    773  // prepare output
    +
    774  make /free /n=(npeaks * 2) /wave result_waves
    +
    775  string s_note
    +
    776  for (ipk = 0; ipk < npeaks; ipk += 1)
    +
    777  make /free /n=0 pk_int
    +
    778  adh5_setup_profile(source, pk_int, 1)
    +
    779  pk_int = nan
    +
    780  sprintf s_note, "AxisLabelD=peak %u integral", ipk+1
    +
    781  Note pk_int, s_note
    +
    782  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * 3]
    +
    783  Note pk_int, s_note
    +
    784  result_waves[ipk] = pk_int
    +
    785 
    +
    786  make /free /n=0 pk_sig
    +
    787  adh5_setup_profile(source, pk_sig, 1)
    +
    788  pk_sig = nan
    +
    789  sprintf s_note, "AxisLabelD=peak %u sigma", ipk+1
    +
    790  Note pk_sig, s_note
    +
    791  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * 3]
    +
    792  Note pk_sig, s_note
    +
    793  result_waves[ipk + npeaks] = pk_sig
    +
    794 
    +
    795  waveclear pk_int, pk_sig
    +
    796  endfor
    +
    797 
    +
    798  // loop over angle scale
    +
    799  variable p0 = 0
    +
    800  variable p1 = dimsize(source, 1) - 1
    +
    801  variable pp
    +
    802  variable wmin
    +
    803  variable wmax
    +
    804  if (ybox > 1)
    +
    805  p0 += ceil((ybox - 1) / 2)
    +
    806  p1 -= ceil((ybox - 1) / 2)
    +
    807  endif
    +
    808  variable V_FitNumIters
    +
    809  variable V_FitError
    +
    810 
    +
    811  for (pp = p0; pp <= p1; pp += 1)
    +
    812  // box average
    +
    813  xprof = source[p][pp]
    +
    814  if (ybox > 1)
    +
    815  xprof += source[p][pp-1] + source[p][pp+1]
    +
    816  endif
    +
    817  xprof_sig = max(sqrt(xprof), 1)
    +
    818  xprof /= ybox
    +
    819  xprof_sig /= ybox
    +
    820 
    +
    821  // generate guess
    +
    822  wmin = wavemin(xprof)
    +
    823  wmax = wavemax(xprof)
    +
    824  w_coef[0] = wmin
    +
    825  w_coef[1] = 0
    +
    826  for (ipk=0; ipk < npeaks; ipk += 1)
    +
    827  w_coef[2 + ipk*3] = wmax - wmin
    +
    828  endfor
    +
    829 
    +
    830  V_FitError = 0
    +
    831  FuncFit /H=hold /Q /NTHR=1 /N /W=2 MultiGaussLinBG_AO w_coef xprof[pl,ph] /C={cmat, cvec} /I=1 /W=xprof_sig[pl,ph]
    +
    832  wave w_sigma
    +
    833 
    +
    834  // retrieve results, leave them at nan if the fit did not converge
    +
    835  if (V_FitNumIters < 40)
    +
    836  for (ipk = 0; ipk < npeaks; ipk += 1)
    +
    837  wave val = result_waves[ipk]
    +
    838  wave sig = result_waves[ipk + npeaks]
    +
    839  val[pp] = max(w_coef[peak_coef[ipk]], 0)
    +
    840  sig[pp] = max(w_sigma[peak_coef[ipk]], 0)
    +
    841  endfor
    +
    842  endif
    +
    843  endfor
    +
    844 
    +
    845  // calculate integral
    +
    846  for (ipk = 0; ipk < npeaks; ipk += 1)
    +
    847  wave val = result_waves[ipk]
    +
    848  wave sig = result_waves[ipk + npeaks]
    +
    849  val *= w_coef[peak_coef[ipk] + 2] * sqrt(pi)
    +
    850  sig *= w_coef[peak_coef[ipk] + 2] * sqrt(pi)
    +
    851  endfor
    +
    852 
    +
    853  return result_waves
    +
    854 end
    +
    855 
    +
    856 threadsafe function /wave gauss6_reduction(source, param)
    +
    857  wave source
    +
    858  string &param
    +
    859 
    +
    860  variable nx = dimsize(source, 0)
    +
    861  variable ny = dimsize(source, 1)
    +
    862 
    +
    863  // read parameters
    +
    864  variable rngl = NumberByKey("rngl", param, "=", ";")
    +
    865  variable rngh = NumberByKey("rngh", param, "=", ";")
    +
    866  variable pos1 = NumberByKey("pos1", param, "=", ";")
    +
    867  variable wid1 = NumberByKey("wid1", param, "=", ";")
    +
    868  variable pos2 = NumberByKey("pos2", param, "=", ";")
    +
    869  variable wid2 = NumberByKey("wid2", param, "=", ";")
    +
    870  variable pos3 = NumberByKey("pos3", param, "=", ";")
    +
    871  variable wid3 = NumberByKey("wid3", param, "=", ";")
    +
    872  variable pos4 = NumberByKey("pos4", param, "=", ";")
    +
    873  variable wid4 = NumberByKey("wid4", param, "=", ";")
    +
    874  variable pos5 = NumberByKey("pos5", param, "=", ";")
    +
    875  variable wid5 = NumberByKey("wid5", param, "=", ";")
    +
    876  variable pos6 = NumberByKey("pos6", param, "=", ";")
    +
    877  variable wid6 = NumberByKey("wid6", param, "=", ";")
    +
    878  variable npeaks = NumberByKey("npeaks", param, "=", ";")
    +
    879  variable ybox = NumberByKey("ybox", param, "=", ";")
    +
    880 
    +
    881  // prepare curve fit
    +
    882  variable ipk
    +
    883  make /free xprof
    +
    884  adh5_setup_profile(source, xprof, 0)
    +
    885  duplicate /free xprof, xprof_sig
    +
    886  variable pl = max(x2pnt(xprof, rngl), 0)
    +
    887  variable ph = min(x2pnt(xprof, rngh), numpnts(xprof) - 1)
    +
    888 
    +
    889  make /free /n=(npeaks) peak_coef
    +
    890  peak_coef = p * 3 + 2
    +
    891  variable n_coef = npeaks * 3 + 2
    +
    892  make /free /d /n=(n_coef) w_coef, W_sigma
    +
    893  w_coef[0] = {0, 0, 1, pos1, wid1, 1, pos2, wid2, 1, pos3, wid3, 1, pos4, wid4, 1, pos5, wid5, 1, pos6, wid6}
    +
    894  redimension /n=(n_coef) w_coef, w_sigma
    +
    895 
    +
    896  // text constraints cannot be used in threadsafe functions.
    +
    897  // the following matrix-vector forumlation is equivalent to:
    +
    898  // make /free /T /N=6 constraints
    +
    899  // constraints[0] = {"K2 >= 0", "K5 >= 0", "K8 >= 0", "K11 >= 0", "K1 <= 0", "K0 => 0"}
    +
    900  make /free /n=(npeaks + 2, numpnts(w_coef)) cmat
    +
    901  make /free /n=(npeaks + 2) cvec
    +
    902  cmat = 0
    +
    903  cmat[0][0] = -1
    +
    904  cmat[1][1] = 1
    +
    905  cvec = 0
    +
    906 
    +
    907  string hold = "00"
    +
    908  for (ipk=0; ipk < npeaks; ipk += 1)
    +
    909  hold += "011"
    +
    910  cmat[2 + ipk][2 + ipk*3] = -1
    +
    911  endfor
    +
    912 
    +
    913  // prepare output
    +
    914  make /free /n=(npeaks * 2) /wave result_waves
    +
    915  string s_note
    +
    916  for (ipk = 0; ipk < npeaks; ipk += 1)
    +
    917  make /free /n=0 pk_int
    +
    918  adh5_setup_profile(source, pk_int, 1)
    +
    919  pk_int = nan
    +
    920  sprintf s_note, "AxisLabelD=peak %u integral", ipk+1
    +
    921  Note pk_int, s_note
    +
    922  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * 3]
    +
    923  Note pk_int, s_note
    +
    924  result_waves[ipk] = pk_int
    +
    925 
    +
    926  make /free /n=0 pk_sig
    +
    927  adh5_setup_profile(source, pk_sig, 1)
    +
    928  pk_sig = nan
    +
    929  sprintf s_note, "AxisLabelD=peak %u sigma", ipk+1
    +
    930  Note pk_sig, s_note
    +
    931  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * 3]
    +
    932  Note pk_sig, s_note
    +
    933  result_waves[ipk + npeaks] = pk_sig
    +
    934 
    +
    935  waveclear pk_int, pk_sig
    +
    936  endfor
    +
    937 
    +
    938  // loop over angle scale
    +
    939  variable p0 = 0
    +
    940  variable p1 = dimsize(source, 1) - 1
    +
    941  variable pp
    +
    942  variable wmin
    +
    943  variable wmax
    +
    944  if (ybox > 1)
    +
    945  p0 += ceil((ybox - 1) / 2)
    +
    946  p1 -= ceil((ybox - 1) / 2)
    +
    947  endif
    +
    948  variable V_FitNumIters
    +
    949  variable V_FitError
    +
    950 
    +
    951  for (pp = p0; pp <= p1; pp += 1)
    +
    952  // box average
    +
    953  xprof = source[p][pp]
    +
    954  if (ybox > 1)
    +
    955  xprof += source[p][pp-1] + source[p][pp+1]
    +
    956  endif
    +
    957  xprof_sig = max(sqrt(xprof), 1)
    +
    958  xprof /= ybox
    +
    959  xprof_sig /= ybox
    +
    960 
    +
    961  // generate guess
    +
    962  wmin = wavemin(xprof)
    +
    963  wmax = wavemax(xprof)
    +
    964  w_coef[0] = wmin
    +
    965  w_coef[1] = 0
    +
    966  for (ipk=0; ipk < npeaks; ipk += 1)
    +
    967  w_coef[2 + ipk*3] = wmax - wmin
    +
    968  endfor
    +
    969 
    +
    970  V_FitError = 0
    +
    971  FuncFit /H=hold /Q /NTHR=1 /N /W=2 MultiGaussLinBG_AO w_coef xprof[pl,ph] /C={cmat, cvec} /I=1 /W=xprof_sig[pl,ph]
    +
    972  wave w_sigma
    +
    973 
    +
    974  // retrieve results, leave them at nan if the fit did not converge
    +
    975  if (V_FitNumIters < 40)
    +
    976  for (ipk = 0; ipk < npeaks; ipk += 1)
    +
    977  wave val = result_waves[ipk]
    +
    978  wave sig = result_waves[ipk + npeaks]
    +
    979  val[pp] = max(w_coef[peak_coef[ipk]], 0)
    +
    980  sig[pp] = max(w_sigma[peak_coef[ipk]], 0)
    +
    981  endfor
    +
    982  endif
    +
    983  endfor
    +
    984 
    +
    985  // calculate integral
    +
    986  for (ipk = 0; ipk < npeaks; ipk += 1)
    +
    987  wave val = result_waves[ipk]
    +
    988  wave sig = result_waves[ipk + npeaks]
    +
    989  val *= w_coef[peak_coef[ipk] + 2] * sqrt(pi)
    +
    990  sig *= w_coef[peak_coef[ipk] + 2] * sqrt(pi)
    +
    991  endfor
    +
    992 
    +
    993  return result_waves
    +
    994 end
    +
    995 
    +
    996 
    +
    997 
    +
    998 
    +
    1030 function /s find_gauss4_reduction_params(spectrum, peakpos)
    +
    1031  wave spectrum
    +
    1032  wave peakpos
    +
    1033  string param = ""
    +
    1034 
    +
    1035  variable wmin = wavemin(spectrum)
    +
    1036  variable wmax = wavemax(spectrum)
    +
    1037 
    +
    1038  // read parameters
    +
    1039  variable rngl = dimoffset(spectrum, 0)
    +
    1040  variable rngh = dimoffset(spectrum, 0) + dimdelta(spectrum, 0) * (dimsize(spectrum, 0) - 1)
    +
    1041  make /n=4 /free positions, widths
    +
    1042  variable npeaks = numpnts(peakpos)
    +
    1043  variable ybox = 1
    +
    1044  positions = 0
    +
    1045  positions[0, npeaks-1] = peakpos[p]
    +
    1046  widths = 0.2
    +
    1047 
    +
    1048  variable n_coef = npeaks * 3 + 2
    +
    1049  make /free /d /n=(n_coef) w_coef
    +
    1050  w_coef = 0
    +
    1051  w_coef[0] = wmin
    +
    1052  w_coef[1] = 0
    +
    1053 
    +
    1054  make /free /n=(2+npeaks, numpnts(w_coef)) cmat
    +
    1055  make /free /n=(2+npeaks) cvec
    +
    1056  cmat = 0
    +
    1057  cmat[0][0] = -1
    +
    1058  cmat[1][1] = 1
    +
    1059  cvec = 0
    +
    1060 
    +
    1061  variable ip
    +
    1062  for (ip=0; ip < npeaks; ip += 1)
    +
    1063  cmat[2 + ip][2 + ip*3] = -1
    +
    1064  w_coef[2 + ip*3] = wmax - wmin
    +
    1065  w_coef[3 + ip*3] = peakpos[ip]
    +
    1066  w_coef[4 + ip*3] = widths[ip]
    +
    1067  endfor
    +
    1068 
    +
    1069  variable V_FitNumIters
    +
    1070  FuncFit /Q /NTHR=1 /N MultiGaussLinBG w_coef spectrum /C={cmat, cvec}
    +
    1071 
    +
    1072  for (ip=0; ip < npeaks; ip += 1)
    +
    1073  positions[ip] = w_coef[3 + ip * 3]
    +
    1074  widths[ip ] = abs(w_coef[4 + ip * 3])
    +
    1075  endfor
    +
    1076  for (ip=npeaks; ip < 4; ip += 1)
    +
    1077  positions[ip] = 0
    +
    1078  widths[ip] = 0.2
    +
    1079  endfor
    +
    1080 
    +
    1081  param = ReplaceNumberByKey("rngl", param, rngl, "=", ";")
    +
    1082  param = ReplaceNumberByKey("rngh", param, rngh, "=", ";")
    +
    1083  param = ReplaceNumberByKey("npeaks", param, npeaks, "=", ";")
    +
    1084  param = ReplaceNumberByKey("ybox", param, ybox, "=", ";")
    +
    1085  param = ReplaceNumberByKey("pos1", param, positions[0], "=", ";")
    +
    1086  param = ReplaceNumberByKey("wid1", param, widths[0], "=", ";")
    +
    1087  param = ReplaceNumberByKey("pos2", param, positions[1], "=", ";")
    +
    1088  param = ReplaceNumberByKey("wid2", param, widths[1], "=", ";")
    +
    1089  param = ReplaceNumberByKey("pos3", param, positions[2], "=", ";")
    +
    1090  param = ReplaceNumberByKey("wid3", param, widths[2], "=", ";")
    +
    1091  param = ReplaceNumberByKey("pos4", param, positions[3], "=", ";")
    +
    1092  param = ReplaceNumberByKey("wid4", param, widths[3], "=", ";")
    +
    1093 
    +
    1094  return param
    +
    1095 end
    +
    1096 
    +
    1138 threadsafe function /wave voigt4_reduction(source, param)
    +
    1139  wave source
    +
    1140  string &param
    +
    1141 
    +
    1142  dfref orig_dfr = GetDataFolderDFR()
    +
    1143 
    +
    1144  variable nx = dimsize(source, 0)
    +
    1145  variable ny = dimsize(source, 1)
    +
    1146 
    +
    1147  // read parameters
    +
    1148  variable rngl = NumberByKey("rngl", param, "=", ";")
    +
    1149  variable rngh = NumberByKey("rngh", param, "=", ";")
    +
    1150  variable pos1 = NumberByKey("pos1", param, "=", ";")
    +
    1151  variable wid1 = NumberByKey("wid1", param, "=", ";")
    +
    1152  variable shp1 = NumberByKey("shp1", param, "=", ";")
    +
    1153  variable pos2 = NumberByKey("pos2", param, "=", ";")
    +
    1154  variable wid2 = NumberByKey("wid2", param, "=", ";")
    +
    1155  variable shp2 = NumberByKey("shp2", param, "=", ";")
    +
    1156  variable pos3 = NumberByKey("pos3", param, "=", ";")
    +
    1157  variable wid3 = NumberByKey("wid3", param, "=", ";")
    +
    1158  variable shp3 = NumberByKey("shp3", param, "=", ";")
    +
    1159  variable pos4 = NumberByKey("pos4", param, "=", ";")
    +
    1160  variable wid4 = NumberByKey("wid4", param, "=", ";")
    +
    1161  variable shp4 = NumberByKey("shp4", param, "=", ";")
    +
    1162  variable npeaks = NumberByKey("npeaks", param, "=", ";")
    +
    1163 
    +
    1164  // prepare curve fit
    +
    1165  variable ipk
    +
    1166  make /free xprof
    +
    1167  adh5_setup_profile(source, xprof, 0)
    +
    1168  duplicate /free xprof, xprof_sig
    +
    1169  variable pl = max(x2pnt(xprof, rngl), 0)
    +
    1170  variable ph = min(x2pnt(xprof, rngh), numpnts(xprof) - 1)
    +
    1171 
    +
    1172  make /free /n=(npeaks) peak_coef
    +
    1173  variable coef_per_peak = 4
    +
    1174  peak_coef = p * coef_per_peak + 2
    +
    1175  variable n_coef = npeaks * coef_per_peak + 2
    +
    1176  make /free /d /n=18 w_coef, W_sigma
    +
    1177  w_coef[0] = {0, 0, 1, pos1, wid1, shp1, 1, pos2, wid2, shp2, 1, pos3, wid3, shp3, 1, pos4, wid4, shp4}
    +
    1178  redimension /n=(n_coef) w_coef, w_sigma
    +
    1179 
    +
    1180  // text constraints cannot be used in threadsafe functions.
    +
    1181  // the following matrix-vector formulation enforces all peak amplitudes to be positive.
    +
    1182  make /free /n=(npeaks, numpnts(w_coef)) cmat
    +
    1183  make /free /n=(npeaks) cvec
    +
    1184  cmat = 0
    +
    1185  cvec = 0
    +
    1186 
    +
    1187  string hold = "00"
    +
    1188  for (ipk=0; ipk < npeaks; ipk += 1)
    +
    1189  hold += "0111"
    +
    1190  cmat[ipk][2 + ipk * coef_per_peak] = -1
    +
    1191  endfor
    +
    1192 
    +
    1193  // prepare output
    +
    1194  make /free /n=(npeaks * 2) /wave result_waves
    +
    1195  string s_note
    +
    1196  for (ipk = 0; ipk < npeaks; ipk += 1)
    +
    1197  make /free /n=0 pk_int
    +
    1198  adh5_setup_profile(source, pk_int, 1)
    +
    1199  pk_int = nan
    +
    1200  sprintf s_note, "AxisLabelD=peak %u integral", ipk+1
    +
    1201  Note pk_int, s_note
    +
    1202  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * coef_per_peak]
    +
    1203  Note pk_int, s_note
    +
    1204  result_waves[ipk] = pk_int
    +
    1205 
    +
    1206  make /free /n=0 pk_sig
    +
    1207  adh5_setup_profile(source, pk_sig, 1)
    +
    1208  pk_sig = nan
    +
    1209  sprintf s_note, "AxisLabelD=peak %u sigma", ipk+1
    +
    1210  Note pk_sig, s_note
    +
    1211  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * coef_per_peak]
    +
    1212  Note pk_sig, s_note
    +
    1213  result_waves[ipk + npeaks] = pk_sig
    +
    1214 
    +
    1215  waveclear pk_int, pk_sig
    +
    1216  endfor
    +
    1217 
    +
    1218  // loop over angle scale
    +
    1219  variable p0 = 0
    +
    1220  variable p1 = dimsize(source, 1) - 1
    +
    1221  variable pp
    +
    1222  variable wmin
    +
    1223  variable wmax
    +
    1224  variable V_FitNumIters
    +
    1225  variable V_FitError
    +
    1226 
    +
    1227  for (pp = p0; pp <= p1; pp += 1)
    +
    1228  xprof = source[p][pp]
    +
    1229  xprof_sig = max(sqrt(xprof), 1)
    +
    1230 
    +
    1231  // generate guess
    +
    1232  wmin = wavemin(xprof)
    +
    1233  wmax = wavemax(xprof)
    +
    1234  w_coef[0] = wmin
    +
    1235  w_coef[1] = 0
    +
    1236 
    +
    1237  for (ipk=0; ipk < npeaks; ipk += 1)
    +
    1238  w_coef[2 + ipk * coef_per_peak] = wmax - wmin
    +
    1239  endfor
    +
    1240 
    +
    1241  V_FitError = 0
    +
    1242  FuncFit /H=hold /Q /N /W=2 MultiVoigtLinBG_AO w_coef xprof[pl,ph] /C={cmat, cvec} /I=1 /W=xprof_sig[pl,ph]
    +
    1243  wave w_sigma
    +
    1244 
    +
    1245  // retrieve results, leave them at nan if the fit did not converge
    +
    1246  if (V_FitNumIters < 40)
    +
    1247  for (ipk = 0; ipk < npeaks; ipk += 1)
    +
    1248  wave val = result_waves[ipk]
    +
    1249  wave sig = result_waves[ipk + npeaks]
    +
    1250  val[pp] = max(w_coef[peak_coef[ipk]], 0)
    +
    1251  sig[pp] = max(w_sigma[peak_coef[ipk]], 0)
    +
    1252  endfor
    +
    1253  endif
    +
    1254  endfor
    +
    1255 
    +
    1256  SetDataFolder orig_dfr
    +
    1257  return result_waves
    +
    1258 end
    +
    1259 
    +
    1260 
    +
    1264 function prompt_voigt4_reduction(param)
    +
    1265  string &param
    +
    1266 
    +
    1267  variable rngl = NumberByKey("rngl", param, "=", ";")
    +
    1268  variable rngh = NumberByKey("rngh", param, "=", ";")
    +
    1269  variable pos1 = NumberByKey("pos1", param, "=", ";")
    +
    1270  variable wid1 = NumberByKey("wid1", param, "=", ";")
    +
    1271  variable shp1 = NumberByKey("shp1", param, "=", ";")
    +
    1272  variable pos2 = NumberByKey("pos2", param, "=", ";")
    +
    1273  variable wid2 = NumberByKey("wid2", param, "=", ";")
    +
    1274  variable shp2 = NumberByKey("shp2", param, "=", ";")
    +
    1275  variable pos3 = NumberByKey("pos3", param, "=", ";")
    +
    1276  variable wid3 = NumberByKey("wid3", param, "=", ";")
    +
    1277  variable shp3 = NumberByKey("shp3", param, "=", ";")
    +
    1278  variable pos4 = NumberByKey("pos4", param, "=", ";")
    +
    1279  variable wid4 = NumberByKey("wid4", param, "=", ";")
    +
    1280  variable shp4 = NumberByKey("shp4", param, "=", ";")
    +
    1281  variable npeaks = NumberByKey("npeaks", param, "=", ";")
    +
    1282  variable dummy = nan
    +
    1283 
    +
    1284  prompt rngl, "range low"
    +
    1285  prompt rngh, "range high"
    +
    1286  prompt pos1, "position 1"
    +
    1287  prompt wid1, "width 1"
    +
    1288  prompt shp1, "shape 1"
    +
    1289  prompt pos2, "position 2"
    +
    1290  prompt wid2, "width 2"
    +
    1291  prompt shp2, "shape 2"
    +
    1292  prompt pos3, "position 3"
    +
    1293  prompt wid3, "width 3"
    +
    1294  prompt shp3, "shape 3"
    +
    1295  prompt pos4, "position 4"
    +
    1296  prompt wid4, "width 4"
    +
    1297  prompt shp4, "shape 4"
    +
    1298  prompt npeaks, "number of peaks"
    +
    1299  prompt dummy, "(not used)"
    +
    1300 
    +
    1301  doprompt "voigt4_reduction reduction parameters (1/2)", rngl, rngh, npeaks, dummy, pos1, pos2, pos3, pos4
    +
    1302  if (v_flag == 0)
    +
    1303  param = ReplaceNumberByKey("rngl", param, rngl, "=", ";")
    +
    1304  param = ReplaceNumberByKey("rngh", param, rngh, "=", ";")
    +
    1305  param = ReplaceNumberByKey("npeaks", param, npeaks, "=", ";")
    +
    1306  param = ReplaceNumberByKey("pos1", param, pos1, "=", ";")
    +
    1307  param = ReplaceNumberByKey("pos2", param, pos2, "=", ";")
    +
    1308  param = ReplaceNumberByKey("pos3", param, pos3, "=", ";")
    +
    1309  param = ReplaceNumberByKey("pos4", param, pos4, "=", ";")
    +
    1310 
    +
    1311  doprompt "voigt4_reduction reduction parameters (2/2)", wid1, shp1, wid2, shp2, wid3, shp3, wid4, shp4
    +
    1312  if (v_flag == 0)
    +
    1313  param = ReplaceNumberByKey("wid1", param, wid1, "=", ";")
    +
    1314  param = ReplaceNumberByKey("shp1", param, shp1, "=", ";")
    +
    1315  param = ReplaceNumberByKey("wid2", param, wid2, "=", ";")
    +
    1316  param = ReplaceNumberByKey("shp2", param, shp2, "=", ";")
    +
    1317  param = ReplaceNumberByKey("wid3", param, wid3, "=", ";")
    +
    1318  param = ReplaceNumberByKey("shp3", param, shp3, "=", ";")
    +
    1319  param = ReplaceNumberByKey("wid4", param, wid4, "=", ";")
    +
    1320  param = ReplaceNumberByKey("shp4", param, shp4, "=", ";")
    +
    1321  endif
    +
    1322  endif
    +
    1323 
    +
    1324  return v_flag
    +
    1325 end
    +
    1326 
    +
    1327 
    +
    1335 function test_shockley_anglefit(image, branch)
    +
    1336  wave image
    +
    1337  variable branch
    +
    1338 
    +
    1339  string param = ""
    +
    1340  param = ReplaceStringByKey("branch", param, num2str(branch), "=", ";")
    +
    1341 
    +
    1342  string s_branch
    +
    1343  if (branch >= 0)
    +
    1344  s_branch = "p"
    +
    1345  else
    +
    1346  s_branch = "n"
    +
    1347  endif
    +
    1348  string pkpos_name = "saf_pkpos_" + s_branch
    +
    1349  string pkwid_name = "saf_pkwid_" + s_branch
    +
    1350 
    +
    1351  wave /wave results = shockley_anglefit(image, param)
    +
    1352  duplicate results[0], $pkpos_name
    +
    1353  duplicate results[1], $pkwid_name
    +
    1354 end
    +
    1355 
    +
    1356 function prompt_Shockley_anglefit(param)
    +
    1357  string &param
    +
    1358 
    +
    1359  variable branch = NumberByKey("branch", param, "=", ";")
    +
    1360 
    +
    1361  prompt branch, "Branch (-1 or +1)"
    +
    1362 
    +
    1363  doprompt "Shockley_anglefit_reduction Parameters", branch
    +
    1364  if (v_flag == 0)
    +
    1365  param = ReplaceNumberByKey("branch", param, branch, "=", ";")
    +
    1366  endif
    +
    1367 
    +
    1368  return v_flag
    +
    1369 end
    +
    1370 
    +
    1393 threadsafe function /wave Shockley_anglefit(source, param)
    +
    1394  wave source
    +
    1395  string &param
    +
    1396 
    +
    1397  variable nx = dimsize(source, 0)
    +
    1398  variable ny = dimsize(source, 1)
    +
    1399 
    +
    1400  // read parameters
    +
    1401  variable branch = NumberByKey("branch", param, "=", ";")
    +
    1402 
    +
    1403  // validate parameters
    +
    1404  if (numtype(branch) != 0)
    +
    1405  branch = +1
    +
    1406  endif
    +
    1407 
    +
    1408  // prepare output
    +
    1409  make /wave /free /n=2 result_waves
    +
    1410  make /free /n=0 dest1, dest2
    +
    1411  result_waves[0] = dest1
    +
    1412  result_waves[1] = dest2
    +
    1413  adh5_setup_profile(source, dest1, 0)
    +
    1414  adh5_setup_profile(source, dest2, 0)
    +
    1415  dest1 = nan
    +
    1416  dest2 = nan
    +
    1417 
    +
    1418  // select angle range
    +
    1419  // hard-coded for a particular measurement series
    +
    1420  variable y0
    +
    1421  variable y1
    +
    1422  if (branch < 0)
    +
    1423  y0 = -5
    +
    1424  y1 = 0
    +
    1425  else
    +
    1426  y0 = 0
    +
    1427  y1 = 5
    +
    1428  endif
    +
    1429 
    +
    1430  // select energy range
    +
    1431  // start at the point of highest intensity and go up 0.45 eV
    +
    1432  variable p0
    +
    1433  variable p1
    +
    1434  variable q0
    +
    1435  variable q1
    +
    1436  duplicate /free dest1, center
    +
    1437  q0 = round((y0 - dimoffset(source, 1)) / dimdelta(source, 1))
    +
    1438  q1 = round((y1 - dimoffset(source, 1)) / dimdelta(source, 1))
    +
    1439  ad_profile_x_w(source, q0, q1, center)
    +
    1440  wavestats /q/m=1 center
    +
    1441  p0 = round((v_maxloc - dimoffset(source, 0)) / dimdelta(source, 0))
    +
    1442  p1 = round((v_maxloc + 0.4 - dimoffset(source, 0)) / dimdelta(source, 0))
    +
    1443 
    +
    1444  // prepare intermediate data buffer
    +
    1445  make /n=(ny)/d/free profile
    +
    1446  setscale /p x dimoffset(source,1), dimdelta(source,1), waveunits(source,1), profile
    +
    1447 
    +
    1448  variable pp
    +
    1449  for (pp = p0; pp <= p1; pp += 1)
    +
    1450  profile = source[pp][p]
    +
    1451  curvefit /Q /NTHR=1 /W=2 gauss profile(y0,y1)
    +
    1452  wave w_coef
    +
    1453  dest1[pp] = w_coef[2]
    +
    1454  dest2[pp] = w_coef[3]
    +
    1455  endfor
    +
    1456 
    +
    1457  return result_waves
    +
    1458 end
    +
    1459 
    +
    1460 function scienta_norm(w, x): fitfunc
    +
    1461  wave w
    +
    1462  variable x
    +
    1463 
    +
    1464  return w[0] * (x^2 - w[1]^2)
    +
    1465 end
    +
    1466 
    +
    1467 function /wave fit_scienta_ang_transm(data, params)
    +
    1468  wave data // measured angular distribution (1D)
    +
    1469  wave /z params
    +
    1470 
    +
    1471  if (!waveexists(params))
    +
    1472  make /n=12 /o params
    +
    1473  endif
    +
    1474  redimension /n=12/d params
    +
    1475 
    +
    1476  variable h = wavemax(data) - wavemin(data)
    +
    1477  params[0] = h / 2
    +
    1478  params[1] = 0
    +
    1479  params[2] = 7
    +
    1480  params[3] = h / 4
    +
    1481  params[4] = -23
    +
    1482  params[5] = 4
    +
    1483  params[6] = h / 4
    +
    1484  params[7] = +23
    +
    1485  params[8] = 4
    +
    1486  params[9] = h / 2
    +
    1487  params[10] = 0
    +
    1488  params[11] = -0.001
    +
    1489  FuncFit /NTHR=0 /q scienta_ang_transm params data
    +
    1490 
    +
    1491  return params
    +
    1492 end
    +
    1493 
    +
    1494 threadsafe function scienta_ang_transm(w, x): fitfunc
    +
    1495  // parameterized angular transmission function of the analyser
    +
    1496  wave w // coefficients
    +
    1497  // w[0] = amplitude gauss 1
    +
    1498  // w[1] = position gauss 1
    +
    1499  // w[2] = width gauss 1
    +
    1500  // w[3] = amplitude gauss 2
    +
    1501  // w[4] = position gauss 2
    +
    1502  // w[5] = width gauss 2
    +
    1503  // w[6] = amplitude gauss 3
    +
    1504  // w[7] = position gauss 3
    +
    1505  // w[8] = width gauss 3
    +
    1506  // w[9] = constant background
    +
    1507  // w[10] = linear background
    +
    1508  // w[11] = quadratic background
    +
    1509  variable x
    +
    1510 
    +
    1511  make /free /n=4 /d w_int
    +
    1512  w_int[0] = 0
    +
    1513  w_int[1,] = w[p - 1]
    +
    1514  variable pk1 = gauss1d(w_int, x)
    +
    1515  w_int[1,] = w[p + 2]
    +
    1516  variable pk2 = gauss1d(w_int, x)
    +
    1517  w_int[1,] = w[p + 5]
    +
    1518  variable pk3 = gauss1d(w_int, x)
    +
    1519  w_int[0,2] = w[9 + p]
    +
    1520  w_int[3] = 0
    +
    1521  variable bg = poly(w_int, x)
    +
    1522 
    +
    1523  return bg + pk1 + pk2 + pk3
    +
    1524 end
    +
    1525 
    +
    1526 function /wave fit_scienta_poly_bg(data, params, bgterms)
    +
    1527  wave data // measured distribution (2D)
    +
    1528  wave /z params // wave, will be redimensioned for the correct size
    +
    1529  variable bgterms // number of terms in the polynomial background: 2, 3, or 4
    +
    1530 
    +
    1531  if (!waveexists(params))
    +
    1532  make /n=15 /o params
    +
    1533  endif
    +
    1534  redimension /n=15 /d params
    +
    1535 
    +
    1536  variable wmax = wavemax(data)
    +
    1537  variable wmin = wavemin(data)
    +
    1538  params[0] = 0
    +
    1539  params[1] = 7
    +
    1540  params[2] = 1 / 2
    +
    1541  params[3] = -23
    +
    1542  params[4] = 4
    +
    1543  params[5] = 1 / 2
    +
    1544  params[6] = +23
    +
    1545  params[7] = 4
    +
    1546  params[8] = 1
    +
    1547  params[9] = 0
    +
    1548  params[10] = -0.001
    +
    1549  params[11] = wmin
    +
    1550  params[12] = (wmax - wmin) / dimdelta(data,1) / dimsize(data,1)
    +
    1551  params[13] = 0
    +
    1552  params[14] = 0
    +
    1553 
    +
    1554  string h = "0000000000000"
    +
    1555  if (bgterms < 3)
    +
    1556  h = h + "1"
    +
    1557  else
    +
    1558  h = h + "0"
    +
    1559  endif
    +
    1560  if (bgterms < 4)
    +
    1561  h = h + "1"
    +
    1562  else
    +
    1563  h = h + "0"
    +
    1564  endif
    +
    1565  FuncFitMD /NTHR=1 /q /h=h scienta_poly_bg params data
    +
    1566 
    +
    1567  return params
    +
    1568 end
    +
    1569 
    +
    1570 function scienta_poly_bg(w, e, a): fitfunc
    +
    1571  // polynomial background with
    +
    1572  // parameterized angular transmission function of the analyser
    +
    1573  wave w // coefficients
    +
    1574  // angular transmission, varies with a
    +
    1575  // amplitude of gauss 1 = 1 constant
    +
    1576  // other peak amplitudes and linear terms are relative to gauss 1
    +
    1577  // w[0] = position gauss 1
    +
    1578  // w[1] = width gauss 1
    +
    1579  // w[2] = amplitude gauss 2, relative to gauss 1
    +
    1580  // w[3] = position gauss 2
    +
    1581  // w[4] = width gauss 2
    +
    1582  // w[5] = amplitude gauss 3, relative to gauss 1
    +
    1583  // w[6] = position gauss 3
    +
    1584  // w[7] = width gauss 3
    +
    1585  // w[8] = constant term
    +
    1586  // w[9] = linear term
    +
    1587  // w[10] = quadratic term
    +
    1588  // spectral background, varies with e
    +
    1589  // w[11] = constant term
    +
    1590  // w[12] = linear term
    +
    1591  // w[13] = quadratic term
    +
    1592  // w[14] = cubic term
    +
    1593  variable a // detection angle
    +
    1594  variable e // electron energy
    +
    1595 
    +
    1596  make /free /n=4 /d w_int
    +
    1597  variable p0 = 0
    +
    1598 
    +
    1599  w_int[0] = 0
    +
    1600  w_int[1] = 1
    +
    1601  w_int[2,] = w[p0 + p - 2]
    +
    1602  variable pk1 = gauss1d(w_int, a)
    +
    1603  p0 += 2
    +
    1604 
    +
    1605  w_int[1,] = w[p0 + p - 1]
    +
    1606  variable pk2 = gauss1d(w_int, a)
    +
    1607  p0 += 3
    +
    1608 
    +
    1609  w_int[1,] = w[p0 + p - 1]
    +
    1610  variable pk3 = gauss1d(w_int, a)
    +
    1611  p0 += 3
    +
    1612 
    +
    1613  w_int[0,2] = w[p0 + p]
    +
    1614  w_int[3] = 0
    +
    1615  variable base = poly(w_int, a)
    +
    1616  p0 += 3
    +
    1617 
    +
    1618  w_int[0,3] = w[p0 + p]
    +
    1619  variable bg = poly(w_int, e)
    +
    1620 
    +
    1621  return bg * (base + pk1 + pk2 + pk3)
    +
    1622 end
    +
    threadsafe wave int_linbg_reduction(wave source, string *param)
    linear-background subtracted integration reduction function.
    +
    variable prompt_int_linbg_reduction(string *param)
    prompt the user for integrate on linear background reduction parameters.
    +
    threadsafe variable MultiVoigtLinBG_AO(wave pw, wave yw, wave xw)
    multiple voigt peaks on a linear background fit function.
    +
    threadsafe variable MultiGaussLinBG_AO(wave pw, wave yw, wave xw)
    multiple gaussian peaks on a linear background fit function (all at once).
    +
    string capture_int_linbg_cursors()
    capture linear background reduction parameters from cursors in a graph.
    +
    threadsafe wave ad_profile_x_w(wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    +
    threadsafe variable adh5_setup_profile(wave image, wave profile, variable dim)
    set up a one-dimensional wave for a line profile based on a 2D original wave.
    +
    variable prompt_gauss4_reduction(string *param)
    prompt for the gauss4_reduction parameters
    +
    threadsafe wave gauss6_reduction(wave source, string *param)
    +
    variable test_gauss4_reduction(wave image)
    apply the gauss4_reduction function to a single image
    +
    string csr_int_linbg_reduction(string win)
    calculate linear background reduction parameters from cursors in a graph.
    +
    threadsafe wave redim_linbg_reduction(wave source, string *param)
    linear background reduction function for incorrectly dimensioned scienta image
    +
    threadsafe wave ad_profile_y_w(wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue)
    1D cut through 2D dataset along X dimension, existing destination wave.
    +
    variable prompt_int_quadbg_reduction(string *param)
    +
    threadsafe wave gauss4_reduction(wave source, string *param)
    fit horizontal cuts of an image with up to four gaussian peaks on a linear background
    +
    variable prompt_redim_linbg_reduction(string *param)
    parameter dialog for the redim_linbg_reduction() function
    +
    threadsafe wave int_quadbg_reduction(wave source, string *param)
    integrate peak area minus a quadratic background
    +
    threadsafe variable MultiGaussLinBG(wave w, variable x)
    multiple gaussian peaks on a linear background fit function.
    diff --git a/doc/html/pearl-tools_8ipf.html b/doc/html/pearl-tools_8ipf.html index 68022e8..2da6fb7 100644 --- a/doc/html/pearl-tools_8ipf.html +++ b/doc/html/pearl-tools_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-tools.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -133,7 +135,7 @@ Functions
    -

    Definition at line 26 of file pearl-tools.ipf.

    +

    Definition at line 27 of file pearl-tools.ipf.

    @@ -163,7 +165,7 @@ Functions
    -

    Definition at line 65 of file pearl-tools.ipf.

    +

    Definition at line 66 of file pearl-tools.ipf.

    @@ -193,7 +195,7 @@ Functions
    -

    Definition at line 18 of file pearl-tools.ipf.

    +

    Definition at line 19 of file pearl-tools.ipf.

    @@ -235,7 +237,7 @@ Functions
    -

    Definition at line 79 of file pearl-tools.ipf.

    +

    Definition at line 80 of file pearl-tools.ipf.

    @@ -271,7 +273,7 @@ Functions
    -

    Definition at line 45 of file pearl-tools.ipf.

    +

    Definition at line 46 of file pearl-tools.ipf.

    @@ -301,7 +303,7 @@ Functions
    -

    Definition at line 34 of file pearl-tools.ipf.

    +

    Definition at line 35 of file pearl-tools.ipf.

    @@ -311,9 +313,9 @@ Functions diff --git a/doc/html/pearl-tools_8ipf_source.html b/doc/html/pearl-tools_8ipf_source.html index da3cecb..8d46172 100644 --- a/doc/html/pearl-tools_8ipf_source.html +++ b/doc/html/pearl-tools_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-tools.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,24 +87,160 @@ $(document).ready(function(){initNavTree('pearl-tools_8ipf_source.html','');});
    pearl-tools.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.00
    3 #pragma IgorVersion = 6.2
    4 #pragma ModuleName = PearlTools
    5 #include "pearl-gui-tools"
    6 
    7 // general programming tools for Igor
    8 
    9 // $Id$
    10 // author: matthias.muntwiler@psi.ch
    11 // Copyright (c) 2009-14 Paul Scherrer Institut
    12 
    13 // Licensed under the Apache License, Version 2.0 (the "License");
    14 // you may not use this file except in compliance with the License.
    15 // You may obtain a copy of the License at
    16 // http://www.apache.org/licenses/LICENSE-2.0
    17 
    18 function DefaultWaveIterator(w, sdata)
    19 // function prototype for IterateWaves
    20  wave w // wave which the iterator is supposed to work on
    21  string &sdata // string with additional data, shared between calls
    22  // this is a pass-by-reference argument,
    23  // the function may modify the string
    24 end
    25 
    26 function AppendToGraphIterator(w, sdata)
    27 // append iterated waves to the current graph
    28  wave w // wave to be displayed
    29  string &sdata // not used
    30 
    31  appendtograph w
    32 end
    33 
    34 function SumWavesIterator(w, sdata)
    35 // sum waves into one result wave
    36  wave w // wave which the iterator is supposed to work on
    37  string &sdata // name of the result wave, can include absolute path
    38  // the wave must exist and compatible with the summands
    39  // the caller is responsible for initialization of the wave
    40 
    41  wave result = $sdata
    42  result += w
    43 end
    44 
    45 function/s IterateWaves(matchStr, iterator, sdata)
    46 // iterate over all waves matching a specified pattern (see built-in WaveList function),
    47 // passing each wave to a user-defined iterator function
    48  string matchStr // matchStr as for WaveList
    49  funcref DefaultWaveIterator iterator // iterator function
    50  // use the DefaultWaveIterator function as a template
    51  string sdata // data string passed to iterator function
    52  // the iterator may modify the string
    53  // the function returns the string at the end
    54 
    55  string wlist = WaveList(matchStr, ";", "")
    56  variable n = ItemsInList(wlist, ";")
    57  variable i
    58  for (i = 0; i < n; i += 1)
    59  wave w = $(StringFromList(i, wlist, ";"))
    60  iterator(w, sdata)
    61  endfor
    62  return sdata
    63 end
    64 
    65 function DefaultFolderIterator(df, sdata)
    66 // function prototype for IterateWaves
    67  dfref df // data folder reference which the iterator is supposed to work on
    68  string &sdata // string with additional data, shared between calls
    69  // this is a pass-by-reference argument,
    70  // the function may modify the string
    71 
    72  // switch to requested data folder
    73  setdatafolder df
    74  // for testing
    75  print getdatafolder(1)
    76  // no need to switch back to original folder
    77 end
    78 
    79 function/s IterateDataFolders(matchStr, iterator, sdata, [progress_title])
    80 // iterate over all data folders matching a specified pattern in the current data folder,
    81 // passing each folder to a user-defined iterator function
    82  string matchStr // matchStr as for the built-in stringmatch function
    83  funcref DefaultFolderIterator iterator // iterator function
    84  // use the DefaultFolderIterator function as a template
    85  string sdata // data string passed to iterator function
    86  // the iterator may modify the string
    87  // the function returns the string at the end
    88  string progress_title // title of the progress window (optional)
    89  // if not specified or empty, the progress window will not be shown.
    90  // if the progress window is show, the user can abort the iteration.
    91  // the function result does not indicate whether the iteration was completed or aborted.
    92  // the iterator and caller must take care of leaving the data in a consistent state.
    93 
    94  if (ParamIsDefault(progress_title))
    95  progress_title = ""
    96  endif
    97  variable show_progress = strlen(progress_title) > 0
    98 
    99  dfref origdf = GetDataFolderDFR()
    100  dfref curdf
    101  variable index = 0
    102  variable abort_req = 0
    103  string objName
    104 
    105  variable ndf = CountObjectsDFR(origdf, 4)
    106  if (show_progress)
    107  display_progress_panel(progress_title, "", ndf)
    108  endif
    109 
    110  do
    111  objName = GetIndexedObjNameDFR(origdf, 4, index)
    112  if (strlen(objName) == 0)
    113  break
    114  endif
    115  if (stringmatch(objname, matchstr))
    116  if (show_progress)
    117  abort_req = update_progress_panel(index, message=objName)
    118  if (abort_req)
    119  break
    120  endif
    121  endif
    122  setdatafolder origdf
    123  curdf = $(":" + objname)
    124  iterator(curdf, sdata)
    125  endif
    126  index += 1
    127  while(1)
    128 
    129  if (show_progress)
    131  endif
    132 
    133  setdatafolder origdf
    134  return sdata
    135 end
    variable kill_progress_panel()
    -
    string IterateDataFolders(string matchStr, funcref iterator, string sdata, string progress_title=defaultValue)
    Definition: pearl-tools.ipf:79
    -
    variable display_progress_panel(string title, string message, variable progress_max)
    -
    variable AppendToGraphIterator(wave w, string *sdata)
    Definition: pearl-tools.ipf:26
    -
    string IterateWaves(string matchStr, funcref iterator, string sdata)
    Definition: pearl-tools.ipf:45
    -
    variable DefaultWaveIterator(wave w, string *sdata)
    Definition: pearl-tools.ipf:18
    -
    variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
    -
    variable SumWavesIterator(wave w, string *sdata)
    Definition: pearl-tools.ipf:34
    -
    variable DefaultFolderIterator(dfref df, string *sdata)
    Definition: pearl-tools.ipf:65
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
    +
    3 #pragma version = 1.00
    +
    4 #pragma IgorVersion = 6.2
    +
    5 #pragma ModuleName = PearlTools
    +
    6 #include "pearl-gui-tools"
    +
    7 
    +
    8 // general programming tools for Igor
    +
    9 
    +
    10 // $Id$
    +
    11 // author: matthias.muntwiler@psi.ch
    +
    12 // Copyright (c) 2009-14 Paul Scherrer Institut
    +
    13 
    +
    14 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    15 // you may not use this file except in compliance with the License.
    +
    16 // You may obtain a copy of the License at
    +
    17 // http://www.apache.org/licenses/LICENSE-2.0
    +
    18 
    +
    19 function DefaultWaveIterator(w, sdata)
    +
    20 // function prototype for IterateWaves
    +
    21  wave w // wave which the iterator is supposed to work on
    +
    22  string &sdata // string with additional data, shared between calls
    +
    23  // this is a pass-by-reference argument,
    +
    24  // the function may modify the string
    +
    25 end
    +
    26 
    +
    27 function AppendToGraphIterator(w, sdata)
    +
    28 // append iterated waves to the current graph
    +
    29  wave w // wave to be displayed
    +
    30  string &sdata // not used
    +
    31 
    +
    32  appendtograph w
    +
    33 end
    +
    34 
    +
    35 function SumWavesIterator(w, sdata)
    +
    36 // sum waves into one result wave
    +
    37  wave w // wave which the iterator is supposed to work on
    +
    38  string &sdata // name of the result wave, can include absolute path
    +
    39  // the wave must exist and compatible with the summands
    +
    40  // the caller is responsible for initialization of the wave
    +
    41 
    +
    42  wave result = $sdata
    +
    43  result += w
    +
    44 end
    +
    45 
    +
    46 function/s IterateWaves(matchStr, iterator, sdata)
    +
    47 // iterate over all waves matching a specified pattern (see built-in WaveList function),
    +
    48 // passing each wave to a user-defined iterator function
    +
    49  string matchStr // matchStr as for WaveList
    +
    50  funcref DefaultWaveIterator iterator // iterator function
    +
    51  // use the DefaultWaveIterator function as a template
    +
    52  string sdata // data string passed to iterator function
    +
    53  // the iterator may modify the string
    +
    54  // the function returns the string at the end
    +
    55 
    +
    56  string wlist = WaveList(matchStr, ";", "")
    +
    57  variable n = ItemsInList(wlist, ";")
    +
    58  variable i
    +
    59  for (i = 0; i < n; i += 1)
    +
    60  wave w = $(StringFromList(i, wlist, ";"))
    +
    61  iterator(w, sdata)
    +
    62  endfor
    +
    63  return sdata
    +
    64 end
    +
    65 
    +
    66 function DefaultFolderIterator(df, sdata)
    +
    67 // function prototype for IterateWaves
    +
    68  dfref df // data folder reference which the iterator is supposed to work on
    +
    69  string &sdata // string with additional data, shared between calls
    +
    70  // this is a pass-by-reference argument,
    +
    71  // the function may modify the string
    +
    72 
    +
    73  // switch to requested data folder
    +
    74  setdatafolder df
    +
    75  // for testing
    +
    76  print getdatafolder(1)
    +
    77  // no need to switch back to original folder
    +
    78 end
    +
    79 
    +
    80 function/s IterateDataFolders(matchStr, iterator, sdata, [progress_title])
    +
    81 // iterate over all data folders matching a specified pattern in the current data folder,
    +
    82 // passing each folder to a user-defined iterator function
    +
    83  string matchStr // matchStr as for the built-in stringmatch function
    +
    84  funcref DefaultFolderIterator iterator // iterator function
    +
    85  // use the DefaultFolderIterator function as a template
    +
    86  string sdata // data string passed to iterator function
    +
    87  // the iterator may modify the string
    +
    88  // the function returns the string at the end
    +
    89  string progress_title // title of the progress window (optional)
    +
    90  // if not specified or empty, the progress window will not be shown.
    +
    91  // if the progress window is show, the user can abort the iteration.
    +
    92  // the function result does not indicate whether the iteration was completed or aborted.
    +
    93  // the iterator and caller must take care of leaving the data in a consistent state.
    +
    94 
    +
    95  if (ParamIsDefault(progress_title))
    +
    96  progress_title = ""
    +
    97  endif
    +
    98  variable show_progress = strlen(progress_title) > 0
    +
    99 
    +
    100  dfref origdf = GetDataFolderDFR()
    +
    101  dfref curdf
    +
    102  variable index = 0
    +
    103  variable abort_req = 0
    +
    104  string objName
    +
    105 
    +
    106  variable ndf = CountObjectsDFR(origdf, 4)
    +
    107  if (show_progress)
    +
    108  display_progress_panel(progress_title, "", ndf)
    +
    109  endif
    +
    110 
    +
    111  do
    +
    112  objName = GetIndexedObjNameDFR(origdf, 4, index)
    +
    113  if (strlen(objName) == 0)
    +
    114  break
    +
    115  endif
    +
    116  if (stringmatch(objname, matchstr))
    +
    117  if (show_progress)
    +
    118  abort_req = update_progress_panel(index, message=objName)
    +
    119  if (abort_req)
    +
    120  break
    +
    121  endif
    +
    122  endif
    +
    123  setdatafolder origdf
    +
    124  curdf = $(":" + objname)
    +
    125  iterator(curdf, sdata)
    +
    126  endif
    +
    127  index += 1
    +
    128  while(1)
    +
    129 
    +
    130  if (show_progress)
    + +
    132  endif
    +
    133 
    +
    134  setdatafolder origdf
    +
    135  return sdata
    +
    136 end
    +
    variable kill_progress_panel()
    +
    variable display_progress_panel(string title, string message, variable progress_max)
    +
    variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
    +
    string IterateDataFolders(string matchStr, funcref iterator, string sdata, string progress_title=defaultValue)
    Definition: pearl-tools.ipf:80
    +
    variable AppendToGraphIterator(wave w, string *sdata)
    Definition: pearl-tools.ipf:27
    +
    string IterateWaves(string matchStr, funcref iterator, string sdata)
    Definition: pearl-tools.ipf:46
    +
    variable DefaultWaveIterator(wave w, string *sdata)
    Definition: pearl-tools.ipf:19
    +
    variable DefaultFolderIterator(dfref df, string *sdata)
    Definition: pearl-tools.ipf:66
    +
    variable SumWavesIterator(wave w, string *sdata)
    Definition: pearl-tools.ipf:35
    diff --git a/doc/html/pearl-vector-operations_8ipf.html b/doc/html/pearl-vector-operations_8ipf.html index f53afcd..cf5c411 100644 --- a/doc/html/pearl-vector-operations_8ipf.html +++ b/doc/html/pearl-vector-operations_8ipf.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-vector-operations.ipf File Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -103,40 +105,40 @@ Namespaces

    Functions

    variable rotate2d_x (variable xx, variable yy, variable angle) - rotate a 2D cartesian vector and returns its x component. More...
    + rotate a 2D cartesian vector and returns its x component. More...
      variable rotate2d_y (variable xx, variable yy, variable angle) - rotate a 2D cartesian vector and returns its y component. More...
    + rotate a 2D cartesian vector and returns its y component. More...
      wave create_rotation_matrix_free () - create a free matrix wave which represents the 3-vector identity. More...
    + create a free matrix wave which represents the 3-vector identity. More...
      wave set_rotation_x (wave matrix, variable angle) - calculate a matrix representing a 3-vector rotation around the x axis. More...
    + calculate a matrix representing a 3-vector rotation around the x axis. More...
      wave set_rotation_y (wave matrix, variable angle) - calculate a matrix representing a 3-vector rotation around the y axis More...
    + calculate a matrix representing a 3-vector rotation around the y axis More...
      wave set_rotation_z (wave matrix, variable angle) - calculate a matrix representing a 3-vector rotation around the z axis More...
    + calculate a matrix representing a 3-vector rotation around the z axis More...
      variable rotate_x_wave (wave inout, variable angle) - rotate a wave of 3-vectors about the x axis. More...
    + rotate a wave of 3-vectors about the x axis. More...
      variable rotate_y_wave (wave inout, variable angle) - rotates a wave of 3-vectors about the y axis More...
    + rotates a wave of 3-vectors about the y axis More...
      variable rotate_z_wave (wave inout, variable angle) - rotates a wave of 3-vectors about the z axis More...
    + rotates a wave of 3-vectors about the z axis More...
     

    Detailed Description

    basic vector geometry operations.

    this procedure file contains basic vector geometry functions, such as rotations.

    Author
    matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
    -
    @@ -207,7 +209,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    x coordinate of the rotated vector.
    -

    Definition at line 45 of file pearl-vector-operations.ipf.

    +

    Definition at line 46 of file pearl-vector-operations.ipf.

    @@ -254,7 +256,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    y coordinate of the rotated vector.
    -

    Definition at line 60 of file pearl-vector-operations.ipf.

    +

    Definition at line 61 of file pearl-vector-operations.ipf.

    @@ -295,7 +297,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    none
    -

    Definition at line 175 of file pearl-vector-operations.ipf.

    +

    Definition at line 176 of file pearl-vector-operations.ipf.

    @@ -336,7 +338,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    none
    -

    Definition at line 203 of file pearl-vector-operations.ipf.

    +

    Definition at line 205 of file pearl-vector-operations.ipf.

    @@ -377,7 +379,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    none
    -

    Definition at line 231 of file pearl-vector-operations.ipf.

    +

    Definition at line 234 of file pearl-vector-operations.ipf.

    @@ -418,7 +420,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    rotation matrix. this is the same wave instance as the matrix input.
    -

    Definition at line 92 of file pearl-vector-operations.ipf.

    +

    Definition at line 93 of file pearl-vector-operations.ipf.

    @@ -459,7 +461,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    rotation matrix. this is the same wave instance as the matrix input.
    -

    Definition at line 120 of file pearl-vector-operations.ipf.

    +

    Definition at line 121 of file pearl-vector-operations.ipf.

    @@ -500,7 +502,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    Returns
    rotation matrix. this is the same wave instance as the matrix input.
    -

    Definition at line 148 of file pearl-vector-operations.ipf.

    +

    Definition at line 149 of file pearl-vector-operations.ipf.

    @@ -510,9 +512,9 @@ Licensed under the Apache License, Version 2.0 (the "License");
    diff --git a/doc/html/pearl-vector-operations_8ipf_source.html b/doc/html/pearl-vector-operations_8ipf_source.html index 9f92910..5b52fdf 100644 --- a/doc/html/pearl-vector-operations_8ipf_source.html +++ b/doc/html/pearl-vector-operations_8ipf_source.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: pearl-vector-operations.ipf Source File @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -85,24 +87,157 @@ $(document).ready(function(){initNavTree('pearl-vector-operations_8ipf_source.ht
    pearl-vector-operations.ipf
    -Go to the documentation of this file.
    1 #pragma rtGlobals=3
    2 #pragma version = 2.1
    3 #pragma IgorVersion = 6.1
    4 #pragma ModuleName = PearlVectorOperations
    5 
    6 // copyright (c) 2011-17 Paul Scherrer Institut
    7 //
    8 // Licensed under the Apache License, Version 2.0 (the "License");
    9 // you may not use this file except in compliance with the License.
    10 // You may obtain a copy of the License at
    11 // http:///www.apache.org/licenses/LICENSE-2.0
    12 //
    13 // Please acknowledge the use of this code.
    14 
    30 
    35 
    36 
    45 function rotate2d_x(xx, yy, angle)
    46  variable xx, yy
    47  variable angle
    48 
    49  return xx * cos(angle * pi / 180) - yy * sin(angle * pi / 180)
    50 end
    51 
    60 function rotate2d_y(xx, yy, angle)
    61  variable xx, yy
    62  variable angle
    63 
    64  return xx * sin(angle * pi / 180) + yy * cos(angle * pi / 180)
    65 end
    66 
    74  make /n=(3,3)/free matrix
    75  matrix = p == q // identity
    76  return matrix
    77 end
    78 
    92 function /wave set_rotation_x(matrix, angle)
    93  wave matrix
    94  variable angle
    95 
    96  variable si = sin(angle * pi / 180)
    97  variable co = cos(angle * pi / 180)
    98 
    99  matrix[1][1] = co
    100  matrix[2][2] = co
    101  matrix[2][1] = si
    102  matrix[1][2] = -si
    103 
    104  return matrix
    105 end
    106 
    120 function /wave set_rotation_y(matrix, angle)
    121  wave matrix
    122  variable angle
    123 
    124  variable si = sin(angle * pi / 180)
    125  variable co = cos(angle * pi / 180)
    126 
    127  matrix[0][0] = co
    128  matrix[2][2] = co
    129  matrix[0][2] = si
    130  matrix[2][0] = -si
    131 
    132  return matrix
    133 end
    134 
    148 function /wave set_rotation_z(matrix, angle)
    149  wave matrix
    150  variable angle
    151 
    152  variable si = sin(angle * pi / 180)
    153  variable co = cos(angle * pi / 180)
    154 
    155  matrix[0][0] = co
    156  matrix[1][1] = co
    157  matrix[1][0] = si
    158  matrix[0][1] = -si
    159 
    160  return matrix
    161 end
    162 
    175 function rotate_x_wave(inout, angle)
    176  wave inout
    177  variable angle
    178 
    179  wave m_rotation_x = create_rotation_matrix_free()
    180  make /n=3/d/free w_temp_rotate_x
    181  variable ivec, nvec
    182  nvec = max(DimSize(inout, 1), 1)
    183  for (ivec = 0; ivec < nvec; ivec += 1)
    184  set_rotation_x(m_rotation_x, angle)
    185  w_temp_rotate_x = inout[p][ivec]
    186  matrixop /free w_temp_rotate_x_result = m_rotation_x x w_temp_rotate_x
    187  inout[0,2][ivec] = w_temp_rotate_x_result[p]
    188  endfor
    189 end
    190 
    203 function rotate_y_wave(inout, angle)
    204  wave inout
    205  variable angle
    206 
    207  wave m_rotation_y = create_rotation_matrix_free()
    208  make /n=3/d/free w_temp_rotate_y
    209  variable ivec, nvec
    210  nvec = max(DimSize(inout, 1), 1)
    211  for (ivec = 0; ivec < nvec; ivec += 1)
    212  set_rotation_y(m_rotation_y, angle)
    213  w_temp_rotate_y = inout[p][ivec]
    214  matrixop /free w_temp_rotate_y_result = m_rotation_y x w_temp_rotate_y
    215  inout[0,2][ivec] = w_temp_rotate_y_result[p]
    216  endfor
    217 end
    218 
    231 function rotate_z_wave(inout, angle)
    232  wave inout
    233  variable angle
    234 
    235  wave m_rotation_z = create_rotation_matrix_free()
    236  make /n=3/d/free w_temp_rotate_z
    237  variable ivec, nvec
    238  nvec = max(DimSize(inout, 1), 1)
    239  for (ivec = 0; ivec < nvec; ivec += 1)
    240  set_rotation_z(m_rotation_z, angle)
    241  w_temp_rotate_z = inout[p][ivec]
    242  matrixop /free w_temp_rotate_z_result = m_rotation_z x w_temp_rotate_z
    243  inout[0,2][ivec] = w_temp_rotate_z_result[p]
    244  endfor
    245 end
    wave set_rotation_x(wave matrix, variable angle)
    calculate a matrix representing a 3-vector rotation around the x axis.
    -
    variable rotate_x_wave(wave inout, variable angle)
    rotate a wave of 3-vectors about the x axis.
    -
    variable rotate2d_x(variable xx, variable yy, variable angle)
    rotate a 2D cartesian vector and returns its x component.
    -
    wave set_rotation_z(wave matrix, variable angle)
    calculate a matrix representing a 3-vector rotation around the z axis
    -
    variable rotate_y_wave(wave inout, variable angle)
    rotates a wave of 3-vectors about the y axis
    -
    variable rotate2d_y(variable xx, variable yy, variable angle)
    rotate a 2D cartesian vector and returns its y component.
    -
    variable rotate_z_wave(wave inout, variable angle)
    rotates a wave of 3-vectors about the z axis
    -
    wave create_rotation_matrix_free()
    create a free matrix wave which represents the 3-vector identity.
    -
    wave set_rotation_y(wave matrix, variable angle)
    calculate a matrix representing a 3-vector rotation around the y axis
    +Go to the documentation of this file.
    1 #pragma TextEncoding = "UTF-8"
    +
    2 #pragma rtGlobals=3
    +
    3 #pragma version = 2.2
    +
    4 #pragma IgorVersion = 6.1
    +
    5 #pragma ModuleName = PearlVectorOperations
    +
    6 
    +
    7 // copyright (c) 2011-21 Paul Scherrer Institut
    +
    8 //
    +
    9 // Licensed under the Apache License, Version 2.0 (the "License");
    +
    10 // you may not use this file except in compliance with the License.
    +
    11 // You may obtain a copy of the License at
    +
    12 // http:///www.apache.org/licenses/LICENSE-2.0
    +
    13 //
    +
    14 // Please acknowledge the use of this code.
    +
    15 
    +
    31 
    +
    36 
    +
    37 
    +
    46 function rotate2d_x(xx, yy, angle)
    +
    47  variable xx, yy
    +
    48  variable angle
    +
    49 
    +
    50  return xx * cos(angle * pi / 180) - yy * sin(angle * pi / 180)
    +
    51 end
    +
    52 
    +
    61 function rotate2d_y(xx, yy, angle)
    +
    62  variable xx, yy
    +
    63  variable angle
    +
    64 
    +
    65  return xx * sin(angle * pi / 180) + yy * cos(angle * pi / 180)
    +
    66 end
    +
    67 
    + +
    75  make /n=(3,3)/free matrix
    +
    76  matrix = p == q // identity
    +
    77  return matrix
    +
    78 end
    +
    79 
    +
    93 function /wave set_rotation_x(matrix, angle)
    +
    94  wave matrix
    +
    95  variable angle
    +
    96 
    +
    97  variable si = sin(angle * pi / 180)
    +
    98  variable co = cos(angle * pi / 180)
    +
    99 
    +
    100  matrix[1][1] = co
    +
    101  matrix[2][2] = co
    +
    102  matrix[2][1] = si
    +
    103  matrix[1][2] = -si
    +
    104 
    +
    105  return matrix
    +
    106 end
    +
    107 
    +
    121 function /wave set_rotation_y(matrix, angle)
    +
    122  wave matrix
    +
    123  variable angle
    +
    124 
    +
    125  variable si = sin(angle * pi / 180)
    +
    126  variable co = cos(angle * pi / 180)
    +
    127 
    +
    128  matrix[0][0] = co
    +
    129  matrix[2][2] = co
    +
    130  matrix[0][2] = si
    +
    131  matrix[2][0] = -si
    +
    132 
    +
    133  return matrix
    +
    134 end
    +
    135 
    +
    149 function /wave set_rotation_z(matrix, angle)
    +
    150  wave matrix
    +
    151  variable angle
    +
    152 
    +
    153  variable si = sin(angle * pi / 180)
    +
    154  variable co = cos(angle * pi / 180)
    +
    155 
    +
    156  matrix[0][0] = co
    +
    157  matrix[1][1] = co
    +
    158  matrix[1][0] = si
    +
    159  matrix[0][1] = -si
    +
    160 
    +
    161  return matrix
    +
    162 end
    +
    163 
    +
    176 function rotate_x_wave(inout, angle)
    +
    177  wave inout
    +
    178  variable angle
    +
    179 
    +
    180  wave m_rotation = create_rotation_matrix_free()
    +
    181  set_rotation_x(m_rotation, angle)
    +
    182 
    +
    183  duplicate /free inout, out
    +
    184  out = 0
    +
    185  variable j
    +
    186  for (j = 0; j < 3; j += 1)
    +
    187  out += m_rotation[p][j] * inout[j][q]
    +
    188  endfor
    +
    189 
    +
    190  inout = out
    +
    191 end
    +
    192 
    +
    205 function rotate_y_wave(inout, angle)
    +
    206  wave inout
    +
    207  variable angle
    +
    208 
    +
    209  wave m_rotation = create_rotation_matrix_free()
    +
    210  set_rotation_y(m_rotation, angle)
    +
    211 
    +
    212  duplicate /free inout, out
    +
    213  out = 0
    +
    214  variable j
    +
    215  for (j = 0; j < 3; j += 1)
    +
    216  out += m_rotation[p][j] * inout[j][q]
    +
    217  endfor
    +
    218 
    +
    219  inout = out
    +
    220 end
    +
    221 
    +
    234 function rotate_z_wave(inout, angle)
    +
    235  wave inout
    +
    236  variable angle
    +
    237 
    +
    238  wave m_rotation = create_rotation_matrix_free()
    +
    239  set_rotation_z(m_rotation, angle)
    +
    240 
    +
    241  duplicate /free inout, out
    +
    242  out = 0
    +
    243  variable j
    +
    244  for (j = 0; j < 3; j += 1)
    +
    245  out += m_rotation[p][j] * inout[j][q]
    +
    246  endfor
    +
    247 
    +
    248  inout = out
    +
    249 end
    +
    variable rotate_y_wave(wave inout, variable angle)
    rotates a wave of 3-vectors about the y axis
    +
    wave set_rotation_y(wave matrix, variable angle)
    calculate a matrix representing a 3-vector rotation around the y axis
    +
    wave set_rotation_x(wave matrix, variable angle)
    calculate a matrix representing a 3-vector rotation around the x axis.
    +
    variable rotate2d_x(variable xx, variable yy, variable angle)
    rotate a 2D cartesian vector and returns its x component.
    +
    wave create_rotation_matrix_free()
    create a free matrix wave which represents the 3-vector identity.
    +
    variable rotate_x_wave(wave inout, variable angle)
    rotate a wave of 3-vectors about the x axis.
    +
    variable rotate2d_y(variable xx, variable yy, variable angle)
    rotate a 2D cartesian vector and returns its y component.
    +
    variable rotate_z_wave(wave inout, variable angle)
    rotates a wave of 3-vectors about the z axis
    +
    wave set_rotation_z(wave matrix, variable angle)
    calculate a matrix representing a 3-vector rotation around the z axis
    diff --git a/doc/html/resize.js b/doc/html/resize.js index 56e4a02..a0bb5f4 100644 --- a/doc/html/resize.js +++ b/doc/html/resize.js @@ -1,3 +1,26 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ function initResizable() { var cookie_namespace = 'doxygen'; @@ -68,6 +91,7 @@ function initResizable() } collapsedWidth=width; } + (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView(); } function collapseExpand() @@ -108,7 +132,6 @@ function initResizable() var _preventDefault = function(evt) { evt.preventDefault(); }; $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); $(".ui-resizable-handle").dblclick(collapseExpand); - $(window).load(resizeHeight); + $(window).on('load',resizeHeight); } - - +/* @license-end */ diff --git a/doc/html/search/all_0.html b/doc/html/search/all_0.html index f25360b..26dd244 100644 --- a/doc/html/search/all_0.html +++ b/doc/html/search/all_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_0.js b/doc/html/search/all_0.js index 0b8d528..789479b 100644 --- a/doc/html/search/all_0.js +++ b/doc/html/search/all_0.js @@ -1,101 +1,103 @@ var searchData= [ - ['ad_5fadd_5foverlay',['ad_add_overlay',['../pearl-area-display_8ipf.html#af9bd125ed4fb4ada10b78bca2607b44d',1,'pearl-area-display.ipf']]], - ['ad_5fbox_5ffilter',['ad_box_filter',['../pearl-area-display_8ipf.html#a27f0957d61f3c2d30a4854911b460c36',1,'pearl-area-display.ipf']]], - ['ad_5fbrick_5fslicer',['ad_brick_slicer',['../pearl-area-display_8ipf.html#ae3b4756cdc12a4a4b15a770ba0069823',1,'pearl-area-display.ipf']]], - ['ad_5fcalc_5fcursor_5fprofiles',['ad_calc_cursor_profiles',['../pearl-area-display_8ipf.html#a72b57037abd27f65986034c0b4cc191e',1,'pearl-area-display.ipf']]], - ['ad_5fcalc_5fhistogram',['ad_calc_histogram',['../pearl-area-display_8ipf.html#a48b08ab53729d9d0477deaceedef2769',1,'pearl-area-display.ipf']]], - ['ad_5fcalc_5fprofiles',['ad_calc_profiles',['../pearl-area-display_8ipf.html#a48044f9ee518d47770e33ee9f381f204',1,'pearl-area-display.ipf']]], - ['ad_5fcollect_5fmultiscan_5fy',['ad_collect_multiscan_y',['../pearl-area-profiles_8ipf.html#a3cadf0b28d1fd84e9922610c20868283',1,'pearl-area-profiles.ipf']]], - ['ad_5fdefault_5fimage_5ffilter',['ad_default_image_filter',['../pearl-area-display_8ipf.html#a6418a1b2d18b82cb71c0fecbd513a934',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay',['ad_display',['../pearl-area-display_8ipf.html#ae2b11295d2715e9af019513923c64570',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay_5fbrick',['ad_display_brick',['../pearl-area-display_8ipf.html#a65b07e355df20cfb692dfb32f472b478',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay_5fhistogram',['ad_display_histogram',['../pearl-area-display_8ipf.html#a8cc3ea3bea4e851e4144140a2da42a03',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay_5fprofiles',['ad_display_profiles',['../pearl-area-display_8ipf.html#a8fad5aebaca72887d5898b4c421bcdae',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay_5fslice',['ad_display_slice',['../pearl-area-display_8ipf.html#af8d5e003fcff1f750685ed6f94717730',1,'pearl-area-display.ipf']]], - ['ad_5fexport_5fprofile',['ad_export_profile',['../pearl-area-display_8ipf.html#ad3e190d1ec1b82ebef00c9f9ac44b50a',1,'pearl-area-display.ipf']]], - ['ad_5fextract_5frod',['ad_extract_rod',['../pearl-area-profiles_8ipf.html#a8de5d4f1bcca91df5bbff568ab7b582d',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5frod_5fx',['ad_extract_rod_x',['../pearl-area-profiles_8ipf.html#a83700e2faf844e2480c89b6ca4c66a79',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5frod_5fy',['ad_extract_rod_y',['../pearl-area-profiles_8ipf.html#a363af257a04d51fff2a8d5b282f65f21',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5frod_5fz',['ad_extract_rod_z',['../pearl-area-profiles_8ipf.html#a3483707fbdbfdbaec069591a5d3b07a6',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5fslab',['ad_extract_slab',['../pearl-area-profiles_8ipf.html#a65bb359c057a9d900c486e186c9974df',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5fslab_5fx',['ad_extract_slab_x',['../pearl-area-profiles_8ipf.html#af612340d1d132cacda9de7bb77c2e0aa',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5fslab_5fy',['ad_extract_slab_y',['../pearl-area-profiles_8ipf.html#a2eb6a0bcced893e827cfa4e1236e8460',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5fslab_5fz',['ad_extract_slab_z',['../pearl-area-profiles_8ipf.html#a71f02613c4a4d21c014493e906dbe922',1,'pearl-area-profiles.ipf']]], - ['ad_5fgizmo_5fset_5fplane',['ad_gizmo_set_plane',['../pearl-area-display_8ipf.html#aee051acfe6a3c8214118b78dfe4854fd',1,'pearl-area-display.ipf']]], - ['ad_5fload_5fdialog',['ad_load_dialog',['../pearl-area-import_8ipf.html#aedff2e67d2e1bac907f2eaf24a6e5c3c',1,'pearl-area-import.ipf']]], - ['ad_5fprofile_5fx',['ad_profile_x',['../pearl-area-profiles_8ipf.html#ab1a65cf82f6933db3dd7b564582e8ed1',1,'pearl-area-profiles.ipf']]], - ['ad_5fprofile_5fx_5fw',['ad_profile_x_w',['../pearl-area-profiles_8ipf.html#aa40fd5049f993e72fd52a66a6cdde7cc',1,'pearl-area-profiles.ipf']]], - ['ad_5fprofile_5fy',['ad_profile_y',['../pearl-area-profiles_8ipf.html#abb1eed32a982037ebab00f5c3ea95e62',1,'pearl-area-profiles.ipf']]], - ['ad_5fprofile_5fy_5fw',['ad_profile_y_w',['../pearl-area-profiles_8ipf.html#a8b09e13162fa47cc076e1e661e80b002',1,'pearl-area-profiles.ipf']]], - ['ad_5fprofiles_5fcrosshairs',['ad_profiles_crosshairs',['../pearl-area-display_8ipf.html#a6d20a8c6bf5ed143d375dee71fb3a6d5',1,'pearl-area-display.ipf']]], - ['ad_5fprofiles_5fcursor_5fmode',['ad_profiles_cursor_mode',['../pearl-area-display_8ipf.html#a5657fc4dcd395aef637c19e8df57a418',1,'pearl-area-display.ipf']]], - ['ad_5fprofiles_5fhook',['ad_profiles_hook',['../pearl-area-display_8ipf.html#a89a5e3e29a0cd09951dcdf13aa28d941',1,'pearl-area-display.ipf']]], - ['ad_5fprofiles_5fset_5fcursor',['ad_profiles_set_cursor',['../pearl-area-display_8ipf.html#ad2a84495ddac89bc8f4203fca56babfd',1,'pearl-area-display.ipf']]], - ['ad_5fprofiles_5fset_5fslice',['ad_profiles_set_slice',['../pearl-area-display_8ipf.html#abaf229d75d9d579a559295795a6bc2e1',1,'pearl-area-display.ipf']]], - ['ad_5fslicer_5finit_5fbg',['ad_slicer_init_bg',['../pearl-area-display_8ipf.html#a7334815c60e2c11e2754c07489a62f4b',1,'pearl-area-display.ipf']]], - ['ad_5fslicer_5fmove_5fbg',['ad_slicer_move_bg',['../pearl-area-display_8ipf.html#a4af98ec7af48a653c6fac716ea8fa505',1,'pearl-area-display.ipf']]], - ['ad_5fslicer_5fstart_5fbg',['ad_slicer_start_bg',['../pearl-area-display_8ipf.html#ad79b37ab4fcf2cbdad6874813d93d4b1',1,'pearl-area-display.ipf']]], - ['ad_5fslicer_5fstop_5fbg',['ad_slicer_stop_bg',['../pearl-area-display_8ipf.html#a77a71985e716a300e0b61c233cd93f40',1,'pearl-area-display.ipf']]], - ['ad_5fsuggest_5ffoldername',['ad_suggest_foldername',['../pearl-area-import_8ipf.html#ad28dbbba73e553f7b5dcf8baf1c86786',1,'pearl-area-import.ipf']]], - ['ad_5ftranspose_5ffilter',['ad_transpose_filter',['../pearl-area-display_8ipf.html#a8411f0cfec3515f1ae4f0140efc14318',1,'pearl-area-display.ipf']]], - ['ad_5fupdate_5fprofiles',['ad_update_profiles',['../pearl-area-display_8ipf.html#afa2546f9cb03dfa8bf0cc9966f0b7a45',1,'pearl-area-display.ipf']]], - ['add_5fimage_5fdata',['add_image_data',['../pearl-anglescan-tracker_8ipf.html#a35a5cd8a21b48be8d726c69eb5fca134',1,'pearl-anglescan-tracker.ipf']]], - ['adh5_5fdefault_5freduction',['adh5_default_reduction',['../pearl-area-import_8ipf.html#ade69cb0f82e0c9cf6082d5fcc29f742f',1,'pearl-area-import.ipf']]], - ['adh5_5fget_5fresult_5fwaves',['adh5_get_result_waves',['../pearl-area-import_8ipf.html#a27a72a3901a5342ca9dea02e3219631c',1,'pearl-area-import.ipf']]], - ['adh5_5flist_5freduction_5ffuncs',['adh5_list_reduction_funcs',['../pearl-area-import_8ipf.html#aa5e29dc1a380311d00a5f85be867e47b',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fcomplete',['adh5_load_complete',['../pearl-area-import_8ipf.html#ab1040bf272c69dc69777b2f91df41fab',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fdetector',['adh5_load_detector',['../pearl-area-import_8ipf.html#a84dc7f466b42dde5d96c49827b2122cf',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fdetector_5fimage',['adh5_load_detector_image',['../pearl-area-import_8ipf.html#a931a7bfaaf75d308a0ce3c74ffc751bc',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fdetector_5fslabs',['adh5_load_detector_slabs',['../pearl-area-import_8ipf.html#a4a9741d1c19b10bb98b73bd5163a497b',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5finfo',['adh5_load_info',['../pearl-area-import_8ipf.html#ac76d5ba94a3d7c864437420d80c77064',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fpreview',['adh5_load_preview',['../pearl-area-import_8ipf.html#a98f29671bdce6a5981e8865de8b9d483',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5freduced',['adh5_load_reduced',['../pearl-area-import_8ipf.html#a98f9339cd2fae80d0d92451df88395aa',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5freduced_5fdetector',['adh5_load_reduced_detector',['../pearl-area-import_8ipf.html#a3f2ac36f961941e46e80a775de8300e5',1,'pearl-area-import.ipf']]], - ['adh5_5floadattr_5fall',['adh5_loadattr_all',['../pearl-area-import_8ipf.html#acde16dc7a393250b17165344f865f7b5',1,'pearl-area-import.ipf']]], - ['adh5_5fredim',['adh5_redim',['../pearl-area-import_8ipf.html#acfa6d2675e63f4f686289ef853b262a9',1,'pearl-area-import.ipf']]], - ['adh5_5freduce_5fbrick',['adh5_reduce_brick',['../pearl-area-import_8ipf.html#ae88bc41882fd16c94c04d856f3e062e4',1,'pearl-area-import.ipf']]], - ['adh5_5fscale',['adh5_scale',['../pearl-area-import_8ipf.html#a774751d1857ea6946a942448dc913128',1,'pearl-area-import.ipf']]], - ['adh5_5fscale_5fscan',['adh5_scale_scan',['../pearl-area-import_8ipf.html#a1fdcc02340375afe8d8cd7537c6e9cfb',1,'pearl-area-import.ipf']]], - ['adh5_5fscale_5fscienta',['adh5_scale_scienta',['../pearl-area-import_8ipf.html#a227e4db1c51a910dcf86d355473fe74e',1,'pearl-area-import.ipf']]], - ['adh5_5fsetup_5fprofile',['adh5_setup_profile',['../pearl-area-import_8ipf.html#a9439de3b676e686eeca4e6b2588c01a6',1,'pearl-area-import.ipf']]], - ['adh5_5ftest_5freduction_5ffunc',['adh5_test_reduction_func',['../pearl-area-import_8ipf.html#a98804ce23a5c2c314ac243baa0824424',1,'pearl-area-import.ipf']]], - ['aftercompiledhook',['AfterCompiledHook',['../pearl-anglescan-panel_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-anglescan-tracker.ipf'],['../pearl-arpes_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-arpes.ipf']]], - ['afterfileopenhook',['AfterFileOpenHook',['../pearl-elog_8ipf.html#a3f524f5190341d2accc8cb8c3ed2ceb5',1,'AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a3f524f5190341d2accc8cb8c3ed2ceb5',1,'AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind): pearl-matrix-import.ipf']]], - ['already_5ffile_5fopen',['ALREADY_FILE_OPEN',['../structerror_code.html#a19dc49bdfb4bd9601f17f907da158026',1,'errorCode']]], - ['analyse_5fcurved_5fedge',['analyse_curved_edge',['../fermi-edge-analysis_8ipf.html#a1c4a805435a1d43c2b6dfb6deb633894',1,'fermi-edge-analysis.ipf']]], - ['analyser_5fenergy_5fresolution',['analyser_energy_resolution',['../fermi-edge-analysis_8ipf.html#ad23de34bb698589e2576ce2836b89d55',1,'fermi-edge-analysis.ipf']]], - ['anglescan_2dprocessing_2edox',['anglescan-processing.dox',['../anglescan-processing_8dox.html',1,'']]], - ['angletok',['AngleToK',['../pearl-anglescan-process_8ipf.html#acf6fddb73624fe2d21429e38c4994088',1,'pearl-anglescan-process.ipf']]], - ['appendtographiterator',['AppendToGraphIterator',['../pearl-tools_8ipf.html#a90c62bdfc186e2482ccb18113a591d5e',1,'pearl-tools.ipf']]], - ['arpes_20package',['ARPES package',['../group___arpes_package.html',1,'']]], - ['arrange_5fcontrols',['arrange_controls',['../pearl-anglescan-panel_8ipf.html#a65dbeab54647d7c27a139035d69c812f',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fcalculate_5foutput',['asp_calculate_output',['../pearl-anglescan-panel_8ipf.html#af21424ce00e4bac1ac990d2bb83d46dc',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fclose_5fgraphs',['asp_close_graphs',['../pearl-anglescan-panel_8ipf.html#aac9d4d0388cbe8e6aa8f47b1c5276d83',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fdisplay_5fdist_5fcheck',['asp_display_dist_check',['../pearl-anglescan-panel_8ipf.html#a59886414c7dc2486c5a17f078896c705',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fdisplay_5foutput',['asp_display_output',['../pearl-anglescan-panel_8ipf.html#a8e540427fab71f879e84003c49c59f22',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fdisplay_5fpreviews',['asp_display_previews',['../pearl-anglescan-panel_8ipf.html#a66b3eef1fd0be13dfef0a66781f55062',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fduplicate_5foutput',['asp_duplicate_output',['../pearl-anglescan-panel_8ipf.html#adf7c5a4e7c66c3d6e13d01674b9cf47f',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fimport_5fraw',['asp_import_raw',['../pearl-anglescan-panel_8ipf.html#a21aab19fbcde395df6e1ea8654b3af9a',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fsave_5foutput_5fetpi',['asp_save_output_etpi',['../pearl-anglescan-panel_8ipf.html#abb4d53822bc34bda0e38332c7777ebac',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fsave_5foutput_5fitx',['asp_save_output_itx',['../pearl-anglescan-panel_8ipf.html#a0e0f10d125f1cdacffa3bff9b0854aa9',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fshow_5fpanel',['asp_show_panel',['../pearl-anglescan-panel_8ipf.html#a452f09c3057638056ac2b5a15ac660b2',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fupdate_5fgraph',['asp_update_graph',['../pearl-anglescan-panel_8ipf.html#a93dc5a029ae9831066e6ad133522ee88',1,'pearl-anglescan-panel.ipf']]], - ['ast_5fadd_5fimage',['ast_add_image',['../pearl-anglescan-tracker_8ipf.html#a43d85b93bb42a67b8e8afb9afc8d8eae',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fcallback_5fdata',['ast_callback_data',['../pearl-anglescan-tracker_8ipf.html#a4cf5ad2fdf771ffc157a3924a03f5a46',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fcallback_5fdetector',['ast_callback_detector',['../pearl-anglescan-tracker_8ipf.html#ac953a75b45d65adf37ce5560bf441876',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fcallback_5fmanip',['ast_callback_manip',['../pearl-anglescan-tracker_8ipf.html#a9b4acc299c5e698695baf0b4817ff7eb',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fclose',['ast_close',['../pearl-anglescan-tracker_8ipf.html#a8a74ddd33e286105a45a89105de72621',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fexport',['ast_export',['../pearl-anglescan-tracker_8ipf.html#ac9c92805f39c7a5c68d4c017d14ee178',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fimport',['ast_import',['../pearl-anglescan-tracker_8ipf.html#ae4ece97352b85ced47e954c025e3b69b',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fprepare',['ast_prepare',['../pearl-anglescan-tracker_8ipf.html#a766f90a9dad70d9deb4272ba480ee84a',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fset_5fprocessing',['ast_set_processing',['../pearl-anglescan-tracker_8ipf.html#a02271bf812a3e3f87c958f4c58e9f71b',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fsetup',['ast_setup',['../pearl-anglescan-tracker_8ipf.html#a5fb1f1abddb56b129f053605035d3281',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fupdate_5fdetector',['ast_update_detector',['../pearl-anglescan-tracker_8ipf.html#a150243e26e8adf8b354b8afde064136d',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fwindow_5fhook',['ast_window_hook',['../pearl-anglescan-tracker_8ipf.html#a33e84ae8e13f405d466b28e83f608cb9',1,'pearl-anglescan-tracker.ipf']]], - ['attributes_5fnotebook',['attributes_notebook',['../pearl-data-explorer_8ipf.html#ad6cfb2c00d5112add84542a25eb68b19',1,'pearl-data-explorer.ipf']]], - ['au4f',['Au4f',['../pearl-fitfuncs_8ipf.html#a13a5ee22049d9a3379cd6e55654e70a3',1,'pearl-fitfuncs.ipf']]], - ['au4f_5f2p2',['Au4f_2p2',['../pearl-fitfuncs_8ipf.html#a24cd6a0c96ef8c720e371bb31ac0a479',1,'pearl-fitfuncs.ipf']]], - ['au4f_5f2p3',['Au4f_2p3',['../pearl-fitfuncs_8ipf.html#a709f7c4585b1d850ea8aae1885ac18cb',1,'pearl-fitfuncs.ipf']]], - ['angle_2dscan_20processing',['Angle-scan processing',['../pag_anglescan_processing.html',1,'']]] + ['ad_5fadd_5foverlay_0',['ad_add_overlay',['../pearl-area-display_8ipf.html#af9bd125ed4fb4ada10b78bca2607b44d',1,'pearl-area-display.ipf']]], + ['ad_5fbox_5ffilter_1',['ad_box_filter',['../pearl-area-display_8ipf.html#a27f0957d61f3c2d30a4854911b460c36',1,'pearl-area-display.ipf']]], + ['ad_5fbrick_5fslicer_2',['ad_brick_slicer',['../pearl-area-display_8ipf.html#ae3b4756cdc12a4a4b15a770ba0069823',1,'pearl-area-display.ipf']]], + ['ad_5fcalc_5fcursor_5fprofiles_3',['ad_calc_cursor_profiles',['../pearl-area-display_8ipf.html#a72b57037abd27f65986034c0b4cc191e',1,'pearl-area-display.ipf']]], + ['ad_5fcalc_5fhistogram_4',['ad_calc_histogram',['../pearl-area-display_8ipf.html#a48b08ab53729d9d0477deaceedef2769',1,'pearl-area-display.ipf']]], + ['ad_5fcalc_5fprofiles_5',['ad_calc_profiles',['../pearl-area-display_8ipf.html#a48044f9ee518d47770e33ee9f381f204',1,'pearl-area-display.ipf']]], + ['ad_5fcollect_5fmultiscan_5fy_6',['ad_collect_multiscan_y',['../pearl-area-profiles_8ipf.html#a3cadf0b28d1fd84e9922610c20868283',1,'pearl-area-profiles.ipf']]], + ['ad_5fdefault_5fimage_5ffilter_7',['ad_default_image_filter',['../pearl-area-display_8ipf.html#a6418a1b2d18b82cb71c0fecbd513a934',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_8',['ad_display',['../pearl-area-display_8ipf.html#ae2b11295d2715e9af019513923c64570',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_5fbrick_9',['ad_display_brick',['../pearl-area-display_8ipf.html#a65b07e355df20cfb692dfb32f472b478',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_5fhistogram_10',['ad_display_histogram',['../pearl-area-display_8ipf.html#a8cc3ea3bea4e851e4144140a2da42a03',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_5fprofiles_11',['ad_display_profiles',['../pearl-area-display_8ipf.html#a8fad5aebaca72887d5898b4c421bcdae',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_5fslice_12',['ad_display_slice',['../pearl-area-display_8ipf.html#af8d5e003fcff1f750685ed6f94717730',1,'pearl-area-display.ipf']]], + ['ad_5fexport_5fprofile_13',['ad_export_profile',['../pearl-area-display_8ipf.html#ad3e190d1ec1b82ebef00c9f9ac44b50a',1,'pearl-area-display.ipf']]], + ['ad_5fextract_5frod_14',['ad_extract_rod',['../pearl-area-profiles_8ipf.html#a8de5d4f1bcca91df5bbff568ab7b582d',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5frod_5fx_15',['ad_extract_rod_x',['../pearl-area-profiles_8ipf.html#a83700e2faf844e2480c89b6ca4c66a79',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5frod_5fy_16',['ad_extract_rod_y',['../pearl-area-profiles_8ipf.html#a363af257a04d51fff2a8d5b282f65f21',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5frod_5fz_17',['ad_extract_rod_z',['../pearl-area-profiles_8ipf.html#a3483707fbdbfdbaec069591a5d3b07a6',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5fslab_18',['ad_extract_slab',['../pearl-area-profiles_8ipf.html#a65bb359c057a9d900c486e186c9974df',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5fslab_5fx_19',['ad_extract_slab_x',['../pearl-area-profiles_8ipf.html#af612340d1d132cacda9de7bb77c2e0aa',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5fslab_5fy_20',['ad_extract_slab_y',['../pearl-area-profiles_8ipf.html#a2eb6a0bcced893e827cfa4e1236e8460',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5fslab_5fz_21',['ad_extract_slab_z',['../pearl-area-profiles_8ipf.html#a71f02613c4a4d21c014493e906dbe922',1,'pearl-area-profiles.ipf']]], + ['ad_5fgizmo_5fset_5fplane_22',['ad_gizmo_set_plane',['../pearl-area-display_8ipf.html#aee051acfe6a3c8214118b78dfe4854fd',1,'pearl-area-display.ipf']]], + ['ad_5fload_5fdialog_23',['ad_load_dialog',['../pearl-area-import_8ipf.html#aedff2e67d2e1bac907f2eaf24a6e5c3c',1,'pearl-area-import.ipf']]], + ['ad_5fprofile_5fx_24',['ad_profile_x',['../pearl-area-profiles_8ipf.html#ab1a65cf82f6933db3dd7b564582e8ed1',1,'pearl-area-profiles.ipf']]], + ['ad_5fprofile_5fx_5fw_25',['ad_profile_x_w',['../pearl-area-profiles_8ipf.html#aa40fd5049f993e72fd52a66a6cdde7cc',1,'pearl-area-profiles.ipf']]], + ['ad_5fprofile_5fy_26',['ad_profile_y',['../pearl-area-profiles_8ipf.html#abb1eed32a982037ebab00f5c3ea95e62',1,'pearl-area-profiles.ipf']]], + ['ad_5fprofile_5fy_5fw_27',['ad_profile_y_w',['../pearl-area-profiles_8ipf.html#a8b09e13162fa47cc076e1e661e80b002',1,'pearl-area-profiles.ipf']]], + ['ad_5fprofiles_5fcrosshairs_28',['ad_profiles_crosshairs',['../pearl-area-display_8ipf.html#a6d20a8c6bf5ed143d375dee71fb3a6d5',1,'pearl-area-display.ipf']]], + ['ad_5fprofiles_5fcursor_5fmode_29',['ad_profiles_cursor_mode',['../pearl-area-display_8ipf.html#a5657fc4dcd395aef637c19e8df57a418',1,'pearl-area-display.ipf']]], + ['ad_5fprofiles_5fhook_30',['ad_profiles_hook',['../pearl-area-display_8ipf.html#a89a5e3e29a0cd09951dcdf13aa28d941',1,'pearl-area-display.ipf']]], + ['ad_5fprofiles_5fset_5fcursor_31',['ad_profiles_set_cursor',['../pearl-area-display_8ipf.html#ad2a84495ddac89bc8f4203fca56babfd',1,'pearl-area-display.ipf']]], + ['ad_5fprofiles_5fset_5fslice_32',['ad_profiles_set_slice',['../pearl-area-display_8ipf.html#abaf229d75d9d579a559295795a6bc2e1',1,'pearl-area-display.ipf']]], + ['ad_5fslicer_5finit_5fbg_33',['ad_slicer_init_bg',['../pearl-area-display_8ipf.html#a7334815c60e2c11e2754c07489a62f4b',1,'pearl-area-display.ipf']]], + ['ad_5fslicer_5fmove_5fbg_34',['ad_slicer_move_bg',['../pearl-area-display_8ipf.html#a4af98ec7af48a653c6fac716ea8fa505',1,'pearl-area-display.ipf']]], + ['ad_5fslicer_5fstart_5fbg_35',['ad_slicer_start_bg',['../pearl-area-display_8ipf.html#ad79b37ab4fcf2cbdad6874813d93d4b1',1,'pearl-area-display.ipf']]], + ['ad_5fslicer_5fstop_5fbg_36',['ad_slicer_stop_bg',['../pearl-area-display_8ipf.html#a77a71985e716a300e0b61c233cd93f40',1,'pearl-area-display.ipf']]], + ['ad_5fsuggest_5ffoldername_37',['ad_suggest_foldername',['../pearl-area-import_8ipf.html#ad28dbbba73e553f7b5dcf8baf1c86786',1,'pearl-area-import.ipf']]], + ['ad_5ftranspose_5ffilter_38',['ad_transpose_filter',['../pearl-area-display_8ipf.html#a8411f0cfec3515f1ae4f0140efc14318',1,'pearl-area-display.ipf']]], + ['ad_5fupdate_5fprofiles_39',['ad_update_profiles',['../pearl-area-display_8ipf.html#afa2546f9cb03dfa8bf0cc9966f0b7a45',1,'pearl-area-display.ipf']]], + ['add_5fanglescan_5fworker_40',['add_anglescan_worker',['../pearl-anglescan-process_8ipf.html#a8c83a187e371783dea62c9f2bc97c52c',1,'pearl-anglescan-process.ipf']]], + ['add_5faziscan_5fcore_41',['add_aziscan_core',['../pearl-anglescan-process_8ipf.html#a8eabc7feca73f9e0db2109a78ee382cb',1,'pearl-anglescan-process.ipf']]], + ['add_5fimage_5fdata_42',['add_image_data',['../pearl-anglescan-tracker_8ipf.html#a35a5cd8a21b48be8d726c69eb5fca134',1,'pearl-anglescan-tracker.ipf']]], + ['adh5_5fdefault_5freduction_43',['adh5_default_reduction',['../pearl-area-import_8ipf.html#ade69cb0f82e0c9cf6082d5fcc29f742f',1,'pearl-area-import.ipf']]], + ['adh5_5fget_5fresult_5fwaves_44',['adh5_get_result_waves',['../pearl-area-import_8ipf.html#a27a72a3901a5342ca9dea02e3219631c',1,'pearl-area-import.ipf']]], + ['adh5_5flist_5freduction_5ffuncs_45',['adh5_list_reduction_funcs',['../pearl-area-import_8ipf.html#aa5e29dc1a380311d00a5f85be867e47b',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fcomplete_46',['adh5_load_complete',['../pearl-area-import_8ipf.html#ab1040bf272c69dc69777b2f91df41fab',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fdetector_47',['adh5_load_detector',['../pearl-area-import_8ipf.html#a84dc7f466b42dde5d96c49827b2122cf',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fdetector_5fimage_48',['adh5_load_detector_image',['../pearl-area-import_8ipf.html#a931a7bfaaf75d308a0ce3c74ffc751bc',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fdetector_5fslabs_49',['adh5_load_detector_slabs',['../pearl-area-import_8ipf.html#a4a9741d1c19b10bb98b73bd5163a497b',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5finfo_50',['adh5_load_info',['../pearl-area-import_8ipf.html#ac76d5ba94a3d7c864437420d80c77064',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fpreview_51',['adh5_load_preview',['../pearl-area-import_8ipf.html#a98f29671bdce6a5981e8865de8b9d483',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5freduced_52',['adh5_load_reduced',['../pearl-area-import_8ipf.html#a98f9339cd2fae80d0d92451df88395aa',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5freduced_5fdetector_53',['adh5_load_reduced_detector',['../pearl-area-import_8ipf.html#a3f2ac36f961941e46e80a775de8300e5',1,'pearl-area-import.ipf']]], + ['adh5_5floadattr_5fall_54',['adh5_loadattr_all',['../pearl-area-import_8ipf.html#acde16dc7a393250b17165344f865f7b5',1,'pearl-area-import.ipf']]], + ['adh5_5fredim_55',['adh5_redim',['../pearl-area-import_8ipf.html#acfa6d2675e63f4f686289ef853b262a9',1,'pearl-area-import.ipf']]], + ['adh5_5freduce_5fbrick_56',['adh5_reduce_brick',['../pearl-area-import_8ipf.html#ae88bc41882fd16c94c04d856f3e062e4',1,'pearl-area-import.ipf']]], + ['adh5_5fscale_57',['adh5_scale',['../pearl-area-import_8ipf.html#a774751d1857ea6946a942448dc913128',1,'pearl-area-import.ipf']]], + ['adh5_5fscale_5fscan_58',['adh5_scale_scan',['../pearl-area-import_8ipf.html#a1fdcc02340375afe8d8cd7537c6e9cfb',1,'pearl-area-import.ipf']]], + ['adh5_5fscale_5fscienta_59',['adh5_scale_scienta',['../pearl-area-import_8ipf.html#a227e4db1c51a910dcf86d355473fe74e',1,'pearl-area-import.ipf']]], + ['adh5_5fsetup_5fprofile_60',['adh5_setup_profile',['../pearl-area-import_8ipf.html#a9439de3b676e686eeca4e6b2588c01a6',1,'pearl-area-import.ipf']]], + ['adh5_5ftest_5freduction_5ffunc_61',['adh5_test_reduction_func',['../pearl-area-import_8ipf.html#a98804ce23a5c2c314ac243baa0824424',1,'pearl-area-import.ipf']]], + ['aftercompiledhook_62',['AfterCompiledHook',['../pearl-anglescan-panel_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-anglescan-tracker.ipf'],['../pearl-arpes_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-arpes.ipf']]], + ['afterfileopenhook_63',['AfterFileOpenHook',['../pearl-elog_8ipf.html#a3f524f5190341d2accc8cb8c3ed2ceb5',1,'AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a3f524f5190341d2accc8cb8c3ed2ceb5',1,'AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind): pearl-matrix-import.ipf']]], + ['already_5ffile_5fopen_64',['ALREADY_FILE_OPEN',['../structerror_code.html#a19dc49bdfb4bd9601f17f907da158026',1,'errorCode']]], + ['analyse_5fcurved_5fedge_65',['analyse_curved_edge',['../fermi-edge-analysis_8ipf.html#a1c4a805435a1d43c2b6dfb6deb633894',1,'fermi-edge-analysis.ipf']]], + ['analyser_5fenergy_5fresolution_66',['analyser_energy_resolution',['../pearl-scienta-live_8ipf.html#ad23de34bb698589e2576ce2836b89d55',1,'pearl-scienta-live.ipf']]], + ['anglescan_2dprocessing_2edox_67',['anglescan-processing.dox',['../anglescan-processing_8dox.html',1,'']]], + ['angletok_68',['AngleToK',['../pearl-anglescan-process_8ipf.html#acf6fddb73624fe2d21429e38c4994088',1,'pearl-anglescan-process.ipf']]], + ['appendtographiterator_69',['AppendToGraphIterator',['../pearl-tools_8ipf.html#a90c62bdfc186e2482ccb18113a591d5e',1,'pearl-tools.ipf']]], + ['arpes_20package_70',['ARPES package',['../group___arpes_package.html',1,'']]], + ['arrange_5fcontrols_71',['arrange_controls',['../pearl-anglescan-panel_8ipf.html#a65dbeab54647d7c27a139035d69c812f',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fcalculate_5foutput_72',['asp_calculate_output',['../pearl-anglescan-panel_8ipf.html#af21424ce00e4bac1ac990d2bb83d46dc',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fclose_5fgraphs_73',['asp_close_graphs',['../pearl-anglescan-panel_8ipf.html#aac9d4d0388cbe8e6aa8f47b1c5276d83',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fdisplay_5fdist_5fcheck_74',['asp_display_dist_check',['../pearl-anglescan-panel_8ipf.html#a59886414c7dc2486c5a17f078896c705',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fdisplay_5foutput_75',['asp_display_output',['../pearl-anglescan-panel_8ipf.html#a8e540427fab71f879e84003c49c59f22',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fdisplay_5fpreviews_76',['asp_display_previews',['../pearl-anglescan-panel_8ipf.html#a66b3eef1fd0be13dfef0a66781f55062',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fduplicate_5foutput_77',['asp_duplicate_output',['../pearl-anglescan-panel_8ipf.html#adf7c5a4e7c66c3d6e13d01674b9cf47f',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fimport_5fraw_78',['asp_import_raw',['../pearl-anglescan-panel_8ipf.html#a21aab19fbcde395df6e1ea8654b3af9a',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fsave_5foutput_5fetpi_79',['asp_save_output_etpi',['../pearl-anglescan-panel_8ipf.html#abb4d53822bc34bda0e38332c7777ebac',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fsave_5foutput_5fitx_80',['asp_save_output_itx',['../pearl-anglescan-panel_8ipf.html#a0e0f10d125f1cdacffa3bff9b0854aa9',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fshow_5fpanel_81',['asp_show_panel',['../pearl-anglescan-panel_8ipf.html#a452f09c3057638056ac2b5a15ac660b2',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fupdate_5fgraph_82',['asp_update_graph',['../pearl-anglescan-panel_8ipf.html#a93dc5a029ae9831066e6ad133522ee88',1,'pearl-anglescan-panel.ipf']]], + ['ast_5fadd_5fimage_83',['ast_add_image',['../pearl-anglescan-tracker_8ipf.html#a43d85b93bb42a67b8e8afb9afc8d8eae',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fcallback_5fdata_84',['ast_callback_data',['../pearl-anglescan-tracker_8ipf.html#a4cf5ad2fdf771ffc157a3924a03f5a46',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fcallback_5fdetector_85',['ast_callback_detector',['../pearl-anglescan-tracker_8ipf.html#ac953a75b45d65adf37ce5560bf441876',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fcallback_5fmanip_86',['ast_callback_manip',['../pearl-anglescan-tracker_8ipf.html#a9b4acc299c5e698695baf0b4817ff7eb',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fclose_87',['ast_close',['../pearl-anglescan-tracker_8ipf.html#a8a74ddd33e286105a45a89105de72621',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fexport_88',['ast_export',['../pearl-anglescan-tracker_8ipf.html#ac9c92805f39c7a5c68d4c017d14ee178',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fimport_89',['ast_import',['../pearl-anglescan-tracker_8ipf.html#ae4ece97352b85ced47e954c025e3b69b',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fprepare_90',['ast_prepare',['../pearl-anglescan-tracker_8ipf.html#a766f90a9dad70d9deb4272ba480ee84a',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fset_5fprocessing_91',['ast_set_processing',['../pearl-anglescan-tracker_8ipf.html#a02271bf812a3e3f87c958f4c58e9f71b',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fsetup_92',['ast_setup',['../pearl-anglescan-tracker_8ipf.html#a5fb1f1abddb56b129f053605035d3281',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fupdate_5fdetector_93',['ast_update_detector',['../pearl-anglescan-tracker_8ipf.html#a150243e26e8adf8b354b8afde064136d',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fwindow_5fhook_94',['ast_window_hook',['../pearl-anglescan-tracker_8ipf.html#a33e84ae8e13f405d466b28e83f608cb9',1,'pearl-anglescan-tracker.ipf']]], + ['attributes_5fnotebook_95',['attributes_notebook',['../pearl-data-explorer_8ipf.html#a844467a592e5b26b2324326f22b7da89',1,'pearl-data-explorer.ipf']]], + ['au4f_96',['Au4f',['../pearl-fitfuncs_8ipf.html#a13a5ee22049d9a3379cd6e55654e70a3',1,'pearl-fitfuncs.ipf']]], + ['au4f_5f2p2_97',['Au4f_2p2',['../pearl-fitfuncs_8ipf.html#a24cd6a0c96ef8c720e371bb31ac0a479',1,'pearl-fitfuncs.ipf']]], + ['au4f_5f2p3_98',['Au4f_2p3',['../pearl-fitfuncs_8ipf.html#a709f7c4585b1d850ea8aae1885ac18cb',1,'pearl-fitfuncs.ipf']]], + ['angle_2dscan_20processing_99',['Angle-scan processing',['../pag_anglescan_processing.html',1,'']]] ]; diff --git a/doc/html/search/all_1.html b/doc/html/search/all_1.html index b13f0f7..8eb215b 100644 --- a/doc/html/search/all_1.html +++ b/doc/html/search/all_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_1.js b/doc/html/search/all_1.js index 1aad0b3..44e4b65 100644 --- a/doc/html/search/all_1.js +++ b/doc/html/search/all_1.js @@ -1,50 +1,48 @@ var searchData= [ - ['beforefileopenhook',['BeforeFileOpenHook',['../pearl-area-import_8ipf.html#ae2cfa1ac6651cfc3fb0dfce03494995b',1,'BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind): pearl-area-import.ipf'],['../pearl-matrix-import_8ipf.html#ae2cfa1ac6651cfc3fb0dfce03494995b',1,'BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind): pearl-matrix-import.ipf']]], - ['bp_5fattach',['bp_attach',['../pearl-elog_8ipf.html#acbba78d869a543edf7c2b80d7a8d2344',1,'pearl-elog.ipf']]], - ['bp_5fattach_5fallnone',['bp_attach_allnone',['../pearl-elog_8ipf.html#a4040736819edadf4b26982bcfdb9c7b9',1,'pearl-elog.ipf']]], - ['bp_5fattach_5ftop',['bp_attach_top',['../pearl-elog_8ipf.html#a91b5f51982d23a36d1760b8874b5736a',1,'pearl-elog.ipf']]], - ['bp_5fattach_5fupdown',['bp_attach_updown',['../pearl-elog_8ipf.html#aa1dfae6d78a367d50ee8fc1ffe9cb69b',1,'pearl-elog.ipf']]], - ['bp_5fattr_5fnotebook',['bp_attr_notebook',['../pearl-data-explorer_8ipf.html#a4ef196f752bb5780ed4f4a588f9ebc81',1,'pearl-data-explorer.ipf']]], - ['bp_5fbrowse_5ffilepath',['bp_browse_filepath',['../pearl-data-explorer_8ipf.html#a02a64144b7ed2c1bc230e265c55e81a1',1,'pearl-data-explorer.ipf']]], - ['bp_5fcapture',['bp_capture',['../pearl-anglescan-tracker_8ipf.html#afaec8443094530fd1e723251e04c5dc9',1,'pearl-anglescan-tracker.ipf']]], - ['bp_5fclear',['bp_clear',['../pearl-elog_8ipf.html#ab39637298c93b7aefd67febf3a4e7672',1,'pearl-elog.ipf']]], - ['bp_5fcrop_5fpreview',['bp_crop_preview',['../pearl-anglescan-panel_8ipf.html#a57c666f93cb4310fadf13b1916eaf134',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fdataset_5fdisplay',['bp_dataset_display',['../pearl-data-explorer_8ipf.html#a5660c6f5f78d880b0805bad4eefed1d5',1,'pearl-data-explorer.ipf']]], - ['bp_5fdataset_5ffolder',['bp_dataset_folder',['../pearl-data-explorer_8ipf.html#a6b642da731bde1029e0fa2ff69d5fb06',1,'pearl-data-explorer.ipf']]], - ['bp_5fdataset_5fnext',['bp_dataset_next',['../pearl-data-explorer_8ipf.html#a3bbb332e319ef7ec5f0fe2d16afaf005',1,'pearl-data-explorer.ipf']]], - ['bp_5fdataset_5fprev',['bp_dataset_prev',['../pearl-data-explorer_8ipf.html#add62ff5193206c9f207952bcd72dac88',1,'pearl-data-explorer.ipf']]], - ['bp_5fextract_5fslice',['bp_extract_slice',['../pearl-area-display_8ipf.html#a31461b664ec651a39442e9a46ffd88c9',1,'pearl-area-display.ipf']]], - ['bp_5ffile_5fnext',['bp_file_next',['../pearl-data-explorer_8ipf.html#a9cefcdc49b2169e99c743b0a683ed3a6',1,'pearl-data-explorer.ipf']]], - ['bp_5ffile_5fprev',['bp_file_prev',['../pearl-data-explorer_8ipf.html#a6aa44ff12b8530adbaaaf7405b1a68ba',1,'pearl-data-explorer.ipf']]], - ['bp_5fgraph_5fpng',['bp_graph_png',['../pearl-anglescan-panel_8ipf.html#a9be861636d98d7891e6d106deac2f90b',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fgraph_5fupdate',['bp_graph_update',['../pearl-anglescan-panel_8ipf.html#a940f2115fb5b47e19516168d15346472',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fload_5ffiles',['bp_load_files',['../pearl-data-explorer_8ipf.html#a742902dfaf2246f10b70f52805c6df1f',1,'pearl-data-explorer.ipf']]], - ['bp_5fload_5ffiles_5fopt',['bp_load_files_opt',['../pearl-data-explorer_8ipf.html#ad61aa85dcf24dbf7e093dac3d0bf6f19',1,'pearl-data-explorer.ipf']]], - ['bp_5fload_5fprefs',['bp_load_prefs',['../pearl-anglescan-panel_8ipf.html#a1868754e64cb1448e564c0936e78574d',1,'bp_load_prefs(WMButtonAction *ba): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#a1868754e64cb1448e564c0936e78574d',1,'bp_load_prefs(WMButtonAction *ba): pearl-data-explorer.ipf']]], - ['bp_5flogin',['bp_login',['../pearl-elog_8ipf.html#a14f8376a0485aa654ccf3d2f30ab4d01',1,'pearl-elog.ipf']]], - ['bp_5flogout',['bp_logout',['../pearl-elog_8ipf.html#ad4472ea917691c41ad0b4ea6f36010a5',1,'pearl-elog.ipf']]], - ['bp_5fmove_5fslice',['bp_move_slice',['../pearl-area-display_8ipf.html#ab8c9979c6f3ab95f983c2a525a69c035',1,'pearl-area-display.ipf']]], - ['bp_5fmove_5fslice_5fcenter',['bp_move_slice_center',['../pearl-area-display_8ipf.html#abe702d40071e3c5e662eb8d47dd6d885',1,'pearl-area-display.ipf']]], - ['bp_5fnorm_5falpha_5fcheck',['bp_norm_alpha_check',['../pearl-anglescan-panel_8ipf.html#a630dfc775d45843c71c279bbb01d05a6',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5falpha_5fpreview',['bp_norm_alpha_preview',['../pearl-anglescan-panel_8ipf.html#aaaf3facc118f90a8f1b32948446899b3',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5fphi_5fcheck',['bp_norm_phi_check',['../pearl-anglescan-panel_8ipf.html#ae42eb7f46e5c1a1b5d334ebb5e94d2d3',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5fphi_5fpreview',['bp_norm_phi_preview',['../pearl-anglescan-panel_8ipf.html#a740c8a80ab2fc0550a05cf3b032821d0',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5ftheta_5fcheck',['bp_norm_theta_check',['../pearl-anglescan-panel_8ipf.html#a0931ce925d2dae6a1bb7e4a65a8a2be7',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5ftheta_5fpreview',['bp_norm_theta_preview',['../pearl-anglescan-panel_8ipf.html#af57abb0a7d41b800d33bb748f9fc5c38',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5fthetaphi_5fcheck',['bp_norm_thetaphi_check',['../pearl-anglescan-panel_8ipf.html#a89caab501e8f15262d6e4f2fa5b4a1bd',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5fthetaphi_5fpreview',['bp_norm_thetaphi_preview',['../pearl-anglescan-panel_8ipf.html#aaa3478a3b0f26b12a12196cfaa87a8ae',1,'pearl-anglescan-panel.ipf']]], - ['bp_5foutput_5fcalc',['bp_output_calc',['../pearl-anglescan-panel_8ipf.html#adefddc5f384948c9dab3ee65b4a0668a',1,'pearl-anglescan-panel.ipf']]], - ['bp_5foutput_5fduplicate',['bp_output_duplicate',['../pearl-anglescan-panel_8ipf.html#ae838bde232c45d81f88303e91b16326b',1,'pearl-anglescan-panel.ipf']]], - ['bp_5foutput_5fetpi',['bp_output_etpi',['../pearl-anglescan-panel_8ipf.html#a16d2f6a58fedc370d7901126bb814bbb',1,'pearl-anglescan-panel.ipf']]], - ['bp_5foutput_5fitx',['bp_output_itx',['../pearl-anglescan-panel_8ipf.html#a0bdc14f90bdc40045200ac23229b225d',1,'pearl-anglescan-panel.ipf']]], - ['bp_5freset_5fcursors',['bp_reset_cursors',['../pearl-area-display_8ipf.html#a24b17f99fafd8043ed3e4502000da316',1,'pearl-area-display.ipf']]], - ['bp_5fsave_5fgraphs',['bp_save_graphs',['../pearl-elog_8ipf.html#a8251cea45c8d1f1993a4051a6d0760c4',1,'pearl-elog.ipf']]], - ['bp_5fsave_5fprefs',['bp_save_prefs',['../pearl-anglescan-panel_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5',1,'bp_save_prefs(WMButtonAction *ba): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5',1,'bp_save_prefs(WMButtonAction *ba): pearl-data-explorer.ipf']]], - ['bp_5fsource_5fselect',['bp_source_select',['../pearl-anglescan-panel_8ipf.html#a1e50019bc895a0787cb3f07d776e9463',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fsource_5fupdate',['bp_source_update',['../pearl-anglescan-panel_8ipf.html#a7ab3962d1d9d50d6cd285d40d4a7ce50',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fsubmit',['bp_submit',['../pearl-elog_8ipf.html#adeff6678e57313cb218824f06d32b5ec',1,'pearl-elog.ipf']]], - ['bp_5fupdate_5fdatasets',['bp_update_datasets',['../pearl-data-explorer_8ipf.html#af9f8769ca2989f152f23d976d1467a48',1,'pearl-data-explorer.ipf']]], - ['bp_5fupdate_5ffilelist',['bp_update_filelist',['../pearl-data-explorer_8ipf.html#a45be265789a5260e3daa05eca0ec309e',1,'pearl-data-explorer.ipf']]], - ['broadening',['broadening',['../struct_doniach_sunjic_struct.html#ac9b18c8b44b43c2ee438f37f8d002a66',1,'DoniachSunjicStruct']]] + ['beforefileopenhook_100',['BeforeFileOpenHook',['../pearl-area-import_8ipf.html#ae2cfa1ac6651cfc3fb0dfce03494995b',1,'BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind): pearl-area-import.ipf'],['../pearl-matrix-import_8ipf.html#ae2cfa1ac6651cfc3fb0dfce03494995b',1,'BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind): pearl-matrix-import.ipf']]], + ['bp_5fattach_101',['bp_attach',['../pearl-elog_8ipf.html#acbba78d869a543edf7c2b80d7a8d2344',1,'pearl-elog.ipf']]], + ['bp_5fattach_5fallnone_102',['bp_attach_allnone',['../pearl-elog_8ipf.html#a4040736819edadf4b26982bcfdb9c7b9',1,'pearl-elog.ipf']]], + ['bp_5fattach_5ftop_103',['bp_attach_top',['../pearl-elog_8ipf.html#a91b5f51982d23a36d1760b8874b5736a',1,'pearl-elog.ipf']]], + ['bp_5fattach_5fupdown_104',['bp_attach_updown',['../pearl-elog_8ipf.html#aa1dfae6d78a367d50ee8fc1ffe9cb69b',1,'pearl-elog.ipf']]], + ['bp_5fattr_5fnotebook_105',['bp_attr_notebook',['../pearl-data-explorer_8ipf.html#a4ef196f752bb5780ed4f4a588f9ebc81',1,'pearl-data-explorer.ipf']]], + ['bp_5fbrowse_5ffilepath_106',['bp_browse_filepath',['../pearl-data-explorer_8ipf.html#a02a64144b7ed2c1bc230e265c55e81a1',1,'pearl-data-explorer.ipf']]], + ['bp_5fcapture_107',['bp_capture',['../pearl-anglescan-tracker_8ipf.html#afaec8443094530fd1e723251e04c5dc9',1,'pearl-anglescan-tracker.ipf']]], + ['bp_5fclear_108',['bp_clear',['../pearl-elog_8ipf.html#ab39637298c93b7aefd67febf3a4e7672',1,'pearl-elog.ipf']]], + ['bp_5fcrop_5fpreview_109',['bp_crop_preview',['../pearl-anglescan-panel_8ipf.html#a57c666f93cb4310fadf13b1916eaf134',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fdisplay_5fdataset_110',['bp_display_dataset',['../pearl-data-explorer_8ipf.html#a0f7473343cf773af9efedee1a18ac5db',1,'pearl-data-explorer.ipf']]], + ['bp_5felog_111',['bp_elog',['../pearl-data-explorer_8ipf.html#a64bd3e5e68b30c94db00c58fa3be3f0d',1,'pearl-data-explorer.ipf']]], + ['bp_5fextract_5fslice_112',['bp_extract_slice',['../pearl-area-display_8ipf.html#a31461b664ec651a39442e9a46ffd88c9',1,'pearl-area-display.ipf']]], + ['bp_5ffile_5fnext_113',['bp_file_next',['../pearl-data-explorer_8ipf.html#a9cefcdc49b2169e99c743b0a683ed3a6',1,'pearl-data-explorer.ipf']]], + ['bp_5ffile_5fprev_114',['bp_file_prev',['../pearl-data-explorer_8ipf.html#a6aa44ff12b8530adbaaaf7405b1a68ba',1,'pearl-data-explorer.ipf']]], + ['bp_5fgoto_5fdataset_115',['bp_goto_dataset',['../pearl-data-explorer_8ipf.html#a01e48e67a22dc56851447bd77abecbe1',1,'pearl-data-explorer.ipf']]], + ['bp_5fgraph_5fpng_116',['bp_graph_png',['../pearl-anglescan-panel_8ipf.html#a9be861636d98d7891e6d106deac2f90b',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fgraph_5fupdate_117',['bp_graph_update',['../pearl-anglescan-panel_8ipf.html#a940f2115fb5b47e19516168d15346472',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fload_5foptions_118',['bp_load_options',['../pearl-data-explorer_8ipf.html#a3fd06ac9aa62de7f00e10ce749ba12c9',1,'pearl-data-explorer.ipf']]], + ['bp_5fload_5fprefs_119',['bp_load_prefs',['../pearl-anglescan-panel_8ipf.html#a1868754e64cb1448e564c0936e78574d',1,'bp_load_prefs(WMButtonAction *ba): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#a1868754e64cb1448e564c0936e78574d',1,'bp_load_prefs(WMButtonAction *ba): pearl-data-explorer.ipf']]], + ['bp_5flogin_120',['bp_login',['../pearl-elog_8ipf.html#a14f8376a0485aa654ccf3d2f30ab4d01',1,'pearl-elog.ipf']]], + ['bp_5flogout_121',['bp_logout',['../pearl-elog_8ipf.html#ad4472ea917691c41ad0b4ea6f36010a5',1,'pearl-elog.ipf']]], + ['bp_5fmove_5fslice_122',['bp_move_slice',['../pearl-area-display_8ipf.html#ab8c9979c6f3ab95f983c2a525a69c035',1,'pearl-area-display.ipf']]], + ['bp_5fmove_5fslice_5fcenter_123',['bp_move_slice_center',['../pearl-area-display_8ipf.html#abe702d40071e3c5e662eb8d47dd6d885',1,'pearl-area-display.ipf']]], + ['bp_5fnorm_5falpha_5fcheck_124',['bp_norm_alpha_check',['../pearl-anglescan-panel_8ipf.html#a630dfc775d45843c71c279bbb01d05a6',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5falpha_5fpreview_125',['bp_norm_alpha_preview',['../pearl-anglescan-panel_8ipf.html#aaaf3facc118f90a8f1b32948446899b3',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5fphi_5fcheck_126',['bp_norm_phi_check',['../pearl-anglescan-panel_8ipf.html#ae42eb7f46e5c1a1b5d334ebb5e94d2d3',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5fphi_5fpreview_127',['bp_norm_phi_preview',['../pearl-anglescan-panel_8ipf.html#a740c8a80ab2fc0550a05cf3b032821d0',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5ftheta_5fcheck_128',['bp_norm_theta_check',['../pearl-anglescan-panel_8ipf.html#a0931ce925d2dae6a1bb7e4a65a8a2be7',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5ftheta_5fpreview_129',['bp_norm_theta_preview',['../pearl-anglescan-panel_8ipf.html#af57abb0a7d41b800d33bb748f9fc5c38',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5fthetaphi_5fcheck_130',['bp_norm_thetaphi_check',['../pearl-anglescan-panel_8ipf.html#a89caab501e8f15262d6e4f2fa5b4a1bd',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5fthetaphi_5fpreview_131',['bp_norm_thetaphi_preview',['../pearl-anglescan-panel_8ipf.html#aaa3478a3b0f26b12a12196cfaa87a8ae',1,'pearl-anglescan-panel.ipf']]], + ['bp_5foutput_5fcalc_132',['bp_output_calc',['../pearl-anglescan-panel_8ipf.html#adefddc5f384948c9dab3ee65b4a0668a',1,'pearl-anglescan-panel.ipf']]], + ['bp_5foutput_5fduplicate_133',['bp_output_duplicate',['../pearl-anglescan-panel_8ipf.html#ae838bde232c45d81f88303e91b16326b',1,'pearl-anglescan-panel.ipf']]], + ['bp_5foutput_5fetpi_134',['bp_output_etpi',['../pearl-anglescan-panel_8ipf.html#a16d2f6a58fedc370d7901126bb814bbb',1,'pearl-anglescan-panel.ipf']]], + ['bp_5foutput_5fitx_135',['bp_output_itx',['../pearl-anglescan-panel_8ipf.html#a0bdc14f90bdc40045200ac23229b225d',1,'pearl-anglescan-panel.ipf']]], + ['bp_5freduction_5fparams_136',['bp_reduction_params',['../pearl-data-explorer_8ipf.html#a70150946799d759473b409b3371e3ae2',1,'pearl-data-explorer.ipf']]], + ['bp_5freset_5fcursors_137',['bp_reset_cursors',['../pearl-area-display_8ipf.html#a24b17f99fafd8043ed3e4502000da316',1,'pearl-area-display.ipf']]], + ['bp_5fsave_5fgraphs_138',['bp_save_graphs',['../pearl-elog_8ipf.html#a8251cea45c8d1f1993a4051a6d0760c4',1,'pearl-elog.ipf']]], + ['bp_5fsave_5fprefs_139',['bp_save_prefs',['../pearl-anglescan-panel_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5',1,'bp_save_prefs(WMButtonAction *ba): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5',1,'bp_save_prefs(WMButtonAction *ba): pearl-data-explorer.ipf']]], + ['bp_5fsource_5fselect_140',['bp_source_select',['../pearl-anglescan-panel_8ipf.html#a1e50019bc895a0787cb3f07d776e9463',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fsource_5fupdate_141',['bp_source_update',['../pearl-anglescan-panel_8ipf.html#a7ab3962d1d9d50d6cd285d40d4a7ce50',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fsubmit_142',['bp_submit',['../pearl-elog_8ipf.html#adeff6678e57313cb218824f06d32b5ec',1,'pearl-elog.ipf']]], + ['bp_5fupdate_5ffilelist_143',['bp_update_filelist',['../pearl-data-explorer_8ipf.html#a45be265789a5260e3daa05eca0ec309e',1,'pearl-data-explorer.ipf']]], + ['broadening_144',['broadening',['../struct_doniach_sunjic_struct.html#ac9b18c8b44b43c2ee438f37f8d002a66',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/all_10.html b/doc/html/search/all_10.html index d1345a1..6fd3a4a 100644 --- a/doc/html/search/all_10.html +++ b/doc/html/search/all_10.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_10.js b/doc/html/search/all_10.js index 81e5645..4c41fdc 100644 --- a/doc/html/search/all_10.js +++ b/doc/html/search/all_10.js @@ -1,15 +1,15 @@ var searchData= [ - ['read_5fattribute_5finfo',['read_attribute_info',['../pearl-area-import_8ipf.html#ac98a5f2d12b559aba4e53192c49a7743',1,'pearl-area-import.ipf']]], - ['record_5fresults',['record_results',['../fermi-edge-analysis_8ipf.html#aac6bac1ee0582caa0676bdc9c2d254f0',1,'fermi-edge-analysis.ipf']]], - ['redim_5flinbg_5freduction',['redim_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a8e2aef3e0d5f2b304399a11423661fdc',1,'pearl-scienta-preprocess.ipf']]], - ['reduce_5fbrick_5fworker',['reduce_brick_worker',['../pearl-area-import_8ipf.html#a4efc9178892310c9e2caf40c61d71bd7',1,'pearl-area-import.ipf']]], - ['reduce_5fslab_5fimage',['reduce_slab_image',['../pearl-area-import_8ipf.html#a44d495fba0dd2b82dec13760a07fd226',1,'reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param): pearl-area-import.ipf'],['../pearl-pshell-import_8ipf.html#a44d495fba0dd2b82dec13760a07fd226',1,'reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param): pearl-pshell-import.ipf']]], - ['reduce_5fslab_5fworker',['reduce_slab_worker',['../pearl-area-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6',1,'reduce_slab_worker(funcref reduction_func): pearl-area-import.ipf'],['../pearl-pshell-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6',1,'reduce_slab_worker(funcref reduction_func): pearl-pshell-import.ipf']]], - ['rotate2d_5fx',['rotate2d_x',['../pearl-vector-operations_8ipf.html#ac579a92f012f0d0ef7b8f097e1c8b3c7',1,'pearl-vector-operations.ipf']]], - ['rotate2d_5fy',['rotate2d_y',['../pearl-vector-operations_8ipf.html#a355150c423ab975fe7f1832917118ea3',1,'pearl-vector-operations.ipf']]], - ['rotate_5fhemi_5fscan',['rotate_hemi_scan',['../pearl-anglescan-process_8ipf.html#a5162488b366e217195d8f8bd7cdde0ce',1,'pearl-anglescan-process.ipf']]], - ['rotate_5fx_5fwave',['rotate_x_wave',['../pearl-vector-operations_8ipf.html#ada80428496dc748b960bd9c65df7da8b',1,'pearl-vector-operations.ipf']]], - ['rotate_5fy_5fwave',['rotate_y_wave',['../pearl-vector-operations_8ipf.html#adfd1d68e739694982fbd00b76568c1c0',1,'pearl-vector-operations.ipf']]], - ['rotate_5fz_5fwave',['rotate_z_wave',['../pearl-vector-operations_8ipf.html#a0030e927980581d57781ad391f2d872a',1,'pearl-vector-operations.ipf']]] + ['read_5fattribute_5finfo_526',['read_attribute_info',['../pearl-area-import_8ipf.html#ac98a5f2d12b559aba4e53192c49a7743',1,'pearl-area-import.ipf']]], + ['record_5fresults_527',['record_results',['../fermi-edge-analysis_8ipf.html#aac6bac1ee0582caa0676bdc9c2d254f0',1,'fermi-edge-analysis.ipf']]], + ['redim_5flinbg_5freduction_528',['redim_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a8e2aef3e0d5f2b304399a11423661fdc',1,'pearl-scienta-preprocess.ipf']]], + ['reduce_5fbrick_5fworker_529',['reduce_brick_worker',['../pearl-area-import_8ipf.html#a4efc9178892310c9e2caf40c61d71bd7',1,'pearl-area-import.ipf']]], + ['reduce_5fslab_5fimage_530',['reduce_slab_image',['../pearl-area-import_8ipf.html#a44d495fba0dd2b82dec13760a07fd226',1,'reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param): pearl-area-import.ipf'],['../pearl-pshell-import_8ipf.html#a8089a75744ffc3626305406e925d320a',1,'reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_params): pearl-pshell-import.ipf']]], + ['reduce_5fslab_5fworker_531',['reduce_slab_worker',['../pearl-area-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6',1,'reduce_slab_worker(funcref reduction_func): pearl-area-import.ipf'],['../pearl-pshell-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6',1,'reduce_slab_worker(funcref reduction_func): pearl-pshell-import.ipf']]], + ['rotate2d_5fx_532',['rotate2d_x',['../pearl-vector-operations_8ipf.html#ac579a92f012f0d0ef7b8f097e1c8b3c7',1,'pearl-vector-operations.ipf']]], + ['rotate2d_5fy_533',['rotate2d_y',['../pearl-vector-operations_8ipf.html#a355150c423ab975fe7f1832917118ea3',1,'pearl-vector-operations.ipf']]], + ['rotate_5fhemi_5fscan_534',['rotate_hemi_scan',['../pearl-anglescan-process_8ipf.html#a5162488b366e217195d8f8bd7cdde0ce',1,'pearl-anglescan-process.ipf']]], + ['rotate_5fx_5fwave_535',['rotate_x_wave',['../pearl-vector-operations_8ipf.html#ada80428496dc748b960bd9c65df7da8b',1,'pearl-vector-operations.ipf']]], + ['rotate_5fy_5fwave_536',['rotate_y_wave',['../pearl-vector-operations_8ipf.html#adfd1d68e739694982fbd00b76568c1c0',1,'pearl-vector-operations.ipf']]], + ['rotate_5fz_5fwave_537',['rotate_z_wave',['../pearl-vector-operations_8ipf.html#a0030e927980581d57781ad391f2d872a',1,'pearl-vector-operations.ipf']]] ]; diff --git a/doc/html/search/all_11.html b/doc/html/search/all_11.html index 2be8b71..f78343b 100644 --- a/doc/html/search/all_11.html +++ b/doc/html/search/all_11.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_11.js b/doc/html/search/all_11.js index 46c8db6..54e1578 100644 --- a/doc/html/search/all_11.js +++ b/doc/html/search/all_11.js @@ -1,36 +1,40 @@ var searchData= [ - ['save_5fhemi_5fscan',['save_hemi_scan',['../pearl-anglescan-process_8ipf.html#a48cbd596656bc6d849c53afb4c58b90d',1,'pearl-anglescan-process.ipf']]], - ['save_5fprefs',['save_prefs',['../pearl-anglescan-panel_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-elog.ipf']]], - ['save_5fscan_5fhelper',['save_scan_helper',['../pearl-pmsco-import_8ipf.html#a0a53a4686b482d62fe1797932a1708db',1,'pearl-pmsco-import.ipf']]], - ['save_5ftracker_5fdata',['save_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a8d6e9058f2b0b4978f56e892ce199e6a',1,'pearl-anglescan-tracker.ipf']]], - ['scientalivedisplay',['ScientaLiveDisplay',['../pearl-scienta-countrate_8ipf.html#a55886895329455b36b64d52ed6a4e228',1,'pearl-scienta-countrate.ipf']]], - ['select_5fdataset',['select_dataset',['../pearl-pshell-import_8ipf.html#abb4afdef6ae4476c25a1ff77b17266c3',1,'pearl-pshell-import.ipf']]], - ['set_5fcontrast',['set_contrast',['../pearl-anglescan-process_8ipf.html#a666dab03bb2e97ffef81cea450184d42',1,'pearl-anglescan-process.ipf']]], - ['set_5fpanel_5fattributes',['set_panel_attributes',['../pearl-elog_8ipf.html#a39a1f418c8a2f9a5e4ab976827d8efca',1,'pearl-elog.ipf']]], - ['set_5fpanel_5fgraphs',['set_panel_graphs',['../pearl-elog_8ipf.html#a6eca5f4fab999984df32b50dd669c0b1',1,'pearl-elog.ipf']]], - ['set_5fpanel_5fmessage',['set_panel_message',['../pearl-elog_8ipf.html#aa7a3988440bb6d73573b50a4698a0e75',1,'pearl-elog.ipf']]], - ['set_5fpolar_5fgraph_5fcursor',['set_polar_graph_cursor',['../pearl-anglescan-process_8ipf.html#a70b0e243bcbd549e2b1da74aab605629',1,'pearl-anglescan-process.ipf']]], - ['set_5frotation_5fx',['set_rotation_x',['../pearl-vector-operations_8ipf.html#a8a8dff94d9f7b992c2c2c0744001e74b',1,'pearl-vector-operations.ipf']]], - ['set_5frotation_5fy',['set_rotation_y',['../pearl-vector-operations_8ipf.html#adfdf1cfe8812d8d0006228f6c14c9582',1,'pearl-vector-operations.ipf']]], - ['set_5frotation_5fz',['set_rotation_z',['../pearl-vector-operations_8ipf.html#a76feca10fe5d3e085f01c73a59b38424',1,'pearl-vector-operations.ipf']]], - ['set_5ftrace_5fcolors',['set_trace_colors',['../pearl-area-display_8ipf.html#abafc4f012b04592724109f4757cbe271',1,'pearl-area-display.ipf']]], - ['setup_5fdata',['setup_data',['../pearl-anglescan-tracker_8ipf.html#a6bfd8b6eba0b206df6ec56c7b6489e0b',1,'pearl-anglescan-tracker.ipf']]], - ['setup_5fdetector',['setup_detector',['../pearl-anglescan-tracker_8ipf.html#aa79c1d1584eb2322adae328bf1437f34',1,'pearl-anglescan-tracker.ipf']]], - ['setup_5fgraph',['setup_graph',['../pearl-anglescan-tracker_8ipf.html#aa7c4e3e0ed255e61bc80f8b27b78fce6',1,'pearl-anglescan-tracker.ipf']]], - ['shirleybg',['ShirleyBG',['../pearl-fitfuncs_8ipf.html#af07f887f3ba8e3e35c9214df8bb6a49f',1,'pearl-fitfuncs.ipf']]], - ['show_5fanalyser_5fline',['show_analyser_line',['../pearl-anglescan-process_8ipf.html#a01bac9e7d4ba743c3c34177a05070466',1,'pearl-anglescan-process.ipf']]], - ['show_5fpreview_5fgraph',['show_preview_graph',['../pearl-data-explorer_8ipf.html#a4db79d04c74beb1af71b72916f8f0362',1,'pearl-data-explorer.ipf']]], - ['show_5fshift',['show_shift',['../fermi-edge-analysis_8ipf.html#acf72d644b8d37b6c26b1e070edba4e30',1,'fermi-edge-analysis.ipf']]], - ['showcomponents_5fau4f_5f2p2',['ShowComponents_Au4f_2p2',['../pearl-fitfuncs_8ipf.html#a84a0278284332631682ce032018d1716',1,'pearl-fitfuncs.ipf']]], - ['showcomponents_5fau4f_5f2p3',['ShowComponents_Au4f_2p3',['../pearl-fitfuncs_8ipf.html#a02368cc4adfbd746cd2f1e7d73884a61',1,'pearl-fitfuncs.ipf']]], - ['slit_5fcorrection',['slit_correction',['../fermi-edge-analysis_8ipf.html#a4cec596c8fd2b21953cb45d6d347211d',1,'fermi-edge-analysis.ipf']]], - ['slit_5fshift',['slit_shift',['../fermi-edge-analysis_8ipf.html#a27f000c3a3ea74c49db31716be3396d4',1,'fermi-edge-analysis.ipf']]], - ['slp_5fslice_5fposition',['slp_slice_position',['../pearl-area-display_8ipf.html#ace169e0824e6bddbd646972946edccbe',1,'pearl-area-display.ipf']]], - ['strip_5fdelete_5fframes',['strip_delete_frames',['../pearl-anglescan-process_8ipf.html#a13e0d37ae23f68cdc5da3d84cb4beed8',1,'pearl-anglescan-process.ipf']]], - ['subtract_5fline_5fbg',['subtract_line_bg',['../pearl-matrix-import_8ipf.html#ab80101bc780dcbe94200e2446bce51d9',1,'pearl-matrix-import.ipf']]], - ['success',['SUCCESS',['../structerror_code.html#a36a53ca508600b841a54cfd3a3fd5402',1,'errorCode']]], - ['sumwavesiterator',['SumWavesIterator',['../pearl-tools_8ipf.html#aea193a1b5fbdbb2a5dec9f25f3c05c45',1,'pearl-tools.ipf']]], - ['svp_5fslice_5fposition',['svp_slice_position',['../pearl-area-display_8ipf.html#a174177742fdce7f37027de8fa832b3bd',1,'pearl-area-display.ipf']]], - ['svp_5fsmoothing',['svp_smoothing',['../pearl-area-display_8ipf.html#ab10a0d94991b9cd958557dbc48d70624',1,'pearl-area-display.ipf']]] + ['save_5fhemi_5fscan_538',['save_hemi_scan',['../pearl-anglescan-process_8ipf.html#a48cbd596656bc6d849c53afb4c58b90d',1,'pearl-anglescan-process.ipf']]], + ['save_5fprefs_539',['save_prefs',['../pearl-anglescan-panel_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-elog.ipf']]], + ['save_5fscan_5fhelper_540',['save_scan_helper',['../pearl-pmsco-import_8ipf.html#a0a53a4686b482d62fe1797932a1708db',1,'pearl-pmsco-import.ipf']]], + ['save_5ftracker_5fdata_541',['save_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a8d6e9058f2b0b4978f56e892ce199e6a',1,'pearl-anglescan-tracker.ipf']]], + ['scientalivedisplay_542',['ScientaLiveDisplay',['../pearl-scienta-live_8ipf.html#a55886895329455b36b64d52ed6a4e228',1,'pearl-scienta-live.ipf']]], + ['selected_5ffile_543',['selected_file',['../pearl-data-explorer_8ipf.html#ac477142f1949dc32d86663f1de4384e5',1,'pearl-data-explorer.ipf']]], + ['send_5fto_5felog_544',['send_to_elog',['../pearl-data-explorer_8ipf.html#aac8d96d9ccaeddab1cb0f463b01616cb',1,'pearl-data-explorer.ipf']]], + ['set_5fcontrast_545',['set_contrast',['../pearl-anglescan-process_8ipf.html#af9874b5c1ce1d216741c7880a5fdcfcc',1,'pearl-anglescan-process.ipf']]], + ['set_5felog_5fattributes_546',['set_elog_attributes',['../pearl-data-explorer_8ipf.html#a93c61109535e1644f5e53aabb895b48a',1,'pearl-data-explorer.ipf']]], + ['set_5fpanel_5fattributes_547',['set_panel_attributes',['../pearl-elog_8ipf.html#a39a1f418c8a2f9a5e4ab976827d8efca',1,'pearl-elog.ipf']]], + ['set_5fpanel_5fgraphs_548',['set_panel_graphs',['../pearl-elog_8ipf.html#a6eca5f4fab999984df32b50dd669c0b1',1,'pearl-elog.ipf']]], + ['set_5fpanel_5fmessage_549',['set_panel_message',['../pearl-elog_8ipf.html#aa7a3988440bb6d73573b50a4698a0e75',1,'pearl-elog.ipf']]], + ['set_5fpolar_5fgraph_5fcursor_550',['set_polar_graph_cursor',['../pearl-anglescan-process_8ipf.html#a70b0e243bcbd549e2b1da74aab605629',1,'pearl-anglescan-process.ipf']]], + ['set_5frotation_5fx_551',['set_rotation_x',['../pearl-vector-operations_8ipf.html#a8a8dff94d9f7b992c2c2c0744001e74b',1,'pearl-vector-operations.ipf']]], + ['set_5frotation_5fy_552',['set_rotation_y',['../pearl-vector-operations_8ipf.html#adfdf1cfe8812d8d0006228f6c14c9582',1,'pearl-vector-operations.ipf']]], + ['set_5frotation_5fz_553',['set_rotation_z',['../pearl-vector-operations_8ipf.html#a76feca10fe5d3e085f01c73a59b38424',1,'pearl-vector-operations.ipf']]], + ['set_5ftrace_5fcolors_554',['set_trace_colors',['../pearl-area-display_8ipf.html#abafc4f012b04592724109f4757cbe271',1,'pearl-area-display.ipf']]], + ['setup_5fdata_555',['setup_data',['../pearl-anglescan-tracker_8ipf.html#a6bfd8b6eba0b206df6ec56c7b6489e0b',1,'pearl-anglescan-tracker.ipf']]], + ['setup_5fdetector_556',['setup_detector',['../pearl-anglescan-tracker_8ipf.html#aa79c1d1584eb2322adae328bf1437f34',1,'pearl-anglescan-tracker.ipf']]], + ['setup_5fgraph_557',['setup_graph',['../pearl-anglescan-tracker_8ipf.html#aa7c4e3e0ed255e61bc80f8b27b78fce6',1,'pearl-anglescan-tracker.ipf']]], + ['shirleybg_558',['ShirleyBG',['../pearl-fitfuncs_8ipf.html#af07f887f3ba8e3e35c9214df8bb6a49f',1,'pearl-fitfuncs.ipf']]], + ['shorten_5ffilepath_559',['shorten_filepath',['../pearl-data-explorer_8ipf.html#a00307dffd6f272f13acfe4dea99a81d4',1,'pearl-data-explorer.ipf']]], + ['show_5fanalyser_5fline_560',['show_analyser_line',['../pearl-anglescan-process_8ipf.html#a01bac9e7d4ba743c3c34177a05070466',1,'pearl-anglescan-process.ipf']]], + ['show_5fpreview_5fgraph_561',['show_preview_graph',['../pearl-data-explorer_8ipf.html#a4db79d04c74beb1af71b72916f8f0362',1,'pearl-data-explorer.ipf']]], + ['show_5fshift_562',['show_shift',['../fermi-edge-analysis_8ipf.html#acf72d644b8d37b6c26b1e070edba4e30',1,'fermi-edge-analysis.ipf']]], + ['showcomponents_5fau4f_5f2p2_563',['ShowComponents_Au4f_2p2',['../pearl-fitfuncs_8ipf.html#a84a0278284332631682ce032018d1716',1,'pearl-fitfuncs.ipf']]], + ['showcomponents_5fau4f_5f2p3_564',['ShowComponents_Au4f_2p3',['../pearl-fitfuncs_8ipf.html#a02368cc4adfbd746cd2f1e7d73884a61',1,'pearl-fitfuncs.ipf']]], + ['slit_5fcorrection_565',['slit_correction',['../fermi-edge-analysis_8ipf.html#a4cec596c8fd2b21953cb45d6d347211d',1,'fermi-edge-analysis.ipf']]], + ['slit_5fshift_566',['slit_shift',['../fermi-edge-analysis_8ipf.html#a27f000c3a3ea74c49db31716be3396d4',1,'fermi-edge-analysis.ipf']]], + ['slp_5fslice_5fposition_567',['slp_slice_position',['../pearl-area-display_8ipf.html#ace169e0824e6bddbd646972946edccbe',1,'pearl-area-display.ipf']]], + ['strip_5fappend_568',['strip_append',['../pearl-anglescan-process_8ipf.html#ab97a936bc0fa6137b6d0b43cb61d39a1',1,'pearl-anglescan-process.ipf']]], + ['strip_5fdelete_5fframes_569',['strip_delete_frames',['../pearl-anglescan-process_8ipf.html#a13e0d37ae23f68cdc5da3d84cb4beed8',1,'pearl-anglescan-process.ipf']]], + ['subtract_5fline_5fbg_570',['subtract_line_bg',['../pearl-matrix-import_8ipf.html#ab80101bc780dcbe94200e2446bce51d9',1,'pearl-matrix-import.ipf']]], + ['success_571',['SUCCESS',['../structerror_code.html#a36a53ca508600b841a54cfd3a3fd5402',1,'errorCode']]], + ['sumwavesiterator_572',['SumWavesIterator',['../pearl-tools_8ipf.html#aea193a1b5fbdbb2a5dec9f25f3c05c45',1,'pearl-tools.ipf']]], + ['svp_5fslice_5fposition_573',['svp_slice_position',['../pearl-area-display_8ipf.html#a174177742fdce7f37027de8fa832b3bd',1,'pearl-area-display.ipf']]], + ['svp_5fsmoothing_574',['svp_smoothing',['../pearl-area-display_8ipf.html#ab10a0d94991b9cd958557dbc48d70624',1,'pearl-area-display.ipf']]] ]; diff --git a/doc/html/search/all_12.html b/doc/html/search/all_12.html index 13c5263..dd9ff1d 100644 --- a/doc/html/search/all_12.html +++ b/doc/html/search/all_12.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_12.js b/doc/html/search/all_12.js index 0fd3575..f233ba9 100644 --- a/doc/html/search/all_12.js +++ b/doc/html/search/all_12.js @@ -1,9 +1,9 @@ var searchData= [ - ['test_5fattributes_5fnotebook',['test_attributes_notebook',['../pearl-data-explorer_8ipf.html#a71f9c277d310c3f4e7739be69dad0ab5',1,'pearl-data-explorer.ipf']]], - ['test_5fgauss4_5freduction',['test_gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#adb78e8b2bbfd9c0faa5eb049b1dcad1c',1,'pearl-scienta-preprocess.ipf']]], - ['todo_20list',['Todo List',['../todo.html',1,'']]], - ['toggle_5fcapture',['toggle_capture',['../pearl-anglescan-tracker_8ipf.html#a02987fe03ea914a53c52d58219979d65',1,'pearl-anglescan-tracker.ipf']]], - ['trim_5fhemi_5fscan',['trim_hemi_scan',['../pearl-anglescan-process_8ipf.html#a5dc0cc7db9d3d7a6b3fa3f1b04d84a5e',1,'pearl-anglescan-process.ipf']]], - ['twave2list',['twave2list',['../pearl-pshell-import_8ipf.html#a92a18d6e81c3f521ba3bb240eaf578a9',1,'pearl-pshell-import.ipf']]] + ['test_5fattributes_5fnotebook_575',['test_attributes_notebook',['../pearl-data-explorer_8ipf.html#a71f9c277d310c3f4e7739be69dad0ab5',1,'pearl-data-explorer.ipf']]], + ['test_5fgauss4_5freduction_576',['test_gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#adb78e8b2bbfd9c0faa5eb049b1dcad1c',1,'pearl-scienta-preprocess.ipf']]], + ['todo_20list_577',['Todo List',['../todo.html',1,'']]], + ['toggle_5fcapture_578',['toggle_capture',['../pearl-anglescan-tracker_8ipf.html#a02987fe03ea914a53c52d58219979d65',1,'pearl-anglescan-tracker.ipf']]], + ['trim_5fhemi_5fscan_579',['trim_hemi_scan',['../pearl-anglescan-process_8ipf.html#a5dc0cc7db9d3d7a6b3fa3f1b04d84a5e',1,'pearl-anglescan-process.ipf']]], + ['twave2list_580',['twave2list',['../pearl-pshell-import_8ipf.html#a92a18d6e81c3f521ba3bb240eaf578a9',1,'pearl-pshell-import.ipf']]] ]; diff --git a/doc/html/search/all_13.html b/doc/html/search/all_13.html index b4a8bca..2611a10 100644 --- a/doc/html/search/all_13.html +++ b/doc/html/search/all_13.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_13.js b/doc/html/search/all_13.js index 79ee31e..319e442 100644 --- a/doc/html/search/all_13.js +++ b/doc/html/search/all_13.js @@ -1,16 +1,18 @@ var searchData= [ - ['unknown_5ferror',['UNKNOWN_ERROR',['../structerror_code.html#a11b729058e2f4a2698ddaecf4e61c846',1,'errorCode']]], - ['unloadpearlarpespackage',['UnloadPearlArpesPackage',['../pearl-arpes_8ipf.html#ac41f24572943dac2b40c255797a6c7a8',1,'pearl-arpes.ipf']]], - ['update_5fattach_5fitems',['update_attach_items',['../pearl-elog_8ipf.html#a9c1cfd320e88e84dcf4f84bbcf3f46a5',1,'pearl-elog.ipf']]], - ['update_5fcapture',['update_capture',['../pearl-anglescan-tracker_8ipf.html#a9751db419b4c0de884450c09ff5822a7',1,'pearl-anglescan-tracker.ipf']]], - ['update_5fdata_5fgraph',['update_data_graph',['../pearl-anglescan-tracker_8ipf.html#a0b8ff36cf3c20b1c0db3217d9065f7cf',1,'pearl-anglescan-tracker.ipf']]], - ['update_5fdatasets',['update_datasets',['../pearl-data-explorer_8ipf.html#ad50f4c430d8bfe0fb5a1356cd9b84bf4',1,'pearl-data-explorer.ipf']]], - ['update_5fdetector',['update_detector',['../pearl-anglescan-tracker_8ipf.html#ab961340af09fed4d2006bca8c0f2edd5',1,'pearl-anglescan-tracker.ipf']]], - ['update_5fdetector_5fgraph',['update_detector_graph',['../pearl-anglescan-tracker_8ipf.html#af5a2960c49626f267fbd2873b27c8e42',1,'pearl-anglescan-tracker.ipf']]], - ['update_5ffilelist',['update_filelist',['../pearl-data-explorer_8ipf.html#a04cc0b9d5e3a649ba3514fcbf126eefe',1,'pearl-data-explorer.ipf']]], - ['update_5fmenus',['update_menus',['../pearl-anglescan-panel_8ipf.html#a7ddecbeeaee3f9da87ac1ecdc26f530b',1,'pearl-anglescan-panel.ipf']]], - ['update_5fpolar_5finfo',['update_polar_info',['../pearl-anglescan-process_8ipf.html#a1baaa3ffd9495ed427b43cbfe6e1edf8',1,'pearl-anglescan-process.ipf']]], - ['update_5fprogress_5fpanel',['update_progress_panel',['../pearl-gui-tools_8ipf.html#a97ad19d83cf0007c4bcf97a32164610f',1,'pearl-gui-tools.ipf']]], - ['update_5fslice_5finfo',['update_slice_info',['../pearl-area-display_8ipf.html#a2442bc044aaa12ab817a5f9fa300d1f8',1,'pearl-area-display.ipf']]] + ['unique_5fstrings_581',['unique_strings',['../pearl-pshell-import_8ipf.html#ae2aedcb7028cccdb683c43411cc8f1e2',1,'pearl-pshell-import.ipf']]], + ['unknown_5ferror_582',['UNKNOWN_ERROR',['../structerror_code.html#a11b729058e2f4a2698ddaecf4e61c846',1,'errorCode']]], + ['unloadpearlarpespackage_583',['UnloadPearlArpesPackage',['../pearl-arpes_8ipf.html#ac41f24572943dac2b40c255797a6c7a8',1,'pearl-arpes.ipf']]], + ['update_5fattach_5fitems_584',['update_attach_items',['../pearl-elog_8ipf.html#a9c1cfd320e88e84dcf4f84bbcf3f46a5',1,'pearl-elog.ipf']]], + ['update_5fcapture_585',['update_capture',['../pearl-anglescan-tracker_8ipf.html#a9751db419b4c0de884450c09ff5822a7',1,'pearl-anglescan-tracker.ipf']]], + ['update_5fcontrols_586',['update_controls',['../pearl-data-explorer_8ipf.html#a57e21bffee4cd64f2ea1efd9cc958bf1',1,'pearl-data-explorer.ipf']]], + ['update_5fdata_5fgraph_587',['update_data_graph',['../pearl-anglescan-tracker_8ipf.html#a0b8ff36cf3c20b1c0db3217d9065f7cf',1,'pearl-anglescan-tracker.ipf']]], + ['update_5fdetector_588',['update_detector',['../pearl-anglescan-tracker_8ipf.html#ab961340af09fed4d2006bca8c0f2edd5',1,'pearl-anglescan-tracker.ipf']]], + ['update_5fdetector_5fgraph_589',['update_detector_graph',['../pearl-anglescan-tracker_8ipf.html#af5a2960c49626f267fbd2873b27c8e42',1,'pearl-anglescan-tracker.ipf']]], + ['update_5ffilelist_590',['update_filelist',['../pearl-data-explorer_8ipf.html#a04cc0b9d5e3a649ba3514fcbf126eefe',1,'pearl-data-explorer.ipf']]], + ['update_5ffilepath_591',['update_filepath',['../pearl-data-explorer_8ipf.html#ae02b954d90dc8f43c007cc3fb1a1ee16',1,'pearl-data-explorer.ipf']]], + ['update_5fmenus_592',['update_menus',['../pearl-anglescan-panel_8ipf.html#a7ddecbeeaee3f9da87ac1ecdc26f530b',1,'pearl-anglescan-panel.ipf']]], + ['update_5fpolar_5finfo_593',['update_polar_info',['../pearl-anglescan-process_8ipf.html#a1baaa3ffd9495ed427b43cbfe6e1edf8',1,'pearl-anglescan-process.ipf']]], + ['update_5fprogress_5fpanel_594',['update_progress_panel',['../pearl-gui-tools_8ipf.html#a97ad19d83cf0007c4bcf97a32164610f',1,'pearl-gui-tools.ipf']]], + ['update_5fslice_5finfo_595',['update_slice_info',['../pearl-area-display_8ipf.html#a2442bc044aaa12ab817a5f9fa300d1f8',1,'pearl-area-display.ipf']]] ]; diff --git a/doc/html/search/all_14.html b/doc/html/search/all_14.html index fb4d0ec..72d12e9 100644 --- a/doc/html/search/all_14.html +++ b/doc/html/search/all_14.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_14.js b/doc/html/search/all_14.js index 5666e3b..c7f6ef1 100644 --- a/doc/html/search/all_14.js +++ b/doc/html/search/all_14.js @@ -1,4 +1,4 @@ var searchData= [ - ['version',['version',['../pearl-anglescan-tracker_8ipf.html#a4c7a521b8f1a0769c09bfa4a1fca7dab',1,'pearl-anglescan-tracker.ipf']]] + ['version_596',['version',['../pearl-anglescan-tracker_8ipf.html#a4c7a521b8f1a0769c09bfa4a1fca7dab',1,'version(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a4c7a521b8f1a0769c09bfa4a1fca7dab',1,'version(): pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/all_15.html b/doc/html/search/all_15.html index 8afe9a0..767aec3 100644 --- a/doc/html/search/all_15.html +++ b/doc/html/search/all_15.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_15.js b/doc/html/search/all_15.js index 1ceb671..6b2a815 100644 --- a/doc/html/search/all_15.js +++ b/doc/html/search/all_15.js @@ -1,6 +1,6 @@ var searchData= [ - ['wave2list',['wave2list',['../pearl-pshell-import_8ipf.html#aa6dc3e3f7dc1ca4346132635a90fc447',1,'pearl-pshell-import.ipf']]], - ['wave_5fexist',['WAVE_EXIST',['../structerror_code.html#aa91bd8ef7a635f4575161813ebb09f3b',1,'errorCode']]], - ['wrong_5fparameter',['WRONG_PARAMETER',['../structerror_code.html#aa4279dfdaceed3bd57336cd4e38ed739',1,'errorCode']]] + ['wave2list_597',['wave2list',['../pearl-pshell-import_8ipf.html#aa6dc3e3f7dc1ca4346132635a90fc447',1,'pearl-pshell-import.ipf']]], + ['wave_5fexist_598',['WAVE_EXIST',['../structerror_code.html#aa91bd8ef7a635f4575161813ebb09f3b',1,'errorCode']]], + ['wrong_5fparameter_599',['WRONG_PARAMETER',['../structerror_code.html#aa4279dfdaceed3bd57336cd4e38ed739',1,'errorCode']]] ]; diff --git a/doc/html/search/all_16.html b/doc/html/search/all_16.html index e511edb..7bd7afe 100644 --- a/doc/html/search/all_16.html +++ b/doc/html/search/all_16.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_16.js b/doc/html/search/all_16.js index 7ff7b6f..8ea4638 100644 --- a/doc/html/search/all_16.js +++ b/doc/html/search/all_16.js @@ -1,5 +1,5 @@ var searchData= [ - ['xdw',['xdw',['../struct_doniach_sunjic_struct.html#a750e7260bf5d4c936dadde714fb2db52',1,'DoniachSunjicStruct']]], - ['xw',['xw',['../struct_doniach_sunjic_struct.html#a45c3a3fa68850032e545907ca65ab982',1,'DoniachSunjicStruct']]] + ['xdw_600',['xdw',['../struct_doniach_sunjic_struct.html#a750e7260bf5d4c936dadde714fb2db52',1,'DoniachSunjicStruct']]], + ['xw_601',['xw',['../struct_doniach_sunjic_struct.html#a45c3a3fa68850032e545907ca65ab982',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/all_17.html b/doc/html/search/all_17.html index 5ca9efd..35702ec 100644 --- a/doc/html/search/all_17.html +++ b/doc/html/search/all_17.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_17.js b/doc/html/search/all_17.js index 246bc4f..f79aec2 100644 --- a/doc/html/search/all_17.js +++ b/doc/html/search/all_17.js @@ -1,4 +1,4 @@ var searchData= [ - ['yw',['yw',['../struct_doniach_sunjic_struct.html#a6cef648ad0cf4be1dd9fbe33ff5df1eb',1,'DoniachSunjicStruct']]] + ['yw_602',['yw',['../struct_doniach_sunjic_struct.html#a6cef648ad0cf4be1dd9fbe33ff5df1eb',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/all_2.html b/doc/html/search/all_2.html index 9543c57..b26d916 100644 --- a/doc/html/search/all_2.html +++ b/doc/html/search/all_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_2.js b/doc/html/search/all_2.js index 15fa069..bb1ec32 100644 --- a/doc/html/search/all_2.js +++ b/doc/html/search/all_2.js @@ -1,34 +1,35 @@ var searchData= [ - ['calc_5fdoniachsunjicbroad',['Calc_DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#aff8e8b103c32c8e723b57ce7ad5ef0f5',1,'pearl-fitfuncs.ipf']]], - ['calc_5fgraph_5fazi',['calc_graph_azi',['../pearl-anglescan-process_8ipf.html#a4fc744e24e3e9c5efb17f14ab622bcae',1,'pearl-anglescan-process.ipf']]], - ['calc_5fgraph_5fpolar',['calc_graph_polar',['../pearl-anglescan-process_8ipf.html#ae2b036a06ffac8d2bb292a65401f8a9a',1,'pearl-anglescan-process.ipf']]], - ['calc_5fgraph_5fradius',['calc_graph_radius',['../pearl-anglescan-process_8ipf.html#a75219b38ea58012abcffc848d536faa4',1,'pearl-anglescan-process.ipf']]], - ['calc_5fnth',['calc_nth',['../pearl-anglescan-process_8ipf.html#a9624070f3e938378631432430d47a389',1,'pearl-anglescan-process.ipf']]], - ['calc_5fphi_5fstep',['calc_phi_step',['../pearl-anglescan-process_8ipf.html#a999a9cd7d00d3e1ec8e768228a664ad1',1,'pearl-anglescan-process.ipf']]], - ['calc_5fthe_5fstep',['Calc_The_step',['../pearl-anglescan-process_8ipf.html#a1fb6aa7870dfbf0ed92660b7aae579e0',1,'pearl-anglescan-process.ipf']]], - ['calc_5fy_5fprofile_5fmins',['calc_y_profile_mins',['../pearl-area-profiles_8ipf.html#ab58b7c0a88743ecbcb0fc8296577a792',1,'pearl-area-profiles.ipf']]], - ['calcn_5ftheta',['CalcN_Theta',['../pearl-anglescan-process_8ipf.html#ac0def1ded61f9cd758df0c99f4ff9470',1,'pearl-anglescan-process.ipf']]], - ['capture_5fint_5flinbg_5fcursors',['capture_int_linbg_cursors',['../pearl-scienta-preprocess_8ipf.html#ae6877c51ad15c2ba8a69c65356cb34b8',1,'pearl-scienta-preprocess.ipf']]], - ['cart2polar',['cart2polar',['../pearl-polar-coordinates_8ipf.html#aca0a5aaa4854d83ef667c53007312fb8',1,'pearl-polar-coordinates.ipf']]], - ['cart2polar_5fwave',['cart2polar_wave',['../pearl-polar-coordinates_8ipf.html#adfc1f0b3cddf672b0ccdb6a22b97ba9e',1,'pearl-polar-coordinates.ipf']]], - ['check_5fcontrast',['check_contrast',['../pearl-anglescan-process_8ipf.html#a2e1ed05781f9eb4be5e77695ef049962',1,'pearl-anglescan-process.ipf']]], - ['check_5fexposure_5fopt',['check_exposure_opt',['../pearl-scienta-countrate_8ipf.html#af2879284b1d1397447a31733fddd6273',1,'pearl-scienta-countrate.ipf']]], - ['check_5fnorm_5falpha',['check_norm_alpha',['../pearl-anglescan-panel_8ipf.html#af5435ccaabba78f855b244929dc09ed0',1,'pearl-anglescan-panel.ipf']]], - ['check_5fnorm_5fphi',['check_norm_phi',['../pearl-anglescan-panel_8ipf.html#a91d5343cc96730de12b535cb0bef9df2',1,'pearl-anglescan-panel.ipf']]], - ['check_5fnorm_5ftheta',['check_norm_theta',['../pearl-anglescan-panel_8ipf.html#addddc12e5b622a3d00756d724e5d05a9',1,'pearl-anglescan-panel.ipf']]], - ['check_5fnorm_5fthetaphi',['check_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#a4708e7385790d1a9f2d58c4d64a60653',1,'pearl-anglescan-panel.ipf']]], - ['check_5fpackage_5ffolder',['check_package_folder',['../pearl-matrix-import_8ipf.html#ac7790f06151821678a65ab0065a5323e',1,'pearl-matrix-import.ipf']]], - ['cleanup_5ftemp_5ffiles',['cleanup_temp_files',['../pearl-elog_8ipf.html#ad7640d06f004ecd4a8980ea29d24dcbe',1,'pearl-elog.ipf']]], - ['clear_5fhemi_5fgrid',['clear_hemi_grid',['../pearl-anglescan-process_8ipf.html#a3ec6935a5903d0974c93a2072d743013',1,'pearl-anglescan-process.ipf']]], - ['convert_5fangles_5fttpa2polar',['convert_angles_ttpa2polar',['../pearl-anglescan-process_8ipf.html#a3cc7eddf5c6b0658260cfb32dd2c026d',1,'pearl-anglescan-process.ipf']]], - ['convert_5fangles_5fttpd2polar',['convert_angles_ttpd2polar',['../pearl-anglescan-process_8ipf.html#a2b38c6c9b6e60593ba69d3773b6bc779',1,'pearl-anglescan-process.ipf']]], - ['convolution',['convolution',['../struct_doniach_sunjic_struct.html#a7f05f7827435fea3c986a8d538496955',1,'DoniachSunjicStruct']]], - ['create_5fcmd_5ffile',['create_cmd_file',['../pearl-elog_8ipf.html#ac8b61eefed231018cc36d47e95bd8c22',1,'pearl-elog.ipf']]], - ['create_5fgraph_5ffile',['create_graph_file',['../pearl-elog_8ipf.html#a2417d079483f773f8231c5f2caba6cf0',1,'pearl-elog.ipf']]], - ['create_5fmessage_5ffile',['create_message_file',['../pearl-elog_8ipf.html#af652f6f257be1ee749fe788d1b03f75f',1,'pearl-elog.ipf']]], - ['create_5frotation_5fmatrix_5ffree',['create_rotation_matrix_free',['../pearl-vector-operations_8ipf.html#a72c3200a7344c708ea76e20cc2c19c43',1,'pearl-vector-operations.ipf']]], - ['crop_5fstrip',['crop_strip',['../pearl-anglescan-process_8ipf.html#ab65d25af7476ed18f7bf7359614a912b',1,'pearl-anglescan-process.ipf']]], - ['crop_5fstrip_5ftheta',['crop_strip_theta',['../pearl-anglescan-process_8ipf.html#aa79c0ff6073bd42e202b9fa3f8c00b9f',1,'pearl-anglescan-process.ipf']]], - ['csr_5fint_5flinbg_5freduction',['csr_int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a95fbd22f52f61d2bff0625b7b8e159d1',1,'pearl-scienta-preprocess.ipf']]] + ['calc_5fdoniachsunjicbroad_145',['Calc_DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#aff8e8b103c32c8e723b57ce7ad5ef0f5',1,'pearl-fitfuncs.ipf']]], + ['calc_5fgraph_5fazi_146',['calc_graph_azi',['../pearl-anglescan-process_8ipf.html#a4fc744e24e3e9c5efb17f14ab622bcae',1,'pearl-anglescan-process.ipf']]], + ['calc_5fgraph_5fpolar_147',['calc_graph_polar',['../pearl-anglescan-process_8ipf.html#ae2b036a06ffac8d2bb292a65401f8a9a',1,'pearl-anglescan-process.ipf']]], + ['calc_5fgraph_5fradius_148',['calc_graph_radius',['../pearl-anglescan-process_8ipf.html#a75219b38ea58012abcffc848d536faa4',1,'pearl-anglescan-process.ipf']]], + ['calc_5fnth_149',['calc_nth',['../pearl-anglescan-process_8ipf.html#a9624070f3e938378631432430d47a389',1,'pearl-anglescan-process.ipf']]], + ['calc_5fphi_5fstep_150',['calc_phi_step',['../pearl-anglescan-process_8ipf.html#a999a9cd7d00d3e1ec8e768228a664ad1',1,'pearl-anglescan-process.ipf']]], + ['calc_5fthe_5fstep_151',['Calc_The_step',['../pearl-anglescan-process_8ipf.html#a1fb6aa7870dfbf0ed92660b7aae579e0',1,'pearl-anglescan-process.ipf']]], + ['calc_5fy_5fprofile_5fmins_152',['calc_y_profile_mins',['../pearl-area-profiles_8ipf.html#ab58b7c0a88743ecbcb0fc8296577a792',1,'pearl-area-profiles.ipf']]], + ['calcn_5ftheta_153',['CalcN_Theta',['../pearl-anglescan-process_8ipf.html#ac0def1ded61f9cd758df0c99f4ff9470',1,'pearl-anglescan-process.ipf']]], + ['capture_5fint_5flinbg_5fcursors_154',['capture_int_linbg_cursors',['../pearl-scienta-preprocess_8ipf.html#ae6877c51ad15c2ba8a69c65356cb34b8',1,'pearl-scienta-preprocess.ipf']]], + ['cart2polar_155',['cart2polar',['../pearl-polar-coordinates_8ipf.html#aca0a5aaa4854d83ef667c53007312fb8',1,'pearl-polar-coordinates.ipf']]], + ['cart2polar_5fwave_156',['cart2polar_wave',['../pearl-polar-coordinates_8ipf.html#adfc1f0b3cddf672b0ccdb6a22b97ba9e',1,'pearl-polar-coordinates.ipf']]], + ['check_5fcontrast_157',['check_contrast',['../pearl-anglescan-process_8ipf.html#a67d53a1c362d7e5bbeccf1c9c12ae0c2',1,'pearl-anglescan-process.ipf']]], + ['check_5fexposure_5fopt_158',['check_exposure_opt',['../pearl-scienta-live_8ipf.html#af2879284b1d1397447a31733fddd6273',1,'pearl-scienta-live.ipf']]], + ['check_5fnorm_5falpha_159',['check_norm_alpha',['../pearl-anglescan-panel_8ipf.html#af5435ccaabba78f855b244929dc09ed0',1,'pearl-anglescan-panel.ipf']]], + ['check_5fnorm_5fphi_160',['check_norm_phi',['../pearl-anglescan-panel_8ipf.html#a91d5343cc96730de12b535cb0bef9df2',1,'pearl-anglescan-panel.ipf']]], + ['check_5fnorm_5ftheta_161',['check_norm_theta',['../pearl-anglescan-panel_8ipf.html#addddc12e5b622a3d00756d724e5d05a9',1,'pearl-anglescan-panel.ipf']]], + ['check_5fnorm_5fthetaphi_162',['check_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#a4708e7385790d1a9f2d58c4d64a60653',1,'pearl-anglescan-panel.ipf']]], + ['check_5fpackage_5ffolder_163',['check_package_folder',['../pearl-matrix-import_8ipf.html#ac7790f06151821678a65ab0065a5323e',1,'pearl-matrix-import.ipf']]], + ['cleanup_5ftemp_5ffiles_164',['cleanup_temp_files',['../pearl-elog_8ipf.html#ad7640d06f004ecd4a8980ea29d24dcbe',1,'pearl-elog.ipf']]], + ['clear_5fhemi_5fgrid_165',['clear_hemi_grid',['../pearl-anglescan-process_8ipf.html#a3ec6935a5903d0974c93a2072d743013',1,'pearl-anglescan-process.ipf']]], + ['convert_5fangles_5fttpa2polar_166',['convert_angles_ttpa2polar',['../pearl-anglescan-process_8ipf.html#a3cc7eddf5c6b0658260cfb32dd2c026d',1,'pearl-anglescan-process.ipf']]], + ['convert_5fangles_5fttpd2polar_167',['convert_angles_ttpd2polar',['../pearl-anglescan-process_8ipf.html#a2b38c6c9b6e60593ba69d3773b6bc779',1,'pearl-anglescan-process.ipf']]], + ['convolution_168',['convolution',['../struct_doniach_sunjic_struct.html#a7f05f7827435fea3c986a8d538496955',1,'DoniachSunjicStruct']]], + ['create_5fattributes_5fnotebook_169',['create_attributes_notebook',['../pearl-data-explorer_8ipf.html#a77047115739da6d28055f7fd44c9fd2c',1,'pearl-data-explorer.ipf']]], + ['create_5fcmd_5ffile_170',['create_cmd_file',['../pearl-elog_8ipf.html#ac8b61eefed231018cc36d47e95bd8c22',1,'pearl-elog.ipf']]], + ['create_5fgraph_5ffile_171',['create_graph_file',['../pearl-elog_8ipf.html#a2417d079483f773f8231c5f2caba6cf0',1,'pearl-elog.ipf']]], + ['create_5fmessage_5ffile_172',['create_message_file',['../pearl-elog_8ipf.html#af652f6f257be1ee749fe788d1b03f75f',1,'pearl-elog.ipf']]], + ['create_5frotation_5fmatrix_5ffree_173',['create_rotation_matrix_free',['../pearl-vector-operations_8ipf.html#a72c3200a7344c708ea76e20cc2c19c43',1,'pearl-vector-operations.ipf']]], + ['crop_5fstrip_174',['crop_strip',['../pearl-anglescan-process_8ipf.html#ab65d25af7476ed18f7bf7359614a912b',1,'pearl-anglescan-process.ipf']]], + ['crop_5fstrip_5ftheta_175',['crop_strip_theta',['../pearl-anglescan-process_8ipf.html#aa79c0ff6073bd42e202b9fa3f8c00b9f',1,'pearl-anglescan-process.ipf']]], + ['csr_5fint_5flinbg_5freduction_176',['csr_int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a95fbd22f52f61d2bff0625b7b8e159d1',1,'pearl-scienta-preprocess.ipf']]] ]; diff --git a/doc/html/search/all_3.html b/doc/html/search/all_3.html index 03405c0..b61b96f 100644 --- a/doc/html/search/all_3.html +++ b/doc/html/search/all_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_3.js b/doc/html/search/all_3.js index 039b122..0a2d656 100644 --- a/doc/html/search/all_3.js +++ b/doc/html/search/all_3.js @@ -1,33 +1,34 @@ var searchData= [ - ['defaultfolderiterator',['DefaultFolderIterator',['../pearl-tools_8ipf.html#a3fb8c06030dc41a599380150807caeb0',1,'pearl-tools.ipf']]], - ['defaultwaveiterator',['DefaultWaveIterator',['../pearl-tools_8ipf.html#a6bdd1c0b269f1d7d99843ce0cb218cc7',1,'pearl-tools.ipf']]], - ['delete_5frows',['delete_rows',['../pearl-anglescan-panel_8ipf.html#a16424e5787967d9c120fb09c7849956e',1,'pearl-anglescan-panel.ipf']]], - ['display2dprofiles',['Display2dProfiles',['../pearl-menu_8ipf.html#aad7d768680c6d8a9b8a7025c7e1ec75d',1,'pearl-menu.ipf']]], - ['display3dslicer',['Display3dSlicer',['../pearl-menu_8ipf.html#ac73a94f760455f19294a9f917b43f145',1,'pearl-menu.ipf']]], - ['display_5fdataset',['display_dataset',['../pearl-data-explorer_8ipf.html#ae79a57a41c734ce8836f427b81011b5d',1,'pearl-data-explorer.ipf']]], - ['display_5fhemi_5fscan',['display_hemi_scan',['../pearl-anglescan-process_8ipf.html#ae57302acfc822c4817f2b7eef55efea2',1,'pearl-anglescan-process.ipf']]], - ['display_5fpolar_5fgraph',['display_polar_graph',['../pearl-anglescan-process_8ipf.html#a46fd99d35a43601c39af6096d4e4f770',1,'pearl-anglescan-process.ipf']]], - ['display_5fpreview_5ftrace',['display_preview_trace',['../pearl-data-explorer_8ipf.html#a001074020ad32b290d390a450a389c69',1,'pearl-data-explorer.ipf']]], - ['display_5fprogress_5fpanel',['display_progress_panel',['../pearl-gui-tools_8ipf.html#aaf29d090c81e00cf44af295193b24c5a',1,'pearl-gui-tools.ipf']]], - ['display_5fscanlines',['display_scanlines',['../pearl-anglescan-process_8ipf.html#a1f4f74a8ae557c56e1e3aacd0b45f3f1',1,'pearl-anglescan-process.ipf']]], - ['displaygizmoslicer',['DisplayGizmoSlicer',['../pearl-menu_8ipf.html#aab34952c2f3b36f9ee8619eb901ff581',1,'pearl-menu.ipf']]], - ['do_5fcrop',['do_crop',['../pearl-anglescan-panel_8ipf.html#af39609fc80e58f2188b3aa564f53b750',1,'pearl-anglescan-panel.ipf']]], - ['do_5finit_5fprocess',['do_init_process',['../pearl-anglescan-panel_8ipf.html#a1836e607851ba4d5a4048f4cfb8121a7',1,'pearl-anglescan-panel.ipf']]], - ['do_5fnorm_5falpha',['do_norm_alpha',['../pearl-anglescan-panel_8ipf.html#a8f7266ac2840155dede704fda66fe6b0',1,'pearl-anglescan-panel.ipf']]], - ['do_5fnorm_5fphi',['do_norm_phi',['../pearl-anglescan-panel_8ipf.html#a790519191391ac03c75eb7b57ea0749e',1,'pearl-anglescan-panel.ipf']]], - ['do_5fnorm_5ftheta',['do_norm_theta',['../pearl-anglescan-panel_8ipf.html#a7b288598e3faa37e414b1443982c1a3e',1,'pearl-anglescan-panel.ipf']]], - ['do_5fnorm_5fthetaphi',['do_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#af6509fc7584b0bcbdc8561df2bc12a58',1,'pearl-anglescan-panel.ipf']]], - ['doniachsunjic',['DoniachSunjic',['../pearl-fitfuncs_8ipf.html#aaa48428994f8720a12e7237ef43e86ea',1,'pearl-fitfuncs.ipf']]], - ['doniachsunjicbroad',['DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#ae2d138beb7cb39e8042487893095b461',1,'pearl-fitfuncs.ipf']]], - ['doniachsunjicbroads',['DoniachSunjicBroadS',['../pearl-fitfuncs_8ipf.html#a9d110819fa3cd2173f3103724e394fdf',1,'pearl-fitfuncs.ipf']]], - ['doniachsunjicstruct',['DoniachSunjicStruct',['../struct_doniach_sunjic_struct.html',1,'']]], - ['doubletgausslinbg_5fao',['DoubletGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#adb438f665e51a8dd104a37cfead04f27',1,'pearl-fitfuncs.ipf']]], - ['draw_5fdiffraction_5fcone',['draw_diffraction_cone',['../pearl-anglescan-process_8ipf.html#afedad38a418cee5d1fb9e08aae2160a0',1,'pearl-anglescan-process.ipf']]], - ['draw_5fhemi_5faxes',['draw_hemi_axes',['../pearl-anglescan-process_8ipf.html#af00d9061e410ad033a9fd1f0ca561e0d',1,'pearl-anglescan-process.ipf']]], - ['ds1_5fbg',['ds1_bg',['../pearl-fitfuncs_8ipf.html#af62cb65b7444ff60e956a45bd5d0ec27',1,'pearl-fitfuncs.ipf']]], - ['ds2_5fbg',['ds2_bg',['../pearl-fitfuncs_8ipf.html#a1e729418252bf0d05ea6ec5cbd65b834',1,'pearl-fitfuncs.ipf']]], - ['ds4_5fbg',['ds4_bg',['../pearl-fitfuncs_8ipf.html#ab32134566b2573672ac674565deebd36',1,'pearl-fitfuncs.ipf']]], - ['ds6_5fbg',['ds6_bg',['../pearl-fitfuncs_8ipf.html#a5a2a03026b88f3dd99214ab1b26e6f80',1,'pearl-fitfuncs.ipf']]], - ['duplicate_5fhemi_5fscan',['duplicate_hemi_scan',['../pearl-anglescan-process_8ipf.html#aa5b1e2ab1dd43a73b7157406b803887e',1,'pearl-anglescan-process.ipf']]] + ['dbldoubletgausslinbg_5fao_177',['DblDoubletGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#aca0bf4ff35794a459e15a3b358dbfa04',1,'pearl-fitfuncs.ipf']]], + ['defaultfolderiterator_178',['DefaultFolderIterator',['../pearl-tools_8ipf.html#a3fb8c06030dc41a599380150807caeb0',1,'pearl-tools.ipf']]], + ['defaultwaveiterator_179',['DefaultWaveIterator',['../pearl-tools_8ipf.html#a6bdd1c0b269f1d7d99843ce0cb218cc7',1,'pearl-tools.ipf']]], + ['delete_5frows_180',['delete_rows',['../pearl-anglescan-panel_8ipf.html#a16424e5787967d9c120fb09c7849956e',1,'pearl-anglescan-panel.ipf']]], + ['display2dprofiles_181',['Display2dProfiles',['../pearl-menu_8ipf.html#aad7d768680c6d8a9b8a7025c7e1ec75d',1,'pearl-menu.ipf']]], + ['display3dslicer_182',['Display3dSlicer',['../pearl-menu_8ipf.html#ac73a94f760455f19294a9f917b43f145',1,'pearl-menu.ipf']]], + ['display_5fdataset_183',['display_dataset',['../pearl-data-explorer_8ipf.html#a67cd1a025e5428d443027c1f57eaec09',1,'pearl-data-explorer.ipf']]], + ['display_5fhemi_5fscan_184',['display_hemi_scan',['../pearl-anglescan-process_8ipf.html#ae57302acfc822c4817f2b7eef55efea2',1,'pearl-anglescan-process.ipf']]], + ['display_5fpolar_5fgraph_185',['display_polar_graph',['../pearl-anglescan-process_8ipf.html#a46fd99d35a43601c39af6096d4e4f770',1,'pearl-anglescan-process.ipf']]], + ['display_5fpreview_5ftrace_186',['display_preview_trace',['../pearl-data-explorer_8ipf.html#a001074020ad32b290d390a450a389c69',1,'pearl-data-explorer.ipf']]], + ['display_5fprogress_5fpanel_187',['display_progress_panel',['../pearl-gui-tools_8ipf.html#aaf29d090c81e00cf44af295193b24c5a',1,'pearl-gui-tools.ipf']]], + ['display_5fscanlines_188',['display_scanlines',['../pearl-anglescan-process_8ipf.html#a1f4f74a8ae557c56e1e3aacd0b45f3f1',1,'pearl-anglescan-process.ipf']]], + ['displaygizmoslicer_189',['DisplayGizmoSlicer',['../pearl-menu_8ipf.html#aab34952c2f3b36f9ee8619eb901ff581',1,'pearl-menu.ipf']]], + ['do_5fcrop_190',['do_crop',['../pearl-anglescan-panel_8ipf.html#af39609fc80e58f2188b3aa564f53b750',1,'pearl-anglescan-panel.ipf']]], + ['do_5finit_5fprocess_191',['do_init_process',['../pearl-anglescan-panel_8ipf.html#a1836e607851ba4d5a4048f4cfb8121a7',1,'pearl-anglescan-panel.ipf']]], + ['do_5fnorm_5falpha_192',['do_norm_alpha',['../pearl-anglescan-panel_8ipf.html#a8f7266ac2840155dede704fda66fe6b0',1,'pearl-anglescan-panel.ipf']]], + ['do_5fnorm_5fphi_193',['do_norm_phi',['../pearl-anglescan-panel_8ipf.html#a790519191391ac03c75eb7b57ea0749e',1,'pearl-anglescan-panel.ipf']]], + ['do_5fnorm_5ftheta_194',['do_norm_theta',['../pearl-anglescan-panel_8ipf.html#a7b288598e3faa37e414b1443982c1a3e',1,'pearl-anglescan-panel.ipf']]], + ['do_5fnorm_5fthetaphi_195',['do_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#af6509fc7584b0bcbdc8561df2bc12a58',1,'pearl-anglescan-panel.ipf']]], + ['doniachsunjic_196',['DoniachSunjic',['../pearl-fitfuncs_8ipf.html#aaa48428994f8720a12e7237ef43e86ea',1,'pearl-fitfuncs.ipf']]], + ['doniachsunjicbroad_197',['DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#ae2d138beb7cb39e8042487893095b461',1,'pearl-fitfuncs.ipf']]], + ['doniachsunjicbroads_198',['DoniachSunjicBroadS',['../pearl-fitfuncs_8ipf.html#a9d110819fa3cd2173f3103724e394fdf',1,'pearl-fitfuncs.ipf']]], + ['doniachsunjicstruct_199',['DoniachSunjicStruct',['../struct_doniach_sunjic_struct.html',1,'']]], + ['doubletgausslinbg_5fao_200',['DoubletGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#adb438f665e51a8dd104a37cfead04f27',1,'pearl-fitfuncs.ipf']]], + ['draw_5fdiffraction_5fcone_201',['draw_diffraction_cone',['../pearl-anglescan-process_8ipf.html#afedad38a418cee5d1fb9e08aae2160a0',1,'pearl-anglescan-process.ipf']]], + ['draw_5fhemi_5faxes_202',['draw_hemi_axes',['../pearl-anglescan-process_8ipf.html#af00d9061e410ad033a9fd1f0ca561e0d',1,'pearl-anglescan-process.ipf']]], + ['ds1_5fbg_203',['ds1_bg',['../pearl-fitfuncs_8ipf.html#af62cb65b7444ff60e956a45bd5d0ec27',1,'pearl-fitfuncs.ipf']]], + ['ds2_5fbg_204',['ds2_bg',['../pearl-fitfuncs_8ipf.html#a1e729418252bf0d05ea6ec5cbd65b834',1,'pearl-fitfuncs.ipf']]], + ['ds4_5fbg_205',['ds4_bg',['../pearl-fitfuncs_8ipf.html#ab32134566b2573672ac674565deebd36',1,'pearl-fitfuncs.ipf']]], + ['ds6_5fbg_206',['ds6_bg',['../pearl-fitfuncs_8ipf.html#a5a2a03026b88f3dd99214ab1b26e6f80',1,'pearl-fitfuncs.ipf']]], + ['duplicate_5fhemi_5fscan_207',['duplicate_hemi_scan',['../pearl-anglescan-process_8ipf.html#aa5b1e2ab1dd43a73b7157406b803887e',1,'pearl-anglescan-process.ipf']]] ]; diff --git a/doc/html/search/all_4.html b/doc/html/search/all_4.html index 8e1f4b9..06de155 100644 --- a/doc/html/search/all_4.html +++ b/doc/html/search/all_4.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_4.js b/doc/html/search/all_4.js index 931ed3c..33f2d6d 100644 --- a/doc/html/search/all_4.js +++ b/doc/html/search/all_4.js @@ -1,26 +1,27 @@ var searchData= [ - ['edit_5foffsets',['edit_offsets',['../pearl-anglescan-tracker_8ipf.html#a37aaf2f08c3910bed554a10dd82616ec',1,'pearl-anglescan-tracker.ipf']]], - ['edit_5freduction_5fparams',['edit_reduction_params',['../pearl-anglescan-tracker_8ipf.html#a3844e7fd93b4f54aa52f084687c2106c',1,'pearl-anglescan-tracker.ipf']]], - ['elog_5fadd_5fattachment',['elog_add_attachment',['../pearl-elog_8ipf.html#ac2f76abed8cfaa7ac02a46c0b89004f0',1,'pearl-elog.ipf']]], - ['elog_5fconfig',['elog_config',['../pearl-elog_8ipf.html#a424460442afd5f6f853e68cd665ed785',1,'pearl-elog.ipf']]], - ['elog_5fcreate_5fentry',['elog_create_entry',['../pearl-elog_8ipf.html#a05301d497e4796e5fb5adde3728ba971',1,'pearl-elog.ipf']]], - ['elog_5fcreate_5flogbook',['elog_create_logbook',['../pearl-elog_8ipf.html#ab6d97edbf33e8ec039b34ff756e7ab93',1,'pearl-elog.ipf']]], - ['elog_5finit_5fpearl_5ftemplates',['elog_init_pearl_templates',['../pearl-elog_8ipf.html#aaca820a0149ce6a0e843ca72b9c9e7ab',1,'pearl-elog.ipf']]], - ['elog_5flogin',['elog_login',['../pearl-elog_8ipf.html#a3eac4012891c2813e401aee2c1134763',1,'pearl-elog.ipf']]], - ['elog_5flogout',['elog_logout',['../pearl-elog_8ipf.html#a96e4cbbdb0fd8c58d87b502dc1883664',1,'pearl-elog.ipf']]], - ['elog_5fpanel_5fhook',['elog_panel_hook',['../pearl-elog_8ipf.html#af8b1ea711208bcc2cd1647abe04131dc',1,'pearl-elog.ipf']]], - ['elog_5fparse_5fid',['elog_parse_id',['../pearl-elog_8ipf.html#a6a9923c6465c91b1f9d1d97b090f424b',1,'pearl-elog.ipf']]], - ['elog_5fprompt_5flogbook',['elog_prompt_logbook',['../pearl-elog_8ipf.html#acedf0c8ae34e9ebadd6fa0d9d1353aa4',1,'pearl-elog.ipf']]], - ['elog_5fprompt_5flogin',['elog_prompt_login',['../pearl-elog_8ipf.html#afbace5ffc3167b42b09657ce6cc854ca',1,'pearl-elog.ipf']]], - ['elog_5fsuccess_5fmsg',['elog_success_msg',['../pearl-elog_8ipf.html#a63aa38b624b66fe502505040c25bc0c3',1,'pearl-elog.ipf']]], - ['elog_5fvalidate_5fattributes',['elog_validate_attributes',['../pearl-elog_8ipf.html#ab2558ef5cd5e5dfba410bd58ed258b64',1,'pearl-elog.ipf']]], - ['empty_5fresultfile',['EMPTY_RESULTFILE',['../structerror_code.html#ab7f29ef2ba8497c55f2bc55c4b9fc186',1,'errorCode']]], - ['epics_5fconnect',['epics_connect',['../pearl-anglescan-tracker_8ipf.html#a306b168cab2f9c4146cee87009e69f6d',1,'pearl-anglescan-tracker.ipf']]], - ['epics_5fdisconnect',['epics_disconnect',['../pearl-anglescan-tracker_8ipf.html#a4619cb98a75adb3c39ea3a62e524b793',1,'pearl-anglescan-tracker.ipf']]], - ['epics_5fdisconnect_5fchid',['epics_disconnect_chid',['../pearl-anglescan-tracker_8ipf.html#acfe94a64ff3e8c4cb32e34ffb9cae594',1,'pearl-anglescan-tracker.ipf']]], - ['errorcode',['errorCode',['../structerror_code.html',1,'']]], - ['export_5ftracker_5fdata',['export_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a09e95dbf1582fcf2e6f71baddb147f86',1,'pearl-anglescan-tracker.ipf']]], - ['extend_5fdata',['extend_data',['../pearl-anglescan-tracker_8ipf.html#a4bde8b2fc39c61c0d5a6879f1d0ae115',1,'pearl-anglescan-tracker.ipf']]], - ['extract_5fpreview_5fimage',['extract_preview_image',['../pearl-data-explorer_8ipf.html#a0adc1b370fd3bf230b61b094b3c0accb',1,'pearl-data-explorer.ipf']]] + ['edit_5foffsets_208',['edit_offsets',['../pearl-anglescan-tracker_8ipf.html#a37aaf2f08c3910bed554a10dd82616ec',1,'pearl-anglescan-tracker.ipf']]], + ['edit_5freduction_5fparams_209',['edit_reduction_params',['../pearl-anglescan-tracker_8ipf.html#a3844e7fd93b4f54aa52f084687c2106c',1,'pearl-anglescan-tracker.ipf']]], + ['elog_5fadd_5fattachment_210',['elog_add_attachment',['../pearl-elog_8ipf.html#ac2f76abed8cfaa7ac02a46c0b89004f0',1,'pearl-elog.ipf']]], + ['elog_5fconfig_211',['elog_config',['../pearl-elog_8ipf.html#a424460442afd5f6f853e68cd665ed785',1,'pearl-elog.ipf']]], + ['elog_5fcreate_5fentry_212',['elog_create_entry',['../pearl-elog_8ipf.html#a05301d497e4796e5fb5adde3728ba971',1,'pearl-elog.ipf']]], + ['elog_5fcreate_5flogbook_213',['elog_create_logbook',['../pearl-elog_8ipf.html#ab6d97edbf33e8ec039b34ff756e7ab93',1,'pearl-elog.ipf']]], + ['elog_5finit_5fpearl_5ftemplates_214',['elog_init_pearl_templates',['../pearl-elog_8ipf.html#aaca820a0149ce6a0e843ca72b9c9e7ab',1,'pearl-elog.ipf']]], + ['elog_5flogin_215',['elog_login',['../pearl-elog_8ipf.html#a3eac4012891c2813e401aee2c1134763',1,'pearl-elog.ipf']]], + ['elog_5flogout_216',['elog_logout',['../pearl-elog_8ipf.html#a96e4cbbdb0fd8c58d87b502dc1883664',1,'pearl-elog.ipf']]], + ['elog_5fpanel_5fhook_217',['elog_panel_hook',['../pearl-elog_8ipf.html#af8b1ea711208bcc2cd1647abe04131dc',1,'pearl-elog.ipf']]], + ['elog_5fparse_5fid_218',['elog_parse_id',['../pearl-elog_8ipf.html#a6a9923c6465c91b1f9d1d97b090f424b',1,'pearl-elog.ipf']]], + ['elog_5fprompt_5flogbook_219',['elog_prompt_logbook',['../pearl-elog_8ipf.html#acedf0c8ae34e9ebadd6fa0d9d1353aa4',1,'pearl-elog.ipf']]], + ['elog_5fprompt_5flogin_220',['elog_prompt_login',['../pearl-elog_8ipf.html#afbace5ffc3167b42b09657ce6cc854ca',1,'pearl-elog.ipf']]], + ['elog_5fsuccess_5fmsg_221',['elog_success_msg',['../pearl-elog_8ipf.html#a63aa38b624b66fe502505040c25bc0c3',1,'pearl-elog.ipf']]], + ['elog_5fvalidate_5fattributes_222',['elog_validate_attributes',['../pearl-elog_8ipf.html#ab2558ef5cd5e5dfba410bd58ed258b64',1,'pearl-elog.ipf']]], + ['empty_5fresultfile_223',['EMPTY_RESULTFILE',['../structerror_code.html#ab7f29ef2ba8497c55f2bc55c4b9fc186',1,'errorCode']]], + ['epics_5fconnect_224',['epics_connect',['../pearl-anglescan-tracker_8ipf.html#a306b168cab2f9c4146cee87009e69f6d',1,'pearl-anglescan-tracker.ipf']]], + ['epics_5fdisconnect_225',['epics_disconnect',['../pearl-anglescan-tracker_8ipf.html#a4619cb98a75adb3c39ea3a62e524b793',1,'pearl-anglescan-tracker.ipf']]], + ['epics_5fdisconnect_5fchid_226',['epics_disconnect_chid',['../pearl-anglescan-tracker_8ipf.html#acfe94a64ff3e8c4cb32e34ffb9cae594',1,'pearl-anglescan-tracker.ipf']]], + ['errorcode_227',['errorCode',['../structerror_code.html',1,'']]], + ['export_5ftracker_5fdata_228',['export_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a09e95dbf1582fcf2e6f71baddb147f86',1,'pearl-anglescan-tracker.ipf']]], + ['extend_5fdata_229',['extend_data',['../pearl-anglescan-tracker_8ipf.html#a4bde8b2fc39c61c0d5a6879f1d0ae115',1,'pearl-anglescan-tracker.ipf']]], + ['extract_5fattributes_230',['extract_attributes',['../pearl-data-explorer_8ipf.html#af4474f34647ec24f27f900226c6bb3bd',1,'pearl-data-explorer.ipf']]], + ['extract_5fpreview_5fimage_231',['extract_preview_image',['../pearl-data-explorer_8ipf.html#a0adc1b370fd3bf230b61b094b3c0accb',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/all_5.html b/doc/html/search/all_5.html index 89a879e..2544c4e 100644 --- a/doc/html/search/all_5.html +++ b/doc/html/search/all_5.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_5.js b/doc/html/search/all_5.js index 0b8abaf..78ef812 100644 --- a/doc/html/search/all_5.js +++ b/doc/html/search/all_5.js @@ -1,13 +1,10 @@ var searchData= [ - ['fermi_2dedge_2danalysis_2eipf',['fermi-edge-analysis.ipf',['../fermi-edge-analysis_8ipf.html',1,'']]], - ['fermifunclindos2d_5fcorr',['FermiFuncLinDOS2D_corr',['../fermi-edge-analysis_8ipf.html#a520d8de9fbc4276c19fb417861f05b0d',1,'fermi-edge-analysis.ipf']]], - ['fermigaussconv',['FermiGaussConv',['../pearl-fitfuncs_8ipf.html#a4d20215153c0e0cee3870dfceded8bc9',1,'pearl-fitfuncs.ipf']]], - ['file_5fnot_5freadable',['FILE_NOT_READABLE',['../structerror_code.html#a71ce7c0413c44515d9570dab1ffd5ffd',1,'errorCode']]], - ['find_5fattr_5ffolder',['find_attr_folder',['../pearl-pshell-import_8ipf.html#a41bf534983b0662ec2609b136c395f14',1,'pearl-pshell-import.ipf']]], - ['find_5fhemi_5fdata',['find_hemi_data',['../pearl-anglescan-process_8ipf.html#aa26c9ed4c4d703e07788d980edc2406d',1,'pearl-anglescan-process.ipf']]], - ['find_5fscale_5fwave',['find_scale_wave',['../pearl-pshell-import_8ipf.html#acfb01ee360b66f286225f6e9c7220ba2',1,'pearl-pshell-import.ipf']]], - ['find_5fscan_5ffolder',['find_scan_folder',['../pearl-pshell-import_8ipf.html#a79b968d7439dfbfbc38c05f933071489',1,'pearl-pshell-import.ipf']]], - ['fit_5fdoniachsunjicbroad',['Fit_DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#a819902ab9f541b75a0fd33a7b52465d0',1,'pearl-fitfuncs.ipf']]], - ['format_5furl',['format_url',['../pearl-elog_8ipf.html#a3cc9074c84d684d207dfdf2045755df4',1,'pearl-elog.ipf']]] + ['fermi_2dedge_2danalysis_2eipf_232',['fermi-edge-analysis.ipf',['../fermi-edge-analysis_8ipf.html',1,'']]], + ['fermifunclindos2d_5fcorr_233',['FermiFuncLinDOS2D_corr',['../fermi-edge-analysis_8ipf.html#a520d8de9fbc4276c19fb417861f05b0d',1,'fermi-edge-analysis.ipf']]], + ['fermigaussconv_234',['FermiGaussConv',['../pearl-fitfuncs_8ipf.html#a4d20215153c0e0cee3870dfceded8bc9',1,'pearl-fitfuncs.ipf']]], + ['file_5fnot_5freadable_235',['FILE_NOT_READABLE',['../structerror_code.html#a71ce7c0413c44515d9570dab1ffd5ffd',1,'errorCode']]], + ['find_5fhemi_5fdata_236',['find_hemi_data',['../pearl-anglescan-process_8ipf.html#aa26c9ed4c4d703e07788d980edc2406d',1,'pearl-anglescan-process.ipf']]], + ['fit_5fdoniachsunjicbroad_237',['Fit_DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#a819902ab9f541b75a0fd33a7b52465d0',1,'pearl-fitfuncs.ipf']]], + ['format_5furl_238',['format_url',['../pearl-elog_8ipf.html#a3cc9074c84d684d207dfdf2045755df4',1,'pearl-elog.ipf']]] ]; diff --git a/doc/html/search/all_6.html b/doc/html/search/all_6.html index 6afac06..43f14ea 100644 --- a/doc/html/search/all_6.html +++ b/doc/html/search/all_6.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_6.js b/doc/html/search/all_6.js index ec5d27c..cc2c27c 100644 --- a/doc/html/search/all_6.js +++ b/doc/html/search/all_6.js @@ -1,19 +1,23 @@ var searchData= [ - ['gather_5fbatch',['gather_batch',['../pearl-otf-import_8ipf.html#ae2640256d7d07c11b41621430279cef6',1,'pearl-otf-import.ipf']]], - ['gauss4_5freduction',['gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#a83cdbd96c5b59011914d53118e5ef71c',1,'pearl-scienta-preprocess.ipf']]], - ['get_5fdefault_5fpanel_5fname',['get_default_panel_name',['../pearl-elog_8ipf.html#a1376b5c9e6b1180a09961bc3296849ae',1,'pearl-elog.ipf']]], - ['get_5felog_5fdf',['get_elog_df',['../pearl-elog_8ipf.html#ac45196cb9ce8b43b76c9daf67689c49a',1,'pearl-elog.ipf']]], - ['get_5fhemi_5fnickname',['get_hemi_nickname',['../pearl-anglescan-process_8ipf.html#a987811346894d8d81fc590b2f5ccec49',1,'pearl-anglescan-process.ipf']]], - ['get_5fhemi_5fprefix',['get_hemi_prefix',['../pearl-anglescan-process_8ipf.html#a1442bc23122d52ba9c77e0f9baaad1da',1,'pearl-anglescan-process.ipf']]], - ['get_5flog_5fpath',['get_log_path',['../pearl-elog_8ipf.html#ad1a72c63f269b2e22b21a72d1ef3b279',1,'pearl-elog.ipf']]], - ['get_5fpanel_5fattributes',['get_panel_attributes',['../pearl-elog_8ipf.html#a66e1200515eff8cd5c961572eccd7220',1,'pearl-elog.ipf']]], - ['get_5fpanel_5fgraphs',['get_panel_graphs',['../pearl-elog_8ipf.html#ace94356f691cbe343761aabd67ced23c',1,'pearl-elog.ipf']]], - ['get_5fpanel_5fmessage',['get_panel_message',['../pearl-elog_8ipf.html#a7ce92b03b6a786129959d44bf1112efa',1,'pearl-elog.ipf']]], - ['get_5fsource_5fimage',['get_source_image',['../pearl-area-display_8ipf.html#a4b76a98582f5997d3810f969dbb6c4ed',1,'pearl-area-display.ipf']]], - ['get_5ftimestamp',['get_timestamp',['../pearl-elog_8ipf.html#a6b2d6cf641c61120332ac1983b2f3846',1,'pearl-elog.ipf']]], - ['get_5fview_5ffolder',['get_view_folder',['../pearl-area-display_8ipf.html#a1bf20e37ed3e9c76be8ebe448c68a048',1,'pearl-area-display.ipf']]], - ['get_5fview_5fimage',['get_view_image',['../pearl-area-display_8ipf.html#a6cc0970b41ca197fa47263556fa2686a',1,'pearl-area-display.ipf']]], - ['getattrdatafolderdfr',['GetAttrDataFolderDFR',['../pearl-area-import_8ipf.html#aa3cdc56096a6a1bf2a2d80a6245a36d2',1,'pearl-area-import.ipf']]], - ['graphname_5ffrom_5fdfref',['graphname_from_dfref',['../pearl-area-display_8ipf.html#a195b12857685c4e535a840c5db324b4a',1,'pearl-area-display.ipf']]] + ['gather_5fbatch_239',['gather_batch',['../pearl-otf-import_8ipf.html#ae2640256d7d07c11b41621430279cef6',1,'pearl-otf-import.ipf']]], + ['gauss4_5freduction_240',['gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#a83cdbd96c5b59011914d53118e5ef71c',1,'pearl-scienta-preprocess.ipf']]], + ['gauss6_5freduction_241',['gauss6_reduction',['../pearl-scienta-preprocess_8ipf.html#a11d42ef1352876666b710b7545360fce',1,'pearl-scienta-preprocess.ipf']]], + ['get_5fdefault_5fpanel_5fname_242',['get_default_panel_name',['../pearl-elog_8ipf.html#a1376b5c9e6b1180a09961bc3296849ae',1,'pearl-elog.ipf']]], + ['get_5felog_5fdf_243',['get_elog_df',['../pearl-elog_8ipf.html#ac45196cb9ce8b43b76c9daf67689c49a',1,'pearl-elog.ipf']]], + ['get_5ffile_5finfo_244',['get_file_info',['../pearl-data-explorer_8ipf.html#a66043ccbe2e8dda258e639cb7a231537',1,'pearl-data-explorer.ipf']]], + ['get_5fhemi_5fnickname_245',['get_hemi_nickname',['../pearl-anglescan-process_8ipf.html#a987811346894d8d81fc590b2f5ccec49',1,'pearl-anglescan-process.ipf']]], + ['get_5fhemi_5fprefix_246',['get_hemi_prefix',['../pearl-anglescan-process_8ipf.html#a1442bc23122d52ba9c77e0f9baaad1da',1,'pearl-anglescan-process.ipf']]], + ['get_5flog_5fpath_247',['get_log_path',['../pearl-elog_8ipf.html#ad1a72c63f269b2e22b21a72d1ef3b279',1,'pearl-elog.ipf']]], + ['get_5fpanel_5fattributes_248',['get_panel_attributes',['../pearl-elog_8ipf.html#a66e1200515eff8cd5c961572eccd7220',1,'pearl-elog.ipf']]], + ['get_5fpanel_5fgraphs_249',['get_panel_graphs',['../pearl-elog_8ipf.html#ace94356f691cbe343761aabd67ced23c',1,'pearl-elog.ipf']]], + ['get_5fpanel_5fmessage_250',['get_panel_message',['../pearl-elog_8ipf.html#a7ce92b03b6a786129959d44bf1112efa',1,'pearl-elog.ipf']]], + ['get_5fpshell_5finfo_251',['get_pshell_info',['../pearl-data-explorer_8ipf.html#a28921b185d4e6fbe9a7a689757269f19',1,'pearl-data-explorer.ipf']]], + ['get_5fsource_5fimage_252',['get_source_image',['../pearl-area-display_8ipf.html#a4b76a98582f5997d3810f969dbb6c4ed',1,'pearl-area-display.ipf']]], + ['get_5ftimestamp_253',['get_timestamp',['../pearl-elog_8ipf.html#a6b2d6cf641c61120332ac1983b2f3846',1,'pearl-elog.ipf']]], + ['get_5fview_5ffolder_254',['get_view_folder',['../pearl-area-display_8ipf.html#a1bf20e37ed3e9c76be8ebe448c68a048',1,'pearl-area-display.ipf']]], + ['get_5fview_5fimage_255',['get_view_image',['../pearl-area-display_8ipf.html#a6cc0970b41ca197fa47263556fa2686a',1,'pearl-area-display.ipf']]], + ['getattrdatafolderdfr_256',['GetAttrDataFolderDFR',['../pearl-area-import_8ipf.html#aa3cdc56096a6a1bf2a2d80a6245a36d2',1,'pearl-area-import.ipf']]], + ['goto_5fdataset_5ffolder_257',['goto_dataset_folder',['../pearl-data-explorer_8ipf.html#a896081071fffecdeff09ae4c9d6e84cb',1,'pearl-data-explorer.ipf']]], + ['graphname_5ffrom_5fdfref_258',['graphname_from_dfref',['../pearl-area-display_8ipf.html#a195b12857685c4e535a840c5db324b4a',1,'pearl-area-display.ipf']]] ]; diff --git a/doc/html/search/all_7.html b/doc/html/search/all_7.html index de19107..af52f82 100644 --- a/doc/html/search/all_7.html +++ b/doc/html/search/all_7.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_7.js b/doc/html/search/all_7.js index ff8d65b..8ab4897 100644 --- a/doc/html/search/all_7.js +++ b/doc/html/search/all_7.js @@ -1,8 +1,16 @@ var searchData= [ - ['hemi_5fadd_5fanglescan',['hemi_add_anglescan',['../pearl-anglescan-process_8ipf.html#a4952bc53e3d6d272d25b5e35e91696b5',1,'pearl-anglescan-process.ipf']]], - ['hemi_5fadd_5faziscan',['hemi_add_aziscan',['../pearl-anglescan-process_8ipf.html#a4641c716180d737700c6df87f5f8974e',1,'pearl-anglescan-process.ipf']]], - ['hemi_5fazi_5fcut',['hemi_azi_cut',['../pearl-anglescan-process_8ipf.html#ab6ac1268de338040028dca8d0ddc967c',1,'pearl-anglescan-process.ipf']]], - ['hemi_5fpolar_5fcut',['hemi_polar_cut',['../pearl-anglescan-process_8ipf.html#aa486e16909d01e2251eeb4d635b972b1',1,'pearl-anglescan-process.ipf']]], - ['hemi_5fradius_5fmm',['hemi_radius_mm',['../fermi-edge-analysis_8ipf.html#a0cb8da36beae05c79fe5b1da918d3897',1,'fermi-edge-analysis.ipf']]] + ['hemi_5fadd_5fanglescan_259',['hemi_add_anglescan',['../pearl-anglescan-process_8ipf.html#a4952bc53e3d6d272d25b5e35e91696b5',1,'pearl-anglescan-process.ipf']]], + ['hemi_5fadd_5faziscan_260',['hemi_add_aziscan',['../pearl-anglescan-process_8ipf.html#a4641c716180d737700c6df87f5f8974e',1,'pearl-anglescan-process.ipf']]], + ['hemi_5fazi_5fcut_261',['hemi_azi_cut',['../pearl-anglescan-process_8ipf.html#ab6ac1268de338040028dca8d0ddc967c',1,'pearl-anglescan-process.ipf']]], + ['hemi_5fpolar_5fcut_262',['hemi_polar_cut',['../pearl-anglescan-process_8ipf.html#aa486e16909d01e2251eeb4d635b972b1',1,'pearl-anglescan-process.ipf']]], + ['hemi_5fradius_5fmm_263',['hemi_radius_mm',['../fermi-edge-analysis_8ipf.html#a0cb8da36beae05c79fe5b1da918d3897',1,'fermi-edge-analysis.ipf']]], + ['hl_5fadd_5fobjects_264',['hl_add_objects',['../pearl-data-explorer_8ipf.html#a54be4e40b17906c281cdf649d6ce537e',1,'pearl-data-explorer.ipf']]], + ['hl_5fcontents_5fclear_265',['hl_contents_clear',['../pearl-data-explorer_8ipf.html#ad95697e197428ff73a1a258ea3bb79b2',1,'pearl-data-explorer.ipf']]], + ['hl_5fcontents_5fupdate_266',['hl_contents_update',['../pearl-data-explorer_8ipf.html#aba2f8be504e49469194cc4b562be3a9c',1,'pearl-data-explorer.ipf']]], + ['hl_5fdefault_5fselection_267',['hl_default_selection',['../pearl-data-explorer_8ipf.html#a7c36ce6ccfaa77cf7a6b68b9014c1b9b',1,'pearl-data-explorer.ipf']]], + ['hl_5fexpand_5fscans_268',['hl_expand_scans',['../pearl-data-explorer_8ipf.html#a5d0c796365e8a24683c73e2b29571018',1,'pearl-data-explorer.ipf']]], + ['hlp_5fcontents_5fopen_269',['hlp_contents_open',['../pearl-data-explorer_8ipf.html#a384a37c2865baf5c21b63cff2488c3b3',1,'pearl-data-explorer.ipf']]], + ['hlp_5fcontents_5fselection_270',['hlp_contents_selection',['../pearl-data-explorer_8ipf.html#a36fd730f2d057513179dd59f8fddaf75',1,'pearl-data-explorer.ipf']]], + ['hlp_5fsetup_271',['hlp_setup',['../pearl-data-explorer_8ipf.html#af616e37167d5753b11e513bd03685ab8',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/all_8.html b/doc/html/search/all_8.html index 11e27cd..cf2b5df 100644 --- a/doc/html/search/all_8.html +++ b/doc/html/search/all_8.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_8.js b/doc/html/search/all_8.js index db5babf..b8ed75d 100644 --- a/doc/html/search/all_8.js +++ b/doc/html/search/all_8.js @@ -1,20 +1,20 @@ var searchData= [ - ['igorbeforenewhook',['IgorBeforeNewHook',['../pearl-elog_8ipf.html#ae824bbf81f8b7d16b36b53e3f3d85f69',1,'pearl-elog.ipf']]], - ['igorquithook',['IgorQuitHook',['../pearl-anglescan-tracker_8ipf.html#a0852e59e9018cf3f7e176aa2355b18e3',1,'IgorQuitHook(string app): pearl-anglescan-tracker.ipf'],['../pearl-elog_8ipf.html#a6fcae5eafc97bca9a637bd7800b13e25',1,'IgorQuitHook(string igorApplicationNameStr): pearl-elog.ipf']]], - ['import_5ftpi_5fscan',['import_tpi_scan',['../pearl-anglescan-process_8ipf.html#a5265fd61f86eb72dd877e4190bfb4adf',1,'pearl-anglescan-process.ipf']]], - ['import_5ftracker_5fdata',['import_tracker_data',['../pearl-anglescan-tracker_8ipf.html#ae53e615892fbc39f831b6bd7a0ae242e',1,'pearl-anglescan-tracker.ipf']]], - ['introduction',['Introduction',['../index.html',1,'']]], - ['init_5fpackage',['init_package',['../pearl-anglescan-panel_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a7a4572f4f861f7eb46c932508d1164f9',1,'init_package(variable clean=defaultValue): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-matrix-import.ipf']]], - ['init_5fvolatile_5fvars',['init_volatile_vars',['../pearl-elog_8ipf.html#a85cf9d39ea917860b463b1b4111705f2',1,'pearl-elog.ipf']]], - ['initstruct',['initStruct',['../pearl-matrix-import_8ipf.html#af0eaec901e06ce59250eb434539a0f6c',1,'pearl-matrix-import.ipf']]], - ['int_5flinbg_5freduction',['int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a1e91197cd7a3581b70bc59a194d3f43b',1,'pearl-scienta-preprocess.ipf']]], - ['int_5fquadbg_5freduction',['int_quadbg_reduction',['../pearl-scienta-preprocess_8ipf.html#ad626526589efec3f2f72ad001702fe39',1,'pearl-scienta-preprocess.ipf']]], - ['integrate_5fcurved_5fedge',['integrate_curved_edge',['../fermi-edge-analysis_8ipf.html#a2a1d7b49c1f88f29ee6d49f6a6f4fbf8',1,'fermi-edge-analysis.ipf']]], - ['internal_5ferror_5fconverting_5fdata',['INTERNAL_ERROR_CONVERTING_DATA',['../structerror_code.html#afb49d1cffe8e7590892b018ac9e648cc',1,'errorCode']]], - ['interpolate_5fhemi_5fscan',['interpolate_hemi_scan',['../pearl-anglescan-process_8ipf.html#acca0130cccf2286863bbf5b7f91c5b3b',1,'pearl-anglescan-process.ipf']]], - ['invalid_5frange',['INVALID_RANGE',['../structerror_code.html#a5477920df1edcc7a1af0513d9120947a',1,'errorCode']]], - ['iteratedatafolders',['IterateDataFolders',['../pearl-tools_8ipf.html#a7c5307e5e7c0202d2b088fdc11887069',1,'pearl-tools.ipf']]], - ['iteratewaves',['IterateWaves',['../pearl-tools_8ipf.html#aabc250f68dd85ca58d7be5077255af99',1,'pearl-tools.ipf']]], - ['itx_5fsuggest_5ffoldername',['itx_suggest_foldername',['../pearl-data-explorer_8ipf.html#a6b5e9729ee6dedbb217c741639a168ed',1,'pearl-data-explorer.ipf']]] + ['igorbeforenewhook_272',['IgorBeforeNewHook',['../pearl-elog_8ipf.html#ae824bbf81f8b7d16b36b53e3f3d85f69',1,'pearl-elog.ipf']]], + ['igorquithook_273',['IgorQuitHook',['../pearl-anglescan-tracker_8ipf.html#a0852e59e9018cf3f7e176aa2355b18e3',1,'IgorQuitHook(string app): pearl-anglescan-tracker.ipf'],['../pearl-elog_8ipf.html#a6fcae5eafc97bca9a637bd7800b13e25',1,'IgorQuitHook(string igorApplicationNameStr): pearl-elog.ipf']]], + ['import_5ftpi_5fscan_274',['import_tpi_scan',['../pearl-anglescan-process_8ipf.html#a5265fd61f86eb72dd877e4190bfb4adf',1,'pearl-anglescan-process.ipf']]], + ['import_5ftracker_5fdata_275',['import_tracker_data',['../pearl-anglescan-tracker_8ipf.html#ae53e615892fbc39f831b6bd7a0ae242e',1,'pearl-anglescan-tracker.ipf']]], + ['introduction_276',['Introduction',['../index.html',1,'']]], + ['init_5fpackage_277',['init_package',['../pearl-anglescan-panel_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a7a4572f4f861f7eb46c932508d1164f9',1,'init_package(variable clean=defaultValue): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-matrix-import.ipf']]], + ['init_5fvolatile_5fvars_278',['init_volatile_vars',['../pearl-elog_8ipf.html#a85cf9d39ea917860b463b1b4111705f2',1,'pearl-elog.ipf']]], + ['initstruct_279',['initStruct',['../pearl-matrix-import_8ipf.html#af0eaec901e06ce59250eb434539a0f6c',1,'pearl-matrix-import.ipf']]], + ['int_5flinbg_5freduction_280',['int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a1e91197cd7a3581b70bc59a194d3f43b',1,'pearl-scienta-preprocess.ipf']]], + ['int_5fquadbg_5freduction_281',['int_quadbg_reduction',['../pearl-scienta-preprocess_8ipf.html#ad626526589efec3f2f72ad001702fe39',1,'pearl-scienta-preprocess.ipf']]], + ['integrate_5fcurved_5fedge_282',['integrate_curved_edge',['../fermi-edge-analysis_8ipf.html#a2a1d7b49c1f88f29ee6d49f6a6f4fbf8',1,'fermi-edge-analysis.ipf']]], + ['internal_5ferror_5fconverting_5fdata_283',['INTERNAL_ERROR_CONVERTING_DATA',['../structerror_code.html#afb49d1cffe8e7590892b018ac9e648cc',1,'errorCode']]], + ['interpolate_5fhemi_5fscan_284',['interpolate_hemi_scan',['../pearl-anglescan-process_8ipf.html#acca0130cccf2286863bbf5b7f91c5b3b',1,'pearl-anglescan-process.ipf']]], + ['invalid_5frange_285',['INVALID_RANGE',['../structerror_code.html#a5477920df1edcc7a1af0513d9120947a',1,'errorCode']]], + ['iteratedatafolders_286',['IterateDataFolders',['../pearl-tools_8ipf.html#a7c5307e5e7c0202d2b088fdc11887069',1,'pearl-tools.ipf']]], + ['iteratewaves_287',['IterateWaves',['../pearl-tools_8ipf.html#aabc250f68dd85ca58d7be5077255af99',1,'pearl-tools.ipf']]], + ['itx_5fsuggest_5ffoldername_288',['itx_suggest_foldername',['../pearl-data-explorer_8ipf.html#a6b5e9729ee6dedbb217c741639a168ed',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/all_9.html b/doc/html/search/all_9.html index f8abbbe..690785a 100644 --- a/doc/html/search/all_9.html +++ b/doc/html/search/all_9.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_9.js b/doc/html/search/all_9.js index 911d49f..2cbc12b 100644 --- a/doc/html/search/all_9.js +++ b/doc/html/search/all_9.js @@ -1,33 +1,47 @@ var searchData= [ - ['kangledimlabel',['kAngleDimLabel',['../pearl-pshell-import_8ipf.html#a83930d4384b0238fc8416ba03dbc0386',1,'pearl-pshell-import.ipf']]], - ['kattachcolname',['kAttachColName',['../pearl-elog_8ipf.html#addbdec64930e9c1e417b16b25df8c723',1,'pearl-elog.ipf']]], - ['kattachcolsel',['kAttachColSel',['../pearl-elog_8ipf.html#aae61ff4d4a4d83dfc55af45d9ed1cbc3',1,'pearl-elog.ipf']]], - ['kattachcoltitle',['kAttachColTitle',['../pearl-elog_8ipf.html#a5afeb893f92034532341ae51471dc2d2',1,'pearl-elog.ipf']]], - ['kdatadimlabel',['kDataDimLabel',['../pearl-pshell-import_8ipf.html#a277cd450cca7832aa44f8097934e6acb',1,'pearl-pshell-import.ipf']]], - ['kdetectorsensitivity',['kDetectorSensitivity',['../pearl-pshell-import_8ipf.html#a5745428740b64cd66394a7fcd78b86f1',1,'pearl-pshell-import.ipf']]], - ['kdfpersistent',['kdfPersistent',['../pearl-elog_8ipf.html#a3498e65d04de046481170b49d4e3d0d6',1,'pearl-elog.ipf']]], - ['kdfroot',['kdfRoot',['../pearl-elog_8ipf.html#af34e46263aa50843f98f755988f9ab5c',1,'pearl-elog.ipf']]], - ['kdftemplates',['kdfTemplates',['../pearl-elog_8ipf.html#a28eb44739e7d5c7f9899a69afa231b8e',1,'pearl-elog.ipf']]], - ['kdfvolatile',['kdfVolatile',['../pearl-elog_8ipf.html#a915905f2e57d0d9a25c75f39fcce485f',1,'pearl-elog.ipf']]], - ['kenergydimlabel',['kEnergyDimLabel',['../pearl-pshell-import_8ipf.html#a5ad52cb10171572c454f9426d3a9be21',1,'pearl-pshell-import.ipf']]], - ['kill_5fprogress_5fpanel',['kill_progress_panel',['../pearl-gui-tools_8ipf.html#aca0a41a0f28a35ac7535df30ddbd79fe',1,'pearl-gui-tools.ipf']]], - ['kpreviewdatasets',['kPreviewDatasets',['../pearl-pshell-import_8ipf.html#a3c72087695969f42ea91c000de47b26e',1,'pearl-pshell-import.ipf']]], - ['kprojarea',['kProjArea',['../pearl-anglescan-process_8ipf.html#a207c56ac03cc18bf1bfde88dbfe2666f',1,'pearl-anglescan-process.ipf']]], - ['kprojdist',['kProjDist',['../pearl-anglescan-process_8ipf.html#aae45cc49d67f79dcedc4420f82acea4c',1,'pearl-anglescan-process.ipf']]], - ['kprojgnom',['kProjGnom',['../pearl-anglescan-process_8ipf.html#a4a40c73c0e03545e0050ea370e9c57d3',1,'pearl-anglescan-process.ipf']]], - ['kprojortho',['kProjOrtho',['../pearl-anglescan-process_8ipf.html#a3b3bd11c35d5f850b34937ab6c45f659',1,'pearl-anglescan-process.ipf']]], - ['kprojscalearea',['kProjScaleArea',['../pearl-anglescan-process_8ipf.html#afa14187803f5b428a96c8234e04ab217',1,'pearl-anglescan-process.ipf']]], - ['kprojscaledist',['kProjScaleDist',['../pearl-anglescan-process_8ipf.html#a04e75675884236b6ed8244d7575d3a13',1,'pearl-anglescan-process.ipf']]], - ['kprojscalegnom',['kProjScaleGnom',['../pearl-anglescan-process_8ipf.html#ab6670abb621d01994c0b9974f58be843',1,'pearl-anglescan-process.ipf']]], - ['kprojscaleortho',['kProjScaleOrtho',['../pearl-anglescan-process_8ipf.html#aa5487fdee22e0da61a511c14239262f5',1,'pearl-anglescan-process.ipf']]], - ['kprojscalestereo',['kProjScaleStereo',['../pearl-anglescan-process_8ipf.html#aed66bda9701d8a69b2174fac974aa665',1,'pearl-anglescan-process.ipf']]], - ['kprojstereo',['kProjStereo',['../pearl-anglescan-process_8ipf.html#ac151c6f989d6a568fdef0acb791f84db',1,'pearl-anglescan-process.ipf']]], - ['ks_5ffilematch_5fadh5',['ks_filematch_adh5',['../pearl-data-explorer_8ipf.html#a181ccce237172811baf3de5a7a06370d',1,'pearl-data-explorer.ipf']]], - ['ks_5ffilematch_5fitx',['ks_filematch_itx',['../pearl-data-explorer_8ipf.html#a53af8689144e3aeb27ca177db5dd0c22',1,'pearl-data-explorer.ipf']]], - ['ks_5ffilematch_5fmtrx',['ks_filematch_mtrx',['../pearl-data-explorer_8ipf.html#ad720655ff881ddecae2e1b8afed58fa0',1,'ks_filematch_mtrx(): pearl-data-explorer.ipf'],['../pearl-matrix-import_8ipf.html#ad720655ff881ddecae2e1b8afed58fa0',1,'ks_filematch_mtrx(): pearl-matrix-import.ipf']]], - ['ks_5ffilematch_5fpshell',['ks_filematch_pshell',['../pearl-data-explorer_8ipf.html#a00bf5267a40b2b3d760c64d73e139878',1,'pearl-data-explorer.ipf']]], - ['kscandimlabel',['kScanDimLabel',['../pearl-pshell-import_8ipf.html#a412b4753ceb753d705a113a26c018b22',1,'pearl-pshell-import.ipf']]], - ['kscientascalingdatasets',['kScientaScalingDatasets',['../pearl-pshell-import_8ipf.html#a03f00b3299bc3df671fcc239f7dd5418',1,'pearl-pshell-import.ipf']]], - ['ktransposeddatasets',['kTransposedDatasets',['../pearl-pshell-import_8ipf.html#a0f2c168c04d075734edb995361aefb82',1,'pearl-pshell-import.ipf']]] + ['kangledimlabel_289',['kAngleDimLabel',['../pearl-pshell-import_8ipf.html#a83930d4384b0238fc8416ba03dbc0386',1,'pearl-pshell-import.ipf']]], + ['kattachcolname_290',['kAttachColName',['../pearl-elog_8ipf.html#addbdec64930e9c1e417b16b25df8c723',1,'pearl-elog.ipf']]], + ['kattachcolsel_291',['kAttachColSel',['../pearl-elog_8ipf.html#aae61ff4d4a4d83dfc55af45d9ed1cbc3',1,'pearl-elog.ipf']]], + ['kattachcoltitle_292',['kAttachColTitle',['../pearl-elog_8ipf.html#a5afeb893f92034532341ae51471dc2d2',1,'pearl-elog.ipf']]], + ['kdatadimlabel_293',['kDataDimLabel',['../pearl-pshell-import_8ipf.html#a277cd450cca7832aa44f8097934e6acb',1,'pearl-pshell-import.ipf']]], + ['kdfpersistent_294',['kdfPersistent',['../pearl-elog_8ipf.html#a3498e65d04de046481170b49d4e3d0d6',1,'pearl-elog.ipf']]], + ['kdfroot_295',['kdfRoot',['../pearl-elog_8ipf.html#af34e46263aa50843f98f755988f9ab5c',1,'pearl-elog.ipf']]], + ['kdftemplates_296',['kdfTemplates',['../pearl-elog_8ipf.html#a28eb44739e7d5c7f9899a69afa231b8e',1,'pearl-elog.ipf']]], + ['kdfvolatile_297',['kdfVolatile',['../pearl-elog_8ipf.html#a915905f2e57d0d9a25c75f39fcce485f',1,'pearl-elog.ipf']]], + ['kdscall_298',['kDSCAll',['../pearl-pshell-import_8ipf.html#a237e95f14b988f58e2d4c37659f17347',1,'pearl-pshell-import.ipf']]], + ['kdscattrs_299',['kDSCAttrs',['../pearl-pshell-import_8ipf.html#a10224f615973777a43fefae8eb1a39f2',1,'pearl-pshell-import.ipf']]], + ['kdscdetectors_300',['kDSCDetectors',['../pearl-pshell-import_8ipf.html#a7c5aaa2f133862ae16ddd735df1ab73d',1,'pearl-pshell-import.ipf']]], + ['kdscdiags_301',['kDSCDiags',['../pearl-pshell-import_8ipf.html#adf778206fa825ab5006bd553c64a8760',1,'pearl-pshell-import.ipf']]], + ['kdscessentialdiags_302',['kDSCEssentialDiags',['../pearl-pshell-import_8ipf.html#aebf53e3de392d631b340ee0747b8bbbf',1,'pearl-pshell-import.ipf']]], + ['kdscmeta_303',['kDSCMeta',['../pearl-pshell-import_8ipf.html#a712ea7a6f18ce4178fd06b07d2d05a9f',1,'pearl-pshell-import.ipf']]], + ['kdscmonitors_304',['kDSCMonitors',['../pearl-pshell-import_8ipf.html#a300847a8e08161a64a199a6e7ef165c8',1,'pearl-pshell-import.ipf']]], + ['kdscother_305',['kDSCOther',['../pearl-pshell-import_8ipf.html#ac81d8f4276cf7bb86a74796cc7199e42',1,'pearl-pshell-import.ipf']]], + ['kdscpositioners_306',['kDSCPositioners',['../pearl-pshell-import_8ipf.html#aeb9a7f56922ff3c862e8b29b5090c01a',1,'pearl-pshell-import.ipf']]], + ['kdscpreview_307',['kDSCPreview',['../pearl-pshell-import_8ipf.html#a654f0b9fe8770a8bd09a6da4182ca3bc',1,'pearl-pshell-import.ipf']]], + ['kdscregions_308',['kDSCRegions',['../pearl-pshell-import_8ipf.html#a48f07030482af8315447ac2c598edd0d',1,'pearl-pshell-import.ipf']]], + ['kdscscientascaling_309',['kDSCScientaScaling',['../pearl-pshell-import_8ipf.html#ab7c2cc8687f6d4550ef90c538b938dad',1,'pearl-pshell-import.ipf']]], + ['kdscsnaps_310',['kDSCSnaps',['../pearl-pshell-import_8ipf.html#a3236744797a780eb144a684b0bd41d4a',1,'pearl-pshell-import.ipf']]], + ['kenergydimlabel_311',['kEnergyDimLabel',['../pearl-pshell-import_8ipf.html#a5ad52cb10171572c454f9426d3a9be21',1,'pearl-pshell-import.ipf']]], + ['kessentialdiagnostics_312',['kEssentialDiagnostics',['../pearl-pshell-import_8ipf.html#ab0bc752ab76659b492cf88c75935336b',1,'pearl-pshell-import.ipf']]], + ['kill_5fmatching_5fwaves_313',['kill_matching_waves',['../pearl-pshell-import_8ipf.html#a972bf23d6da0bb33e9f12e50c9d7f5e5',1,'pearl-pshell-import.ipf']]], + ['kill_5fprogress_5fpanel_314',['kill_progress_panel',['../pearl-gui-tools_8ipf.html#aca0a41a0f28a35ac7535df30ddbd79fe',1,'pearl-gui-tools.ipf']]], + ['kpreviewdatasets_315',['kPreviewDatasets',['../pearl-pshell-import_8ipf.html#a3c72087695969f42ea91c000de47b26e',1,'pearl-pshell-import.ipf']]], + ['kprojarea_316',['kProjArea',['../pearl-anglescan-process_8ipf.html#a207c56ac03cc18bf1bfde88dbfe2666f',1,'pearl-anglescan-process.ipf']]], + ['kprojdist_317',['kProjDist',['../pearl-anglescan-process_8ipf.html#aae45cc49d67f79dcedc4420f82acea4c',1,'pearl-anglescan-process.ipf']]], + ['kprojgnom_318',['kProjGnom',['../pearl-anglescan-process_8ipf.html#a4a40c73c0e03545e0050ea370e9c57d3',1,'pearl-anglescan-process.ipf']]], + ['kprojortho_319',['kProjOrtho',['../pearl-anglescan-process_8ipf.html#a3b3bd11c35d5f850b34937ab6c45f659',1,'pearl-anglescan-process.ipf']]], + ['kprojscalearea_320',['kProjScaleArea',['../pearl-anglescan-process_8ipf.html#afa14187803f5b428a96c8234e04ab217',1,'pearl-anglescan-process.ipf']]], + ['kprojscaledist_321',['kProjScaleDist',['../pearl-anglescan-process_8ipf.html#a04e75675884236b6ed8244d7575d3a13',1,'pearl-anglescan-process.ipf']]], + ['kprojscalegnom_322',['kProjScaleGnom',['../pearl-anglescan-process_8ipf.html#ab6670abb621d01994c0b9974f58be843',1,'pearl-anglescan-process.ipf']]], + ['kprojscaleortho_323',['kProjScaleOrtho',['../pearl-anglescan-process_8ipf.html#aa5487fdee22e0da61a511c14239262f5',1,'pearl-anglescan-process.ipf']]], + ['kprojscalestereo_324',['kProjScaleStereo',['../pearl-anglescan-process_8ipf.html#aed66bda9701d8a69b2174fac974aa665',1,'pearl-anglescan-process.ipf']]], + ['kprojstereo_325',['kProjStereo',['../pearl-anglescan-process_8ipf.html#ac151c6f989d6a568fdef0acb791f84db',1,'pearl-anglescan-process.ipf']]], + ['ks_5ffilematch_5fadh5_326',['ks_filematch_adh5',['../pearl-data-explorer_8ipf.html#a181ccce237172811baf3de5a7a06370d',1,'pearl-data-explorer.ipf']]], + ['ks_5ffilematch_5fitx_327',['ks_filematch_itx',['../pearl-data-explorer_8ipf.html#a53af8689144e3aeb27ca177db5dd0c22',1,'pearl-data-explorer.ipf']]], + ['ks_5ffilematch_5fmtrx_328',['ks_filematch_mtrx',['../pearl-matrix-import_8ipf.html#ad720655ff881ddecae2e1b8afed58fa0',1,'pearl-matrix-import.ipf']]], + ['ks_5ffilematch_5fpshell_329',['ks_filematch_pshell',['../pearl-data-explorer_8ipf.html#a00bf5267a40b2b3d760c64d73e139878',1,'pearl-data-explorer.ipf']]], + ['kscandimlabel_330',['kScanDimLabel',['../pearl-pshell-import_8ipf.html#a412b4753ceb753d705a113a26c018b22',1,'pearl-pshell-import.ipf']]], + ['kscientascalingdatasets_331',['kScientaScalingDatasets',['../pearl-pshell-import_8ipf.html#a03f00b3299bc3df671fcc239f7dd5418',1,'pearl-pshell-import.ipf']]], + ['ktransposeddatasets_332',['kTransposedDatasets',['../pearl-pshell-import_8ipf.html#a0f2c168c04d075734edb995361aefb82',1,'pearl-pshell-import.ipf']]] ]; diff --git a/doc/html/search/all_a.html b/doc/html/search/all_a.html index 9601fce..f2f3d3a 100644 --- a/doc/html/search/all_a.html +++ b/doc/html/search/all_a.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_a.js b/doc/html/search/all_a.js index 360290d..3de2b52 100644 --- a/doc/html/search/all_a.js +++ b/doc/html/search/all_a.js @@ -1,19 +1,19 @@ var searchData= [ - ['lbp_5fdatasets',['lbp_datasets',['../pearl-data-explorer_8ipf.html#a8ec37ab6c651003957d7e1ba728de89e',1,'pearl-data-explorer.ipf']]], - ['lbp_5ffilelist',['lbp_filelist',['../pearl-data-explorer_8ipf.html#a614e89b9c06511144ccb380e61cc7bd6',1,'pearl-data-explorer.ipf']]], - ['line_5faverage',['line_average',['../pearl-anglescan-process_8ipf.html#aa54a550eccad2c8ccd82d2b4167f7a92',1,'pearl-anglescan-process.ipf']]], - ['list_5flogbooks',['list_logbooks',['../pearl-elog_8ipf.html#a356bebea8eb41c9ac3ea2148af22707f',1,'pearl-elog.ipf']]], - ['load_5ffile',['load_file',['../pearl-data-explorer_8ipf.html#a1bbf3e1592f3344f3628526fa549dfdf',1,'pearl-data-explorer.ipf']]], - ['load_5fhdf_5ffile',['load_hdf_file',['../pearl-data-explorer_8ipf.html#a0c839d5f8f49e6937a6532bba3ef3714',1,'pearl-data-explorer.ipf']]], - ['load_5fhemi_5fscan',['load_hemi_scan',['../pearl-anglescan-process_8ipf.html#a89f73edcd51a675f4c3933cd0242484e',1,'pearl-anglescan-process.ipf']]], - ['load_5fitx_5ffile',['load_itx_file',['../pearl-data-explorer_8ipf.html#a26f2f2bf5efc39dabb2a01abcc559e3e',1,'pearl-data-explorer.ipf']]], - ['load_5fmtrx_5ffile',['load_mtrx_file',['../pearl-data-explorer_8ipf.html#a98e327fa65bbcb3cd7c97545f7201afe',1,'pearl-data-explorer.ipf']]], - ['load_5fprefs',['load_prefs',['../pearl-anglescan-panel_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-elog.ipf']]], - ['load_5fpshell_5ffile',['load_pshell_file',['../pearl-data-explorer_8ipf.html#a74c69e870329c5dd3b08f92bdeb21d87',1,'pearl-data-explorer.ipf']]], - ['load_5fselected_5ffiles',['load_selected_files',['../pearl-data-explorer_8ipf.html#a2178d5acf21fe4372ecc06224bec28ba',1,'pearl-data-explorer.ipf']]], - ['load_5ftracker_5fdata',['load_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a3882038c0ad82396b6591fd756817535',1,'pearl-anglescan-tracker.ipf']]], - ['loadpearlarpes',['LoadPearlArpes',['../pearl-menu_8ipf.html#aa70ef420d6fe0f6a433cd2371fc4a03d',1,'pearl-menu.ipf']]], - ['loadpearloptics',['LoadPearlOptics',['../pearl-menu_8ipf.html#af6c9740540c6242eb7bf57fc49de82ab',1,'pearl-menu.ipf']]], - ['loadpearlpreparation',['LoadPearlPreparation',['../pearl-menu_8ipf.html#a3658ae687e12987fa1d70636849a060f',1,'pearl-menu.ipf']]] + ['lbp_5ffilelist_333',['lbp_filelist',['../pearl-data-explorer_8ipf.html#a614e89b9c06511144ccb380e61cc7bd6',1,'pearl-data-explorer.ipf']]], + ['line_5faverage_334',['line_average',['../pearl-anglescan-process_8ipf.html#aa54a550eccad2c8ccd82d2b4167f7a92',1,'pearl-anglescan-process.ipf']]], + ['list_5flogbooks_335',['list_logbooks',['../pearl-elog_8ipf.html#a356bebea8eb41c9ac3ea2148af22707f',1,'pearl-elog.ipf']]], + ['load_5ffile_336',['load_file',['../pearl-data-explorer_8ipf.html#a435adef620193e09110ff69ca8d106de',1,'pearl-data-explorer.ipf']]], + ['load_5fhdf_5ffile_337',['load_hdf_file',['../pearl-data-explorer_8ipf.html#a96a3ef643cc29948ba57a3bfa1339c4d',1,'pearl-data-explorer.ipf']]], + ['load_5fhemi_5fscan_338',['load_hemi_scan',['../pearl-anglescan-process_8ipf.html#a89f73edcd51a675f4c3933cd0242484e',1,'pearl-anglescan-process.ipf']]], + ['load_5fitx_5ffile_339',['load_itx_file',['../pearl-data-explorer_8ipf.html#ababd5be120b526ca410c53b4a2ba3f8d',1,'pearl-data-explorer.ipf']]], + ['load_5fpmsco_5fresult_340',['load_pmsco_result',['../pearl-pmsco-import_8ipf.html#afae0650a37e89f18c9c54f8adc9eafb2',1,'pearl-pmsco-import.ipf']]], + ['load_5fpmsco_5fscan_341',['load_pmsco_scan',['../pearl-pmsco-import_8ipf.html#a98bbe8db14dba5aea9588a1b433baca7',1,'pearl-pmsco-import.ipf']]], + ['load_5fprefs_342',['load_prefs',['../pearl-anglescan-panel_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-elog.ipf']]], + ['load_5fpshell_5ffile_343',['load_pshell_file',['../pearl-data-explorer_8ipf.html#a0e1e23060294bd4b18980e59229c70ed',1,'pearl-data-explorer.ipf']]], + ['load_5fselected_5ffiles_344',['load_selected_files',['../pearl-data-explorer_8ipf.html#a2178d5acf21fe4372ecc06224bec28ba',1,'pearl-data-explorer.ipf']]], + ['load_5ftracker_5fdata_345',['load_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a3882038c0ad82396b6591fd756817535',1,'pearl-anglescan-tracker.ipf']]], + ['loadpearlarpes_346',['LoadPearlArpes',['../pearl-menu_8ipf.html#aa70ef420d6fe0f6a433cd2371fc4a03d',1,'pearl-menu.ipf']]], + ['loadpearloptics_347',['LoadPearlOptics',['../pearl-menu_8ipf.html#af6c9740540c6242eb7bf57fc49de82ab',1,'pearl-menu.ipf']]], + ['loadpearlpreparation_348',['LoadPearlPreparation',['../pearl-menu_8ipf.html#a3658ae687e12987fa1d70636849a060f',1,'pearl-menu.ipf']]] ]; diff --git a/doc/html/search/all_b.html b/doc/html/search/all_b.html index 0814e4e..14f3403 100644 --- a/doc/html/search/all_b.html +++ b/doc/html/search/all_b.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_b.js b/doc/html/search/all_b.js index 396da27..7586cdd 100644 --- a/doc/html/search/all_b.js +++ b/doc/html/search/all_b.js @@ -1,28 +1,29 @@ var searchData= [ - ['mainpage_2edox',['mainpage.dox',['../mainpage_8dox.html',1,'']]], - ['make_5fhemi_5fgrid',['make_hemi_grid',['../pearl-anglescan-process_8ipf.html#a902ac3a24e33f651e83ee03d31707da7',1,'pearl-anglescan-process.ipf']]], - ['make_5fview_5ffolder',['make_view_folder',['../pearl-area-display_8ipf.html#a2b183a27ec795b0ec1f8efabe3068369',1,'pearl-area-display.ipf']]], - ['matrix_5fformat_5felog_5fmessage',['matrix_format_elog_message',['../pearl-matrix-import_8ipf.html#a81b1d81261a32d0ed4cf79b81487f1b4',1,'pearl-matrix-import.ipf']]], - ['matrix_5fpreview_5f2d',['matrix_preview_2d',['../pearl-matrix-import_8ipf.html#a856478705a78e8105ea5d91a2228975b',1,'pearl-matrix-import.ipf']]], - ['mcp_5fradius_5fepass',['mcp_radius_epass',['../fermi-edge-analysis_8ipf.html#a4749b9bce3e1d0381bd9daeb97c9754c',1,'fermi-edge-analysis.ipf']]], - ['mcp_5fradius_5fmm',['mcp_radius_mm',['../fermi-edge-analysis_8ipf.html#a4dcc00b93822f1663be2908b10d2ad3e',1,'fermi-edge-analysis.ipf']]], - ['mcp_5fradius_5fpix',['mcp_radius_pix',['../fermi-edge-analysis_8ipf.html#a09f26b0a0fd940a3d8c6f92aa769c8bc',1,'fermi-edge-analysis.ipf']]], - ['model',['model',['../struct_doniach_sunjic_struct.html#a02c13fdcf15e9adfee13464701bb7de2',1,'DoniachSunjicStruct']]], - ['move_5fattach_5fitem',['move_attach_item',['../pearl-elog_8ipf.html#a7990f2948d48aefe990271d1961df833',1,'pearl-elog.ipf']]], - ['mtrx_5fcreate_5ffolder',['mtrx_create_folder',['../pearl-matrix-import_8ipf.html#a893405a122fdf70429f4f75b8877ed7d',1,'pearl-matrix-import.ipf']]], - ['mtrx_5ffile_5fbrickletid',['mtrx_file_brickletID',['../pearl-matrix-import_8ipf.html#ad74d5afa71179728a9237d1ec5884482',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fget_5fcycle_5ffolder',['mtrx_get_cycle_folder',['../pearl-matrix-import_8ipf.html#a1a46b042e41daffee61706ab2cf54351',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fload_5fall',['mtrx_load_all',['../pearl-matrix-import_8ipf.html#a6ac0c685976b0e0c1944fb616a4f3a3c',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fload_5ffile',['mtrx_load_file',['../pearl-matrix-import_8ipf.html#a6aeef317fd468c88c99a274338c70ae3',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fload_5finfo',['mtrx_load_info',['../pearl-matrix-import_8ipf.html#a3a0ba4a7ad64739303b705d92be53267',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fload_5fpreview',['mtrx_load_preview',['../pearl-matrix-import_8ipf.html#abd09594d22038853e1e8021e0f36363d',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fopen_5ffile',['mtrx_open_file',['../pearl-matrix-import_8ipf.html#a59e72c849f4314aaa8339fd899665d85',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fparse_5ffilename',['mtrx_parse_filename',['../pearl-matrix-import_8ipf.html#a4bfeaf81ac483df0a38b26b6a8cf74a6',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fscale_5fdataset',['mtrx_scale_dataset',['../pearl-matrix-import_8ipf.html#ad8532f1473f92539fe88217d5d6e3368',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fsplit_5ffilename',['mtrx_split_filename',['../pearl-matrix-import_8ipf.html#a0dc1efa23739e10b7558543b166e95b9',1,'pearl-matrix-import.ipf']]], - ['multidoniachsunjiclinbg',['MultiDoniachSunjicLinBG',['../pearl-fitfuncs_8ipf.html#a1520bd078ef77fd16ba20e95dbc6829d',1,'pearl-fitfuncs.ipf']]], - ['multigausslinbg',['MultiGaussLinBG',['../pearl-fitfuncs_8ipf.html#aad1418e71830c1ec71d7dd62b2ecf9ba',1,'pearl-fitfuncs.ipf']]], - ['multigausslinbg_5fao',['MultiGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#a2c6547164c0b46efecf4d372ea04c263',1,'pearl-fitfuncs.ipf']]], - ['multivoigtlinbg',['MultiVoigtLinBG',['../pearl-fitfuncs_8ipf.html#a3a94468da285a31eed5e990cd90e5cdf',1,'pearl-fitfuncs.ipf']]] + ['mainpage_2edox_349',['mainpage.dox',['../mainpage_8dox.html',1,'']]], + ['make_5fhemi_5fgrid_350',['make_hemi_grid',['../pearl-anglescan-process_8ipf.html#a902ac3a24e33f651e83ee03d31707da7',1,'pearl-anglescan-process.ipf']]], + ['make_5fview_5ffolder_351',['make_view_folder',['../pearl-area-display_8ipf.html#a2b183a27ec795b0ec1f8efabe3068369',1,'pearl-area-display.ipf']]], + ['matrix_5fformat_5felog_5fmessage_352',['matrix_format_elog_message',['../pearl-matrix-import_8ipf.html#a81b1d81261a32d0ed4cf79b81487f1b4',1,'pearl-matrix-import.ipf']]], + ['matrix_5fpreview_5f2d_353',['matrix_preview_2d',['../pearl-matrix-import_8ipf.html#a856478705a78e8105ea5d91a2228975b',1,'pearl-matrix-import.ipf']]], + ['mcp_5fradius_5fepass_354',['mcp_radius_epass',['../fermi-edge-analysis_8ipf.html#a4749b9bce3e1d0381bd9daeb97c9754c',1,'fermi-edge-analysis.ipf']]], + ['mcp_5fradius_5fmm_355',['mcp_radius_mm',['../fermi-edge-analysis_8ipf.html#a4dcc00b93822f1663be2908b10d2ad3e',1,'fermi-edge-analysis.ipf']]], + ['mcp_5fradius_5fpix_356',['mcp_radius_pix',['../fermi-edge-analysis_8ipf.html#a09f26b0a0fd940a3d8c6f92aa769c8bc',1,'fermi-edge-analysis.ipf']]], + ['model_357',['model',['../struct_doniach_sunjic_struct.html#a02c13fdcf15e9adfee13464701bb7de2',1,'DoniachSunjicStruct']]], + ['move_5fattach_5fitem_358',['move_attach_item',['../pearl-elog_8ipf.html#a7990f2948d48aefe990271d1961df833',1,'pearl-elog.ipf']]], + ['mtrx_5fcreate_5ffolder_359',['mtrx_create_folder',['../pearl-matrix-import_8ipf.html#a893405a122fdf70429f4f75b8877ed7d',1,'pearl-matrix-import.ipf']]], + ['mtrx_5ffile_5fbrickletid_360',['mtrx_file_brickletID',['../pearl-matrix-import_8ipf.html#ad74d5afa71179728a9237d1ec5884482',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fget_5fcycle_5ffolder_361',['mtrx_get_cycle_folder',['../pearl-matrix-import_8ipf.html#a1a46b042e41daffee61706ab2cf54351',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fload_5fall_362',['mtrx_load_all',['../pearl-matrix-import_8ipf.html#a6ac0c685976b0e0c1944fb616a4f3a3c',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fload_5ffile_363',['mtrx_load_file',['../pearl-matrix-import_8ipf.html#a6aeef317fd468c88c99a274338c70ae3',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fload_5finfo_364',['mtrx_load_info',['../pearl-matrix-import_8ipf.html#a3a0ba4a7ad64739303b705d92be53267',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fload_5fpreview_365',['mtrx_load_preview',['../pearl-matrix-import_8ipf.html#abd09594d22038853e1e8021e0f36363d',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fopen_5ffile_366',['mtrx_open_file',['../pearl-matrix-import_8ipf.html#a59e72c849f4314aaa8339fd899665d85',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fparse_5ffilename_367',['mtrx_parse_filename',['../pearl-matrix-import_8ipf.html#a4bfeaf81ac483df0a38b26b6a8cf74a6',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fscale_5fdataset_368',['mtrx_scale_dataset',['../pearl-matrix-import_8ipf.html#ad8532f1473f92539fe88217d5d6e3368',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fsplit_5ffilename_369',['mtrx_split_filename',['../pearl-matrix-import_8ipf.html#a0dc1efa23739e10b7558543b166e95b9',1,'pearl-matrix-import.ipf']]], + ['multidoniachsunjiclinbg_370',['MultiDoniachSunjicLinBG',['../pearl-fitfuncs_8ipf.html#af669aa08d0c32d3647007155f4b7ea3c',1,'pearl-fitfuncs.ipf']]], + ['multigausslinbg_371',['MultiGaussLinBG',['../pearl-fitfuncs_8ipf.html#aad1418e71830c1ec71d7dd62b2ecf9ba',1,'pearl-fitfuncs.ipf']]], + ['multigausslinbg_5fao_372',['MultiGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#a2c6547164c0b46efecf4d372ea04c263',1,'pearl-fitfuncs.ipf']]], + ['multivoigtlinbg_373',['MultiVoigtLinBG',['../pearl-fitfuncs_8ipf.html#a704de4b170620d07b75f2093fe052272',1,'pearl-fitfuncs.ipf']]], + ['multivoigtlinbg_5fao_374',['MultiVoigtLinBG_AO',['../pearl-fitfuncs_8ipf.html#a81da09e30e2800703dd178248f0c55be',1,'pearl-fitfuncs.ipf']]] ]; diff --git a/doc/html/search/all_c.html b/doc/html/search/all_c.html index da08c38..da60ab8 100644 --- a/doc/html/search/all_c.html +++ b/doc/html/search/all_c.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_c.js b/doc/html/search/all_c.js index b421cfd..c4a3f1a 100644 --- a/doc/html/search/all_c.js +++ b/doc/html/search/all_c.js @@ -1,12 +1,12 @@ var searchData= [ - ['no_5ffile_5fopen',['NO_FILE_OPEN',['../structerror_code.html#affc9a8a46877373b0212d82d867ca5fa',1,'errorCode']]], - ['no_5fnew_5fbricklets',['NO_NEW_BRICKLETS',['../structerror_code.html#a4ec3cbf922809b99b04d324d3a0bbb22',1,'errorCode']]], - ['normalize_5fstrip_5f2d',['normalize_strip_2d',['../pearl-anglescan-process_8ipf.html#ac617c3b400488b656493af8ca08f1791',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5fphi',['normalize_strip_phi',['../pearl-anglescan-process_8ipf.html#aaa734fddecdd75c7cabe20ba777b41b9',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5ftheta',['normalize_strip_theta',['../pearl-anglescan-process_8ipf.html#a9b56897bd92d926d65f4c67bef1d41bb',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5ftheta_5fscans',['normalize_strip_theta_scans',['../pearl-anglescan-process_8ipf.html#a992920d621023e6b483ff51eee68b508',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5fthetaphi',['normalize_strip_thetaphi',['../pearl-anglescan-process_8ipf.html#ad0a93367d2e9b66bb7b81697e87adfaf',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5fx',['normalize_strip_x',['../pearl-anglescan-process_8ipf.html#a48b7d774ed8d3f4329e9923e18e580e8',1,'pearl-anglescan-process.ipf']]], - ['notebook_5fadd_5fattributes',['notebook_add_attributes',['../pearl-data-explorer_8ipf.html#a0c162346b59b0f66d34ee26ce5fe1e52',1,'pearl-data-explorer.ipf']]] + ['no_5ffile_5fopen_375',['NO_FILE_OPEN',['../structerror_code.html#affc9a8a46877373b0212d82d867ca5fa',1,'errorCode']]], + ['no_5fnew_5fbricklets_376',['NO_NEW_BRICKLETS',['../structerror_code.html#a4ec3cbf922809b99b04d324d3a0bbb22',1,'errorCode']]], + ['normalize_5fstrip_5f2d_377',['normalize_strip_2d',['../pearl-anglescan-process_8ipf.html#ac617c3b400488b656493af8ca08f1791',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5fphi_378',['normalize_strip_phi',['../pearl-anglescan-process_8ipf.html#aaa734fddecdd75c7cabe20ba777b41b9',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5ftheta_379',['normalize_strip_theta',['../pearl-anglescan-process_8ipf.html#a9b56897bd92d926d65f4c67bef1d41bb',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5ftheta_5fscans_380',['normalize_strip_theta_scans',['../pearl-anglescan-process_8ipf.html#a992920d621023e6b483ff51eee68b508',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5fthetaphi_381',['normalize_strip_thetaphi',['../pearl-anglescan-process_8ipf.html#ad0a93367d2e9b66bb7b81697e87adfaf',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5fx_382',['normalize_strip_x',['../pearl-anglescan-process_8ipf.html#a48b7d774ed8d3f4329e9923e18e580e8',1,'pearl-anglescan-process.ipf']]], + ['notebook_5fadd_5fattributes_383',['notebook_add_attributes',['../pearl-data-explorer_8ipf.html#a0c162346b59b0f66d34ee26ce5fe1e52',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/all_d.html b/doc/html/search/all_d.html index 9986c9c..bc376fe 100644 --- a/doc/html/search/all_d.html +++ b/doc/html/search/all_d.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_d.js b/doc/html/search/all_d.js index ba9be49..1cf58c1 100644 --- a/doc/html/search/all_d.js +++ b/doc/html/search/all_d.js @@ -1,13 +1,13 @@ var searchData= [ - ['otf_5fgather_5fbatch',['otf_gather_batch',['../pearl-otf-import_8ipf.html#ad2a83b85030a7d7769d434d6e2e9e557',1,'pearl-otf-import.ipf']]], - ['otf_5fgather_5fiterator',['otf_gather_iterator',['../pearl-otf-import_8ipf.html#a44078e1d8f26e515539acb96973fc630',1,'pearl-otf-import.ipf']]], - ['otf_5finterp',['otf_interp',['../pearl-otf-import_8ipf.html#abd8897317366046dfb97c6ca53813d18',1,'pearl-otf-import.ipf']]], - ['otf_5fload_5fitx',['otf_load_itx',['../pearl-otf-import_8ipf.html#a3632f8a5c0ee32a14a3e589b74a0c496',1,'pearl-otf-import.ipf']]], - ['otf_5fload_5fitx_5fall',['otf_load_itx_all',['../pearl-otf-import_8ipf.html#a603b71176ed838713ec555c440082e22',1,'pearl-otf-import.ipf']]], - ['otf_5fload_5fitx_5fmatch',['otf_load_itx_match',['../pearl-otf-import_8ipf.html#aa47fc4b956ee84a993b6d285b628fe20',1,'pearl-otf-import.ipf']]], - ['otf_5frename_5ffolders',['otf_rename_folders',['../pearl-otf-import_8ipf.html#a715f9cf2d2b1ffb04f2f9a0e344a80ee',1,'pearl-otf-import.ipf']]], - ['otf_5frename_5ffolders_5fiterator',['otf_rename_folders_iterator',['../pearl-otf-import_8ipf.html#a882da254075e8d89f0117e491af90df0',1,'pearl-otf-import.ipf']]], - ['otf_5fsmo_5fint',['otf_smo_int',['../pearl-otf-import_8ipf.html#aba965b854836658aa00e3ec2b361d7c9',1,'pearl-otf-import.ipf']]], - ['oversampling',['oversampling',['../struct_doniach_sunjic_struct.html#ab5a630be50286c3cf04e40d5880506e6',1,'DoniachSunjicStruct']]] + ['otf_5fgather_5fbatch_384',['otf_gather_batch',['../pearl-otf-import_8ipf.html#ad2a83b85030a7d7769d434d6e2e9e557',1,'pearl-otf-import.ipf']]], + ['otf_5fgather_5fiterator_385',['otf_gather_iterator',['../pearl-otf-import_8ipf.html#a44078e1d8f26e515539acb96973fc630',1,'pearl-otf-import.ipf']]], + ['otf_5finterp_386',['otf_interp',['../pearl-otf-import_8ipf.html#abd8897317366046dfb97c6ca53813d18',1,'pearl-otf-import.ipf']]], + ['otf_5fload_5fitx_387',['otf_load_itx',['../pearl-otf-import_8ipf.html#a3632f8a5c0ee32a14a3e589b74a0c496',1,'pearl-otf-import.ipf']]], + ['otf_5fload_5fitx_5fall_388',['otf_load_itx_all',['../pearl-otf-import_8ipf.html#a603b71176ed838713ec555c440082e22',1,'pearl-otf-import.ipf']]], + ['otf_5fload_5fitx_5fmatch_389',['otf_load_itx_match',['../pearl-otf-import_8ipf.html#aa47fc4b956ee84a993b6d285b628fe20',1,'pearl-otf-import.ipf']]], + ['otf_5frename_5ffolders_390',['otf_rename_folders',['../pearl-otf-import_8ipf.html#a715f9cf2d2b1ffb04f2f9a0e344a80ee',1,'pearl-otf-import.ipf']]], + ['otf_5frename_5ffolders_5fiterator_391',['otf_rename_folders_iterator',['../pearl-otf-import_8ipf.html#a882da254075e8d89f0117e491af90df0',1,'pearl-otf-import.ipf']]], + ['otf_5fsmo_5fint_392',['otf_smo_int',['../pearl-otf-import_8ipf.html#aba965b854836658aa00e3ec2b361d7c9',1,'pearl-otf-import.ipf']]], + ['oversampling_393',['oversampling',['../struct_doniach_sunjic_struct.html#ab5a630be50286c3cf04e40d5880506e6',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/all_e.html b/doc/html/search/all_e.html index 9fa42bb..2e3c74d 100644 --- a/doc/html/search/all_e.html +++ b/doc/html/search/all_e.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_e.js b/doc/html/search/all_e.js index a49fb74..ec272f0 100644 --- a/doc/html/search/all_e.js +++ b/doc/html/search/all_e.js @@ -1,131 +1,134 @@ var searchData= [ - ['package_5fname',['package_name',['../pearl-anglescan-panel_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-matrix-import.ipf']]], - ['package_5fpath',['package_path',['../pearl-anglescan-panel_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-matrix-import.ipf']]], - ['projections',['Projections',['../_page_projections.html',1,'']]], - ['parse_5fresult',['parse_result',['../pearl-elog_8ipf.html#a5306514bf7d1a582aec146256ae45a12',1,'pearl-elog.ipf']]], - ['pearl_2danglescan_2dpanel_2eipf',['pearl-anglescan-panel.ipf',['../pearl-anglescan-panel_8ipf.html',1,'']]], - ['pearl_2danglescan_2dprocess_2eipf',['pearl-anglescan-process.ipf',['../pearl-anglescan-process_8ipf.html',1,'']]], - ['pearl_2danglescan_2dtracker_2eipf',['pearl-anglescan-tracker.ipf',['../pearl-anglescan-tracker_8ipf.html',1,'']]], - ['pearl_2darea_2ddisplay_2eipf',['pearl-area-display.ipf',['../pearl-area-display_8ipf.html',1,'']]], - ['pearl_2darea_2dimport_2eipf',['pearl-area-import.ipf',['../pearl-area-import_8ipf.html',1,'']]], - ['pearl_2darea_2dprofiles_2eipf',['pearl-area-profiles.ipf',['../pearl-area-profiles_8ipf.html',1,'']]], - ['pearl_2darpes_2eipf',['pearl-arpes.ipf',['../pearl-arpes_8ipf.html',1,'']]], - ['pearl_2dcompat_2eipf',['pearl-compat.ipf',['../pearl-compat_8ipf.html',1,'']]], - ['pearl_2ddata_2dexplorer_2eipf',['pearl-data-explorer.ipf',['../pearl-data-explorer_8ipf.html',1,'']]], - ['pearl_2delog_2eipf',['pearl-elog.ipf',['../pearl-elog_8ipf.html',1,'']]], - ['pearl_2dfitfuncs_2eipf',['pearl-fitfuncs.ipf',['../pearl-fitfuncs_8ipf.html',1,'']]], - ['pearl_2dgui_2dtools_2eipf',['pearl-gui-tools.ipf',['../pearl-gui-tools_8ipf.html',1,'']]], - ['pearl_2dmatrix_2dimport_2eipf',['pearl-matrix-import.ipf',['../pearl-matrix-import_8ipf.html',1,'']]], - ['pearl_2dmenu_2eipf',['pearl-menu.ipf',['../pearl-menu_8ipf.html',1,'']]], - ['pearl_2dotf_2dimport_2eipf',['pearl-otf-import.ipf',['../pearl-otf-import_8ipf.html',1,'']]], - ['pearl_2dpmsco_2dimport_2eipf',['pearl-pmsco-import.ipf',['../pearl-pmsco-import_8ipf.html',1,'']]], - ['pearl_2dpolar_2dcoordinates_2eipf',['pearl-polar-coordinates.ipf',['../pearl-polar-coordinates_8ipf.html',1,'']]], - ['pearl_2dpshell_2dimport_2eipf',['pearl-pshell-import.ipf',['../pearl-pshell-import_8ipf.html',1,'']]], - ['pearl_2dscienta_2dcountrate_2eipf',['pearl-scienta-countrate.ipf',['../pearl-scienta-countrate_8ipf.html',1,'']]], - ['pearl_2dscienta_2dpreprocess_2eipf',['pearl-scienta-preprocess.ipf',['../pearl-scienta-preprocess_8ipf.html',1,'']]], - ['pearl_2dtools_2eipf',['pearl-tools.ipf',['../pearl-tools_8ipf.html',1,'']]], - ['pearl_2dvector_2doperations_2eipf',['pearl-vector-operations.ipf',['../pearl-vector-operations_8ipf.html',1,'']]], - ['pearl_5fdata_5fexplorer',['pearl_data_explorer',['../pearl-data-explorer_8ipf.html#ab7e3b3a0a901f7559ee9f5affb9a6fca',1,'pearl-data-explorer.ipf']]], - ['pearl_5felog',['pearl_elog',['../pearl-elog_8ipf.html#a4088a48a8428629f120c08a419af62d6',1,'pearl-elog.ipf']]], - ['pearl_5ffile_5ftype',['pearl_file_type',['../pearl-data-explorer_8ipf.html#a8a923d7095071e7e6f99018379807732',1,'pearl-data-explorer.ipf']]], - ['pearlanglescanpanel',['PearlAnglescanPanel',['../namespace_pearl_anglescan_panel.html',1,'']]], - ['pearlanglescanprocess',['PearlAnglescanProcess',['../namespace_pearl_anglescan_process.html',1,'']]], - ['pearlanglescantracker',['PearlAnglescanTracker',['../pearl-menu_8ipf.html#a74bc5da7843ee6c25f2d9c93d22a6ffa',1,'pearl-menu.ipf']]], - ['pearlareadisplay',['PearlAreaDisplay',['../namespace_pearl_area_display.html',1,'']]], - ['pearlareaimport',['PearlAreaImport',['../namespace_pearl_area_import.html',1,'']]], - ['pearlareaprofiles',['PearlAreaProfiles',['../namespace_pearl_area_profiles.html',1,'']]], - ['pearlarpes',['PearlArpes',['../namespace_pearl_arpes.html',1,'']]], - ['pearlcameradisplay',['PearlCameraDisplay',['../pearl-menu_8ipf.html#aab4ec7bc68f93029377b7657f40fbd6a',1,'pearl-menu.ipf']]], - ['pearlcleanupname',['PearlCleanupName',['../pearl-compat_8ipf.html#aa1f59acc532c7eee75c83b70ee1feaa9',1,'pearl-compat.ipf']]], - ['pearlcompat',['PearlCompat',['../namespace_pearl_compat.html',1,'']]], - ['pearldataexplorer',['PearlDataExplorer',['../namespace_pearl_data_explorer.html',1,'PearlDataExplorer'],['../pearl-data-explorer_8ipf.html#a5b824531904179a94e0eaa3ffa09172e',1,'PearlDataExplorer(): pearl-data-explorer.ipf']]], - ['pearlelog',['PearlElog',['../namespace_pearl_elog.html',1,'']]], - ['pearlelogpanel',['PearlElogPanel',['../pearl-elog_8ipf.html#a6da33f1bb2639cb912e9b25af25bf663',1,'pearl-elog.ipf']]], - ['pearlfitfuncs',['PearlFitFuncs',['../namespace_pearl_fit_funcs.html',1,'']]], - ['pearllivedisplay',['PearlLiveDisplay',['../pearl-menu_8ipf.html#a61ded60be72959b00f22842afa37c56f',1,'pearl-menu.ipf']]], - ['pearlmatriximport',['PearlMatrixImport',['../namespace_pearl_matrix_import.html',1,'']]], - ['pearlmenuenablefunc',['PearlMenuEnableFunc',['../pearl-menu_8ipf.html#a3404a53bf13a01c1e811d1af6c35b726',1,'pearl-menu.ipf']]], - ['pearlpmscoimport',['PearlPmscoImport',['../namespace_pearl_pmsco_import.html',1,'']]], - ['pearlpshellimport',['PearlPShellImport',['../namespace_pearl_p_shell_import.html',1,'']]], - ['pearlsampletracker',['PearlSampleTracker',['../pearl-menu_8ipf.html#a1437f6baee0bd6d04bbcd2236c2d1f7f',1,'pearl-menu.ipf']]], - ['pearlscientacountrate',['PearlScientaCountrate',['../namespace_pearl_scienta_countrate.html',1,'']]], - ['pearlscientapreprocess',['PearlScientaPreprocess',['../namespace_pearl_scienta_preprocess.html',1,'']]], - ['pearlvectoroperations',['PearlVectorOperations',['../namespace_pearl_vector_operations.html',1,'']]], - ['pizza_5fservice',['pizza_service',['../pearl-anglescan-process_8ipf.html#afed227ae79873fd32c96afbf606d1965',1,'pearl-anglescan-process.ipf']]], - ['pizza_5fservice_5f2',['pizza_service_2',['../pearl-anglescan-process_8ipf.html#a229770447193d4fd12032b235aab4d28',1,'pearl-anglescan-process.ipf']]], - ['pmp_5fdata',['pmp_data',['../pearl-anglescan-tracker_8ipf.html#a07efc5d6a7121540cc185c251353677c',1,'pearl-anglescan-tracker.ipf']]], - ['pmp_5fdata_5fmouseup',['pmp_data_mouseup',['../pearl-anglescan-tracker_8ipf.html#a4dad34b0481be20234fa5e8d25b262c4',1,'pearl-anglescan-tracker.ipf']]], - ['pmp_5fexport',['pmp_export',['../pearl-area-display_8ipf.html#ac5c7a25e9a8c0b001a429bae23639da9',1,'pearl-area-display.ipf']]], - ['pmp_5fgraph_5fcolortable',['pmp_graph_colortable',['../pearl-anglescan-panel_8ipf.html#ac80c675f6f1a5505e9b6f0349ff5fe92',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fgraph_5fmode',['pmp_graph_mode',['../pearl-anglescan-panel_8ipf.html#a1b41c992729d627445dbba0637b31ece',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fgraph_5fprojection',['pmp_graph_projection',['../pearl-anglescan-panel_8ipf.html#af83bfcf48723e7f6eeb78b4e0d84277d',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fnorm_5falpha_5fmode',['pmp_norm_alpha_mode',['../pearl-anglescan-panel_8ipf.html#acc1028dcd046f441ceaac268ffac9af6',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fnorm_5ftheta_5fdomain',['pmp_norm_theta_domain',['../pearl-anglescan-panel_8ipf.html#a0153f4ed4892dd3b48276af190590e4f',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fnorm_5ftheta_5fmode',['pmp_norm_theta_mode',['../pearl-anglescan-panel_8ipf.html#ae68496dbe344dc8a2c7c99b2d3f4b01c',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fnorm_5fthetaphi_5fmode',['pmp_norm_thetaphi_mode',['../pearl-anglescan-panel_8ipf.html#a289996a12d0ef46af1dac49a67289931',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fparameters',['pmp_parameters',['../pearl-anglescan-tracker_8ipf.html#a6d484e3bb5f8c18d3b2910e8346b2c17',1,'pearl-anglescan-tracker.ipf']]], - ['pmp_5fparameters_5fmouseup',['pmp_parameters_mouseup',['../pearl-anglescan-tracker_8ipf.html#ad06e1354226f4f617ad0a8d6d7572dca',1,'pearl-anglescan-tracker.ipf']]], - ['pmsco_5fload_5fxyz',['pmsco_load_xyz',['../pearl-pmsco-import_8ipf.html#ab3421c7f54aa64e5e493b267d700c0c8',1,'pearl-pmsco-import.ipf']]], - ['pmsco_5fsave_5fscan',['pmsco_save_scan',['../pearl-pmsco-import_8ipf.html#aa31bbaa2fc77b447e6c6f386b23abdd9',1,'pearl-pmsco-import.ipf']]], - ['polar2cart',['polar2cart',['../pearl-polar-coordinates_8ipf.html#a94ccfa9cf52c55eb1f66c2704478c396',1,'pearl-polar-coordinates.ipf']]], - ['polar2cart_5fwave',['polar2cart_wave',['../pearl-polar-coordinates_8ipf.html#a6a0ffb6b9160413d9694b1fd8e10c858',1,'pearl-polar-coordinates.ipf']]], - ['polar_5fdistance',['polar_distance',['../pearl-polar-coordinates_8ipf.html#a58139e6ebfba242b6b2ba3533b865a9a',1,'pearl-polar-coordinates.ipf']]], - ['polar_5fgraph_5fhook',['polar_graph_hook',['../pearl-anglescan-process_8ipf.html#ac4dbd1ece37b2cf22fa976a153977288',1,'pearl-anglescan-process.ipf']]], - ['precision',['precision',['../struct_doniach_sunjic_struct.html#a906e214875392bc470dbd4bb4bdda2db',1,'DoniachSunjicStruct']]], - ['prefs_5fobjects',['prefs_objects',['../pearl-anglescan-tracker_8ipf.html#a20720748c82a7eaa4b02d4084a4219b2',1,'pearl-anglescan-tracker.ipf']]], - ['prepare_5fcommand_5fline',['prepare_command_line',['../pearl-elog_8ipf.html#abd15431defaec6d770cc8cab2a40e6b0',1,'pearl-elog.ipf']]], - ['prepare_5fgraph_5fattachments',['prepare_graph_attachments',['../pearl-elog_8ipf.html#a4986de01085dc5481500240ef7667419',1,'pearl-elog.ipf']]], - ['prepare_5fhemi_5fscan_5fdisplay',['prepare_hemi_scan_display',['../pearl-anglescan-process_8ipf.html#ac15ebd5a19c558dde666ab36aeb9906f',1,'pearl-anglescan-process.ipf']]], - ['preview_5fattributes',['preview_attributes',['../pearl-data-explorer_8ipf.html#a415e4867be1ee37d84fd609b06f6dcb8',1,'pearl-data-explorer.ipf']]], - ['preview_5fcrop',['preview_crop',['../pearl-anglescan-panel_8ipf.html#a2268cc96a879c1a055c1ff29c1b040ea',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fdatafolder',['preview_datafolder',['../pearl-data-explorer_8ipf.html#a6e8eaf8c092f5da60bd425f9bd8bf178',1,'pearl-data-explorer.ipf']]], - ['preview_5fdataset',['preview_dataset',['../pearl-data-explorer_8ipf.html#a68d38e9464f7d13520ec040cffdf5c3b',1,'pearl-data-explorer.ipf']]], - ['preview_5ffile',['preview_file',['../pearl-data-explorer_8ipf.html#a3232c51a8c19eaf86b9bc67352967a9f',1,'pearl-data-explorer.ipf']]], - ['preview_5fhdf_5ffile',['preview_hdf_file',['../pearl-data-explorer_8ipf.html#a1731f8e1507d90e285885723ae32ba13',1,'pearl-data-explorer.ipf']]], - ['preview_5fitx_5ffile',['preview_itx_file',['../pearl-data-explorer_8ipf.html#a4633885afab755fbc5d262178b9ddcb8',1,'pearl-data-explorer.ipf']]], - ['preview_5fmatrix_5ffile',['preview_matrix_file',['../pearl-matrix-import_8ipf.html#a8acd2b03343ef9bdfecaa75e831392d1',1,'pearl-matrix-import.ipf']]], - ['preview_5fmtrx_5ffile',['preview_mtrx_file',['../pearl-data-explorer_8ipf.html#a340f334c6caa966ee1eb891614e57b5b',1,'pearl-data-explorer.ipf']]], - ['preview_5fnorm_5falpha',['preview_norm_alpha',['../pearl-anglescan-panel_8ipf.html#ad355d06d3b57bb458bd62e6d6f1f2417',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fnorm_5fphi',['preview_norm_phi',['../pearl-anglescan-panel_8ipf.html#a0c228ce2048827dc8161691ec5c425fc',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fnorm_5ftheta',['preview_norm_theta',['../pearl-anglescan-panel_8ipf.html#abe1237d8bf79a2ec3791ad9fe184bc3f',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fnorm_5fthetaphi',['preview_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#a3e798e20a99a03a789dd7914612e4fd2',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fpshell_5ffile',['preview_pshell_file',['../pearl-data-explorer_8ipf.html#a457d2257ffd5880ab858fa583a5d1c99',1,'pearl-data-explorer.ipf']]], - ['preview_5fsetscale_5fx',['preview_setscale_x',['../pearl-data-explorer_8ipf.html#a5a7d3c00360944c00f236900b992694d',1,'pearl-data-explorer.ipf']]], - ['process_5fimage_5fdata',['process_image_data',['../pearl-anglescan-tracker_8ipf.html#a4bc40cded4d4d7676b084f7200ca5e0d',1,'pearl-anglescan-tracker.ipf']]], - ['prompt_5fdefault_5fprocess',['prompt_default_process',['../pearl-data-explorer_8ipf.html#a505ebda6bdecc4120e01766d7aedaf5d',1,'pearl-data-explorer.ipf']]], - ['prompt_5ffunc_5fparams',['prompt_func_params',['../pearl-data-explorer_8ipf.html#a1d7f4ad59b81ecd84bb63cfabd9f24dc',1,'pearl-data-explorer.ipf']]], - ['prompt_5fgauss4_5freduction',['prompt_gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#a1514250704b40aa2614d389a2e250d61',1,'pearl-scienta-preprocess.ipf']]], - ['prompt_5fhdf_5foptions',['prompt_hdf_options',['../pearl-data-explorer_8ipf.html#a200e7ba052fbce4614fb4254701646ab',1,'pearl-data-explorer.ipf']]], - ['prompt_5fint_5flinbg_5freduction',['prompt_int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a145c7275b8809c5e789b932ef46e4811',1,'pearl-scienta-preprocess.ipf']]], - ['prompt_5fint_5fquadbg_5freduction',['prompt_int_quadbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a6d06ea5a11ba79160efeea7fe673af8c',1,'pearl-scienta-preprocess.ipf']]], - ['prompt_5fredim_5flinbg_5freduction',['prompt_redim_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a6e7de6441bbcba217760448babaca827',1,'pearl-scienta-preprocess.ipf']]], - ['ps_5fdetect_5fscale',['ps_detect_scale',['../pearl-pshell-import_8ipf.html#acba7f4b98f67cc112c02dfeefe3e5acd',1,'pearl-pshell-import.ipf']]], - ['ps_5fscale_5fdataset',['ps_scale_dataset',['../pearl-pshell-import_8ipf.html#adc11ea797562b3d99c247f4866618d39',1,'pearl-pshell-import.ipf']]], - ['ps_5fscale_5fdataset_5f2',['ps_scale_dataset_2',['../pearl-pshell-import_8ipf.html#a2c456397c36d4116bfddca452eff5954',1,'pearl-pshell-import.ipf']]], - ['ps_5fscale_5fdatasets',['ps_scale_datasets',['../pearl-pshell-import_8ipf.html#af08a467036c64f70ca3dfe644fcc457c',1,'pearl-pshell-import.ipf']]], - ['ps_5fset_5fdimlabels',['ps_set_dimlabels',['../pearl-pshell-import_8ipf.html#aba25eb98e4c6cc9066c46ef6be1cde15',1,'pearl-pshell-import.ipf']]], - ['ps_5fset_5fdimlabels2',['ps_set_dimlabels2',['../pearl-pshell-import_8ipf.html#a8704627410409bcd27a1adeda4082c47',1,'pearl-pshell-import.ipf']]], - ['psh5_5fclose_5ffile',['psh5_close_file',['../pearl-pshell-import_8ipf.html#a2fc497747287d6fe40c6de997ed4a90d',1,'pearl-pshell-import.ipf']]], - ['psh5_5flist_5fscan_5fdatasets',['psh5_list_scan_datasets',['../pearl-pshell-import_8ipf.html#a4508bd507c4c935bd8463d9b2b84c6fc',1,'pearl-pshell-import.ipf']]], - ['psh5_5flist_5fscan_5fregions',['psh5_list_scan_regions',['../pearl-pshell-import_8ipf.html#acb317b57ef137d4d5da5938013dbe442',1,'pearl-pshell-import.ipf']]], - ['psh5_5flist_5fscans',['psh5_list_scans',['../pearl-pshell-import_8ipf.html#a2152f7c39a187b740cf9890767ffac3f',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fcomplete',['psh5_load_complete',['../pearl-pshell-import_8ipf.html#a8a5ce6c2767607de194b4c148ee98c27',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset',['psh5_load_dataset',['../pearl-pshell-import_8ipf.html#ac4dfb90b951d29b56501e904f5cc38aa',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset_5fmeta',['psh5_load_dataset_meta',['../pearl-pshell-import_8ipf.html#afde787a00a18dc8c63b100d8ac7d992f',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset_5freduced',['psh5_load_dataset_reduced',['../pearl-pshell-import_8ipf.html#a13a45e8618c1ab7406e1aa5e608e21fe',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset_5fslab',['psh5_load_dataset_slab',['../pearl-pshell-import_8ipf.html#a035a4df9f4508144149abdb0b46c87d1',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset_5fslabs',['psh5_load_dataset_slabs',['../pearl-pshell-import_8ipf.html#a2972587ec82cc2a261b8119a582b4215',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5finfo',['psh5_load_info',['../pearl-pshell-import_8ipf.html#aa14b28120a07a8213e5a692930704a4b',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fpreview',['psh5_load_preview',['../pearl-pshell-import_8ipf.html#a1dc6c971120749b378014f1f63cb6668',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5freduced',['psh5_load_reduced',['../pearl-pshell-import_8ipf.html#a3eefc2f84a09f2ce29893c71ef44ae32',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fattrs',['psh5_load_scan_attrs',['../pearl-pshell-import_8ipf.html#aec191d0167bbf606d24396f4658104b5',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fcomplete',['psh5_load_scan_complete',['../pearl-pshell-import_8ipf.html#a0a02f87e19e825964aa17c46ed51df8c',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fdata',['psh5_load_scan_data',['../pearl-pshell-import_8ipf.html#ad26b0b56d7ccd23547535091c9430569',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5finfo',['psh5_load_scan_info',['../pearl-pshell-import_8ipf.html#a79ac37bb666b42c3332e9984196ccfe7',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fmeta',['psh5_load_scan_meta',['../pearl-pshell-import_8ipf.html#aa56c25d64b3e59f74d6dd92a599cce4f',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fpreview',['psh5_load_scan_preview',['../pearl-pshell-import_8ipf.html#ad3b9354b137ba4f1bc3ed2e74f24dc88',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fsection',['psh5_load_scan_section',['../pearl-pshell-import_8ipf.html#a83804ba9637debed6ef8b13e7b9b19e0',1,'pearl-pshell-import.ipf']]], - ['psh5_5fopen_5ffile',['psh5_open_file',['../pearl-pshell-import_8ipf.html#accc20b0fc6bda95ba0cd0aea6633086f',1,'pearl-pshell-import.ipf']]], - ['pw',['pw',['../struct_doniach_sunjic_struct.html#a92bbb374f66840510e7cb8b316057610',1,'DoniachSunjicStruct']]] + ['package_5fname_394',['package_name',['../pearl-anglescan-panel_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-anglescan-panel.ipf'],['../pearl-elog_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-matrix-import.ipf']]], + ['package_5fpath_395',['package_path',['../pearl-anglescan-panel_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-matrix-import.ipf']]], + ['projections_396',['Projections',['../_page_projections.html',1,'']]], + ['parse_5fresult_397',['parse_result',['../pearl-elog_8ipf.html#a5306514bf7d1a582aec146256ae45a12',1,'pearl-elog.ipf']]], + ['pearl_2danglescan_2dpanel_2eipf_398',['pearl-anglescan-panel.ipf',['../pearl-anglescan-panel_8ipf.html',1,'']]], + ['pearl_2danglescan_2dprocess_2eipf_399',['pearl-anglescan-process.ipf',['../pearl-anglescan-process_8ipf.html',1,'']]], + ['pearl_2danglescan_2dtracker_2eipf_400',['pearl-anglescan-tracker.ipf',['../pearl-anglescan-tracker_8ipf.html',1,'']]], + ['pearl_2darea_2ddisplay_2eipf_401',['pearl-area-display.ipf',['../pearl-area-display_8ipf.html',1,'']]], + ['pearl_2darea_2dimport_2eipf_402',['pearl-area-import.ipf',['../pearl-area-import_8ipf.html',1,'']]], + ['pearl_2darea_2dprofiles_2eipf_403',['pearl-area-profiles.ipf',['../pearl-area-profiles_8ipf.html',1,'']]], + ['pearl_2darpes_2eipf_404',['pearl-arpes.ipf',['../pearl-arpes_8ipf.html',1,'']]], + ['pearl_2dcompat_2eipf_405',['pearl-compat.ipf',['../pearl-compat_8ipf.html',1,'']]], + ['pearl_2ddata_2dexplorer_2eipf_406',['pearl-data-explorer.ipf',['../pearl-data-explorer_8ipf.html',1,'']]], + ['pearl_2delog_2eipf_407',['pearl-elog.ipf',['../pearl-elog_8ipf.html',1,'']]], + ['pearl_2dfitfuncs_2eipf_408',['pearl-fitfuncs.ipf',['../pearl-fitfuncs_8ipf.html',1,'']]], + ['pearl_2dgui_2dtools_2eipf_409',['pearl-gui-tools.ipf',['../pearl-gui-tools_8ipf.html',1,'']]], + ['pearl_2dmatrix_2dimport_2eipf_410',['pearl-matrix-import.ipf',['../pearl-matrix-import_8ipf.html',1,'']]], + ['pearl_2dmenu_2eipf_411',['pearl-menu.ipf',['../pearl-menu_8ipf.html',1,'']]], + ['pearl_2dotf_2dimport_2eipf_412',['pearl-otf-import.ipf',['../pearl-otf-import_8ipf.html',1,'']]], + ['pearl_2dpmsco_2dimport_2eipf_413',['pearl-pmsco-import.ipf',['../pearl-pmsco-import_8ipf.html',1,'']]], + ['pearl_2dpolar_2dcoordinates_2eipf_414',['pearl-polar-coordinates.ipf',['../pearl-polar-coordinates_8ipf.html',1,'']]], + ['pearl_2dpshell_2dimport_2eipf_415',['pearl-pshell-import.ipf',['../pearl-pshell-import_8ipf.html',1,'']]], + ['pearl_2dscienta_2dlive_2eipf_416',['pearl-scienta-live.ipf',['../pearl-scienta-live_8ipf.html',1,'']]], + ['pearl_2dscienta_2dpreprocess_2eipf_417',['pearl-scienta-preprocess.ipf',['../pearl-scienta-preprocess_8ipf.html',1,'']]], + ['pearl_2dtools_2eipf_418',['pearl-tools.ipf',['../pearl-tools_8ipf.html',1,'']]], + ['pearl_2dvector_2doperations_2eipf_419',['pearl-vector-operations.ipf',['../pearl-vector-operations_8ipf.html',1,'']]], + ['pearl_5fdata_5fexplorer_420',['pearl_data_explorer',['../pearl-data-explorer_8ipf.html#ab7e3b3a0a901f7559ee9f5affb9a6fca',1,'pearl-data-explorer.ipf']]], + ['pearl_5felog_421',['pearl_elog',['../pearl-elog_8ipf.html#a4088a48a8428629f120c08a419af62d6',1,'pearl-elog.ipf']]], + ['pearl_5ffile_5ftype_422',['pearl_file_type',['../pearl-data-explorer_8ipf.html#a8a923d7095071e7e6f99018379807732',1,'pearl-data-explorer.ipf']]], + ['pearlanglescanpanel_423',['PearlAnglescanPanel',['../namespace_pearl_anglescan_panel.html',1,'']]], + ['pearlanglescanprocess_424',['PearlAnglescanProcess',['../namespace_pearl_anglescan_process.html',1,'']]], + ['pearlanglescantracker_425',['PearlAnglescanTracker',['../pearl-menu_8ipf.html#a74bc5da7843ee6c25f2d9c93d22a6ffa',1,'pearl-menu.ipf']]], + ['pearlareadisplay_426',['PearlAreaDisplay',['../namespace_pearl_area_display.html',1,'']]], + ['pearlareaimport_427',['PearlAreaImport',['../namespace_pearl_area_import.html',1,'']]], + ['pearlareaprofiles_428',['PearlAreaProfiles',['../namespace_pearl_area_profiles.html',1,'']]], + ['pearlarpes_429',['PearlArpes',['../namespace_pearl_arpes.html',1,'']]], + ['pearlcameradisplay_430',['PearlCameraDisplay',['../pearl-menu_8ipf.html#aab4ec7bc68f93029377b7657f40fbd6a',1,'pearl-menu.ipf']]], + ['pearlcleanupname_431',['PearlCleanupName',['../pearl-compat_8ipf.html#aa1f59acc532c7eee75c83b70ee1feaa9',1,'pearl-compat.ipf']]], + ['pearlcompat_432',['PearlCompat',['../namespace_pearl_compat.html',1,'']]], + ['pearldataexplorer_433',['PearlDataExplorer',['../pearl-data-explorer_8ipf.html#a5b824531904179a94e0eaa3ffa09172e',1,'pearl-data-explorer.ipf']]], + ['pearlelog_434',['PearlElog',['../namespace_pearl_elog.html',1,'']]], + ['pearlelogpanel_435',['PearlElogPanel',['../pearl-elog_8ipf.html#a6da33f1bb2639cb912e9b25af25bf663',1,'pearl-elog.ipf']]], + ['pearlfitfuncs_436',['PearlFitFuncs',['../namespace_pearl_fit_funcs.html',1,'']]], + ['pearllivedisplay_437',['PearlLiveDisplay',['../pearl-menu_8ipf.html#a61ded60be72959b00f22842afa37c56f',1,'pearl-menu.ipf']]], + ['pearlmatriximport_438',['PearlMatrixImport',['../namespace_pearl_matrix_import.html',1,'']]], + ['pearlmenuenablefunc_439',['PearlMenuEnableFunc',['../pearl-menu_8ipf.html#a3404a53bf13a01c1e811d1af6c35b726',1,'pearl-menu.ipf']]], + ['pearlpmscoimport_440',['PearlPmscoImport',['../namespace_pearl_pmsco_import.html',1,'']]], + ['pearlpshellimport_441',['PearlPShellImport',['../namespace_pearl_p_shell_import.html',1,'']]], + ['pearlsampletracker_442',['PearlSampleTracker',['../pearl-menu_8ipf.html#a1437f6baee0bd6d04bbcd2236c2d1f7f',1,'pearl-menu.ipf']]], + ['pearlscientalive_443',['PearlScientaLive',['../namespace_pearl_scienta_live.html',1,'']]], + ['pearlscientapreprocess_444',['PearlScientaPreprocess',['../namespace_pearl_scienta_preprocess.html',1,'']]], + ['pearlvectoroperations_445',['PearlVectorOperations',['../namespace_pearl_vector_operations.html',1,'']]], + ['pizza_5fservice_446',['pizza_service',['../pearl-anglescan-process_8ipf.html#afed227ae79873fd32c96afbf606d1965',1,'pearl-anglescan-process.ipf']]], + ['pizza_5fservice_5f2_447',['pizza_service_2',['../pearl-anglescan-process_8ipf.html#a229770447193d4fd12032b235aab4d28',1,'pearl-anglescan-process.ipf']]], + ['pm_5freduction_5fvalues_448',['pm_reduction_values',['../pearl-data-explorer_8ipf.html#a638a13044aede37cabe0c2c7a7c0cb06',1,'pearl-data-explorer.ipf']]], + ['pmp_5fdata_449',['pmp_data',['../pearl-anglescan-tracker_8ipf.html#a07efc5d6a7121540cc185c251353677c',1,'pearl-anglescan-tracker.ipf']]], + ['pmp_5fdata_5fmouseup_450',['pmp_data_mouseup',['../pearl-anglescan-tracker_8ipf.html#a4dad34b0481be20234fa5e8d25b262c4',1,'pearl-anglescan-tracker.ipf']]], + ['pmp_5fexport_451',['pmp_export',['../pearl-area-display_8ipf.html#ac5c7a25e9a8c0b001a429bae23639da9',1,'pearl-area-display.ipf']]], + ['pmp_5fgraph_5fcolortable_452',['pmp_graph_colortable',['../pearl-anglescan-panel_8ipf.html#ac80c675f6f1a5505e9b6f0349ff5fe92',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fgraph_5fmode_453',['pmp_graph_mode',['../pearl-anglescan-panel_8ipf.html#a1b41c992729d627445dbba0637b31ece',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fgraph_5fprojection_454',['pmp_graph_projection',['../pearl-anglescan-panel_8ipf.html#af83bfcf48723e7f6eeb78b4e0d84277d',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fnorm_5falpha_5fmode_455',['pmp_norm_alpha_mode',['../pearl-anglescan-panel_8ipf.html#acc1028dcd046f441ceaac268ffac9af6',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fnorm_5ftheta_5fdomain_456',['pmp_norm_theta_domain',['../pearl-anglescan-panel_8ipf.html#a0153f4ed4892dd3b48276af190590e4f',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fnorm_5ftheta_5fmode_457',['pmp_norm_theta_mode',['../pearl-anglescan-panel_8ipf.html#ae68496dbe344dc8a2c7c99b2d3f4b01c',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fnorm_5fthetaphi_5fmode_458',['pmp_norm_thetaphi_mode',['../pearl-anglescan-panel_8ipf.html#a289996a12d0ef46af1dac49a67289931',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fparameters_459',['pmp_parameters',['../pearl-anglescan-tracker_8ipf.html#a6d484e3bb5f8c18d3b2910e8346b2c17',1,'pearl-anglescan-tracker.ipf']]], + ['pmp_5fparameters_5fmouseup_460',['pmp_parameters_mouseup',['../pearl-anglescan-tracker_8ipf.html#ad06e1354226f4f617ad0a8d6d7572dca',1,'pearl-anglescan-tracker.ipf']]], + ['pmp_5freduction_5ffunc_461',['pmp_reduction_func',['../pearl-data-explorer_8ipf.html#a166273677188a66c25a84616c6f4baa9',1,'pearl-data-explorer.ipf']]], + ['pmsco_5fload_5fxyz_462',['pmsco_load_xyz',['../pearl-pmsco-import_8ipf.html#ab3421c7f54aa64e5e493b267d700c0c8',1,'pearl-pmsco-import.ipf']]], + ['pmsco_5fsave_5fscan_463',['pmsco_save_scan',['../pearl-pmsco-import_8ipf.html#aa31bbaa2fc77b447e6c6f386b23abdd9',1,'pearl-pmsco-import.ipf']]], + ['polar2cart_464',['polar2cart',['../pearl-polar-coordinates_8ipf.html#a94ccfa9cf52c55eb1f66c2704478c396',1,'pearl-polar-coordinates.ipf']]], + ['polar2cart_5fwave_465',['polar2cart_wave',['../pearl-polar-coordinates_8ipf.html#a6a0ffb6b9160413d9694b1fd8e10c858',1,'pearl-polar-coordinates.ipf']]], + ['polar_5fdistance_466',['polar_distance',['../pearl-polar-coordinates_8ipf.html#a58139e6ebfba242b6b2ba3533b865a9a',1,'pearl-polar-coordinates.ipf']]], + ['polar_5fgraph_5fhook_467',['polar_graph_hook',['../pearl-anglescan-process_8ipf.html#ac4dbd1ece37b2cf22fa976a153977288',1,'pearl-anglescan-process.ipf']]], + ['precision_468',['precision',['../struct_doniach_sunjic_struct.html#a906e214875392bc470dbd4bb4bdda2db',1,'DoniachSunjicStruct']]], + ['prefs_5fobjects_469',['prefs_objects',['../pearl-anglescan-tracker_8ipf.html#a20720748c82a7eaa4b02d4084a4219b2',1,'pearl-anglescan-tracker.ipf']]], + ['prepare_5fcommand_5fline_470',['prepare_command_line',['../pearl-elog_8ipf.html#abd15431defaec6d770cc8cab2a40e6b0',1,'pearl-elog.ipf']]], + ['prepare_5fgraph_5fattachments_471',['prepare_graph_attachments',['../pearl-elog_8ipf.html#a4986de01085dc5481500240ef7667419',1,'pearl-elog.ipf']]], + ['prepare_5fhemi_5fscan_5fdisplay_472',['prepare_hemi_scan_display',['../pearl-anglescan-process_8ipf.html#ac15ebd5a19c558dde666ab36aeb9906f',1,'pearl-anglescan-process.ipf']]], + ['preview_5fcrop_473',['preview_crop',['../pearl-anglescan-panel_8ipf.html#a2268cc96a879c1a055c1ff29c1b040ea',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fdatafolder_474',['preview_datafolder',['../pearl-data-explorer_8ipf.html#a6e8eaf8c092f5da60bd425f9bd8bf178',1,'pearl-data-explorer.ipf']]], + ['preview_5ffile_475',['preview_file',['../pearl-data-explorer_8ipf.html#a3232c51a8c19eaf86b9bc67352967a9f',1,'pearl-data-explorer.ipf']]], + ['preview_5fhdf_5ffile_476',['preview_hdf_file',['../pearl-data-explorer_8ipf.html#a1731f8e1507d90e285885723ae32ba13',1,'pearl-data-explorer.ipf']]], + ['preview_5fitx_5ffile_477',['preview_itx_file',['../pearl-data-explorer_8ipf.html#a4633885afab755fbc5d262178b9ddcb8',1,'pearl-data-explorer.ipf']]], + ['preview_5fmatrix_5ffile_478',['preview_matrix_file',['../pearl-matrix-import_8ipf.html#a8acd2b03343ef9bdfecaa75e831392d1',1,'pearl-matrix-import.ipf']]], + ['preview_5fnorm_5falpha_479',['preview_norm_alpha',['../pearl-anglescan-panel_8ipf.html#ad355d06d3b57bb458bd62e6d6f1f2417',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fnorm_5fphi_480',['preview_norm_phi',['../pearl-anglescan-panel_8ipf.html#a0c228ce2048827dc8161691ec5c425fc',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fnorm_5ftheta_481',['preview_norm_theta',['../pearl-anglescan-panel_8ipf.html#abe1237d8bf79a2ec3791ad9fe184bc3f',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fnorm_5fthetaphi_482',['preview_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#a3e798e20a99a03a789dd7914612e4fd2',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fpshell_5ffile_483',['preview_pshell_file',['../pearl-data-explorer_8ipf.html#a457d2257ffd5880ab858fa583a5d1c99',1,'pearl-data-explorer.ipf']]], + ['preview_5fsetscale_5fx_484',['preview_setscale_x',['../pearl-data-explorer_8ipf.html#a5a7d3c00360944c00f236900b992694d',1,'pearl-data-explorer.ipf']]], + ['process_5fimage_5fdata_485',['process_image_data',['../pearl-anglescan-tracker_8ipf.html#a4bc40cded4d4d7676b084f7200ca5e0d',1,'pearl-anglescan-tracker.ipf']]], + ['prompt_5fdefault_5fprocess_486',['prompt_default_process',['../pearl-data-explorer_8ipf.html#a505ebda6bdecc4120e01766d7aedaf5d',1,'pearl-data-explorer.ipf']]], + ['prompt_5ffunc_5fparams_487',['prompt_func_params',['../pearl-data-explorer_8ipf.html#a1d7f4ad59b81ecd84bb63cfabd9f24dc',1,'pearl-data-explorer.ipf']]], + ['prompt_5fgauss4_5freduction_488',['prompt_gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#a1514250704b40aa2614d389a2e250d61',1,'pearl-scienta-preprocess.ipf']]], + ['prompt_5fhdf_5foptions_489',['prompt_hdf_options',['../pearl-data-explorer_8ipf.html#a200e7ba052fbce4614fb4254701646ab',1,'pearl-data-explorer.ipf']]], + ['prompt_5fint_5flinbg_5freduction_490',['prompt_int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a145c7275b8809c5e789b932ef46e4811',1,'pearl-scienta-preprocess.ipf']]], + ['prompt_5fint_5fquadbg_5freduction_491',['prompt_int_quadbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a6d06ea5a11ba79160efeea7fe673af8c',1,'pearl-scienta-preprocess.ipf']]], + ['prompt_5fredim_5flinbg_5freduction_492',['prompt_redim_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a6e7de6441bbcba217760448babaca827',1,'pearl-scienta-preprocess.ipf']]], + ['ps_5fdetect_5fscale_493',['ps_detect_scale',['../pearl-pshell-import_8ipf.html#ad2275b0b8a0a1ed05afc50ef50564243',1,'pearl-pshell-import.ipf']]], + ['ps_5ffind_5fattr_5ffolder_494',['ps_find_attr_folder',['../pearl-pshell-import_8ipf.html#a476f19c72d6e54787535ab6989ee778d',1,'pearl-pshell-import.ipf']]], + ['ps_5ffind_5fscale_5fwave_495',['ps_find_scale_wave',['../pearl-pshell-import_8ipf.html#a2f39f9379e66ead0d25c33adfbe05ee9',1,'pearl-pshell-import.ipf']]], + ['ps_5ffind_5fscan_5ffolder_496',['ps_find_scan_folder',['../pearl-pshell-import_8ipf.html#a513091ea9a4e23f76765aa37f1d34055',1,'pearl-pshell-import.ipf']]], + ['ps_5ffix_5ffolder_5fname_497',['ps_fix_folder_name',['../pearl-pshell-import_8ipf.html#a7d7b67c9f983d3446c5c6f274284b82a',1,'pearl-pshell-import.ipf']]], + ['ps_5fscale_5fdataset_498',['ps_scale_dataset',['../pearl-pshell-import_8ipf.html#adc11ea797562b3d99c247f4866618d39',1,'pearl-pshell-import.ipf']]], + ['ps_5fscale_5fdataset_5f2_499',['ps_scale_dataset_2',['../pearl-pshell-import_8ipf.html#a2c456397c36d4116bfddca452eff5954',1,'pearl-pshell-import.ipf']]], + ['ps_5fscale_5fdatasets_500',['ps_scale_datasets',['../pearl-pshell-import_8ipf.html#a5a1961e05ea900e72d6a886ac5744f2d',1,'pearl-pshell-import.ipf']]], + ['ps_5fset_5fdimlabels_501',['ps_set_dimlabels',['../pearl-pshell-import_8ipf.html#aba25eb98e4c6cc9066c46ef6be1cde15',1,'pearl-pshell-import.ipf']]], + ['ps_5fset_5fdimlabels2_502',['ps_set_dimlabels2',['../pearl-pshell-import_8ipf.html#a8704627410409bcd27a1adeda4082c47',1,'pearl-pshell-import.ipf']]], + ['psh5_5fclose_5ffile_503',['psh5_close_file',['../pearl-pshell-import_8ipf.html#a47513a1db5693f88d64739a5b28926b2',1,'pearl-pshell-import.ipf']]], + ['psh5_5fcreate_5ffolders_504',['psh5_create_folders',['../pearl-pshell-import_8ipf.html#aa7a48b65e465abde9aad80377605ae59',1,'pearl-pshell-import.ipf']]], + ['psh5_5fdataset_5fto_5ffolder_505',['psh5_dataset_to_folder',['../pearl-pshell-import_8ipf.html#acda8bf0493a2e8ba1955f12de08e28f2',1,'pearl-pshell-import.ipf']]], + ['psh5_5fextract_5fregion_5fpaths_506',['psh5_extract_region_paths',['../pearl-pshell-import_8ipf.html#a4f5d11063bd50ded36ca013a2656b539',1,'pearl-pshell-import.ipf']]], + ['psh5_5fextract_5fscan_5fpaths_507',['psh5_extract_scan_paths',['../pearl-pshell-import_8ipf.html#ab86e42bb6f9ff20f685ad5627b446b77',1,'pearl-pshell-import.ipf']]], + ['psh5_5ffilter_5fdatasets_5frank_508',['psh5_filter_datasets_rank',['../pearl-pshell-import_8ipf.html#a7c191ea7367f2f328333b9986c7dd538',1,'pearl-pshell-import.ipf']]], + ['psh5_5flist_5fall_5fdatasets_509',['psh5_list_all_datasets',['../pearl-pshell-import_8ipf.html#a113622ae05611e5051a97d223fae59d0',1,'pearl-pshell-import.ipf']]], + ['psh5_5flist_5fdataset_5finfo_510',['psh5_list_dataset_info',['../pearl-pshell-import_8ipf.html#ad811542ccfc7c73156c2a107faa93d87',1,'pearl-pshell-import.ipf']]], + ['psh5_5flist_5fscans_511',['psh5_list_scans',['../pearl-pshell-import_8ipf.html#a85c1fbd2aefff2028e084ea61314dc67',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_512',['psh5_load',['../pearl-pshell-import_8ipf.html#ab41e955a4ff70f9c78571faad1b43d7b',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdataset_513',['psh5_load_dataset',['../pearl-pshell-import_8ipf.html#af7a6eefbda58d31336c81a3dda6e9a2d',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdataset_5fmeta_514',['psh5_load_dataset_meta',['../pearl-pshell-import_8ipf.html#abcf01e205858a512aa713da914eaf966',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdataset_5freduced_515',['psh5_load_dataset_reduced',['../pearl-pshell-import_8ipf.html#af662500c4f992ef7b956f37ed463513d',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdataset_5fslabs_516',['psh5_load_dataset_slabs',['../pearl-pshell-import_8ipf.html#afc4fa60c5fbfdb08c2a9d3072d3e16ce',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdatasets_517',['psh5_load_datasets',['../pearl-pshell-import_8ipf.html#ae539a7501119cb2349707e2027f0f759',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fgeneral_5fgroup_518',['psh5_load_general_group',['../pearl-pshell-import_8ipf.html#ac782084655d44d222742e3397051619d',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fscan_5fmeta_519',['psh5_load_scan_meta',['../pearl-pshell-import_8ipf.html#a23a2e4cb2dc5364bfdbab4367ed6f234',1,'pearl-pshell-import.ipf']]], + ['psh5_5fmatch_5fdataset_5fclasses_520',['psh5_match_dataset_classes',['../pearl-pshell-import_8ipf.html#af3b5005859915f410ec27a31ac9519ca',1,'pearl-pshell-import.ipf']]], + ['psh5_5fopen_5ffile_521',['psh5_open_file',['../pearl-pshell-import_8ipf.html#ab684c44d5f0668631e42d9c9c9dfea9e',1,'pearl-pshell-import.ipf']]], + ['psh5_5fpreview_522',['psh5_preview',['../pearl-pshell-import_8ipf.html#a24afba76ed5323d8cd0abc3c7b0d9912',1,'pearl-pshell-import.ipf']]], + ['psh_5fload_5fgeneral_5fstring_523',['psh_load_general_string',['../pearl-pshell-import_8ipf.html#a72465006d4e8379fad08d1a1064de2a3',1,'pearl-pshell-import.ipf']]], + ['pw_524',['pw',['../struct_doniach_sunjic_struct.html#a92bbb374f66840510e7cb8b316057610',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/all_f.html b/doc/html/search/all_f.html index 6ecfc0e..246f8ab 100644 --- a/doc/html/search/all_f.html +++ b/doc/html/search/all_f.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/all_f.js b/doc/html/search/all_f.js index 676dec0..aecf018 100644 --- a/doc/html/search/all_f.js +++ b/doc/html/search/all_f.js @@ -1,4 +1,4 @@ var searchData= [ - ['quick_5fpizza_5fimage',['quick_pizza_image',['../pearl-anglescan-process_8ipf.html#a0b9e2b025e1d55d2a064edccf6c1c3e3',1,'pearl-anglescan-process.ipf']]] + ['quick_5fpizza_5fimage_525',['quick_pizza_image',['../pearl-anglescan-process_8ipf.html#a0b9e2b025e1d55d2a064edccf6c1c3e3',1,'pearl-anglescan-process.ipf']]] ]; diff --git a/doc/html/search/classes_0.html b/doc/html/search/classes_0.html index 1c3e406..f7e4c14 100644 --- a/doc/html/search/classes_0.html +++ b/doc/html/search/classes_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/classes_0.js b/doc/html/search/classes_0.js index 9852cae..ad1aa32 100644 --- a/doc/html/search/classes_0.js +++ b/doc/html/search/classes_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['doniachsunjicstruct',['DoniachSunjicStruct',['../struct_doniach_sunjic_struct.html',1,'']]] + ['doniachsunjicstruct_603',['DoniachSunjicStruct',['../struct_doniach_sunjic_struct.html',1,'']]] ]; diff --git a/doc/html/search/classes_1.html b/doc/html/search/classes_1.html index a8e7069..c7ff4b3 100644 --- a/doc/html/search/classes_1.html +++ b/doc/html/search/classes_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/classes_1.js b/doc/html/search/classes_1.js index dd18681..2fff0e1 100644 --- a/doc/html/search/classes_1.js +++ b/doc/html/search/classes_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['errorcode',['errorCode',['../structerror_code.html',1,'']]] + ['errorcode_604',['errorCode',['../structerror_code.html',1,'']]] ]; diff --git a/doc/html/search/files_0.html b/doc/html/search/files_0.html index 4f272b8..737608e 100644 --- a/doc/html/search/files_0.html +++ b/doc/html/search/files_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/files_0.js b/doc/html/search/files_0.js index e032ed1..2e24994 100644 --- a/doc/html/search/files_0.js +++ b/doc/html/search/files_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['anglescan_2dprocessing_2edox',['anglescan-processing.dox',['../anglescan-processing_8dox.html',1,'']]] + ['anglescan_2dprocessing_2edox_620',['anglescan-processing.dox',['../anglescan-processing_8dox.html',1,'']]] ]; diff --git a/doc/html/search/files_1.html b/doc/html/search/files_1.html index dcce422..f27a62d 100644 --- a/doc/html/search/files_1.html +++ b/doc/html/search/files_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/files_1.js b/doc/html/search/files_1.js index e89aa0a..18a90d6 100644 --- a/doc/html/search/files_1.js +++ b/doc/html/search/files_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['fermi_2dedge_2danalysis_2eipf',['fermi-edge-analysis.ipf',['../fermi-edge-analysis_8ipf.html',1,'']]] + ['fermi_2dedge_2danalysis_2eipf_621',['fermi-edge-analysis.ipf',['../fermi-edge-analysis_8ipf.html',1,'']]] ]; diff --git a/doc/html/search/files_2.html b/doc/html/search/files_2.html index d5c6c3b..a45066e 100644 --- a/doc/html/search/files_2.html +++ b/doc/html/search/files_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/files_2.js b/doc/html/search/files_2.js index a490ea9..d7c325f 100644 --- a/doc/html/search/files_2.js +++ b/doc/html/search/files_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['mainpage_2edox',['mainpage.dox',['../mainpage_8dox.html',1,'']]] + ['mainpage_2edox_622',['mainpage.dox',['../mainpage_8dox.html',1,'']]] ]; diff --git a/doc/html/search/files_3.html b/doc/html/search/files_3.html index d5a9528..1076bc5 100644 --- a/doc/html/search/files_3.html +++ b/doc/html/search/files_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/files_3.js b/doc/html/search/files_3.js index 028592e..744e15c 100644 --- a/doc/html/search/files_3.js +++ b/doc/html/search/files_3.js @@ -1,25 +1,25 @@ var searchData= [ - ['pearl_2danglescan_2dpanel_2eipf',['pearl-anglescan-panel.ipf',['../pearl-anglescan-panel_8ipf.html',1,'']]], - ['pearl_2danglescan_2dprocess_2eipf',['pearl-anglescan-process.ipf',['../pearl-anglescan-process_8ipf.html',1,'']]], - ['pearl_2danglescan_2dtracker_2eipf',['pearl-anglescan-tracker.ipf',['../pearl-anglescan-tracker_8ipf.html',1,'']]], - ['pearl_2darea_2ddisplay_2eipf',['pearl-area-display.ipf',['../pearl-area-display_8ipf.html',1,'']]], - ['pearl_2darea_2dimport_2eipf',['pearl-area-import.ipf',['../pearl-area-import_8ipf.html',1,'']]], - ['pearl_2darea_2dprofiles_2eipf',['pearl-area-profiles.ipf',['../pearl-area-profiles_8ipf.html',1,'']]], - ['pearl_2darpes_2eipf',['pearl-arpes.ipf',['../pearl-arpes_8ipf.html',1,'']]], - ['pearl_2dcompat_2eipf',['pearl-compat.ipf',['../pearl-compat_8ipf.html',1,'']]], - ['pearl_2ddata_2dexplorer_2eipf',['pearl-data-explorer.ipf',['../pearl-data-explorer_8ipf.html',1,'']]], - ['pearl_2delog_2eipf',['pearl-elog.ipf',['../pearl-elog_8ipf.html',1,'']]], - ['pearl_2dfitfuncs_2eipf',['pearl-fitfuncs.ipf',['../pearl-fitfuncs_8ipf.html',1,'']]], - ['pearl_2dgui_2dtools_2eipf',['pearl-gui-tools.ipf',['../pearl-gui-tools_8ipf.html',1,'']]], - ['pearl_2dmatrix_2dimport_2eipf',['pearl-matrix-import.ipf',['../pearl-matrix-import_8ipf.html',1,'']]], - ['pearl_2dmenu_2eipf',['pearl-menu.ipf',['../pearl-menu_8ipf.html',1,'']]], - ['pearl_2dotf_2dimport_2eipf',['pearl-otf-import.ipf',['../pearl-otf-import_8ipf.html',1,'']]], - ['pearl_2dpmsco_2dimport_2eipf',['pearl-pmsco-import.ipf',['../pearl-pmsco-import_8ipf.html',1,'']]], - ['pearl_2dpolar_2dcoordinates_2eipf',['pearl-polar-coordinates.ipf',['../pearl-polar-coordinates_8ipf.html',1,'']]], - ['pearl_2dpshell_2dimport_2eipf',['pearl-pshell-import.ipf',['../pearl-pshell-import_8ipf.html',1,'']]], - ['pearl_2dscienta_2dcountrate_2eipf',['pearl-scienta-countrate.ipf',['../pearl-scienta-countrate_8ipf.html',1,'']]], - ['pearl_2dscienta_2dpreprocess_2eipf',['pearl-scienta-preprocess.ipf',['../pearl-scienta-preprocess_8ipf.html',1,'']]], - ['pearl_2dtools_2eipf',['pearl-tools.ipf',['../pearl-tools_8ipf.html',1,'']]], - ['pearl_2dvector_2doperations_2eipf',['pearl-vector-operations.ipf',['../pearl-vector-operations_8ipf.html',1,'']]] + ['pearl_2danglescan_2dpanel_2eipf_623',['pearl-anglescan-panel.ipf',['../pearl-anglescan-panel_8ipf.html',1,'']]], + ['pearl_2danglescan_2dprocess_2eipf_624',['pearl-anglescan-process.ipf',['../pearl-anglescan-process_8ipf.html',1,'']]], + ['pearl_2danglescan_2dtracker_2eipf_625',['pearl-anglescan-tracker.ipf',['../pearl-anglescan-tracker_8ipf.html',1,'']]], + ['pearl_2darea_2ddisplay_2eipf_626',['pearl-area-display.ipf',['../pearl-area-display_8ipf.html',1,'']]], + ['pearl_2darea_2dimport_2eipf_627',['pearl-area-import.ipf',['../pearl-area-import_8ipf.html',1,'']]], + ['pearl_2darea_2dprofiles_2eipf_628',['pearl-area-profiles.ipf',['../pearl-area-profiles_8ipf.html',1,'']]], + ['pearl_2darpes_2eipf_629',['pearl-arpes.ipf',['../pearl-arpes_8ipf.html',1,'']]], + ['pearl_2dcompat_2eipf_630',['pearl-compat.ipf',['../pearl-compat_8ipf.html',1,'']]], + ['pearl_2ddata_2dexplorer_2eipf_631',['pearl-data-explorer.ipf',['../pearl-data-explorer_8ipf.html',1,'']]], + ['pearl_2delog_2eipf_632',['pearl-elog.ipf',['../pearl-elog_8ipf.html',1,'']]], + ['pearl_2dfitfuncs_2eipf_633',['pearl-fitfuncs.ipf',['../pearl-fitfuncs_8ipf.html',1,'']]], + ['pearl_2dgui_2dtools_2eipf_634',['pearl-gui-tools.ipf',['../pearl-gui-tools_8ipf.html',1,'']]], + ['pearl_2dmatrix_2dimport_2eipf_635',['pearl-matrix-import.ipf',['../pearl-matrix-import_8ipf.html',1,'']]], + ['pearl_2dmenu_2eipf_636',['pearl-menu.ipf',['../pearl-menu_8ipf.html',1,'']]], + ['pearl_2dotf_2dimport_2eipf_637',['pearl-otf-import.ipf',['../pearl-otf-import_8ipf.html',1,'']]], + ['pearl_2dpmsco_2dimport_2eipf_638',['pearl-pmsco-import.ipf',['../pearl-pmsco-import_8ipf.html',1,'']]], + ['pearl_2dpolar_2dcoordinates_2eipf_639',['pearl-polar-coordinates.ipf',['../pearl-polar-coordinates_8ipf.html',1,'']]], + ['pearl_2dpshell_2dimport_2eipf_640',['pearl-pshell-import.ipf',['../pearl-pshell-import_8ipf.html',1,'']]], + ['pearl_2dscienta_2dlive_2eipf_641',['pearl-scienta-live.ipf',['../pearl-scienta-live_8ipf.html',1,'']]], + ['pearl_2dscienta_2dpreprocess_2eipf_642',['pearl-scienta-preprocess.ipf',['../pearl-scienta-preprocess_8ipf.html',1,'']]], + ['pearl_2dtools_2eipf_643',['pearl-tools.ipf',['../pearl-tools_8ipf.html',1,'']]], + ['pearl_2dvector_2doperations_2eipf_644',['pearl-vector-operations.ipf',['../pearl-vector-operations_8ipf.html',1,'']]] ]; diff --git a/doc/html/search/functions_0.html b/doc/html/search/functions_0.html index 4e6d87d..e17c711 100644 --- a/doc/html/search/functions_0.html +++ b/doc/html/search/functions_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_0.js b/doc/html/search/functions_0.js index caeb9a4..b7325af 100644 --- a/doc/html/search/functions_0.js +++ b/doc/html/search/functions_0.js @@ -1,97 +1,99 @@ var searchData= [ - ['ad_5fadd_5foverlay',['ad_add_overlay',['../pearl-area-display_8ipf.html#af9bd125ed4fb4ada10b78bca2607b44d',1,'pearl-area-display.ipf']]], - ['ad_5fbox_5ffilter',['ad_box_filter',['../pearl-area-display_8ipf.html#a27f0957d61f3c2d30a4854911b460c36',1,'pearl-area-display.ipf']]], - ['ad_5fbrick_5fslicer',['ad_brick_slicer',['../pearl-area-display_8ipf.html#ae3b4756cdc12a4a4b15a770ba0069823',1,'pearl-area-display.ipf']]], - ['ad_5fcalc_5fcursor_5fprofiles',['ad_calc_cursor_profiles',['../pearl-area-display_8ipf.html#a72b57037abd27f65986034c0b4cc191e',1,'pearl-area-display.ipf']]], - ['ad_5fcalc_5fhistogram',['ad_calc_histogram',['../pearl-area-display_8ipf.html#a48b08ab53729d9d0477deaceedef2769',1,'pearl-area-display.ipf']]], - ['ad_5fcalc_5fprofiles',['ad_calc_profiles',['../pearl-area-display_8ipf.html#a48044f9ee518d47770e33ee9f381f204',1,'pearl-area-display.ipf']]], - ['ad_5fcollect_5fmultiscan_5fy',['ad_collect_multiscan_y',['../pearl-area-profiles_8ipf.html#a3cadf0b28d1fd84e9922610c20868283',1,'pearl-area-profiles.ipf']]], - ['ad_5fdefault_5fimage_5ffilter',['ad_default_image_filter',['../pearl-area-display_8ipf.html#a6418a1b2d18b82cb71c0fecbd513a934',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay',['ad_display',['../pearl-area-display_8ipf.html#ae2b11295d2715e9af019513923c64570',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay_5fbrick',['ad_display_brick',['../pearl-area-display_8ipf.html#a65b07e355df20cfb692dfb32f472b478',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay_5fhistogram',['ad_display_histogram',['../pearl-area-display_8ipf.html#a8cc3ea3bea4e851e4144140a2da42a03',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay_5fprofiles',['ad_display_profiles',['../pearl-area-display_8ipf.html#a8fad5aebaca72887d5898b4c421bcdae',1,'pearl-area-display.ipf']]], - ['ad_5fdisplay_5fslice',['ad_display_slice',['../pearl-area-display_8ipf.html#af8d5e003fcff1f750685ed6f94717730',1,'pearl-area-display.ipf']]], - ['ad_5fexport_5fprofile',['ad_export_profile',['../pearl-area-display_8ipf.html#ad3e190d1ec1b82ebef00c9f9ac44b50a',1,'pearl-area-display.ipf']]], - ['ad_5fextract_5frod',['ad_extract_rod',['../pearl-area-profiles_8ipf.html#a8de5d4f1bcca91df5bbff568ab7b582d',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5frod_5fx',['ad_extract_rod_x',['../pearl-area-profiles_8ipf.html#a83700e2faf844e2480c89b6ca4c66a79',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5frod_5fy',['ad_extract_rod_y',['../pearl-area-profiles_8ipf.html#a363af257a04d51fff2a8d5b282f65f21',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5frod_5fz',['ad_extract_rod_z',['../pearl-area-profiles_8ipf.html#a3483707fbdbfdbaec069591a5d3b07a6',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5fslab',['ad_extract_slab',['../pearl-area-profiles_8ipf.html#a65bb359c057a9d900c486e186c9974df',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5fslab_5fx',['ad_extract_slab_x',['../pearl-area-profiles_8ipf.html#af612340d1d132cacda9de7bb77c2e0aa',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5fslab_5fy',['ad_extract_slab_y',['../pearl-area-profiles_8ipf.html#a2eb6a0bcced893e827cfa4e1236e8460',1,'pearl-area-profiles.ipf']]], - ['ad_5fextract_5fslab_5fz',['ad_extract_slab_z',['../pearl-area-profiles_8ipf.html#a71f02613c4a4d21c014493e906dbe922',1,'pearl-area-profiles.ipf']]], - ['ad_5fgizmo_5fset_5fplane',['ad_gizmo_set_plane',['../pearl-area-display_8ipf.html#aee051acfe6a3c8214118b78dfe4854fd',1,'pearl-area-display.ipf']]], - ['ad_5fload_5fdialog',['ad_load_dialog',['../pearl-area-import_8ipf.html#aedff2e67d2e1bac907f2eaf24a6e5c3c',1,'pearl-area-import.ipf']]], - ['ad_5fprofile_5fx',['ad_profile_x',['../pearl-area-profiles_8ipf.html#ab1a65cf82f6933db3dd7b564582e8ed1',1,'pearl-area-profiles.ipf']]], - ['ad_5fprofile_5fx_5fw',['ad_profile_x_w',['../pearl-area-profiles_8ipf.html#aa40fd5049f993e72fd52a66a6cdde7cc',1,'pearl-area-profiles.ipf']]], - ['ad_5fprofile_5fy',['ad_profile_y',['../pearl-area-profiles_8ipf.html#abb1eed32a982037ebab00f5c3ea95e62',1,'pearl-area-profiles.ipf']]], - ['ad_5fprofile_5fy_5fw',['ad_profile_y_w',['../pearl-area-profiles_8ipf.html#a8b09e13162fa47cc076e1e661e80b002',1,'pearl-area-profiles.ipf']]], - ['ad_5fprofiles_5fcrosshairs',['ad_profiles_crosshairs',['../pearl-area-display_8ipf.html#a6d20a8c6bf5ed143d375dee71fb3a6d5',1,'pearl-area-display.ipf']]], - ['ad_5fprofiles_5fcursor_5fmode',['ad_profiles_cursor_mode',['../pearl-area-display_8ipf.html#a5657fc4dcd395aef637c19e8df57a418',1,'pearl-area-display.ipf']]], - ['ad_5fprofiles_5fhook',['ad_profiles_hook',['../pearl-area-display_8ipf.html#a89a5e3e29a0cd09951dcdf13aa28d941',1,'pearl-area-display.ipf']]], - ['ad_5fprofiles_5fset_5fcursor',['ad_profiles_set_cursor',['../pearl-area-display_8ipf.html#ad2a84495ddac89bc8f4203fca56babfd',1,'pearl-area-display.ipf']]], - ['ad_5fprofiles_5fset_5fslice',['ad_profiles_set_slice',['../pearl-area-display_8ipf.html#abaf229d75d9d579a559295795a6bc2e1',1,'pearl-area-display.ipf']]], - ['ad_5fslicer_5finit_5fbg',['ad_slicer_init_bg',['../pearl-area-display_8ipf.html#a7334815c60e2c11e2754c07489a62f4b',1,'pearl-area-display.ipf']]], - ['ad_5fslicer_5fmove_5fbg',['ad_slicer_move_bg',['../pearl-area-display_8ipf.html#a4af98ec7af48a653c6fac716ea8fa505',1,'pearl-area-display.ipf']]], - ['ad_5fslicer_5fstart_5fbg',['ad_slicer_start_bg',['../pearl-area-display_8ipf.html#ad79b37ab4fcf2cbdad6874813d93d4b1',1,'pearl-area-display.ipf']]], - ['ad_5fslicer_5fstop_5fbg',['ad_slicer_stop_bg',['../pearl-area-display_8ipf.html#a77a71985e716a300e0b61c233cd93f40',1,'pearl-area-display.ipf']]], - ['ad_5fsuggest_5ffoldername',['ad_suggest_foldername',['../pearl-area-import_8ipf.html#ad28dbbba73e553f7b5dcf8baf1c86786',1,'pearl-area-import.ipf']]], - ['ad_5ftranspose_5ffilter',['ad_transpose_filter',['../pearl-area-display_8ipf.html#a8411f0cfec3515f1ae4f0140efc14318',1,'pearl-area-display.ipf']]], - ['ad_5fupdate_5fprofiles',['ad_update_profiles',['../pearl-area-display_8ipf.html#afa2546f9cb03dfa8bf0cc9966f0b7a45',1,'pearl-area-display.ipf']]], - ['add_5fimage_5fdata',['add_image_data',['../pearl-anglescan-tracker_8ipf.html#a35a5cd8a21b48be8d726c69eb5fca134',1,'pearl-anglescan-tracker.ipf']]], - ['adh5_5fdefault_5freduction',['adh5_default_reduction',['../pearl-area-import_8ipf.html#ade69cb0f82e0c9cf6082d5fcc29f742f',1,'pearl-area-import.ipf']]], - ['adh5_5fget_5fresult_5fwaves',['adh5_get_result_waves',['../pearl-area-import_8ipf.html#a27a72a3901a5342ca9dea02e3219631c',1,'pearl-area-import.ipf']]], - ['adh5_5flist_5freduction_5ffuncs',['adh5_list_reduction_funcs',['../pearl-area-import_8ipf.html#aa5e29dc1a380311d00a5f85be867e47b',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fcomplete',['adh5_load_complete',['../pearl-area-import_8ipf.html#ab1040bf272c69dc69777b2f91df41fab',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fdetector',['adh5_load_detector',['../pearl-area-import_8ipf.html#a84dc7f466b42dde5d96c49827b2122cf',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fdetector_5fimage',['adh5_load_detector_image',['../pearl-area-import_8ipf.html#a931a7bfaaf75d308a0ce3c74ffc751bc',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fdetector_5fslabs',['adh5_load_detector_slabs',['../pearl-area-import_8ipf.html#a4a9741d1c19b10bb98b73bd5163a497b',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5finfo',['adh5_load_info',['../pearl-area-import_8ipf.html#ac76d5ba94a3d7c864437420d80c77064',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5fpreview',['adh5_load_preview',['../pearl-area-import_8ipf.html#a98f29671bdce6a5981e8865de8b9d483',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5freduced',['adh5_load_reduced',['../pearl-area-import_8ipf.html#a98f9339cd2fae80d0d92451df88395aa',1,'pearl-area-import.ipf']]], - ['adh5_5fload_5freduced_5fdetector',['adh5_load_reduced_detector',['../pearl-area-import_8ipf.html#a3f2ac36f961941e46e80a775de8300e5',1,'pearl-area-import.ipf']]], - ['adh5_5floadattr_5fall',['adh5_loadattr_all',['../pearl-area-import_8ipf.html#acde16dc7a393250b17165344f865f7b5',1,'pearl-area-import.ipf']]], - ['adh5_5fredim',['adh5_redim',['../pearl-area-import_8ipf.html#acfa6d2675e63f4f686289ef853b262a9',1,'pearl-area-import.ipf']]], - ['adh5_5freduce_5fbrick',['adh5_reduce_brick',['../pearl-area-import_8ipf.html#ae88bc41882fd16c94c04d856f3e062e4',1,'pearl-area-import.ipf']]], - ['adh5_5fscale',['adh5_scale',['../pearl-area-import_8ipf.html#a774751d1857ea6946a942448dc913128',1,'pearl-area-import.ipf']]], - ['adh5_5fscale_5fscan',['adh5_scale_scan',['../pearl-area-import_8ipf.html#a1fdcc02340375afe8d8cd7537c6e9cfb',1,'pearl-area-import.ipf']]], - ['adh5_5fscale_5fscienta',['adh5_scale_scienta',['../pearl-area-import_8ipf.html#a227e4db1c51a910dcf86d355473fe74e',1,'pearl-area-import.ipf']]], - ['adh5_5fsetup_5fprofile',['adh5_setup_profile',['../pearl-area-import_8ipf.html#a9439de3b676e686eeca4e6b2588c01a6',1,'pearl-area-import.ipf']]], - ['adh5_5ftest_5freduction_5ffunc',['adh5_test_reduction_func',['../pearl-area-import_8ipf.html#a98804ce23a5c2c314ac243baa0824424',1,'pearl-area-import.ipf']]], - ['aftercompiledhook',['AfterCompiledHook',['../pearl-anglescan-panel_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-anglescan-tracker.ipf'],['../pearl-arpes_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-arpes.ipf']]], - ['afterfileopenhook',['AfterFileOpenHook',['../pearl-elog_8ipf.html#a3f524f5190341d2accc8cb8c3ed2ceb5',1,'AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a3f524f5190341d2accc8cb8c3ed2ceb5',1,'AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind): pearl-matrix-import.ipf']]], - ['analyse_5fcurved_5fedge',['analyse_curved_edge',['../fermi-edge-analysis_8ipf.html#a1c4a805435a1d43c2b6dfb6deb633894',1,'fermi-edge-analysis.ipf']]], - ['analyser_5fenergy_5fresolution',['analyser_energy_resolution',['../fermi-edge-analysis_8ipf.html#ad23de34bb698589e2576ce2836b89d55',1,'fermi-edge-analysis.ipf']]], - ['angletok',['AngleToK',['../pearl-anglescan-process_8ipf.html#acf6fddb73624fe2d21429e38c4994088',1,'pearl-anglescan-process.ipf']]], - ['appendtographiterator',['AppendToGraphIterator',['../pearl-tools_8ipf.html#a90c62bdfc186e2482ccb18113a591d5e',1,'pearl-tools.ipf']]], - ['arrange_5fcontrols',['arrange_controls',['../pearl-anglescan-panel_8ipf.html#a65dbeab54647d7c27a139035d69c812f',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fcalculate_5foutput',['asp_calculate_output',['../pearl-anglescan-panel_8ipf.html#af21424ce00e4bac1ac990d2bb83d46dc',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fclose_5fgraphs',['asp_close_graphs',['../pearl-anglescan-panel_8ipf.html#aac9d4d0388cbe8e6aa8f47b1c5276d83',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fdisplay_5fdist_5fcheck',['asp_display_dist_check',['../pearl-anglescan-panel_8ipf.html#a59886414c7dc2486c5a17f078896c705',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fdisplay_5foutput',['asp_display_output',['../pearl-anglescan-panel_8ipf.html#a8e540427fab71f879e84003c49c59f22',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fdisplay_5fpreviews',['asp_display_previews',['../pearl-anglescan-panel_8ipf.html#a66b3eef1fd0be13dfef0a66781f55062',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fduplicate_5foutput',['asp_duplicate_output',['../pearl-anglescan-panel_8ipf.html#adf7c5a4e7c66c3d6e13d01674b9cf47f',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fimport_5fraw',['asp_import_raw',['../pearl-anglescan-panel_8ipf.html#a21aab19fbcde395df6e1ea8654b3af9a',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fsave_5foutput_5fetpi',['asp_save_output_etpi',['../pearl-anglescan-panel_8ipf.html#abb4d53822bc34bda0e38332c7777ebac',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fsave_5foutput_5fitx',['asp_save_output_itx',['../pearl-anglescan-panel_8ipf.html#a0e0f10d125f1cdacffa3bff9b0854aa9',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fshow_5fpanel',['asp_show_panel',['../pearl-anglescan-panel_8ipf.html#a452f09c3057638056ac2b5a15ac660b2',1,'pearl-anglescan-panel.ipf']]], - ['asp_5fupdate_5fgraph',['asp_update_graph',['../pearl-anglescan-panel_8ipf.html#a93dc5a029ae9831066e6ad133522ee88',1,'pearl-anglescan-panel.ipf']]], - ['ast_5fadd_5fimage',['ast_add_image',['../pearl-anglescan-tracker_8ipf.html#a43d85b93bb42a67b8e8afb9afc8d8eae',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fcallback_5fdata',['ast_callback_data',['../pearl-anglescan-tracker_8ipf.html#a4cf5ad2fdf771ffc157a3924a03f5a46',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fcallback_5fdetector',['ast_callback_detector',['../pearl-anglescan-tracker_8ipf.html#ac953a75b45d65adf37ce5560bf441876',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fcallback_5fmanip',['ast_callback_manip',['../pearl-anglescan-tracker_8ipf.html#a9b4acc299c5e698695baf0b4817ff7eb',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fclose',['ast_close',['../pearl-anglescan-tracker_8ipf.html#a8a74ddd33e286105a45a89105de72621',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fexport',['ast_export',['../pearl-anglescan-tracker_8ipf.html#ac9c92805f39c7a5c68d4c017d14ee178',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fimport',['ast_import',['../pearl-anglescan-tracker_8ipf.html#ae4ece97352b85ced47e954c025e3b69b',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fprepare',['ast_prepare',['../pearl-anglescan-tracker_8ipf.html#a766f90a9dad70d9deb4272ba480ee84a',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fset_5fprocessing',['ast_set_processing',['../pearl-anglescan-tracker_8ipf.html#a02271bf812a3e3f87c958f4c58e9f71b',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fsetup',['ast_setup',['../pearl-anglescan-tracker_8ipf.html#a5fb1f1abddb56b129f053605035d3281',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fupdate_5fdetector',['ast_update_detector',['../pearl-anglescan-tracker_8ipf.html#a150243e26e8adf8b354b8afde064136d',1,'pearl-anglescan-tracker.ipf']]], - ['ast_5fwindow_5fhook',['ast_window_hook',['../pearl-anglescan-tracker_8ipf.html#a33e84ae8e13f405d466b28e83f608cb9',1,'pearl-anglescan-tracker.ipf']]], - ['attributes_5fnotebook',['attributes_notebook',['../pearl-data-explorer_8ipf.html#ad6cfb2c00d5112add84542a25eb68b19',1,'pearl-data-explorer.ipf']]], - ['au4f',['Au4f',['../pearl-fitfuncs_8ipf.html#a13a5ee22049d9a3379cd6e55654e70a3',1,'pearl-fitfuncs.ipf']]], - ['au4f_5f2p2',['Au4f_2p2',['../pearl-fitfuncs_8ipf.html#a24cd6a0c96ef8c720e371bb31ac0a479',1,'pearl-fitfuncs.ipf']]], - ['au4f_5f2p3',['Au4f_2p3',['../pearl-fitfuncs_8ipf.html#a709f7c4585b1d850ea8aae1885ac18cb',1,'pearl-fitfuncs.ipf']]] + ['ad_5fadd_5foverlay_645',['ad_add_overlay',['../pearl-area-display_8ipf.html#af9bd125ed4fb4ada10b78bca2607b44d',1,'pearl-area-display.ipf']]], + ['ad_5fbox_5ffilter_646',['ad_box_filter',['../pearl-area-display_8ipf.html#a27f0957d61f3c2d30a4854911b460c36',1,'pearl-area-display.ipf']]], + ['ad_5fbrick_5fslicer_647',['ad_brick_slicer',['../pearl-area-display_8ipf.html#ae3b4756cdc12a4a4b15a770ba0069823',1,'pearl-area-display.ipf']]], + ['ad_5fcalc_5fcursor_5fprofiles_648',['ad_calc_cursor_profiles',['../pearl-area-display_8ipf.html#a72b57037abd27f65986034c0b4cc191e',1,'pearl-area-display.ipf']]], + ['ad_5fcalc_5fhistogram_649',['ad_calc_histogram',['../pearl-area-display_8ipf.html#a48b08ab53729d9d0477deaceedef2769',1,'pearl-area-display.ipf']]], + ['ad_5fcalc_5fprofiles_650',['ad_calc_profiles',['../pearl-area-display_8ipf.html#a48044f9ee518d47770e33ee9f381f204',1,'pearl-area-display.ipf']]], + ['ad_5fcollect_5fmultiscan_5fy_651',['ad_collect_multiscan_y',['../pearl-area-profiles_8ipf.html#a3cadf0b28d1fd84e9922610c20868283',1,'pearl-area-profiles.ipf']]], + ['ad_5fdefault_5fimage_5ffilter_652',['ad_default_image_filter',['../pearl-area-display_8ipf.html#a6418a1b2d18b82cb71c0fecbd513a934',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_653',['ad_display',['../pearl-area-display_8ipf.html#ae2b11295d2715e9af019513923c64570',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_5fbrick_654',['ad_display_brick',['../pearl-area-display_8ipf.html#a65b07e355df20cfb692dfb32f472b478',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_5fhistogram_655',['ad_display_histogram',['../pearl-area-display_8ipf.html#a8cc3ea3bea4e851e4144140a2da42a03',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_5fprofiles_656',['ad_display_profiles',['../pearl-area-display_8ipf.html#a8fad5aebaca72887d5898b4c421bcdae',1,'pearl-area-display.ipf']]], + ['ad_5fdisplay_5fslice_657',['ad_display_slice',['../pearl-area-display_8ipf.html#af8d5e003fcff1f750685ed6f94717730',1,'pearl-area-display.ipf']]], + ['ad_5fexport_5fprofile_658',['ad_export_profile',['../pearl-area-display_8ipf.html#ad3e190d1ec1b82ebef00c9f9ac44b50a',1,'pearl-area-display.ipf']]], + ['ad_5fextract_5frod_659',['ad_extract_rod',['../pearl-area-profiles_8ipf.html#a8de5d4f1bcca91df5bbff568ab7b582d',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5frod_5fx_660',['ad_extract_rod_x',['../pearl-area-profiles_8ipf.html#a83700e2faf844e2480c89b6ca4c66a79',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5frod_5fy_661',['ad_extract_rod_y',['../pearl-area-profiles_8ipf.html#a363af257a04d51fff2a8d5b282f65f21',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5frod_5fz_662',['ad_extract_rod_z',['../pearl-area-profiles_8ipf.html#a3483707fbdbfdbaec069591a5d3b07a6',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5fslab_663',['ad_extract_slab',['../pearl-area-profiles_8ipf.html#a65bb359c057a9d900c486e186c9974df',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5fslab_5fx_664',['ad_extract_slab_x',['../pearl-area-profiles_8ipf.html#af612340d1d132cacda9de7bb77c2e0aa',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5fslab_5fy_665',['ad_extract_slab_y',['../pearl-area-profiles_8ipf.html#a2eb6a0bcced893e827cfa4e1236e8460',1,'pearl-area-profiles.ipf']]], + ['ad_5fextract_5fslab_5fz_666',['ad_extract_slab_z',['../pearl-area-profiles_8ipf.html#a71f02613c4a4d21c014493e906dbe922',1,'pearl-area-profiles.ipf']]], + ['ad_5fgizmo_5fset_5fplane_667',['ad_gizmo_set_plane',['../pearl-area-display_8ipf.html#aee051acfe6a3c8214118b78dfe4854fd',1,'pearl-area-display.ipf']]], + ['ad_5fload_5fdialog_668',['ad_load_dialog',['../pearl-area-import_8ipf.html#aedff2e67d2e1bac907f2eaf24a6e5c3c',1,'pearl-area-import.ipf']]], + ['ad_5fprofile_5fx_669',['ad_profile_x',['../pearl-area-profiles_8ipf.html#ab1a65cf82f6933db3dd7b564582e8ed1',1,'pearl-area-profiles.ipf']]], + ['ad_5fprofile_5fx_5fw_670',['ad_profile_x_w',['../pearl-area-profiles_8ipf.html#aa40fd5049f993e72fd52a66a6cdde7cc',1,'pearl-area-profiles.ipf']]], + ['ad_5fprofile_5fy_671',['ad_profile_y',['../pearl-area-profiles_8ipf.html#abb1eed32a982037ebab00f5c3ea95e62',1,'pearl-area-profiles.ipf']]], + ['ad_5fprofile_5fy_5fw_672',['ad_profile_y_w',['../pearl-area-profiles_8ipf.html#a8b09e13162fa47cc076e1e661e80b002',1,'pearl-area-profiles.ipf']]], + ['ad_5fprofiles_5fcrosshairs_673',['ad_profiles_crosshairs',['../pearl-area-display_8ipf.html#a6d20a8c6bf5ed143d375dee71fb3a6d5',1,'pearl-area-display.ipf']]], + ['ad_5fprofiles_5fcursor_5fmode_674',['ad_profiles_cursor_mode',['../pearl-area-display_8ipf.html#a5657fc4dcd395aef637c19e8df57a418',1,'pearl-area-display.ipf']]], + ['ad_5fprofiles_5fhook_675',['ad_profiles_hook',['../pearl-area-display_8ipf.html#a89a5e3e29a0cd09951dcdf13aa28d941',1,'pearl-area-display.ipf']]], + ['ad_5fprofiles_5fset_5fcursor_676',['ad_profiles_set_cursor',['../pearl-area-display_8ipf.html#ad2a84495ddac89bc8f4203fca56babfd',1,'pearl-area-display.ipf']]], + ['ad_5fprofiles_5fset_5fslice_677',['ad_profiles_set_slice',['../pearl-area-display_8ipf.html#abaf229d75d9d579a559295795a6bc2e1',1,'pearl-area-display.ipf']]], + ['ad_5fslicer_5finit_5fbg_678',['ad_slicer_init_bg',['../pearl-area-display_8ipf.html#a7334815c60e2c11e2754c07489a62f4b',1,'pearl-area-display.ipf']]], + ['ad_5fslicer_5fmove_5fbg_679',['ad_slicer_move_bg',['../pearl-area-display_8ipf.html#a4af98ec7af48a653c6fac716ea8fa505',1,'pearl-area-display.ipf']]], + ['ad_5fslicer_5fstart_5fbg_680',['ad_slicer_start_bg',['../pearl-area-display_8ipf.html#ad79b37ab4fcf2cbdad6874813d93d4b1',1,'pearl-area-display.ipf']]], + ['ad_5fslicer_5fstop_5fbg_681',['ad_slicer_stop_bg',['../pearl-area-display_8ipf.html#a77a71985e716a300e0b61c233cd93f40',1,'pearl-area-display.ipf']]], + ['ad_5fsuggest_5ffoldername_682',['ad_suggest_foldername',['../pearl-area-import_8ipf.html#ad28dbbba73e553f7b5dcf8baf1c86786',1,'pearl-area-import.ipf']]], + ['ad_5ftranspose_5ffilter_683',['ad_transpose_filter',['../pearl-area-display_8ipf.html#a8411f0cfec3515f1ae4f0140efc14318',1,'pearl-area-display.ipf']]], + ['ad_5fupdate_5fprofiles_684',['ad_update_profiles',['../pearl-area-display_8ipf.html#afa2546f9cb03dfa8bf0cc9966f0b7a45',1,'pearl-area-display.ipf']]], + ['add_5fanglescan_5fworker_685',['add_anglescan_worker',['../pearl-anglescan-process_8ipf.html#a8c83a187e371783dea62c9f2bc97c52c',1,'pearl-anglescan-process.ipf']]], + ['add_5faziscan_5fcore_686',['add_aziscan_core',['../pearl-anglescan-process_8ipf.html#a8eabc7feca73f9e0db2109a78ee382cb',1,'pearl-anglescan-process.ipf']]], + ['add_5fimage_5fdata_687',['add_image_data',['../pearl-anglescan-tracker_8ipf.html#a35a5cd8a21b48be8d726c69eb5fca134',1,'pearl-anglescan-tracker.ipf']]], + ['adh5_5fdefault_5freduction_688',['adh5_default_reduction',['../pearl-area-import_8ipf.html#ade69cb0f82e0c9cf6082d5fcc29f742f',1,'pearl-area-import.ipf']]], + ['adh5_5fget_5fresult_5fwaves_689',['adh5_get_result_waves',['../pearl-area-import_8ipf.html#a27a72a3901a5342ca9dea02e3219631c',1,'pearl-area-import.ipf']]], + ['adh5_5flist_5freduction_5ffuncs_690',['adh5_list_reduction_funcs',['../pearl-area-import_8ipf.html#aa5e29dc1a380311d00a5f85be867e47b',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fcomplete_691',['adh5_load_complete',['../pearl-area-import_8ipf.html#ab1040bf272c69dc69777b2f91df41fab',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fdetector_692',['adh5_load_detector',['../pearl-area-import_8ipf.html#a84dc7f466b42dde5d96c49827b2122cf',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fdetector_5fimage_693',['adh5_load_detector_image',['../pearl-area-import_8ipf.html#a931a7bfaaf75d308a0ce3c74ffc751bc',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fdetector_5fslabs_694',['adh5_load_detector_slabs',['../pearl-area-import_8ipf.html#a4a9741d1c19b10bb98b73bd5163a497b',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5finfo_695',['adh5_load_info',['../pearl-area-import_8ipf.html#ac76d5ba94a3d7c864437420d80c77064',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5fpreview_696',['adh5_load_preview',['../pearl-area-import_8ipf.html#a98f29671bdce6a5981e8865de8b9d483',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5freduced_697',['adh5_load_reduced',['../pearl-area-import_8ipf.html#a98f9339cd2fae80d0d92451df88395aa',1,'pearl-area-import.ipf']]], + ['adh5_5fload_5freduced_5fdetector_698',['adh5_load_reduced_detector',['../pearl-area-import_8ipf.html#a3f2ac36f961941e46e80a775de8300e5',1,'pearl-area-import.ipf']]], + ['adh5_5floadattr_5fall_699',['adh5_loadattr_all',['../pearl-area-import_8ipf.html#acde16dc7a393250b17165344f865f7b5',1,'pearl-area-import.ipf']]], + ['adh5_5fredim_700',['adh5_redim',['../pearl-area-import_8ipf.html#acfa6d2675e63f4f686289ef853b262a9',1,'pearl-area-import.ipf']]], + ['adh5_5freduce_5fbrick_701',['adh5_reduce_brick',['../pearl-area-import_8ipf.html#ae88bc41882fd16c94c04d856f3e062e4',1,'pearl-area-import.ipf']]], + ['adh5_5fscale_702',['adh5_scale',['../pearl-area-import_8ipf.html#a774751d1857ea6946a942448dc913128',1,'pearl-area-import.ipf']]], + ['adh5_5fscale_5fscan_703',['adh5_scale_scan',['../pearl-area-import_8ipf.html#a1fdcc02340375afe8d8cd7537c6e9cfb',1,'pearl-area-import.ipf']]], + ['adh5_5fscale_5fscienta_704',['adh5_scale_scienta',['../pearl-area-import_8ipf.html#a227e4db1c51a910dcf86d355473fe74e',1,'pearl-area-import.ipf']]], + ['adh5_5fsetup_5fprofile_705',['adh5_setup_profile',['../pearl-area-import_8ipf.html#a9439de3b676e686eeca4e6b2588c01a6',1,'pearl-area-import.ipf']]], + ['adh5_5ftest_5freduction_5ffunc_706',['adh5_test_reduction_func',['../pearl-area-import_8ipf.html#a98804ce23a5c2c314ac243baa0824424',1,'pearl-area-import.ipf']]], + ['aftercompiledhook_707',['AfterCompiledHook',['../pearl-anglescan-panel_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-anglescan-tracker.ipf'],['../pearl-arpes_8ipf.html#a8e4eacc6efacf2c65615c1ea72d722ed',1,'AfterCompiledHook(): pearl-arpes.ipf']]], + ['afterfileopenhook_708',['AfterFileOpenHook',['../pearl-elog_8ipf.html#a3f524f5190341d2accc8cb8c3ed2ceb5',1,'AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a3f524f5190341d2accc8cb8c3ed2ceb5',1,'AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind): pearl-matrix-import.ipf']]], + ['analyse_5fcurved_5fedge_709',['analyse_curved_edge',['../fermi-edge-analysis_8ipf.html#a1c4a805435a1d43c2b6dfb6deb633894',1,'fermi-edge-analysis.ipf']]], + ['analyser_5fenergy_5fresolution_710',['analyser_energy_resolution',['../pearl-scienta-live_8ipf.html#ad23de34bb698589e2576ce2836b89d55',1,'pearl-scienta-live.ipf']]], + ['angletok_711',['AngleToK',['../pearl-anglescan-process_8ipf.html#acf6fddb73624fe2d21429e38c4994088',1,'pearl-anglescan-process.ipf']]], + ['appendtographiterator_712',['AppendToGraphIterator',['../pearl-tools_8ipf.html#a90c62bdfc186e2482ccb18113a591d5e',1,'pearl-tools.ipf']]], + ['arrange_5fcontrols_713',['arrange_controls',['../pearl-anglescan-panel_8ipf.html#a65dbeab54647d7c27a139035d69c812f',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fcalculate_5foutput_714',['asp_calculate_output',['../pearl-anglescan-panel_8ipf.html#af21424ce00e4bac1ac990d2bb83d46dc',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fclose_5fgraphs_715',['asp_close_graphs',['../pearl-anglescan-panel_8ipf.html#aac9d4d0388cbe8e6aa8f47b1c5276d83',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fdisplay_5fdist_5fcheck_716',['asp_display_dist_check',['../pearl-anglescan-panel_8ipf.html#a59886414c7dc2486c5a17f078896c705',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fdisplay_5foutput_717',['asp_display_output',['../pearl-anglescan-panel_8ipf.html#a8e540427fab71f879e84003c49c59f22',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fdisplay_5fpreviews_718',['asp_display_previews',['../pearl-anglescan-panel_8ipf.html#a66b3eef1fd0be13dfef0a66781f55062',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fduplicate_5foutput_719',['asp_duplicate_output',['../pearl-anglescan-panel_8ipf.html#adf7c5a4e7c66c3d6e13d01674b9cf47f',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fimport_5fraw_720',['asp_import_raw',['../pearl-anglescan-panel_8ipf.html#a21aab19fbcde395df6e1ea8654b3af9a',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fsave_5foutput_5fetpi_721',['asp_save_output_etpi',['../pearl-anglescan-panel_8ipf.html#abb4d53822bc34bda0e38332c7777ebac',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fsave_5foutput_5fitx_722',['asp_save_output_itx',['../pearl-anglescan-panel_8ipf.html#a0e0f10d125f1cdacffa3bff9b0854aa9',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fshow_5fpanel_723',['asp_show_panel',['../pearl-anglescan-panel_8ipf.html#a452f09c3057638056ac2b5a15ac660b2',1,'pearl-anglescan-panel.ipf']]], + ['asp_5fupdate_5fgraph_724',['asp_update_graph',['../pearl-anglescan-panel_8ipf.html#a93dc5a029ae9831066e6ad133522ee88',1,'pearl-anglescan-panel.ipf']]], + ['ast_5fadd_5fimage_725',['ast_add_image',['../pearl-anglescan-tracker_8ipf.html#a43d85b93bb42a67b8e8afb9afc8d8eae',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fcallback_5fdata_726',['ast_callback_data',['../pearl-anglescan-tracker_8ipf.html#a4cf5ad2fdf771ffc157a3924a03f5a46',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fcallback_5fdetector_727',['ast_callback_detector',['../pearl-anglescan-tracker_8ipf.html#ac953a75b45d65adf37ce5560bf441876',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fcallback_5fmanip_728',['ast_callback_manip',['../pearl-anglescan-tracker_8ipf.html#a9b4acc299c5e698695baf0b4817ff7eb',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fclose_729',['ast_close',['../pearl-anglescan-tracker_8ipf.html#a8a74ddd33e286105a45a89105de72621',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fexport_730',['ast_export',['../pearl-anglescan-tracker_8ipf.html#ac9c92805f39c7a5c68d4c017d14ee178',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fimport_731',['ast_import',['../pearl-anglescan-tracker_8ipf.html#ae4ece97352b85ced47e954c025e3b69b',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fprepare_732',['ast_prepare',['../pearl-anglescan-tracker_8ipf.html#a766f90a9dad70d9deb4272ba480ee84a',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fset_5fprocessing_733',['ast_set_processing',['../pearl-anglescan-tracker_8ipf.html#a02271bf812a3e3f87c958f4c58e9f71b',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fsetup_734',['ast_setup',['../pearl-anglescan-tracker_8ipf.html#a5fb1f1abddb56b129f053605035d3281',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fupdate_5fdetector_735',['ast_update_detector',['../pearl-anglescan-tracker_8ipf.html#a150243e26e8adf8b354b8afde064136d',1,'pearl-anglescan-tracker.ipf']]], + ['ast_5fwindow_5fhook_736',['ast_window_hook',['../pearl-anglescan-tracker_8ipf.html#a33e84ae8e13f405d466b28e83f608cb9',1,'pearl-anglescan-tracker.ipf']]], + ['attributes_5fnotebook_737',['attributes_notebook',['../pearl-data-explorer_8ipf.html#a844467a592e5b26b2324326f22b7da89',1,'pearl-data-explorer.ipf']]], + ['au4f_738',['Au4f',['../pearl-fitfuncs_8ipf.html#a13a5ee22049d9a3379cd6e55654e70a3',1,'pearl-fitfuncs.ipf']]], + ['au4f_5f2p2_739',['Au4f_2p2',['../pearl-fitfuncs_8ipf.html#a24cd6a0c96ef8c720e371bb31ac0a479',1,'pearl-fitfuncs.ipf']]], + ['au4f_5f2p3_740',['Au4f_2p3',['../pearl-fitfuncs_8ipf.html#a709f7c4585b1d850ea8aae1885ac18cb',1,'pearl-fitfuncs.ipf']]] ]; diff --git a/doc/html/search/functions_1.html b/doc/html/search/functions_1.html index b343e2d..0ddac0a 100644 --- a/doc/html/search/functions_1.html +++ b/doc/html/search/functions_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_1.js b/doc/html/search/functions_1.js index 328bc98..9011aea 100644 --- a/doc/html/search/functions_1.js +++ b/doc/html/search/functions_1.js @@ -1,49 +1,47 @@ var searchData= [ - ['beforefileopenhook',['BeforeFileOpenHook',['../pearl-area-import_8ipf.html#ae2cfa1ac6651cfc3fb0dfce03494995b',1,'BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind): pearl-area-import.ipf'],['../pearl-matrix-import_8ipf.html#ae2cfa1ac6651cfc3fb0dfce03494995b',1,'BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind): pearl-matrix-import.ipf']]], - ['bp_5fattach',['bp_attach',['../pearl-elog_8ipf.html#acbba78d869a543edf7c2b80d7a8d2344',1,'pearl-elog.ipf']]], - ['bp_5fattach_5fallnone',['bp_attach_allnone',['../pearl-elog_8ipf.html#a4040736819edadf4b26982bcfdb9c7b9',1,'pearl-elog.ipf']]], - ['bp_5fattach_5ftop',['bp_attach_top',['../pearl-elog_8ipf.html#a91b5f51982d23a36d1760b8874b5736a',1,'pearl-elog.ipf']]], - ['bp_5fattach_5fupdown',['bp_attach_updown',['../pearl-elog_8ipf.html#aa1dfae6d78a367d50ee8fc1ffe9cb69b',1,'pearl-elog.ipf']]], - ['bp_5fattr_5fnotebook',['bp_attr_notebook',['../pearl-data-explorer_8ipf.html#a4ef196f752bb5780ed4f4a588f9ebc81',1,'pearl-data-explorer.ipf']]], - ['bp_5fbrowse_5ffilepath',['bp_browse_filepath',['../pearl-data-explorer_8ipf.html#a02a64144b7ed2c1bc230e265c55e81a1',1,'pearl-data-explorer.ipf']]], - ['bp_5fcapture',['bp_capture',['../pearl-anglescan-tracker_8ipf.html#afaec8443094530fd1e723251e04c5dc9',1,'pearl-anglescan-tracker.ipf']]], - ['bp_5fclear',['bp_clear',['../pearl-elog_8ipf.html#ab39637298c93b7aefd67febf3a4e7672',1,'pearl-elog.ipf']]], - ['bp_5fcrop_5fpreview',['bp_crop_preview',['../pearl-anglescan-panel_8ipf.html#a57c666f93cb4310fadf13b1916eaf134',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fdataset_5fdisplay',['bp_dataset_display',['../pearl-data-explorer_8ipf.html#a5660c6f5f78d880b0805bad4eefed1d5',1,'pearl-data-explorer.ipf']]], - ['bp_5fdataset_5ffolder',['bp_dataset_folder',['../pearl-data-explorer_8ipf.html#a6b642da731bde1029e0fa2ff69d5fb06',1,'pearl-data-explorer.ipf']]], - ['bp_5fdataset_5fnext',['bp_dataset_next',['../pearl-data-explorer_8ipf.html#a3bbb332e319ef7ec5f0fe2d16afaf005',1,'pearl-data-explorer.ipf']]], - ['bp_5fdataset_5fprev',['bp_dataset_prev',['../pearl-data-explorer_8ipf.html#add62ff5193206c9f207952bcd72dac88',1,'pearl-data-explorer.ipf']]], - ['bp_5fextract_5fslice',['bp_extract_slice',['../pearl-area-display_8ipf.html#a31461b664ec651a39442e9a46ffd88c9',1,'pearl-area-display.ipf']]], - ['bp_5ffile_5fnext',['bp_file_next',['../pearl-data-explorer_8ipf.html#a9cefcdc49b2169e99c743b0a683ed3a6',1,'pearl-data-explorer.ipf']]], - ['bp_5ffile_5fprev',['bp_file_prev',['../pearl-data-explorer_8ipf.html#a6aa44ff12b8530adbaaaf7405b1a68ba',1,'pearl-data-explorer.ipf']]], - ['bp_5fgraph_5fpng',['bp_graph_png',['../pearl-anglescan-panel_8ipf.html#a9be861636d98d7891e6d106deac2f90b',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fgraph_5fupdate',['bp_graph_update',['../pearl-anglescan-panel_8ipf.html#a940f2115fb5b47e19516168d15346472',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fload_5ffiles',['bp_load_files',['../pearl-data-explorer_8ipf.html#a742902dfaf2246f10b70f52805c6df1f',1,'pearl-data-explorer.ipf']]], - ['bp_5fload_5ffiles_5fopt',['bp_load_files_opt',['../pearl-data-explorer_8ipf.html#ad61aa85dcf24dbf7e093dac3d0bf6f19',1,'pearl-data-explorer.ipf']]], - ['bp_5fload_5fprefs',['bp_load_prefs',['../pearl-anglescan-panel_8ipf.html#a1868754e64cb1448e564c0936e78574d',1,'bp_load_prefs(WMButtonAction *ba): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#a1868754e64cb1448e564c0936e78574d',1,'bp_load_prefs(WMButtonAction *ba): pearl-data-explorer.ipf']]], - ['bp_5flogin',['bp_login',['../pearl-elog_8ipf.html#a14f8376a0485aa654ccf3d2f30ab4d01',1,'pearl-elog.ipf']]], - ['bp_5flogout',['bp_logout',['../pearl-elog_8ipf.html#ad4472ea917691c41ad0b4ea6f36010a5',1,'pearl-elog.ipf']]], - ['bp_5fmove_5fslice',['bp_move_slice',['../pearl-area-display_8ipf.html#ab8c9979c6f3ab95f983c2a525a69c035',1,'pearl-area-display.ipf']]], - ['bp_5fmove_5fslice_5fcenter',['bp_move_slice_center',['../pearl-area-display_8ipf.html#abe702d40071e3c5e662eb8d47dd6d885',1,'pearl-area-display.ipf']]], - ['bp_5fnorm_5falpha_5fcheck',['bp_norm_alpha_check',['../pearl-anglescan-panel_8ipf.html#a630dfc775d45843c71c279bbb01d05a6',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5falpha_5fpreview',['bp_norm_alpha_preview',['../pearl-anglescan-panel_8ipf.html#aaaf3facc118f90a8f1b32948446899b3',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5fphi_5fcheck',['bp_norm_phi_check',['../pearl-anglescan-panel_8ipf.html#ae42eb7f46e5c1a1b5d334ebb5e94d2d3',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5fphi_5fpreview',['bp_norm_phi_preview',['../pearl-anglescan-panel_8ipf.html#a740c8a80ab2fc0550a05cf3b032821d0',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5ftheta_5fcheck',['bp_norm_theta_check',['../pearl-anglescan-panel_8ipf.html#a0931ce925d2dae6a1bb7e4a65a8a2be7',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5ftheta_5fpreview',['bp_norm_theta_preview',['../pearl-anglescan-panel_8ipf.html#af57abb0a7d41b800d33bb748f9fc5c38',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5fthetaphi_5fcheck',['bp_norm_thetaphi_check',['../pearl-anglescan-panel_8ipf.html#a89caab501e8f15262d6e4f2fa5b4a1bd',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fnorm_5fthetaphi_5fpreview',['bp_norm_thetaphi_preview',['../pearl-anglescan-panel_8ipf.html#aaa3478a3b0f26b12a12196cfaa87a8ae',1,'pearl-anglescan-panel.ipf']]], - ['bp_5foutput_5fcalc',['bp_output_calc',['../pearl-anglescan-panel_8ipf.html#adefddc5f384948c9dab3ee65b4a0668a',1,'pearl-anglescan-panel.ipf']]], - ['bp_5foutput_5fduplicate',['bp_output_duplicate',['../pearl-anglescan-panel_8ipf.html#ae838bde232c45d81f88303e91b16326b',1,'pearl-anglescan-panel.ipf']]], - ['bp_5foutput_5fetpi',['bp_output_etpi',['../pearl-anglescan-panel_8ipf.html#a16d2f6a58fedc370d7901126bb814bbb',1,'pearl-anglescan-panel.ipf']]], - ['bp_5foutput_5fitx',['bp_output_itx',['../pearl-anglescan-panel_8ipf.html#a0bdc14f90bdc40045200ac23229b225d',1,'pearl-anglescan-panel.ipf']]], - ['bp_5freset_5fcursors',['bp_reset_cursors',['../pearl-area-display_8ipf.html#a24b17f99fafd8043ed3e4502000da316',1,'pearl-area-display.ipf']]], - ['bp_5fsave_5fgraphs',['bp_save_graphs',['../pearl-elog_8ipf.html#a8251cea45c8d1f1993a4051a6d0760c4',1,'pearl-elog.ipf']]], - ['bp_5fsave_5fprefs',['bp_save_prefs',['../pearl-anglescan-panel_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5',1,'bp_save_prefs(WMButtonAction *ba): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5',1,'bp_save_prefs(WMButtonAction *ba): pearl-data-explorer.ipf']]], - ['bp_5fsource_5fselect',['bp_source_select',['../pearl-anglescan-panel_8ipf.html#a1e50019bc895a0787cb3f07d776e9463',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fsource_5fupdate',['bp_source_update',['../pearl-anglescan-panel_8ipf.html#a7ab3962d1d9d50d6cd285d40d4a7ce50',1,'pearl-anglescan-panel.ipf']]], - ['bp_5fsubmit',['bp_submit',['../pearl-elog_8ipf.html#adeff6678e57313cb218824f06d32b5ec',1,'pearl-elog.ipf']]], - ['bp_5fupdate_5fdatasets',['bp_update_datasets',['../pearl-data-explorer_8ipf.html#af9f8769ca2989f152f23d976d1467a48',1,'pearl-data-explorer.ipf']]], - ['bp_5fupdate_5ffilelist',['bp_update_filelist',['../pearl-data-explorer_8ipf.html#a45be265789a5260e3daa05eca0ec309e',1,'pearl-data-explorer.ipf']]] + ['beforefileopenhook_741',['BeforeFileOpenHook',['../pearl-area-import_8ipf.html#ae2cfa1ac6651cfc3fb0dfce03494995b',1,'BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind): pearl-area-import.ipf'],['../pearl-matrix-import_8ipf.html#ae2cfa1ac6651cfc3fb0dfce03494995b',1,'BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind): pearl-matrix-import.ipf']]], + ['bp_5fattach_742',['bp_attach',['../pearl-elog_8ipf.html#acbba78d869a543edf7c2b80d7a8d2344',1,'pearl-elog.ipf']]], + ['bp_5fattach_5fallnone_743',['bp_attach_allnone',['../pearl-elog_8ipf.html#a4040736819edadf4b26982bcfdb9c7b9',1,'pearl-elog.ipf']]], + ['bp_5fattach_5ftop_744',['bp_attach_top',['../pearl-elog_8ipf.html#a91b5f51982d23a36d1760b8874b5736a',1,'pearl-elog.ipf']]], + ['bp_5fattach_5fupdown_745',['bp_attach_updown',['../pearl-elog_8ipf.html#aa1dfae6d78a367d50ee8fc1ffe9cb69b',1,'pearl-elog.ipf']]], + ['bp_5fattr_5fnotebook_746',['bp_attr_notebook',['../pearl-data-explorer_8ipf.html#a4ef196f752bb5780ed4f4a588f9ebc81',1,'pearl-data-explorer.ipf']]], + ['bp_5fbrowse_5ffilepath_747',['bp_browse_filepath',['../pearl-data-explorer_8ipf.html#a02a64144b7ed2c1bc230e265c55e81a1',1,'pearl-data-explorer.ipf']]], + ['bp_5fcapture_748',['bp_capture',['../pearl-anglescan-tracker_8ipf.html#afaec8443094530fd1e723251e04c5dc9',1,'pearl-anglescan-tracker.ipf']]], + ['bp_5fclear_749',['bp_clear',['../pearl-elog_8ipf.html#ab39637298c93b7aefd67febf3a4e7672',1,'pearl-elog.ipf']]], + ['bp_5fcrop_5fpreview_750',['bp_crop_preview',['../pearl-anglescan-panel_8ipf.html#a57c666f93cb4310fadf13b1916eaf134',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fdisplay_5fdataset_751',['bp_display_dataset',['../pearl-data-explorer_8ipf.html#a0f7473343cf773af9efedee1a18ac5db',1,'pearl-data-explorer.ipf']]], + ['bp_5felog_752',['bp_elog',['../pearl-data-explorer_8ipf.html#a64bd3e5e68b30c94db00c58fa3be3f0d',1,'pearl-data-explorer.ipf']]], + ['bp_5fextract_5fslice_753',['bp_extract_slice',['../pearl-area-display_8ipf.html#a31461b664ec651a39442e9a46ffd88c9',1,'pearl-area-display.ipf']]], + ['bp_5ffile_5fnext_754',['bp_file_next',['../pearl-data-explorer_8ipf.html#a9cefcdc49b2169e99c743b0a683ed3a6',1,'pearl-data-explorer.ipf']]], + ['bp_5ffile_5fprev_755',['bp_file_prev',['../pearl-data-explorer_8ipf.html#a6aa44ff12b8530adbaaaf7405b1a68ba',1,'pearl-data-explorer.ipf']]], + ['bp_5fgoto_5fdataset_756',['bp_goto_dataset',['../pearl-data-explorer_8ipf.html#a01e48e67a22dc56851447bd77abecbe1',1,'pearl-data-explorer.ipf']]], + ['bp_5fgraph_5fpng_757',['bp_graph_png',['../pearl-anglescan-panel_8ipf.html#a9be861636d98d7891e6d106deac2f90b',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fgraph_5fupdate_758',['bp_graph_update',['../pearl-anglescan-panel_8ipf.html#a940f2115fb5b47e19516168d15346472',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fload_5foptions_759',['bp_load_options',['../pearl-data-explorer_8ipf.html#a3fd06ac9aa62de7f00e10ce749ba12c9',1,'pearl-data-explorer.ipf']]], + ['bp_5fload_5fprefs_760',['bp_load_prefs',['../pearl-anglescan-panel_8ipf.html#a1868754e64cb1448e564c0936e78574d',1,'bp_load_prefs(WMButtonAction *ba): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#a1868754e64cb1448e564c0936e78574d',1,'bp_load_prefs(WMButtonAction *ba): pearl-data-explorer.ipf']]], + ['bp_5flogin_761',['bp_login',['../pearl-elog_8ipf.html#a14f8376a0485aa654ccf3d2f30ab4d01',1,'pearl-elog.ipf']]], + ['bp_5flogout_762',['bp_logout',['../pearl-elog_8ipf.html#ad4472ea917691c41ad0b4ea6f36010a5',1,'pearl-elog.ipf']]], + ['bp_5fmove_5fslice_763',['bp_move_slice',['../pearl-area-display_8ipf.html#ab8c9979c6f3ab95f983c2a525a69c035',1,'pearl-area-display.ipf']]], + ['bp_5fmove_5fslice_5fcenter_764',['bp_move_slice_center',['../pearl-area-display_8ipf.html#abe702d40071e3c5e662eb8d47dd6d885',1,'pearl-area-display.ipf']]], + ['bp_5fnorm_5falpha_5fcheck_765',['bp_norm_alpha_check',['../pearl-anglescan-panel_8ipf.html#a630dfc775d45843c71c279bbb01d05a6',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5falpha_5fpreview_766',['bp_norm_alpha_preview',['../pearl-anglescan-panel_8ipf.html#aaaf3facc118f90a8f1b32948446899b3',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5fphi_5fcheck_767',['bp_norm_phi_check',['../pearl-anglescan-panel_8ipf.html#ae42eb7f46e5c1a1b5d334ebb5e94d2d3',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5fphi_5fpreview_768',['bp_norm_phi_preview',['../pearl-anglescan-panel_8ipf.html#a740c8a80ab2fc0550a05cf3b032821d0',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5ftheta_5fcheck_769',['bp_norm_theta_check',['../pearl-anglescan-panel_8ipf.html#a0931ce925d2dae6a1bb7e4a65a8a2be7',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5ftheta_5fpreview_770',['bp_norm_theta_preview',['../pearl-anglescan-panel_8ipf.html#af57abb0a7d41b800d33bb748f9fc5c38',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5fthetaphi_5fcheck_771',['bp_norm_thetaphi_check',['../pearl-anglescan-panel_8ipf.html#a89caab501e8f15262d6e4f2fa5b4a1bd',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fnorm_5fthetaphi_5fpreview_772',['bp_norm_thetaphi_preview',['../pearl-anglescan-panel_8ipf.html#aaa3478a3b0f26b12a12196cfaa87a8ae',1,'pearl-anglescan-panel.ipf']]], + ['bp_5foutput_5fcalc_773',['bp_output_calc',['../pearl-anglescan-panel_8ipf.html#adefddc5f384948c9dab3ee65b4a0668a',1,'pearl-anglescan-panel.ipf']]], + ['bp_5foutput_5fduplicate_774',['bp_output_duplicate',['../pearl-anglescan-panel_8ipf.html#ae838bde232c45d81f88303e91b16326b',1,'pearl-anglescan-panel.ipf']]], + ['bp_5foutput_5fetpi_775',['bp_output_etpi',['../pearl-anglescan-panel_8ipf.html#a16d2f6a58fedc370d7901126bb814bbb',1,'pearl-anglescan-panel.ipf']]], + ['bp_5foutput_5fitx_776',['bp_output_itx',['../pearl-anglescan-panel_8ipf.html#a0bdc14f90bdc40045200ac23229b225d',1,'pearl-anglescan-panel.ipf']]], + ['bp_5freduction_5fparams_777',['bp_reduction_params',['../pearl-data-explorer_8ipf.html#a70150946799d759473b409b3371e3ae2',1,'pearl-data-explorer.ipf']]], + ['bp_5freset_5fcursors_778',['bp_reset_cursors',['../pearl-area-display_8ipf.html#a24b17f99fafd8043ed3e4502000da316',1,'pearl-area-display.ipf']]], + ['bp_5fsave_5fgraphs_779',['bp_save_graphs',['../pearl-elog_8ipf.html#a8251cea45c8d1f1993a4051a6d0760c4',1,'pearl-elog.ipf']]], + ['bp_5fsave_5fprefs_780',['bp_save_prefs',['../pearl-anglescan-panel_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5',1,'bp_save_prefs(WMButtonAction *ba): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#ad8a01428a137278a31d4f1f4f9c634c5',1,'bp_save_prefs(WMButtonAction *ba): pearl-data-explorer.ipf']]], + ['bp_5fsource_5fselect_781',['bp_source_select',['../pearl-anglescan-panel_8ipf.html#a1e50019bc895a0787cb3f07d776e9463',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fsource_5fupdate_782',['bp_source_update',['../pearl-anglescan-panel_8ipf.html#a7ab3962d1d9d50d6cd285d40d4a7ce50',1,'pearl-anglescan-panel.ipf']]], + ['bp_5fsubmit_783',['bp_submit',['../pearl-elog_8ipf.html#adeff6678e57313cb218824f06d32b5ec',1,'pearl-elog.ipf']]], + ['bp_5fupdate_5ffilelist_784',['bp_update_filelist',['../pearl-data-explorer_8ipf.html#a45be265789a5260e3daa05eca0ec309e',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/functions_10.html b/doc/html/search/functions_10.html index 72bc1ea..09422e1 100644 --- a/doc/html/search/functions_10.html +++ b/doc/html/search/functions_10.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_10.js b/doc/html/search/functions_10.js index 81e5645..79cc149 100644 --- a/doc/html/search/functions_10.js +++ b/doc/html/search/functions_10.js @@ -1,15 +1,15 @@ var searchData= [ - ['read_5fattribute_5finfo',['read_attribute_info',['../pearl-area-import_8ipf.html#ac98a5f2d12b559aba4e53192c49a7743',1,'pearl-area-import.ipf']]], - ['record_5fresults',['record_results',['../fermi-edge-analysis_8ipf.html#aac6bac1ee0582caa0676bdc9c2d254f0',1,'fermi-edge-analysis.ipf']]], - ['redim_5flinbg_5freduction',['redim_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a8e2aef3e0d5f2b304399a11423661fdc',1,'pearl-scienta-preprocess.ipf']]], - ['reduce_5fbrick_5fworker',['reduce_brick_worker',['../pearl-area-import_8ipf.html#a4efc9178892310c9e2caf40c61d71bd7',1,'pearl-area-import.ipf']]], - ['reduce_5fslab_5fimage',['reduce_slab_image',['../pearl-area-import_8ipf.html#a44d495fba0dd2b82dec13760a07fd226',1,'reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param): pearl-area-import.ipf'],['../pearl-pshell-import_8ipf.html#a44d495fba0dd2b82dec13760a07fd226',1,'reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param): pearl-pshell-import.ipf']]], - ['reduce_5fslab_5fworker',['reduce_slab_worker',['../pearl-area-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6',1,'reduce_slab_worker(funcref reduction_func): pearl-area-import.ipf'],['../pearl-pshell-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6',1,'reduce_slab_worker(funcref reduction_func): pearl-pshell-import.ipf']]], - ['rotate2d_5fx',['rotate2d_x',['../pearl-vector-operations_8ipf.html#ac579a92f012f0d0ef7b8f097e1c8b3c7',1,'pearl-vector-operations.ipf']]], - ['rotate2d_5fy',['rotate2d_y',['../pearl-vector-operations_8ipf.html#a355150c423ab975fe7f1832917118ea3',1,'pearl-vector-operations.ipf']]], - ['rotate_5fhemi_5fscan',['rotate_hemi_scan',['../pearl-anglescan-process_8ipf.html#a5162488b366e217195d8f8bd7cdde0ce',1,'pearl-anglescan-process.ipf']]], - ['rotate_5fx_5fwave',['rotate_x_wave',['../pearl-vector-operations_8ipf.html#ada80428496dc748b960bd9c65df7da8b',1,'pearl-vector-operations.ipf']]], - ['rotate_5fy_5fwave',['rotate_y_wave',['../pearl-vector-operations_8ipf.html#adfd1d68e739694982fbd00b76568c1c0',1,'pearl-vector-operations.ipf']]], - ['rotate_5fz_5fwave',['rotate_z_wave',['../pearl-vector-operations_8ipf.html#a0030e927980581d57781ad391f2d872a',1,'pearl-vector-operations.ipf']]] + ['read_5fattribute_5finfo_1061',['read_attribute_info',['../pearl-area-import_8ipf.html#ac98a5f2d12b559aba4e53192c49a7743',1,'pearl-area-import.ipf']]], + ['record_5fresults_1062',['record_results',['../fermi-edge-analysis_8ipf.html#aac6bac1ee0582caa0676bdc9c2d254f0',1,'fermi-edge-analysis.ipf']]], + ['redim_5flinbg_5freduction_1063',['redim_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a8e2aef3e0d5f2b304399a11423661fdc',1,'pearl-scienta-preprocess.ipf']]], + ['reduce_5fbrick_5fworker_1064',['reduce_brick_worker',['../pearl-area-import_8ipf.html#a4efc9178892310c9e2caf40c61d71bd7',1,'pearl-area-import.ipf']]], + ['reduce_5fslab_5fimage_1065',['reduce_slab_image',['../pearl-area-import_8ipf.html#a44d495fba0dd2b82dec13760a07fd226',1,'reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param): pearl-area-import.ipf'],['../pearl-pshell-import_8ipf.html#a8089a75744ffc3626305406e925d320a',1,'reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_params): pearl-pshell-import.ipf']]], + ['reduce_5fslab_5fworker_1066',['reduce_slab_worker',['../pearl-area-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6',1,'reduce_slab_worker(funcref reduction_func): pearl-area-import.ipf'],['../pearl-pshell-import_8ipf.html#a33f8faf117450af1d6dae9ef48786cd6',1,'reduce_slab_worker(funcref reduction_func): pearl-pshell-import.ipf']]], + ['rotate2d_5fx_1067',['rotate2d_x',['../pearl-vector-operations_8ipf.html#ac579a92f012f0d0ef7b8f097e1c8b3c7',1,'pearl-vector-operations.ipf']]], + ['rotate2d_5fy_1068',['rotate2d_y',['../pearl-vector-operations_8ipf.html#a355150c423ab975fe7f1832917118ea3',1,'pearl-vector-operations.ipf']]], + ['rotate_5fhemi_5fscan_1069',['rotate_hemi_scan',['../pearl-anglescan-process_8ipf.html#a5162488b366e217195d8f8bd7cdde0ce',1,'pearl-anglescan-process.ipf']]], + ['rotate_5fx_5fwave_1070',['rotate_x_wave',['../pearl-vector-operations_8ipf.html#ada80428496dc748b960bd9c65df7da8b',1,'pearl-vector-operations.ipf']]], + ['rotate_5fy_5fwave_1071',['rotate_y_wave',['../pearl-vector-operations_8ipf.html#adfd1d68e739694982fbd00b76568c1c0',1,'pearl-vector-operations.ipf']]], + ['rotate_5fz_5fwave_1072',['rotate_z_wave',['../pearl-vector-operations_8ipf.html#a0030e927980581d57781ad391f2d872a',1,'pearl-vector-operations.ipf']]] ]; diff --git a/doc/html/search/functions_11.html b/doc/html/search/functions_11.html index 6948a61..1cde7b4 100644 --- a/doc/html/search/functions_11.html +++ b/doc/html/search/functions_11.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_11.js b/doc/html/search/functions_11.js index 5a429cb..8a540b0 100644 --- a/doc/html/search/functions_11.js +++ b/doc/html/search/functions_11.js @@ -1,35 +1,39 @@ var searchData= [ - ['save_5fhemi_5fscan',['save_hemi_scan',['../pearl-anglescan-process_8ipf.html#a48cbd596656bc6d849c53afb4c58b90d',1,'pearl-anglescan-process.ipf']]], - ['save_5fprefs',['save_prefs',['../pearl-anglescan-panel_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-elog.ipf']]], - ['save_5fscan_5fhelper',['save_scan_helper',['../pearl-pmsco-import_8ipf.html#a0a53a4686b482d62fe1797932a1708db',1,'pearl-pmsco-import.ipf']]], - ['save_5ftracker_5fdata',['save_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a8d6e9058f2b0b4978f56e892ce199e6a',1,'pearl-anglescan-tracker.ipf']]], - ['scientalivedisplay',['ScientaLiveDisplay',['../pearl-scienta-countrate_8ipf.html#a55886895329455b36b64d52ed6a4e228',1,'pearl-scienta-countrate.ipf']]], - ['select_5fdataset',['select_dataset',['../pearl-pshell-import_8ipf.html#abb4afdef6ae4476c25a1ff77b17266c3',1,'pearl-pshell-import.ipf']]], - ['set_5fcontrast',['set_contrast',['../pearl-anglescan-process_8ipf.html#a666dab03bb2e97ffef81cea450184d42',1,'pearl-anglescan-process.ipf']]], - ['set_5fpanel_5fattributes',['set_panel_attributes',['../pearl-elog_8ipf.html#a39a1f418c8a2f9a5e4ab976827d8efca',1,'pearl-elog.ipf']]], - ['set_5fpanel_5fgraphs',['set_panel_graphs',['../pearl-elog_8ipf.html#a6eca5f4fab999984df32b50dd669c0b1',1,'pearl-elog.ipf']]], - ['set_5fpanel_5fmessage',['set_panel_message',['../pearl-elog_8ipf.html#aa7a3988440bb6d73573b50a4698a0e75',1,'pearl-elog.ipf']]], - ['set_5fpolar_5fgraph_5fcursor',['set_polar_graph_cursor',['../pearl-anglescan-process_8ipf.html#a70b0e243bcbd549e2b1da74aab605629',1,'pearl-anglescan-process.ipf']]], - ['set_5frotation_5fx',['set_rotation_x',['../pearl-vector-operations_8ipf.html#a8a8dff94d9f7b992c2c2c0744001e74b',1,'pearl-vector-operations.ipf']]], - ['set_5frotation_5fy',['set_rotation_y',['../pearl-vector-operations_8ipf.html#adfdf1cfe8812d8d0006228f6c14c9582',1,'pearl-vector-operations.ipf']]], - ['set_5frotation_5fz',['set_rotation_z',['../pearl-vector-operations_8ipf.html#a76feca10fe5d3e085f01c73a59b38424',1,'pearl-vector-operations.ipf']]], - ['set_5ftrace_5fcolors',['set_trace_colors',['../pearl-area-display_8ipf.html#abafc4f012b04592724109f4757cbe271',1,'pearl-area-display.ipf']]], - ['setup_5fdata',['setup_data',['../pearl-anglescan-tracker_8ipf.html#a6bfd8b6eba0b206df6ec56c7b6489e0b',1,'pearl-anglescan-tracker.ipf']]], - ['setup_5fdetector',['setup_detector',['../pearl-anglescan-tracker_8ipf.html#aa79c1d1584eb2322adae328bf1437f34',1,'pearl-anglescan-tracker.ipf']]], - ['setup_5fgraph',['setup_graph',['../pearl-anglescan-tracker_8ipf.html#aa7c4e3e0ed255e61bc80f8b27b78fce6',1,'pearl-anglescan-tracker.ipf']]], - ['shirleybg',['ShirleyBG',['../pearl-fitfuncs_8ipf.html#af07f887f3ba8e3e35c9214df8bb6a49f',1,'pearl-fitfuncs.ipf']]], - ['show_5fanalyser_5fline',['show_analyser_line',['../pearl-anglescan-process_8ipf.html#a01bac9e7d4ba743c3c34177a05070466',1,'pearl-anglescan-process.ipf']]], - ['show_5fpreview_5fgraph',['show_preview_graph',['../pearl-data-explorer_8ipf.html#a4db79d04c74beb1af71b72916f8f0362',1,'pearl-data-explorer.ipf']]], - ['show_5fshift',['show_shift',['../fermi-edge-analysis_8ipf.html#acf72d644b8d37b6c26b1e070edba4e30',1,'fermi-edge-analysis.ipf']]], - ['showcomponents_5fau4f_5f2p2',['ShowComponents_Au4f_2p2',['../pearl-fitfuncs_8ipf.html#a84a0278284332631682ce032018d1716',1,'pearl-fitfuncs.ipf']]], - ['showcomponents_5fau4f_5f2p3',['ShowComponents_Au4f_2p3',['../pearl-fitfuncs_8ipf.html#a02368cc4adfbd746cd2f1e7d73884a61',1,'pearl-fitfuncs.ipf']]], - ['slit_5fcorrection',['slit_correction',['../fermi-edge-analysis_8ipf.html#a4cec596c8fd2b21953cb45d6d347211d',1,'fermi-edge-analysis.ipf']]], - ['slit_5fshift',['slit_shift',['../fermi-edge-analysis_8ipf.html#a27f000c3a3ea74c49db31716be3396d4',1,'fermi-edge-analysis.ipf']]], - ['slp_5fslice_5fposition',['slp_slice_position',['../pearl-area-display_8ipf.html#ace169e0824e6bddbd646972946edccbe',1,'pearl-area-display.ipf']]], - ['strip_5fdelete_5fframes',['strip_delete_frames',['../pearl-anglescan-process_8ipf.html#a13e0d37ae23f68cdc5da3d84cb4beed8',1,'pearl-anglescan-process.ipf']]], - ['subtract_5fline_5fbg',['subtract_line_bg',['../pearl-matrix-import_8ipf.html#ab80101bc780dcbe94200e2446bce51d9',1,'pearl-matrix-import.ipf']]], - ['sumwavesiterator',['SumWavesIterator',['../pearl-tools_8ipf.html#aea193a1b5fbdbb2a5dec9f25f3c05c45',1,'pearl-tools.ipf']]], - ['svp_5fslice_5fposition',['svp_slice_position',['../pearl-area-display_8ipf.html#a174177742fdce7f37027de8fa832b3bd',1,'pearl-area-display.ipf']]], - ['svp_5fsmoothing',['svp_smoothing',['../pearl-area-display_8ipf.html#ab10a0d94991b9cd958557dbc48d70624',1,'pearl-area-display.ipf']]] + ['save_5fhemi_5fscan_1073',['save_hemi_scan',['../pearl-anglescan-process_8ipf.html#a48cbd596656bc6d849c53afb4c58b90d',1,'pearl-anglescan-process.ipf']]], + ['save_5fprefs_1074',['save_prefs',['../pearl-anglescan-panel_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#ac729557a307bddd2f2ad298199976c01',1,'save_prefs(): pearl-elog.ipf']]], + ['save_5fscan_5fhelper_1075',['save_scan_helper',['../pearl-pmsco-import_8ipf.html#a0a53a4686b482d62fe1797932a1708db',1,'pearl-pmsco-import.ipf']]], + ['save_5ftracker_5fdata_1076',['save_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a8d6e9058f2b0b4978f56e892ce199e6a',1,'pearl-anglescan-tracker.ipf']]], + ['scientalivedisplay_1077',['ScientaLiveDisplay',['../pearl-scienta-live_8ipf.html#a55886895329455b36b64d52ed6a4e228',1,'pearl-scienta-live.ipf']]], + ['selected_5ffile_1078',['selected_file',['../pearl-data-explorer_8ipf.html#ac477142f1949dc32d86663f1de4384e5',1,'pearl-data-explorer.ipf']]], + ['send_5fto_5felog_1079',['send_to_elog',['../pearl-data-explorer_8ipf.html#aac8d96d9ccaeddab1cb0f463b01616cb',1,'pearl-data-explorer.ipf']]], + ['set_5fcontrast_1080',['set_contrast',['../pearl-anglescan-process_8ipf.html#af9874b5c1ce1d216741c7880a5fdcfcc',1,'pearl-anglescan-process.ipf']]], + ['set_5felog_5fattributes_1081',['set_elog_attributes',['../pearl-data-explorer_8ipf.html#a93c61109535e1644f5e53aabb895b48a',1,'pearl-data-explorer.ipf']]], + ['set_5fpanel_5fattributes_1082',['set_panel_attributes',['../pearl-elog_8ipf.html#a39a1f418c8a2f9a5e4ab976827d8efca',1,'pearl-elog.ipf']]], + ['set_5fpanel_5fgraphs_1083',['set_panel_graphs',['../pearl-elog_8ipf.html#a6eca5f4fab999984df32b50dd669c0b1',1,'pearl-elog.ipf']]], + ['set_5fpanel_5fmessage_1084',['set_panel_message',['../pearl-elog_8ipf.html#aa7a3988440bb6d73573b50a4698a0e75',1,'pearl-elog.ipf']]], + ['set_5fpolar_5fgraph_5fcursor_1085',['set_polar_graph_cursor',['../pearl-anglescan-process_8ipf.html#a70b0e243bcbd549e2b1da74aab605629',1,'pearl-anglescan-process.ipf']]], + ['set_5frotation_5fx_1086',['set_rotation_x',['../pearl-vector-operations_8ipf.html#a8a8dff94d9f7b992c2c2c0744001e74b',1,'pearl-vector-operations.ipf']]], + ['set_5frotation_5fy_1087',['set_rotation_y',['../pearl-vector-operations_8ipf.html#adfdf1cfe8812d8d0006228f6c14c9582',1,'pearl-vector-operations.ipf']]], + ['set_5frotation_5fz_1088',['set_rotation_z',['../pearl-vector-operations_8ipf.html#a76feca10fe5d3e085f01c73a59b38424',1,'pearl-vector-operations.ipf']]], + ['set_5ftrace_5fcolors_1089',['set_trace_colors',['../pearl-area-display_8ipf.html#abafc4f012b04592724109f4757cbe271',1,'pearl-area-display.ipf']]], + ['setup_5fdata_1090',['setup_data',['../pearl-anglescan-tracker_8ipf.html#a6bfd8b6eba0b206df6ec56c7b6489e0b',1,'pearl-anglescan-tracker.ipf']]], + ['setup_5fdetector_1091',['setup_detector',['../pearl-anglescan-tracker_8ipf.html#aa79c1d1584eb2322adae328bf1437f34',1,'pearl-anglescan-tracker.ipf']]], + ['setup_5fgraph_1092',['setup_graph',['../pearl-anglescan-tracker_8ipf.html#aa7c4e3e0ed255e61bc80f8b27b78fce6',1,'pearl-anglescan-tracker.ipf']]], + ['shirleybg_1093',['ShirleyBG',['../pearl-fitfuncs_8ipf.html#af07f887f3ba8e3e35c9214df8bb6a49f',1,'pearl-fitfuncs.ipf']]], + ['shorten_5ffilepath_1094',['shorten_filepath',['../pearl-data-explorer_8ipf.html#a00307dffd6f272f13acfe4dea99a81d4',1,'pearl-data-explorer.ipf']]], + ['show_5fanalyser_5fline_1095',['show_analyser_line',['../pearl-anglescan-process_8ipf.html#a01bac9e7d4ba743c3c34177a05070466',1,'pearl-anglescan-process.ipf']]], + ['show_5fpreview_5fgraph_1096',['show_preview_graph',['../pearl-data-explorer_8ipf.html#a4db79d04c74beb1af71b72916f8f0362',1,'pearl-data-explorer.ipf']]], + ['show_5fshift_1097',['show_shift',['../fermi-edge-analysis_8ipf.html#acf72d644b8d37b6c26b1e070edba4e30',1,'fermi-edge-analysis.ipf']]], + ['showcomponents_5fau4f_5f2p2_1098',['ShowComponents_Au4f_2p2',['../pearl-fitfuncs_8ipf.html#a84a0278284332631682ce032018d1716',1,'pearl-fitfuncs.ipf']]], + ['showcomponents_5fau4f_5f2p3_1099',['ShowComponents_Au4f_2p3',['../pearl-fitfuncs_8ipf.html#a02368cc4adfbd746cd2f1e7d73884a61',1,'pearl-fitfuncs.ipf']]], + ['slit_5fcorrection_1100',['slit_correction',['../fermi-edge-analysis_8ipf.html#a4cec596c8fd2b21953cb45d6d347211d',1,'fermi-edge-analysis.ipf']]], + ['slit_5fshift_1101',['slit_shift',['../fermi-edge-analysis_8ipf.html#a27f000c3a3ea74c49db31716be3396d4',1,'fermi-edge-analysis.ipf']]], + ['slp_5fslice_5fposition_1102',['slp_slice_position',['../pearl-area-display_8ipf.html#ace169e0824e6bddbd646972946edccbe',1,'pearl-area-display.ipf']]], + ['strip_5fappend_1103',['strip_append',['../pearl-anglescan-process_8ipf.html#ab97a936bc0fa6137b6d0b43cb61d39a1',1,'pearl-anglescan-process.ipf']]], + ['strip_5fdelete_5fframes_1104',['strip_delete_frames',['../pearl-anglescan-process_8ipf.html#a13e0d37ae23f68cdc5da3d84cb4beed8',1,'pearl-anglescan-process.ipf']]], + ['subtract_5fline_5fbg_1105',['subtract_line_bg',['../pearl-matrix-import_8ipf.html#ab80101bc780dcbe94200e2446bce51d9',1,'pearl-matrix-import.ipf']]], + ['sumwavesiterator_1106',['SumWavesIterator',['../pearl-tools_8ipf.html#aea193a1b5fbdbb2a5dec9f25f3c05c45',1,'pearl-tools.ipf']]], + ['svp_5fslice_5fposition_1107',['svp_slice_position',['../pearl-area-display_8ipf.html#a174177742fdce7f37027de8fa832b3bd',1,'pearl-area-display.ipf']]], + ['svp_5fsmoothing_1108',['svp_smoothing',['../pearl-area-display_8ipf.html#ab10a0d94991b9cd958557dbc48d70624',1,'pearl-area-display.ipf']]] ]; diff --git a/doc/html/search/functions_12.html b/doc/html/search/functions_12.html index 3df8489..48e5915 100644 --- a/doc/html/search/functions_12.html +++ b/doc/html/search/functions_12.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_12.js b/doc/html/search/functions_12.js index b40bbe8..34ae0f9 100644 --- a/doc/html/search/functions_12.js +++ b/doc/html/search/functions_12.js @@ -1,8 +1,8 @@ var searchData= [ - ['test_5fattributes_5fnotebook',['test_attributes_notebook',['../pearl-data-explorer_8ipf.html#a71f9c277d310c3f4e7739be69dad0ab5',1,'pearl-data-explorer.ipf']]], - ['test_5fgauss4_5freduction',['test_gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#adb78e8b2bbfd9c0faa5eb049b1dcad1c',1,'pearl-scienta-preprocess.ipf']]], - ['toggle_5fcapture',['toggle_capture',['../pearl-anglescan-tracker_8ipf.html#a02987fe03ea914a53c52d58219979d65',1,'pearl-anglescan-tracker.ipf']]], - ['trim_5fhemi_5fscan',['trim_hemi_scan',['../pearl-anglescan-process_8ipf.html#a5dc0cc7db9d3d7a6b3fa3f1b04d84a5e',1,'pearl-anglescan-process.ipf']]], - ['twave2list',['twave2list',['../pearl-pshell-import_8ipf.html#a92a18d6e81c3f521ba3bb240eaf578a9',1,'pearl-pshell-import.ipf']]] + ['test_5fattributes_5fnotebook_1109',['test_attributes_notebook',['../pearl-data-explorer_8ipf.html#a71f9c277d310c3f4e7739be69dad0ab5',1,'pearl-data-explorer.ipf']]], + ['test_5fgauss4_5freduction_1110',['test_gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#adb78e8b2bbfd9c0faa5eb049b1dcad1c',1,'pearl-scienta-preprocess.ipf']]], + ['toggle_5fcapture_1111',['toggle_capture',['../pearl-anglescan-tracker_8ipf.html#a02987fe03ea914a53c52d58219979d65',1,'pearl-anglescan-tracker.ipf']]], + ['trim_5fhemi_5fscan_1112',['trim_hemi_scan',['../pearl-anglescan-process_8ipf.html#a5dc0cc7db9d3d7a6b3fa3f1b04d84a5e',1,'pearl-anglescan-process.ipf']]], + ['twave2list_1113',['twave2list',['../pearl-pshell-import_8ipf.html#a92a18d6e81c3f521ba3bb240eaf578a9',1,'pearl-pshell-import.ipf']]] ]; diff --git a/doc/html/search/functions_13.html b/doc/html/search/functions_13.html index febf8e0..f1fc553 100644 --- a/doc/html/search/functions_13.html +++ b/doc/html/search/functions_13.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_13.js b/doc/html/search/functions_13.js index efa315e..32fdcae 100644 --- a/doc/html/search/functions_13.js +++ b/doc/html/search/functions_13.js @@ -1,15 +1,17 @@ var searchData= [ - ['unloadpearlarpespackage',['UnloadPearlArpesPackage',['../pearl-arpes_8ipf.html#ac41f24572943dac2b40c255797a6c7a8',1,'pearl-arpes.ipf']]], - ['update_5fattach_5fitems',['update_attach_items',['../pearl-elog_8ipf.html#a9c1cfd320e88e84dcf4f84bbcf3f46a5',1,'pearl-elog.ipf']]], - ['update_5fcapture',['update_capture',['../pearl-anglescan-tracker_8ipf.html#a9751db419b4c0de884450c09ff5822a7',1,'pearl-anglescan-tracker.ipf']]], - ['update_5fdata_5fgraph',['update_data_graph',['../pearl-anglescan-tracker_8ipf.html#a0b8ff36cf3c20b1c0db3217d9065f7cf',1,'pearl-anglescan-tracker.ipf']]], - ['update_5fdatasets',['update_datasets',['../pearl-data-explorer_8ipf.html#ad50f4c430d8bfe0fb5a1356cd9b84bf4',1,'pearl-data-explorer.ipf']]], - ['update_5fdetector',['update_detector',['../pearl-anglescan-tracker_8ipf.html#ab961340af09fed4d2006bca8c0f2edd5',1,'pearl-anglescan-tracker.ipf']]], - ['update_5fdetector_5fgraph',['update_detector_graph',['../pearl-anglescan-tracker_8ipf.html#af5a2960c49626f267fbd2873b27c8e42',1,'pearl-anglescan-tracker.ipf']]], - ['update_5ffilelist',['update_filelist',['../pearl-data-explorer_8ipf.html#a04cc0b9d5e3a649ba3514fcbf126eefe',1,'pearl-data-explorer.ipf']]], - ['update_5fmenus',['update_menus',['../pearl-anglescan-panel_8ipf.html#a7ddecbeeaee3f9da87ac1ecdc26f530b',1,'pearl-anglescan-panel.ipf']]], - ['update_5fpolar_5finfo',['update_polar_info',['../pearl-anglescan-process_8ipf.html#a1baaa3ffd9495ed427b43cbfe6e1edf8',1,'pearl-anglescan-process.ipf']]], - ['update_5fprogress_5fpanel',['update_progress_panel',['../pearl-gui-tools_8ipf.html#a97ad19d83cf0007c4bcf97a32164610f',1,'pearl-gui-tools.ipf']]], - ['update_5fslice_5finfo',['update_slice_info',['../pearl-area-display_8ipf.html#a2442bc044aaa12ab817a5f9fa300d1f8',1,'pearl-area-display.ipf']]] + ['unique_5fstrings_1114',['unique_strings',['../pearl-pshell-import_8ipf.html#ae2aedcb7028cccdb683c43411cc8f1e2',1,'pearl-pshell-import.ipf']]], + ['unloadpearlarpespackage_1115',['UnloadPearlArpesPackage',['../pearl-arpes_8ipf.html#ac41f24572943dac2b40c255797a6c7a8',1,'pearl-arpes.ipf']]], + ['update_5fattach_5fitems_1116',['update_attach_items',['../pearl-elog_8ipf.html#a9c1cfd320e88e84dcf4f84bbcf3f46a5',1,'pearl-elog.ipf']]], + ['update_5fcapture_1117',['update_capture',['../pearl-anglescan-tracker_8ipf.html#a9751db419b4c0de884450c09ff5822a7',1,'pearl-anglescan-tracker.ipf']]], + ['update_5fcontrols_1118',['update_controls',['../pearl-data-explorer_8ipf.html#a57e21bffee4cd64f2ea1efd9cc958bf1',1,'pearl-data-explorer.ipf']]], + ['update_5fdata_5fgraph_1119',['update_data_graph',['../pearl-anglescan-tracker_8ipf.html#a0b8ff36cf3c20b1c0db3217d9065f7cf',1,'pearl-anglescan-tracker.ipf']]], + ['update_5fdetector_1120',['update_detector',['../pearl-anglescan-tracker_8ipf.html#ab961340af09fed4d2006bca8c0f2edd5',1,'pearl-anglescan-tracker.ipf']]], + ['update_5fdetector_5fgraph_1121',['update_detector_graph',['../pearl-anglescan-tracker_8ipf.html#af5a2960c49626f267fbd2873b27c8e42',1,'pearl-anglescan-tracker.ipf']]], + ['update_5ffilelist_1122',['update_filelist',['../pearl-data-explorer_8ipf.html#a04cc0b9d5e3a649ba3514fcbf126eefe',1,'pearl-data-explorer.ipf']]], + ['update_5ffilepath_1123',['update_filepath',['../pearl-data-explorer_8ipf.html#ae02b954d90dc8f43c007cc3fb1a1ee16',1,'pearl-data-explorer.ipf']]], + ['update_5fmenus_1124',['update_menus',['../pearl-anglescan-panel_8ipf.html#a7ddecbeeaee3f9da87ac1ecdc26f530b',1,'pearl-anglescan-panel.ipf']]], + ['update_5fpolar_5finfo_1125',['update_polar_info',['../pearl-anglescan-process_8ipf.html#a1baaa3ffd9495ed427b43cbfe6e1edf8',1,'pearl-anglescan-process.ipf']]], + ['update_5fprogress_5fpanel_1126',['update_progress_panel',['../pearl-gui-tools_8ipf.html#a97ad19d83cf0007c4bcf97a32164610f',1,'pearl-gui-tools.ipf']]], + ['update_5fslice_5finfo_1127',['update_slice_info',['../pearl-area-display_8ipf.html#a2442bc044aaa12ab817a5f9fa300d1f8',1,'pearl-area-display.ipf']]] ]; diff --git a/doc/html/search/functions_14.html b/doc/html/search/functions_14.html index 4c814f5..0302cd9 100644 --- a/doc/html/search/functions_14.html +++ b/doc/html/search/functions_14.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_14.js b/doc/html/search/functions_14.js index d62da80..980877a 100644 --- a/doc/html/search/functions_14.js +++ b/doc/html/search/functions_14.js @@ -1,4 +1,4 @@ var searchData= [ - ['wave2list',['wave2list',['../pearl-pshell-import_8ipf.html#aa6dc3e3f7dc1ca4346132635a90fc447',1,'pearl-pshell-import.ipf']]] + ['wave2list_1128',['wave2list',['../pearl-pshell-import_8ipf.html#aa6dc3e3f7dc1ca4346132635a90fc447',1,'pearl-pshell-import.ipf']]] ]; diff --git a/doc/html/search/functions_2.html b/doc/html/search/functions_2.html index ecce2f3..2737c5a 100644 --- a/doc/html/search/functions_2.html +++ b/doc/html/search/functions_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_2.js b/doc/html/search/functions_2.js index 7283f5a..d37d345 100644 --- a/doc/html/search/functions_2.js +++ b/doc/html/search/functions_2.js @@ -1,33 +1,34 @@ var searchData= [ - ['calc_5fdoniachsunjicbroad',['Calc_DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#aff8e8b103c32c8e723b57ce7ad5ef0f5',1,'pearl-fitfuncs.ipf']]], - ['calc_5fgraph_5fazi',['calc_graph_azi',['../pearl-anglescan-process_8ipf.html#a4fc744e24e3e9c5efb17f14ab622bcae',1,'pearl-anglescan-process.ipf']]], - ['calc_5fgraph_5fpolar',['calc_graph_polar',['../pearl-anglescan-process_8ipf.html#ae2b036a06ffac8d2bb292a65401f8a9a',1,'pearl-anglescan-process.ipf']]], - ['calc_5fgraph_5fradius',['calc_graph_radius',['../pearl-anglescan-process_8ipf.html#a75219b38ea58012abcffc848d536faa4',1,'pearl-anglescan-process.ipf']]], - ['calc_5fnth',['calc_nth',['../pearl-anglescan-process_8ipf.html#a9624070f3e938378631432430d47a389',1,'pearl-anglescan-process.ipf']]], - ['calc_5fphi_5fstep',['calc_phi_step',['../pearl-anglescan-process_8ipf.html#a999a9cd7d00d3e1ec8e768228a664ad1',1,'pearl-anglescan-process.ipf']]], - ['calc_5fthe_5fstep',['Calc_The_step',['../pearl-anglescan-process_8ipf.html#a1fb6aa7870dfbf0ed92660b7aae579e0',1,'pearl-anglescan-process.ipf']]], - ['calc_5fy_5fprofile_5fmins',['calc_y_profile_mins',['../pearl-area-profiles_8ipf.html#ab58b7c0a88743ecbcb0fc8296577a792',1,'pearl-area-profiles.ipf']]], - ['calcn_5ftheta',['CalcN_Theta',['../pearl-anglescan-process_8ipf.html#ac0def1ded61f9cd758df0c99f4ff9470',1,'pearl-anglescan-process.ipf']]], - ['capture_5fint_5flinbg_5fcursors',['capture_int_linbg_cursors',['../pearl-scienta-preprocess_8ipf.html#ae6877c51ad15c2ba8a69c65356cb34b8',1,'pearl-scienta-preprocess.ipf']]], - ['cart2polar',['cart2polar',['../pearl-polar-coordinates_8ipf.html#aca0a5aaa4854d83ef667c53007312fb8',1,'pearl-polar-coordinates.ipf']]], - ['cart2polar_5fwave',['cart2polar_wave',['../pearl-polar-coordinates_8ipf.html#adfc1f0b3cddf672b0ccdb6a22b97ba9e',1,'pearl-polar-coordinates.ipf']]], - ['check_5fcontrast',['check_contrast',['../pearl-anglescan-process_8ipf.html#a2e1ed05781f9eb4be5e77695ef049962',1,'pearl-anglescan-process.ipf']]], - ['check_5fexposure_5fopt',['check_exposure_opt',['../pearl-scienta-countrate_8ipf.html#af2879284b1d1397447a31733fddd6273',1,'pearl-scienta-countrate.ipf']]], - ['check_5fnorm_5falpha',['check_norm_alpha',['../pearl-anglescan-panel_8ipf.html#af5435ccaabba78f855b244929dc09ed0',1,'pearl-anglescan-panel.ipf']]], - ['check_5fnorm_5fphi',['check_norm_phi',['../pearl-anglescan-panel_8ipf.html#a91d5343cc96730de12b535cb0bef9df2',1,'pearl-anglescan-panel.ipf']]], - ['check_5fnorm_5ftheta',['check_norm_theta',['../pearl-anglescan-panel_8ipf.html#addddc12e5b622a3d00756d724e5d05a9',1,'pearl-anglescan-panel.ipf']]], - ['check_5fnorm_5fthetaphi',['check_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#a4708e7385790d1a9f2d58c4d64a60653',1,'pearl-anglescan-panel.ipf']]], - ['check_5fpackage_5ffolder',['check_package_folder',['../pearl-matrix-import_8ipf.html#ac7790f06151821678a65ab0065a5323e',1,'pearl-matrix-import.ipf']]], - ['cleanup_5ftemp_5ffiles',['cleanup_temp_files',['../pearl-elog_8ipf.html#ad7640d06f004ecd4a8980ea29d24dcbe',1,'pearl-elog.ipf']]], - ['clear_5fhemi_5fgrid',['clear_hemi_grid',['../pearl-anglescan-process_8ipf.html#a3ec6935a5903d0974c93a2072d743013',1,'pearl-anglescan-process.ipf']]], - ['convert_5fangles_5fttpa2polar',['convert_angles_ttpa2polar',['../pearl-anglescan-process_8ipf.html#a3cc7eddf5c6b0658260cfb32dd2c026d',1,'pearl-anglescan-process.ipf']]], - ['convert_5fangles_5fttpd2polar',['convert_angles_ttpd2polar',['../pearl-anglescan-process_8ipf.html#a2b38c6c9b6e60593ba69d3773b6bc779',1,'pearl-anglescan-process.ipf']]], - ['create_5fcmd_5ffile',['create_cmd_file',['../pearl-elog_8ipf.html#ac8b61eefed231018cc36d47e95bd8c22',1,'pearl-elog.ipf']]], - ['create_5fgraph_5ffile',['create_graph_file',['../pearl-elog_8ipf.html#a2417d079483f773f8231c5f2caba6cf0',1,'pearl-elog.ipf']]], - ['create_5fmessage_5ffile',['create_message_file',['../pearl-elog_8ipf.html#af652f6f257be1ee749fe788d1b03f75f',1,'pearl-elog.ipf']]], - ['create_5frotation_5fmatrix_5ffree',['create_rotation_matrix_free',['../pearl-vector-operations_8ipf.html#a72c3200a7344c708ea76e20cc2c19c43',1,'pearl-vector-operations.ipf']]], - ['crop_5fstrip',['crop_strip',['../pearl-anglescan-process_8ipf.html#ab65d25af7476ed18f7bf7359614a912b',1,'pearl-anglescan-process.ipf']]], - ['crop_5fstrip_5ftheta',['crop_strip_theta',['../pearl-anglescan-process_8ipf.html#aa79c0ff6073bd42e202b9fa3f8c00b9f',1,'pearl-anglescan-process.ipf']]], - ['csr_5fint_5flinbg_5freduction',['csr_int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a95fbd22f52f61d2bff0625b7b8e159d1',1,'pearl-scienta-preprocess.ipf']]] + ['calc_5fdoniachsunjicbroad_785',['Calc_DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#aff8e8b103c32c8e723b57ce7ad5ef0f5',1,'pearl-fitfuncs.ipf']]], + ['calc_5fgraph_5fazi_786',['calc_graph_azi',['../pearl-anglescan-process_8ipf.html#a4fc744e24e3e9c5efb17f14ab622bcae',1,'pearl-anglescan-process.ipf']]], + ['calc_5fgraph_5fpolar_787',['calc_graph_polar',['../pearl-anglescan-process_8ipf.html#ae2b036a06ffac8d2bb292a65401f8a9a',1,'pearl-anglescan-process.ipf']]], + ['calc_5fgraph_5fradius_788',['calc_graph_radius',['../pearl-anglescan-process_8ipf.html#a75219b38ea58012abcffc848d536faa4',1,'pearl-anglescan-process.ipf']]], + ['calc_5fnth_789',['calc_nth',['../pearl-anglescan-process_8ipf.html#a9624070f3e938378631432430d47a389',1,'pearl-anglescan-process.ipf']]], + ['calc_5fphi_5fstep_790',['calc_phi_step',['../pearl-anglescan-process_8ipf.html#a999a9cd7d00d3e1ec8e768228a664ad1',1,'pearl-anglescan-process.ipf']]], + ['calc_5fthe_5fstep_791',['Calc_The_step',['../pearl-anglescan-process_8ipf.html#a1fb6aa7870dfbf0ed92660b7aae579e0',1,'pearl-anglescan-process.ipf']]], + ['calc_5fy_5fprofile_5fmins_792',['calc_y_profile_mins',['../pearl-area-profiles_8ipf.html#ab58b7c0a88743ecbcb0fc8296577a792',1,'pearl-area-profiles.ipf']]], + ['calcn_5ftheta_793',['CalcN_Theta',['../pearl-anglescan-process_8ipf.html#ac0def1ded61f9cd758df0c99f4ff9470',1,'pearl-anglescan-process.ipf']]], + ['capture_5fint_5flinbg_5fcursors_794',['capture_int_linbg_cursors',['../pearl-scienta-preprocess_8ipf.html#ae6877c51ad15c2ba8a69c65356cb34b8',1,'pearl-scienta-preprocess.ipf']]], + ['cart2polar_795',['cart2polar',['../pearl-polar-coordinates_8ipf.html#aca0a5aaa4854d83ef667c53007312fb8',1,'pearl-polar-coordinates.ipf']]], + ['cart2polar_5fwave_796',['cart2polar_wave',['../pearl-polar-coordinates_8ipf.html#adfc1f0b3cddf672b0ccdb6a22b97ba9e',1,'pearl-polar-coordinates.ipf']]], + ['check_5fcontrast_797',['check_contrast',['../pearl-anglescan-process_8ipf.html#a67d53a1c362d7e5bbeccf1c9c12ae0c2',1,'pearl-anglescan-process.ipf']]], + ['check_5fexposure_5fopt_798',['check_exposure_opt',['../pearl-scienta-live_8ipf.html#af2879284b1d1397447a31733fddd6273',1,'pearl-scienta-live.ipf']]], + ['check_5fnorm_5falpha_799',['check_norm_alpha',['../pearl-anglescan-panel_8ipf.html#af5435ccaabba78f855b244929dc09ed0',1,'pearl-anglescan-panel.ipf']]], + ['check_5fnorm_5fphi_800',['check_norm_phi',['../pearl-anglescan-panel_8ipf.html#a91d5343cc96730de12b535cb0bef9df2',1,'pearl-anglescan-panel.ipf']]], + ['check_5fnorm_5ftheta_801',['check_norm_theta',['../pearl-anglescan-panel_8ipf.html#addddc12e5b622a3d00756d724e5d05a9',1,'pearl-anglescan-panel.ipf']]], + ['check_5fnorm_5fthetaphi_802',['check_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#a4708e7385790d1a9f2d58c4d64a60653',1,'pearl-anglescan-panel.ipf']]], + ['check_5fpackage_5ffolder_803',['check_package_folder',['../pearl-matrix-import_8ipf.html#ac7790f06151821678a65ab0065a5323e',1,'pearl-matrix-import.ipf']]], + ['cleanup_5ftemp_5ffiles_804',['cleanup_temp_files',['../pearl-elog_8ipf.html#ad7640d06f004ecd4a8980ea29d24dcbe',1,'pearl-elog.ipf']]], + ['clear_5fhemi_5fgrid_805',['clear_hemi_grid',['../pearl-anglescan-process_8ipf.html#a3ec6935a5903d0974c93a2072d743013',1,'pearl-anglescan-process.ipf']]], + ['convert_5fangles_5fttpa2polar_806',['convert_angles_ttpa2polar',['../pearl-anglescan-process_8ipf.html#a3cc7eddf5c6b0658260cfb32dd2c026d',1,'pearl-anglescan-process.ipf']]], + ['convert_5fangles_5fttpd2polar_807',['convert_angles_ttpd2polar',['../pearl-anglescan-process_8ipf.html#a2b38c6c9b6e60593ba69d3773b6bc779',1,'pearl-anglescan-process.ipf']]], + ['create_5fattributes_5fnotebook_808',['create_attributes_notebook',['../pearl-data-explorer_8ipf.html#a77047115739da6d28055f7fd44c9fd2c',1,'pearl-data-explorer.ipf']]], + ['create_5fcmd_5ffile_809',['create_cmd_file',['../pearl-elog_8ipf.html#ac8b61eefed231018cc36d47e95bd8c22',1,'pearl-elog.ipf']]], + ['create_5fgraph_5ffile_810',['create_graph_file',['../pearl-elog_8ipf.html#a2417d079483f773f8231c5f2caba6cf0',1,'pearl-elog.ipf']]], + ['create_5fmessage_5ffile_811',['create_message_file',['../pearl-elog_8ipf.html#af652f6f257be1ee749fe788d1b03f75f',1,'pearl-elog.ipf']]], + ['create_5frotation_5fmatrix_5ffree_812',['create_rotation_matrix_free',['../pearl-vector-operations_8ipf.html#a72c3200a7344c708ea76e20cc2c19c43',1,'pearl-vector-operations.ipf']]], + ['crop_5fstrip_813',['crop_strip',['../pearl-anglescan-process_8ipf.html#ab65d25af7476ed18f7bf7359614a912b',1,'pearl-anglescan-process.ipf']]], + ['crop_5fstrip_5ftheta_814',['crop_strip_theta',['../pearl-anglescan-process_8ipf.html#aa79c0ff6073bd42e202b9fa3f8c00b9f',1,'pearl-anglescan-process.ipf']]], + ['csr_5fint_5flinbg_5freduction_815',['csr_int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a95fbd22f52f61d2bff0625b7b8e159d1',1,'pearl-scienta-preprocess.ipf']]] ]; diff --git a/doc/html/search/functions_3.html b/doc/html/search/functions_3.html index 15f06ab..6da86e7 100644 --- a/doc/html/search/functions_3.html +++ b/doc/html/search/functions_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_3.js b/doc/html/search/functions_3.js index 8bd531a..dd0160a 100644 --- a/doc/html/search/functions_3.js +++ b/doc/html/search/functions_3.js @@ -1,32 +1,33 @@ var searchData= [ - ['defaultfolderiterator',['DefaultFolderIterator',['../pearl-tools_8ipf.html#a3fb8c06030dc41a599380150807caeb0',1,'pearl-tools.ipf']]], - ['defaultwaveiterator',['DefaultWaveIterator',['../pearl-tools_8ipf.html#a6bdd1c0b269f1d7d99843ce0cb218cc7',1,'pearl-tools.ipf']]], - ['delete_5frows',['delete_rows',['../pearl-anglescan-panel_8ipf.html#a16424e5787967d9c120fb09c7849956e',1,'pearl-anglescan-panel.ipf']]], - ['display2dprofiles',['Display2dProfiles',['../pearl-menu_8ipf.html#aad7d768680c6d8a9b8a7025c7e1ec75d',1,'pearl-menu.ipf']]], - ['display3dslicer',['Display3dSlicer',['../pearl-menu_8ipf.html#ac73a94f760455f19294a9f917b43f145',1,'pearl-menu.ipf']]], - ['display_5fdataset',['display_dataset',['../pearl-data-explorer_8ipf.html#ae79a57a41c734ce8836f427b81011b5d',1,'pearl-data-explorer.ipf']]], - ['display_5fhemi_5fscan',['display_hemi_scan',['../pearl-anglescan-process_8ipf.html#ae57302acfc822c4817f2b7eef55efea2',1,'pearl-anglescan-process.ipf']]], - ['display_5fpolar_5fgraph',['display_polar_graph',['../pearl-anglescan-process_8ipf.html#a46fd99d35a43601c39af6096d4e4f770',1,'pearl-anglescan-process.ipf']]], - ['display_5fpreview_5ftrace',['display_preview_trace',['../pearl-data-explorer_8ipf.html#a001074020ad32b290d390a450a389c69',1,'pearl-data-explorer.ipf']]], - ['display_5fprogress_5fpanel',['display_progress_panel',['../pearl-gui-tools_8ipf.html#aaf29d090c81e00cf44af295193b24c5a',1,'pearl-gui-tools.ipf']]], - ['display_5fscanlines',['display_scanlines',['../pearl-anglescan-process_8ipf.html#a1f4f74a8ae557c56e1e3aacd0b45f3f1',1,'pearl-anglescan-process.ipf']]], - ['displaygizmoslicer',['DisplayGizmoSlicer',['../pearl-menu_8ipf.html#aab34952c2f3b36f9ee8619eb901ff581',1,'pearl-menu.ipf']]], - ['do_5fcrop',['do_crop',['../pearl-anglescan-panel_8ipf.html#af39609fc80e58f2188b3aa564f53b750',1,'pearl-anglescan-panel.ipf']]], - ['do_5finit_5fprocess',['do_init_process',['../pearl-anglescan-panel_8ipf.html#a1836e607851ba4d5a4048f4cfb8121a7',1,'pearl-anglescan-panel.ipf']]], - ['do_5fnorm_5falpha',['do_norm_alpha',['../pearl-anglescan-panel_8ipf.html#a8f7266ac2840155dede704fda66fe6b0',1,'pearl-anglescan-panel.ipf']]], - ['do_5fnorm_5fphi',['do_norm_phi',['../pearl-anglescan-panel_8ipf.html#a790519191391ac03c75eb7b57ea0749e',1,'pearl-anglescan-panel.ipf']]], - ['do_5fnorm_5ftheta',['do_norm_theta',['../pearl-anglescan-panel_8ipf.html#a7b288598e3faa37e414b1443982c1a3e',1,'pearl-anglescan-panel.ipf']]], - ['do_5fnorm_5fthetaphi',['do_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#af6509fc7584b0bcbdc8561df2bc12a58',1,'pearl-anglescan-panel.ipf']]], - ['doniachsunjic',['DoniachSunjic',['../pearl-fitfuncs_8ipf.html#aaa48428994f8720a12e7237ef43e86ea',1,'pearl-fitfuncs.ipf']]], - ['doniachsunjicbroad',['DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#ae2d138beb7cb39e8042487893095b461',1,'pearl-fitfuncs.ipf']]], - ['doniachsunjicbroads',['DoniachSunjicBroadS',['../pearl-fitfuncs_8ipf.html#a9d110819fa3cd2173f3103724e394fdf',1,'pearl-fitfuncs.ipf']]], - ['doubletgausslinbg_5fao',['DoubletGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#adb438f665e51a8dd104a37cfead04f27',1,'pearl-fitfuncs.ipf']]], - ['draw_5fdiffraction_5fcone',['draw_diffraction_cone',['../pearl-anglescan-process_8ipf.html#afedad38a418cee5d1fb9e08aae2160a0',1,'pearl-anglescan-process.ipf']]], - ['draw_5fhemi_5faxes',['draw_hemi_axes',['../pearl-anglescan-process_8ipf.html#af00d9061e410ad033a9fd1f0ca561e0d',1,'pearl-anglescan-process.ipf']]], - ['ds1_5fbg',['ds1_bg',['../pearl-fitfuncs_8ipf.html#af62cb65b7444ff60e956a45bd5d0ec27',1,'pearl-fitfuncs.ipf']]], - ['ds2_5fbg',['ds2_bg',['../pearl-fitfuncs_8ipf.html#a1e729418252bf0d05ea6ec5cbd65b834',1,'pearl-fitfuncs.ipf']]], - ['ds4_5fbg',['ds4_bg',['../pearl-fitfuncs_8ipf.html#ab32134566b2573672ac674565deebd36',1,'pearl-fitfuncs.ipf']]], - ['ds6_5fbg',['ds6_bg',['../pearl-fitfuncs_8ipf.html#a5a2a03026b88f3dd99214ab1b26e6f80',1,'pearl-fitfuncs.ipf']]], - ['duplicate_5fhemi_5fscan',['duplicate_hemi_scan',['../pearl-anglescan-process_8ipf.html#aa5b1e2ab1dd43a73b7157406b803887e',1,'pearl-anglescan-process.ipf']]] + ['dbldoubletgausslinbg_5fao_816',['DblDoubletGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#aca0bf4ff35794a459e15a3b358dbfa04',1,'pearl-fitfuncs.ipf']]], + ['defaultfolderiterator_817',['DefaultFolderIterator',['../pearl-tools_8ipf.html#a3fb8c06030dc41a599380150807caeb0',1,'pearl-tools.ipf']]], + ['defaultwaveiterator_818',['DefaultWaveIterator',['../pearl-tools_8ipf.html#a6bdd1c0b269f1d7d99843ce0cb218cc7',1,'pearl-tools.ipf']]], + ['delete_5frows_819',['delete_rows',['../pearl-anglescan-panel_8ipf.html#a16424e5787967d9c120fb09c7849956e',1,'pearl-anglescan-panel.ipf']]], + ['display2dprofiles_820',['Display2dProfiles',['../pearl-menu_8ipf.html#aad7d768680c6d8a9b8a7025c7e1ec75d',1,'pearl-menu.ipf']]], + ['display3dslicer_821',['Display3dSlicer',['../pearl-menu_8ipf.html#ac73a94f760455f19294a9f917b43f145',1,'pearl-menu.ipf']]], + ['display_5fdataset_822',['display_dataset',['../pearl-data-explorer_8ipf.html#a67cd1a025e5428d443027c1f57eaec09',1,'pearl-data-explorer.ipf']]], + ['display_5fhemi_5fscan_823',['display_hemi_scan',['../pearl-anglescan-process_8ipf.html#ae57302acfc822c4817f2b7eef55efea2',1,'pearl-anglescan-process.ipf']]], + ['display_5fpolar_5fgraph_824',['display_polar_graph',['../pearl-anglescan-process_8ipf.html#a46fd99d35a43601c39af6096d4e4f770',1,'pearl-anglescan-process.ipf']]], + ['display_5fpreview_5ftrace_825',['display_preview_trace',['../pearl-data-explorer_8ipf.html#a001074020ad32b290d390a450a389c69',1,'pearl-data-explorer.ipf']]], + ['display_5fprogress_5fpanel_826',['display_progress_panel',['../pearl-gui-tools_8ipf.html#aaf29d090c81e00cf44af295193b24c5a',1,'pearl-gui-tools.ipf']]], + ['display_5fscanlines_827',['display_scanlines',['../pearl-anglescan-process_8ipf.html#a1f4f74a8ae557c56e1e3aacd0b45f3f1',1,'pearl-anglescan-process.ipf']]], + ['displaygizmoslicer_828',['DisplayGizmoSlicer',['../pearl-menu_8ipf.html#aab34952c2f3b36f9ee8619eb901ff581',1,'pearl-menu.ipf']]], + ['do_5fcrop_829',['do_crop',['../pearl-anglescan-panel_8ipf.html#af39609fc80e58f2188b3aa564f53b750',1,'pearl-anglescan-panel.ipf']]], + ['do_5finit_5fprocess_830',['do_init_process',['../pearl-anglescan-panel_8ipf.html#a1836e607851ba4d5a4048f4cfb8121a7',1,'pearl-anglescan-panel.ipf']]], + ['do_5fnorm_5falpha_831',['do_norm_alpha',['../pearl-anglescan-panel_8ipf.html#a8f7266ac2840155dede704fda66fe6b0',1,'pearl-anglescan-panel.ipf']]], + ['do_5fnorm_5fphi_832',['do_norm_phi',['../pearl-anglescan-panel_8ipf.html#a790519191391ac03c75eb7b57ea0749e',1,'pearl-anglescan-panel.ipf']]], + ['do_5fnorm_5ftheta_833',['do_norm_theta',['../pearl-anglescan-panel_8ipf.html#a7b288598e3faa37e414b1443982c1a3e',1,'pearl-anglescan-panel.ipf']]], + ['do_5fnorm_5fthetaphi_834',['do_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#af6509fc7584b0bcbdc8561df2bc12a58',1,'pearl-anglescan-panel.ipf']]], + ['doniachsunjic_835',['DoniachSunjic',['../pearl-fitfuncs_8ipf.html#aaa48428994f8720a12e7237ef43e86ea',1,'pearl-fitfuncs.ipf']]], + ['doniachsunjicbroad_836',['DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#ae2d138beb7cb39e8042487893095b461',1,'pearl-fitfuncs.ipf']]], + ['doniachsunjicbroads_837',['DoniachSunjicBroadS',['../pearl-fitfuncs_8ipf.html#a9d110819fa3cd2173f3103724e394fdf',1,'pearl-fitfuncs.ipf']]], + ['doubletgausslinbg_5fao_838',['DoubletGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#adb438f665e51a8dd104a37cfead04f27',1,'pearl-fitfuncs.ipf']]], + ['draw_5fdiffraction_5fcone_839',['draw_diffraction_cone',['../pearl-anglescan-process_8ipf.html#afedad38a418cee5d1fb9e08aae2160a0',1,'pearl-anglescan-process.ipf']]], + ['draw_5fhemi_5faxes_840',['draw_hemi_axes',['../pearl-anglescan-process_8ipf.html#af00d9061e410ad033a9fd1f0ca561e0d',1,'pearl-anglescan-process.ipf']]], + ['ds1_5fbg_841',['ds1_bg',['../pearl-fitfuncs_8ipf.html#af62cb65b7444ff60e956a45bd5d0ec27',1,'pearl-fitfuncs.ipf']]], + ['ds2_5fbg_842',['ds2_bg',['../pearl-fitfuncs_8ipf.html#a1e729418252bf0d05ea6ec5cbd65b834',1,'pearl-fitfuncs.ipf']]], + ['ds4_5fbg_843',['ds4_bg',['../pearl-fitfuncs_8ipf.html#ab32134566b2573672ac674565deebd36',1,'pearl-fitfuncs.ipf']]], + ['ds6_5fbg_844',['ds6_bg',['../pearl-fitfuncs_8ipf.html#a5a2a03026b88f3dd99214ab1b26e6f80',1,'pearl-fitfuncs.ipf']]], + ['duplicate_5fhemi_5fscan_845',['duplicate_hemi_scan',['../pearl-anglescan-process_8ipf.html#aa5b1e2ab1dd43a73b7157406b803887e',1,'pearl-anglescan-process.ipf']]] ]; diff --git a/doc/html/search/functions_4.html b/doc/html/search/functions_4.html index 8985ff2..911304e 100644 --- a/doc/html/search/functions_4.html +++ b/doc/html/search/functions_4.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_4.js b/doc/html/search/functions_4.js index c2ba15e..31547eb 100644 --- a/doc/html/search/functions_4.js +++ b/doc/html/search/functions_4.js @@ -1,22 +1,23 @@ var searchData= [ - ['edit_5foffsets',['edit_offsets',['../pearl-anglescan-tracker_8ipf.html#a37aaf2f08c3910bed554a10dd82616ec',1,'pearl-anglescan-tracker.ipf']]], - ['edit_5freduction_5fparams',['edit_reduction_params',['../pearl-anglescan-tracker_8ipf.html#a3844e7fd93b4f54aa52f084687c2106c',1,'pearl-anglescan-tracker.ipf']]], - ['elog_5fadd_5fattachment',['elog_add_attachment',['../pearl-elog_8ipf.html#ac2f76abed8cfaa7ac02a46c0b89004f0',1,'pearl-elog.ipf']]], - ['elog_5fconfig',['elog_config',['../pearl-elog_8ipf.html#a424460442afd5f6f853e68cd665ed785',1,'pearl-elog.ipf']]], - ['elog_5fcreate_5fentry',['elog_create_entry',['../pearl-elog_8ipf.html#a05301d497e4796e5fb5adde3728ba971',1,'pearl-elog.ipf']]], - ['elog_5fcreate_5flogbook',['elog_create_logbook',['../pearl-elog_8ipf.html#ab6d97edbf33e8ec039b34ff756e7ab93',1,'pearl-elog.ipf']]], - ['elog_5finit_5fpearl_5ftemplates',['elog_init_pearl_templates',['../pearl-elog_8ipf.html#aaca820a0149ce6a0e843ca72b9c9e7ab',1,'pearl-elog.ipf']]], - ['elog_5flogin',['elog_login',['../pearl-elog_8ipf.html#a3eac4012891c2813e401aee2c1134763',1,'pearl-elog.ipf']]], - ['elog_5flogout',['elog_logout',['../pearl-elog_8ipf.html#a96e4cbbdb0fd8c58d87b502dc1883664',1,'pearl-elog.ipf']]], - ['elog_5fpanel_5fhook',['elog_panel_hook',['../pearl-elog_8ipf.html#af8b1ea711208bcc2cd1647abe04131dc',1,'pearl-elog.ipf']]], - ['elog_5fprompt_5flogbook',['elog_prompt_logbook',['../pearl-elog_8ipf.html#acedf0c8ae34e9ebadd6fa0d9d1353aa4',1,'pearl-elog.ipf']]], - ['elog_5fprompt_5flogin',['elog_prompt_login',['../pearl-elog_8ipf.html#afbace5ffc3167b42b09657ce6cc854ca',1,'pearl-elog.ipf']]], - ['elog_5fvalidate_5fattributes',['elog_validate_attributes',['../pearl-elog_8ipf.html#ab2558ef5cd5e5dfba410bd58ed258b64',1,'pearl-elog.ipf']]], - ['epics_5fconnect',['epics_connect',['../pearl-anglescan-tracker_8ipf.html#a306b168cab2f9c4146cee87009e69f6d',1,'pearl-anglescan-tracker.ipf']]], - ['epics_5fdisconnect',['epics_disconnect',['../pearl-anglescan-tracker_8ipf.html#a4619cb98a75adb3c39ea3a62e524b793',1,'pearl-anglescan-tracker.ipf']]], - ['epics_5fdisconnect_5fchid',['epics_disconnect_chid',['../pearl-anglescan-tracker_8ipf.html#acfe94a64ff3e8c4cb32e34ffb9cae594',1,'pearl-anglescan-tracker.ipf']]], - ['export_5ftracker_5fdata',['export_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a09e95dbf1582fcf2e6f71baddb147f86',1,'pearl-anglescan-tracker.ipf']]], - ['extend_5fdata',['extend_data',['../pearl-anglescan-tracker_8ipf.html#a4bde8b2fc39c61c0d5a6879f1d0ae115',1,'pearl-anglescan-tracker.ipf']]], - ['extract_5fpreview_5fimage',['extract_preview_image',['../pearl-data-explorer_8ipf.html#a0adc1b370fd3bf230b61b094b3c0accb',1,'pearl-data-explorer.ipf']]] + ['edit_5foffsets_846',['edit_offsets',['../pearl-anglescan-tracker_8ipf.html#a37aaf2f08c3910bed554a10dd82616ec',1,'pearl-anglescan-tracker.ipf']]], + ['edit_5freduction_5fparams_847',['edit_reduction_params',['../pearl-anglescan-tracker_8ipf.html#a3844e7fd93b4f54aa52f084687c2106c',1,'pearl-anglescan-tracker.ipf']]], + ['elog_5fadd_5fattachment_848',['elog_add_attachment',['../pearl-elog_8ipf.html#ac2f76abed8cfaa7ac02a46c0b89004f0',1,'pearl-elog.ipf']]], + ['elog_5fconfig_849',['elog_config',['../pearl-elog_8ipf.html#a424460442afd5f6f853e68cd665ed785',1,'pearl-elog.ipf']]], + ['elog_5fcreate_5fentry_850',['elog_create_entry',['../pearl-elog_8ipf.html#a05301d497e4796e5fb5adde3728ba971',1,'pearl-elog.ipf']]], + ['elog_5fcreate_5flogbook_851',['elog_create_logbook',['../pearl-elog_8ipf.html#ab6d97edbf33e8ec039b34ff756e7ab93',1,'pearl-elog.ipf']]], + ['elog_5finit_5fpearl_5ftemplates_852',['elog_init_pearl_templates',['../pearl-elog_8ipf.html#aaca820a0149ce6a0e843ca72b9c9e7ab',1,'pearl-elog.ipf']]], + ['elog_5flogin_853',['elog_login',['../pearl-elog_8ipf.html#a3eac4012891c2813e401aee2c1134763',1,'pearl-elog.ipf']]], + ['elog_5flogout_854',['elog_logout',['../pearl-elog_8ipf.html#a96e4cbbdb0fd8c58d87b502dc1883664',1,'pearl-elog.ipf']]], + ['elog_5fpanel_5fhook_855',['elog_panel_hook',['../pearl-elog_8ipf.html#af8b1ea711208bcc2cd1647abe04131dc',1,'pearl-elog.ipf']]], + ['elog_5fprompt_5flogbook_856',['elog_prompt_logbook',['../pearl-elog_8ipf.html#acedf0c8ae34e9ebadd6fa0d9d1353aa4',1,'pearl-elog.ipf']]], + ['elog_5fprompt_5flogin_857',['elog_prompt_login',['../pearl-elog_8ipf.html#afbace5ffc3167b42b09657ce6cc854ca',1,'pearl-elog.ipf']]], + ['elog_5fvalidate_5fattributes_858',['elog_validate_attributes',['../pearl-elog_8ipf.html#ab2558ef5cd5e5dfba410bd58ed258b64',1,'pearl-elog.ipf']]], + ['epics_5fconnect_859',['epics_connect',['../pearl-anglescan-tracker_8ipf.html#a306b168cab2f9c4146cee87009e69f6d',1,'pearl-anglescan-tracker.ipf']]], + ['epics_5fdisconnect_860',['epics_disconnect',['../pearl-anglescan-tracker_8ipf.html#a4619cb98a75adb3c39ea3a62e524b793',1,'pearl-anglescan-tracker.ipf']]], + ['epics_5fdisconnect_5fchid_861',['epics_disconnect_chid',['../pearl-anglescan-tracker_8ipf.html#acfe94a64ff3e8c4cb32e34ffb9cae594',1,'pearl-anglescan-tracker.ipf']]], + ['export_5ftracker_5fdata_862',['export_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a09e95dbf1582fcf2e6f71baddb147f86',1,'pearl-anglescan-tracker.ipf']]], + ['extend_5fdata_863',['extend_data',['../pearl-anglescan-tracker_8ipf.html#a4bde8b2fc39c61c0d5a6879f1d0ae115',1,'pearl-anglescan-tracker.ipf']]], + ['extract_5fattributes_864',['extract_attributes',['../pearl-data-explorer_8ipf.html#af4474f34647ec24f27f900226c6bb3bd',1,'pearl-data-explorer.ipf']]], + ['extract_5fpreview_5fimage_865',['extract_preview_image',['../pearl-data-explorer_8ipf.html#a0adc1b370fd3bf230b61b094b3c0accb',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/functions_5.html b/doc/html/search/functions_5.html index 0314918..61b920d 100644 --- a/doc/html/search/functions_5.html +++ b/doc/html/search/functions_5.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_5.js b/doc/html/search/functions_5.js index 3b2d3e7..eef40c5 100644 --- a/doc/html/search/functions_5.js +++ b/doc/html/search/functions_5.js @@ -1,11 +1,8 @@ var searchData= [ - ['fermifunclindos2d_5fcorr',['FermiFuncLinDOS2D_corr',['../fermi-edge-analysis_8ipf.html#a520d8de9fbc4276c19fb417861f05b0d',1,'fermi-edge-analysis.ipf']]], - ['fermigaussconv',['FermiGaussConv',['../pearl-fitfuncs_8ipf.html#a4d20215153c0e0cee3870dfceded8bc9',1,'pearl-fitfuncs.ipf']]], - ['find_5fattr_5ffolder',['find_attr_folder',['../pearl-pshell-import_8ipf.html#a41bf534983b0662ec2609b136c395f14',1,'pearl-pshell-import.ipf']]], - ['find_5fhemi_5fdata',['find_hemi_data',['../pearl-anglescan-process_8ipf.html#aa26c9ed4c4d703e07788d980edc2406d',1,'pearl-anglescan-process.ipf']]], - ['find_5fscale_5fwave',['find_scale_wave',['../pearl-pshell-import_8ipf.html#acfb01ee360b66f286225f6e9c7220ba2',1,'pearl-pshell-import.ipf']]], - ['find_5fscan_5ffolder',['find_scan_folder',['../pearl-pshell-import_8ipf.html#a79b968d7439dfbfbc38c05f933071489',1,'pearl-pshell-import.ipf']]], - ['fit_5fdoniachsunjicbroad',['Fit_DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#a819902ab9f541b75a0fd33a7b52465d0',1,'pearl-fitfuncs.ipf']]], - ['format_5furl',['format_url',['../pearl-elog_8ipf.html#a3cc9074c84d684d207dfdf2045755df4',1,'pearl-elog.ipf']]] + ['fermifunclindos2d_5fcorr_866',['FermiFuncLinDOS2D_corr',['../fermi-edge-analysis_8ipf.html#a520d8de9fbc4276c19fb417861f05b0d',1,'fermi-edge-analysis.ipf']]], + ['fermigaussconv_867',['FermiGaussConv',['../pearl-fitfuncs_8ipf.html#a4d20215153c0e0cee3870dfceded8bc9',1,'pearl-fitfuncs.ipf']]], + ['find_5fhemi_5fdata_868',['find_hemi_data',['../pearl-anglescan-process_8ipf.html#aa26c9ed4c4d703e07788d980edc2406d',1,'pearl-anglescan-process.ipf']]], + ['fit_5fdoniachsunjicbroad_869',['Fit_DoniachSunjicBroad',['../pearl-fitfuncs_8ipf.html#a819902ab9f541b75a0fd33a7b52465d0',1,'pearl-fitfuncs.ipf']]], + ['format_5furl_870',['format_url',['../pearl-elog_8ipf.html#a3cc9074c84d684d207dfdf2045755df4',1,'pearl-elog.ipf']]] ]; diff --git a/doc/html/search/functions_6.html b/doc/html/search/functions_6.html index c506123..dc70a4a 100644 --- a/doc/html/search/functions_6.html +++ b/doc/html/search/functions_6.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_6.js b/doc/html/search/functions_6.js index ec5d27c..51471e9 100644 --- a/doc/html/search/functions_6.js +++ b/doc/html/search/functions_6.js @@ -1,19 +1,23 @@ var searchData= [ - ['gather_5fbatch',['gather_batch',['../pearl-otf-import_8ipf.html#ae2640256d7d07c11b41621430279cef6',1,'pearl-otf-import.ipf']]], - ['gauss4_5freduction',['gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#a83cdbd96c5b59011914d53118e5ef71c',1,'pearl-scienta-preprocess.ipf']]], - ['get_5fdefault_5fpanel_5fname',['get_default_panel_name',['../pearl-elog_8ipf.html#a1376b5c9e6b1180a09961bc3296849ae',1,'pearl-elog.ipf']]], - ['get_5felog_5fdf',['get_elog_df',['../pearl-elog_8ipf.html#ac45196cb9ce8b43b76c9daf67689c49a',1,'pearl-elog.ipf']]], - ['get_5fhemi_5fnickname',['get_hemi_nickname',['../pearl-anglescan-process_8ipf.html#a987811346894d8d81fc590b2f5ccec49',1,'pearl-anglescan-process.ipf']]], - ['get_5fhemi_5fprefix',['get_hemi_prefix',['../pearl-anglescan-process_8ipf.html#a1442bc23122d52ba9c77e0f9baaad1da',1,'pearl-anglescan-process.ipf']]], - ['get_5flog_5fpath',['get_log_path',['../pearl-elog_8ipf.html#ad1a72c63f269b2e22b21a72d1ef3b279',1,'pearl-elog.ipf']]], - ['get_5fpanel_5fattributes',['get_panel_attributes',['../pearl-elog_8ipf.html#a66e1200515eff8cd5c961572eccd7220',1,'pearl-elog.ipf']]], - ['get_5fpanel_5fgraphs',['get_panel_graphs',['../pearl-elog_8ipf.html#ace94356f691cbe343761aabd67ced23c',1,'pearl-elog.ipf']]], - ['get_5fpanel_5fmessage',['get_panel_message',['../pearl-elog_8ipf.html#a7ce92b03b6a786129959d44bf1112efa',1,'pearl-elog.ipf']]], - ['get_5fsource_5fimage',['get_source_image',['../pearl-area-display_8ipf.html#a4b76a98582f5997d3810f969dbb6c4ed',1,'pearl-area-display.ipf']]], - ['get_5ftimestamp',['get_timestamp',['../pearl-elog_8ipf.html#a6b2d6cf641c61120332ac1983b2f3846',1,'pearl-elog.ipf']]], - ['get_5fview_5ffolder',['get_view_folder',['../pearl-area-display_8ipf.html#a1bf20e37ed3e9c76be8ebe448c68a048',1,'pearl-area-display.ipf']]], - ['get_5fview_5fimage',['get_view_image',['../pearl-area-display_8ipf.html#a6cc0970b41ca197fa47263556fa2686a',1,'pearl-area-display.ipf']]], - ['getattrdatafolderdfr',['GetAttrDataFolderDFR',['../pearl-area-import_8ipf.html#aa3cdc56096a6a1bf2a2d80a6245a36d2',1,'pearl-area-import.ipf']]], - ['graphname_5ffrom_5fdfref',['graphname_from_dfref',['../pearl-area-display_8ipf.html#a195b12857685c4e535a840c5db324b4a',1,'pearl-area-display.ipf']]] + ['gather_5fbatch_871',['gather_batch',['../pearl-otf-import_8ipf.html#ae2640256d7d07c11b41621430279cef6',1,'pearl-otf-import.ipf']]], + ['gauss4_5freduction_872',['gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#a83cdbd96c5b59011914d53118e5ef71c',1,'pearl-scienta-preprocess.ipf']]], + ['gauss6_5freduction_873',['gauss6_reduction',['../pearl-scienta-preprocess_8ipf.html#a11d42ef1352876666b710b7545360fce',1,'pearl-scienta-preprocess.ipf']]], + ['get_5fdefault_5fpanel_5fname_874',['get_default_panel_name',['../pearl-elog_8ipf.html#a1376b5c9e6b1180a09961bc3296849ae',1,'pearl-elog.ipf']]], + ['get_5felog_5fdf_875',['get_elog_df',['../pearl-elog_8ipf.html#ac45196cb9ce8b43b76c9daf67689c49a',1,'pearl-elog.ipf']]], + ['get_5ffile_5finfo_876',['get_file_info',['../pearl-data-explorer_8ipf.html#a66043ccbe2e8dda258e639cb7a231537',1,'pearl-data-explorer.ipf']]], + ['get_5fhemi_5fnickname_877',['get_hemi_nickname',['../pearl-anglescan-process_8ipf.html#a987811346894d8d81fc590b2f5ccec49',1,'pearl-anglescan-process.ipf']]], + ['get_5fhemi_5fprefix_878',['get_hemi_prefix',['../pearl-anglescan-process_8ipf.html#a1442bc23122d52ba9c77e0f9baaad1da',1,'pearl-anglescan-process.ipf']]], + ['get_5flog_5fpath_879',['get_log_path',['../pearl-elog_8ipf.html#ad1a72c63f269b2e22b21a72d1ef3b279',1,'pearl-elog.ipf']]], + ['get_5fpanel_5fattributes_880',['get_panel_attributes',['../pearl-elog_8ipf.html#a66e1200515eff8cd5c961572eccd7220',1,'pearl-elog.ipf']]], + ['get_5fpanel_5fgraphs_881',['get_panel_graphs',['../pearl-elog_8ipf.html#ace94356f691cbe343761aabd67ced23c',1,'pearl-elog.ipf']]], + ['get_5fpanel_5fmessage_882',['get_panel_message',['../pearl-elog_8ipf.html#a7ce92b03b6a786129959d44bf1112efa',1,'pearl-elog.ipf']]], + ['get_5fpshell_5finfo_883',['get_pshell_info',['../pearl-data-explorer_8ipf.html#a28921b185d4e6fbe9a7a689757269f19',1,'pearl-data-explorer.ipf']]], + ['get_5fsource_5fimage_884',['get_source_image',['../pearl-area-display_8ipf.html#a4b76a98582f5997d3810f969dbb6c4ed',1,'pearl-area-display.ipf']]], + ['get_5ftimestamp_885',['get_timestamp',['../pearl-elog_8ipf.html#a6b2d6cf641c61120332ac1983b2f3846',1,'pearl-elog.ipf']]], + ['get_5fview_5ffolder_886',['get_view_folder',['../pearl-area-display_8ipf.html#a1bf20e37ed3e9c76be8ebe448c68a048',1,'pearl-area-display.ipf']]], + ['get_5fview_5fimage_887',['get_view_image',['../pearl-area-display_8ipf.html#a6cc0970b41ca197fa47263556fa2686a',1,'pearl-area-display.ipf']]], + ['getattrdatafolderdfr_888',['GetAttrDataFolderDFR',['../pearl-area-import_8ipf.html#aa3cdc56096a6a1bf2a2d80a6245a36d2',1,'pearl-area-import.ipf']]], + ['goto_5fdataset_5ffolder_889',['goto_dataset_folder',['../pearl-data-explorer_8ipf.html#a896081071fffecdeff09ae4c9d6e84cb',1,'pearl-data-explorer.ipf']]], + ['graphname_5ffrom_5fdfref_890',['graphname_from_dfref',['../pearl-area-display_8ipf.html#a195b12857685c4e535a840c5db324b4a',1,'pearl-area-display.ipf']]] ]; diff --git a/doc/html/search/functions_7.html b/doc/html/search/functions_7.html index 83a7b84..7de3106 100644 --- a/doc/html/search/functions_7.html +++ b/doc/html/search/functions_7.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_7.js b/doc/html/search/functions_7.js index 36fd0ad..e9f5edf 100644 --- a/doc/html/search/functions_7.js +++ b/doc/html/search/functions_7.js @@ -1,7 +1,15 @@ var searchData= [ - ['hemi_5fadd_5fanglescan',['hemi_add_anglescan',['../pearl-anglescan-process_8ipf.html#a4952bc53e3d6d272d25b5e35e91696b5',1,'pearl-anglescan-process.ipf']]], - ['hemi_5fadd_5faziscan',['hemi_add_aziscan',['../pearl-anglescan-process_8ipf.html#a4641c716180d737700c6df87f5f8974e',1,'pearl-anglescan-process.ipf']]], - ['hemi_5fazi_5fcut',['hemi_azi_cut',['../pearl-anglescan-process_8ipf.html#ab6ac1268de338040028dca8d0ddc967c',1,'pearl-anglescan-process.ipf']]], - ['hemi_5fpolar_5fcut',['hemi_polar_cut',['../pearl-anglescan-process_8ipf.html#aa486e16909d01e2251eeb4d635b972b1',1,'pearl-anglescan-process.ipf']]] + ['hemi_5fadd_5fanglescan_891',['hemi_add_anglescan',['../pearl-anglescan-process_8ipf.html#a4952bc53e3d6d272d25b5e35e91696b5',1,'pearl-anglescan-process.ipf']]], + ['hemi_5fadd_5faziscan_892',['hemi_add_aziscan',['../pearl-anglescan-process_8ipf.html#a4641c716180d737700c6df87f5f8974e',1,'pearl-anglescan-process.ipf']]], + ['hemi_5fazi_5fcut_893',['hemi_azi_cut',['../pearl-anglescan-process_8ipf.html#ab6ac1268de338040028dca8d0ddc967c',1,'pearl-anglescan-process.ipf']]], + ['hemi_5fpolar_5fcut_894',['hemi_polar_cut',['../pearl-anglescan-process_8ipf.html#aa486e16909d01e2251eeb4d635b972b1',1,'pearl-anglescan-process.ipf']]], + ['hl_5fadd_5fobjects_895',['hl_add_objects',['../pearl-data-explorer_8ipf.html#a54be4e40b17906c281cdf649d6ce537e',1,'pearl-data-explorer.ipf']]], + ['hl_5fcontents_5fclear_896',['hl_contents_clear',['../pearl-data-explorer_8ipf.html#ad95697e197428ff73a1a258ea3bb79b2',1,'pearl-data-explorer.ipf']]], + ['hl_5fcontents_5fupdate_897',['hl_contents_update',['../pearl-data-explorer_8ipf.html#aba2f8be504e49469194cc4b562be3a9c',1,'pearl-data-explorer.ipf']]], + ['hl_5fdefault_5fselection_898',['hl_default_selection',['../pearl-data-explorer_8ipf.html#a7c36ce6ccfaa77cf7a6b68b9014c1b9b',1,'pearl-data-explorer.ipf']]], + ['hl_5fexpand_5fscans_899',['hl_expand_scans',['../pearl-data-explorer_8ipf.html#a5d0c796365e8a24683c73e2b29571018',1,'pearl-data-explorer.ipf']]], + ['hlp_5fcontents_5fopen_900',['hlp_contents_open',['../pearl-data-explorer_8ipf.html#a384a37c2865baf5c21b63cff2488c3b3',1,'pearl-data-explorer.ipf']]], + ['hlp_5fcontents_5fselection_901',['hlp_contents_selection',['../pearl-data-explorer_8ipf.html#a36fd730f2d057513179dd59f8fddaf75',1,'pearl-data-explorer.ipf']]], + ['hlp_5fsetup_902',['hlp_setup',['../pearl-data-explorer_8ipf.html#af616e37167d5753b11e513bd03685ab8',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/functions_8.html b/doc/html/search/functions_8.html index b55f0e6..7422be2 100644 --- a/doc/html/search/functions_8.html +++ b/doc/html/search/functions_8.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_8.js b/doc/html/search/functions_8.js index c8163b8..988bea2 100644 --- a/doc/html/search/functions_8.js +++ b/doc/html/search/functions_8.js @@ -1,17 +1,17 @@ var searchData= [ - ['igorbeforenewhook',['IgorBeforeNewHook',['../pearl-elog_8ipf.html#ae824bbf81f8b7d16b36b53e3f3d85f69',1,'pearl-elog.ipf']]], - ['igorquithook',['IgorQuitHook',['../pearl-anglescan-tracker_8ipf.html#a0852e59e9018cf3f7e176aa2355b18e3',1,'IgorQuitHook(string app): pearl-anglescan-tracker.ipf'],['../pearl-elog_8ipf.html#a6fcae5eafc97bca9a637bd7800b13e25',1,'IgorQuitHook(string igorApplicationNameStr): pearl-elog.ipf']]], - ['import_5ftpi_5fscan',['import_tpi_scan',['../pearl-anglescan-process_8ipf.html#a5265fd61f86eb72dd877e4190bfb4adf',1,'pearl-anglescan-process.ipf']]], - ['import_5ftracker_5fdata',['import_tracker_data',['../pearl-anglescan-tracker_8ipf.html#ae53e615892fbc39f831b6bd7a0ae242e',1,'pearl-anglescan-tracker.ipf']]], - ['init_5fpackage',['init_package',['../pearl-anglescan-panel_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a7a4572f4f861f7eb46c932508d1164f9',1,'init_package(variable clean=defaultValue): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-matrix-import.ipf']]], - ['init_5fvolatile_5fvars',['init_volatile_vars',['../pearl-elog_8ipf.html#a85cf9d39ea917860b463b1b4111705f2',1,'pearl-elog.ipf']]], - ['initstruct',['initStruct',['../pearl-matrix-import_8ipf.html#af0eaec901e06ce59250eb434539a0f6c',1,'pearl-matrix-import.ipf']]], - ['int_5flinbg_5freduction',['int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a1e91197cd7a3581b70bc59a194d3f43b',1,'pearl-scienta-preprocess.ipf']]], - ['int_5fquadbg_5freduction',['int_quadbg_reduction',['../pearl-scienta-preprocess_8ipf.html#ad626526589efec3f2f72ad001702fe39',1,'pearl-scienta-preprocess.ipf']]], - ['integrate_5fcurved_5fedge',['integrate_curved_edge',['../fermi-edge-analysis_8ipf.html#a2a1d7b49c1f88f29ee6d49f6a6f4fbf8',1,'fermi-edge-analysis.ipf']]], - ['interpolate_5fhemi_5fscan',['interpolate_hemi_scan',['../pearl-anglescan-process_8ipf.html#acca0130cccf2286863bbf5b7f91c5b3b',1,'pearl-anglescan-process.ipf']]], - ['iteratedatafolders',['IterateDataFolders',['../pearl-tools_8ipf.html#a7c5307e5e7c0202d2b088fdc11887069',1,'pearl-tools.ipf']]], - ['iteratewaves',['IterateWaves',['../pearl-tools_8ipf.html#aabc250f68dd85ca58d7be5077255af99',1,'pearl-tools.ipf']]], - ['itx_5fsuggest_5ffoldername',['itx_suggest_foldername',['../pearl-data-explorer_8ipf.html#a6b5e9729ee6dedbb217c741639a168ed',1,'pearl-data-explorer.ipf']]] + ['igorbeforenewhook_903',['IgorBeforeNewHook',['../pearl-elog_8ipf.html#ae824bbf81f8b7d16b36b53e3f3d85f69',1,'pearl-elog.ipf']]], + ['igorquithook_904',['IgorQuitHook',['../pearl-anglescan-tracker_8ipf.html#a0852e59e9018cf3f7e176aa2355b18e3',1,'IgorQuitHook(string app): pearl-anglescan-tracker.ipf'],['../pearl-elog_8ipf.html#a6fcae5eafc97bca9a637bd7800b13e25',1,'IgorQuitHook(string igorApplicationNameStr): pearl-elog.ipf']]], + ['import_5ftpi_5fscan_905',['import_tpi_scan',['../pearl-anglescan-process_8ipf.html#a5265fd61f86eb72dd877e4190bfb4adf',1,'pearl-anglescan-process.ipf']]], + ['import_5ftracker_5fdata_906',['import_tracker_data',['../pearl-anglescan-tracker_8ipf.html#ae53e615892fbc39f831b6bd7a0ae242e',1,'pearl-anglescan-tracker.ipf']]], + ['init_5fpackage_907',['init_package',['../pearl-anglescan-panel_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a7a4572f4f861f7eb46c932508d1164f9',1,'init_package(variable clean=defaultValue): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a45e930b8eadd7cf6a5f664befd87d725',1,'init_package(): pearl-matrix-import.ipf']]], + ['init_5fvolatile_5fvars_908',['init_volatile_vars',['../pearl-elog_8ipf.html#a85cf9d39ea917860b463b1b4111705f2',1,'pearl-elog.ipf']]], + ['initstruct_909',['initStruct',['../pearl-matrix-import_8ipf.html#af0eaec901e06ce59250eb434539a0f6c',1,'pearl-matrix-import.ipf']]], + ['int_5flinbg_5freduction_910',['int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a1e91197cd7a3581b70bc59a194d3f43b',1,'pearl-scienta-preprocess.ipf']]], + ['int_5fquadbg_5freduction_911',['int_quadbg_reduction',['../pearl-scienta-preprocess_8ipf.html#ad626526589efec3f2f72ad001702fe39',1,'pearl-scienta-preprocess.ipf']]], + ['integrate_5fcurved_5fedge_912',['integrate_curved_edge',['../fermi-edge-analysis_8ipf.html#a2a1d7b49c1f88f29ee6d49f6a6f4fbf8',1,'fermi-edge-analysis.ipf']]], + ['interpolate_5fhemi_5fscan_913',['interpolate_hemi_scan',['../pearl-anglescan-process_8ipf.html#acca0130cccf2286863bbf5b7f91c5b3b',1,'pearl-anglescan-process.ipf']]], + ['iteratedatafolders_914',['IterateDataFolders',['../pearl-tools_8ipf.html#a7c5307e5e7c0202d2b088fdc11887069',1,'pearl-tools.ipf']]], + ['iteratewaves_915',['IterateWaves',['../pearl-tools_8ipf.html#aabc250f68dd85ca58d7be5077255af99',1,'pearl-tools.ipf']]], + ['itx_5fsuggest_5ffoldername_916',['itx_suggest_foldername',['../pearl-data-explorer_8ipf.html#a6b5e9729ee6dedbb217c741639a168ed',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/functions_9.html b/doc/html/search/functions_9.html index c73f07b..befd4fa 100644 --- a/doc/html/search/functions_9.html +++ b/doc/html/search/functions_9.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_9.js b/doc/html/search/functions_9.js index 2e20fd4..be90707 100644 --- a/doc/html/search/functions_9.js +++ b/doc/html/search/functions_9.js @@ -1,4 +1,5 @@ var searchData= [ - ['kill_5fprogress_5fpanel',['kill_progress_panel',['../pearl-gui-tools_8ipf.html#aca0a41a0f28a35ac7535df30ddbd79fe',1,'pearl-gui-tools.ipf']]] + ['kill_5fmatching_5fwaves_917',['kill_matching_waves',['../pearl-pshell-import_8ipf.html#a972bf23d6da0bb33e9f12e50c9d7f5e5',1,'pearl-pshell-import.ipf']]], + ['kill_5fprogress_5fpanel_918',['kill_progress_panel',['../pearl-gui-tools_8ipf.html#aca0a41a0f28a35ac7535df30ddbd79fe',1,'pearl-gui-tools.ipf']]] ]; diff --git a/doc/html/search/functions_a.html b/doc/html/search/functions_a.html index f10ad63..a81e963 100644 --- a/doc/html/search/functions_a.html +++ b/doc/html/search/functions_a.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_a.js b/doc/html/search/functions_a.js index 360290d..323fbc0 100644 --- a/doc/html/search/functions_a.js +++ b/doc/html/search/functions_a.js @@ -1,19 +1,19 @@ var searchData= [ - ['lbp_5fdatasets',['lbp_datasets',['../pearl-data-explorer_8ipf.html#a8ec37ab6c651003957d7e1ba728de89e',1,'pearl-data-explorer.ipf']]], - ['lbp_5ffilelist',['lbp_filelist',['../pearl-data-explorer_8ipf.html#a614e89b9c06511144ccb380e61cc7bd6',1,'pearl-data-explorer.ipf']]], - ['line_5faverage',['line_average',['../pearl-anglescan-process_8ipf.html#aa54a550eccad2c8ccd82d2b4167f7a92',1,'pearl-anglescan-process.ipf']]], - ['list_5flogbooks',['list_logbooks',['../pearl-elog_8ipf.html#a356bebea8eb41c9ac3ea2148af22707f',1,'pearl-elog.ipf']]], - ['load_5ffile',['load_file',['../pearl-data-explorer_8ipf.html#a1bbf3e1592f3344f3628526fa549dfdf',1,'pearl-data-explorer.ipf']]], - ['load_5fhdf_5ffile',['load_hdf_file',['../pearl-data-explorer_8ipf.html#a0c839d5f8f49e6937a6532bba3ef3714',1,'pearl-data-explorer.ipf']]], - ['load_5fhemi_5fscan',['load_hemi_scan',['../pearl-anglescan-process_8ipf.html#a89f73edcd51a675f4c3933cd0242484e',1,'pearl-anglescan-process.ipf']]], - ['load_5fitx_5ffile',['load_itx_file',['../pearl-data-explorer_8ipf.html#a26f2f2bf5efc39dabb2a01abcc559e3e',1,'pearl-data-explorer.ipf']]], - ['load_5fmtrx_5ffile',['load_mtrx_file',['../pearl-data-explorer_8ipf.html#a98e327fa65bbcb3cd7c97545f7201afe',1,'pearl-data-explorer.ipf']]], - ['load_5fprefs',['load_prefs',['../pearl-anglescan-panel_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-elog.ipf']]], - ['load_5fpshell_5ffile',['load_pshell_file',['../pearl-data-explorer_8ipf.html#a74c69e870329c5dd3b08f92bdeb21d87',1,'pearl-data-explorer.ipf']]], - ['load_5fselected_5ffiles',['load_selected_files',['../pearl-data-explorer_8ipf.html#a2178d5acf21fe4372ecc06224bec28ba',1,'pearl-data-explorer.ipf']]], - ['load_5ftracker_5fdata',['load_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a3882038c0ad82396b6591fd756817535',1,'pearl-anglescan-tracker.ipf']]], - ['loadpearlarpes',['LoadPearlArpes',['../pearl-menu_8ipf.html#aa70ef420d6fe0f6a433cd2371fc4a03d',1,'pearl-menu.ipf']]], - ['loadpearloptics',['LoadPearlOptics',['../pearl-menu_8ipf.html#af6c9740540c6242eb7bf57fc49de82ab',1,'pearl-menu.ipf']]], - ['loadpearlpreparation',['LoadPearlPreparation',['../pearl-menu_8ipf.html#a3658ae687e12987fa1d70636849a060f',1,'pearl-menu.ipf']]] + ['lbp_5ffilelist_919',['lbp_filelist',['../pearl-data-explorer_8ipf.html#a614e89b9c06511144ccb380e61cc7bd6',1,'pearl-data-explorer.ipf']]], + ['line_5faverage_920',['line_average',['../pearl-anglescan-process_8ipf.html#aa54a550eccad2c8ccd82d2b4167f7a92',1,'pearl-anglescan-process.ipf']]], + ['list_5flogbooks_921',['list_logbooks',['../pearl-elog_8ipf.html#a356bebea8eb41c9ac3ea2148af22707f',1,'pearl-elog.ipf']]], + ['load_5ffile_922',['load_file',['../pearl-data-explorer_8ipf.html#a435adef620193e09110ff69ca8d106de',1,'pearl-data-explorer.ipf']]], + ['load_5fhdf_5ffile_923',['load_hdf_file',['../pearl-data-explorer_8ipf.html#a96a3ef643cc29948ba57a3bfa1339c4d',1,'pearl-data-explorer.ipf']]], + ['load_5fhemi_5fscan_924',['load_hemi_scan',['../pearl-anglescan-process_8ipf.html#a89f73edcd51a675f4c3933cd0242484e',1,'pearl-anglescan-process.ipf']]], + ['load_5fitx_5ffile_925',['load_itx_file',['../pearl-data-explorer_8ipf.html#ababd5be120b526ca410c53b4a2ba3f8d',1,'pearl-data-explorer.ipf']]], + ['load_5fpmsco_5fresult_926',['load_pmsco_result',['../pearl-pmsco-import_8ipf.html#afae0650a37e89f18c9c54f8adc9eafb2',1,'pearl-pmsco-import.ipf']]], + ['load_5fpmsco_5fscan_927',['load_pmsco_scan',['../pearl-pmsco-import_8ipf.html#a98bbe8db14dba5aea9588a1b433baca7',1,'pearl-pmsco-import.ipf']]], + ['load_5fprefs_928',['load_prefs',['../pearl-anglescan-panel_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a92c27964d49ab8bcd7afc858ebe214a3',1,'load_prefs(): pearl-elog.ipf']]], + ['load_5fpshell_5ffile_929',['load_pshell_file',['../pearl-data-explorer_8ipf.html#a0e1e23060294bd4b18980e59229c70ed',1,'pearl-data-explorer.ipf']]], + ['load_5fselected_5ffiles_930',['load_selected_files',['../pearl-data-explorer_8ipf.html#a2178d5acf21fe4372ecc06224bec28ba',1,'pearl-data-explorer.ipf']]], + ['load_5ftracker_5fdata_931',['load_tracker_data',['../pearl-anglescan-tracker_8ipf.html#a3882038c0ad82396b6591fd756817535',1,'pearl-anglescan-tracker.ipf']]], + ['loadpearlarpes_932',['LoadPearlArpes',['../pearl-menu_8ipf.html#aa70ef420d6fe0f6a433cd2371fc4a03d',1,'pearl-menu.ipf']]], + ['loadpearloptics_933',['LoadPearlOptics',['../pearl-menu_8ipf.html#af6c9740540c6242eb7bf57fc49de82ab',1,'pearl-menu.ipf']]], + ['loadpearlpreparation_934',['LoadPearlPreparation',['../pearl-menu_8ipf.html#a3658ae687e12987fa1d70636849a060f',1,'pearl-menu.ipf']]] ]; diff --git a/doc/html/search/functions_b.html b/doc/html/search/functions_b.html index 172ea1b..345265d 100644 --- a/doc/html/search/functions_b.html +++ b/doc/html/search/functions_b.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_b.js b/doc/html/search/functions_b.js index f0dd8bd..3c0cb57 100644 --- a/doc/html/search/functions_b.js +++ b/doc/html/search/functions_b.js @@ -1,23 +1,24 @@ var searchData= [ - ['make_5fhemi_5fgrid',['make_hemi_grid',['../pearl-anglescan-process_8ipf.html#a902ac3a24e33f651e83ee03d31707da7',1,'pearl-anglescan-process.ipf']]], - ['make_5fview_5ffolder',['make_view_folder',['../pearl-area-display_8ipf.html#a2b183a27ec795b0ec1f8efabe3068369',1,'pearl-area-display.ipf']]], - ['matrix_5fformat_5felog_5fmessage',['matrix_format_elog_message',['../pearl-matrix-import_8ipf.html#a81b1d81261a32d0ed4cf79b81487f1b4',1,'pearl-matrix-import.ipf']]], - ['matrix_5fpreview_5f2d',['matrix_preview_2d',['../pearl-matrix-import_8ipf.html#a856478705a78e8105ea5d91a2228975b',1,'pearl-matrix-import.ipf']]], - ['move_5fattach_5fitem',['move_attach_item',['../pearl-elog_8ipf.html#a7990f2948d48aefe990271d1961df833',1,'pearl-elog.ipf']]], - ['mtrx_5fcreate_5ffolder',['mtrx_create_folder',['../pearl-matrix-import_8ipf.html#a893405a122fdf70429f4f75b8877ed7d',1,'pearl-matrix-import.ipf']]], - ['mtrx_5ffile_5fbrickletid',['mtrx_file_brickletID',['../pearl-matrix-import_8ipf.html#ad74d5afa71179728a9237d1ec5884482',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fget_5fcycle_5ffolder',['mtrx_get_cycle_folder',['../pearl-matrix-import_8ipf.html#a1a46b042e41daffee61706ab2cf54351',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fload_5fall',['mtrx_load_all',['../pearl-matrix-import_8ipf.html#a6ac0c685976b0e0c1944fb616a4f3a3c',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fload_5ffile',['mtrx_load_file',['../pearl-matrix-import_8ipf.html#a6aeef317fd468c88c99a274338c70ae3',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fload_5finfo',['mtrx_load_info',['../pearl-matrix-import_8ipf.html#a3a0ba4a7ad64739303b705d92be53267',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fload_5fpreview',['mtrx_load_preview',['../pearl-matrix-import_8ipf.html#abd09594d22038853e1e8021e0f36363d',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fopen_5ffile',['mtrx_open_file',['../pearl-matrix-import_8ipf.html#a59e72c849f4314aaa8339fd899665d85',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fparse_5ffilename',['mtrx_parse_filename',['../pearl-matrix-import_8ipf.html#a4bfeaf81ac483df0a38b26b6a8cf74a6',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fscale_5fdataset',['mtrx_scale_dataset',['../pearl-matrix-import_8ipf.html#ad8532f1473f92539fe88217d5d6e3368',1,'pearl-matrix-import.ipf']]], - ['mtrx_5fsplit_5ffilename',['mtrx_split_filename',['../pearl-matrix-import_8ipf.html#a0dc1efa23739e10b7558543b166e95b9',1,'pearl-matrix-import.ipf']]], - ['multidoniachsunjiclinbg',['MultiDoniachSunjicLinBG',['../pearl-fitfuncs_8ipf.html#a1520bd078ef77fd16ba20e95dbc6829d',1,'pearl-fitfuncs.ipf']]], - ['multigausslinbg',['MultiGaussLinBG',['../pearl-fitfuncs_8ipf.html#aad1418e71830c1ec71d7dd62b2ecf9ba',1,'pearl-fitfuncs.ipf']]], - ['multigausslinbg_5fao',['MultiGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#a2c6547164c0b46efecf4d372ea04c263',1,'pearl-fitfuncs.ipf']]], - ['multivoigtlinbg',['MultiVoigtLinBG',['../pearl-fitfuncs_8ipf.html#a3a94468da285a31eed5e990cd90e5cdf',1,'pearl-fitfuncs.ipf']]] + ['make_5fhemi_5fgrid_935',['make_hemi_grid',['../pearl-anglescan-process_8ipf.html#a902ac3a24e33f651e83ee03d31707da7',1,'pearl-anglescan-process.ipf']]], + ['make_5fview_5ffolder_936',['make_view_folder',['../pearl-area-display_8ipf.html#a2b183a27ec795b0ec1f8efabe3068369',1,'pearl-area-display.ipf']]], + ['matrix_5fformat_5felog_5fmessage_937',['matrix_format_elog_message',['../pearl-matrix-import_8ipf.html#a81b1d81261a32d0ed4cf79b81487f1b4',1,'pearl-matrix-import.ipf']]], + ['matrix_5fpreview_5f2d_938',['matrix_preview_2d',['../pearl-matrix-import_8ipf.html#a856478705a78e8105ea5d91a2228975b',1,'pearl-matrix-import.ipf']]], + ['move_5fattach_5fitem_939',['move_attach_item',['../pearl-elog_8ipf.html#a7990f2948d48aefe990271d1961df833',1,'pearl-elog.ipf']]], + ['mtrx_5fcreate_5ffolder_940',['mtrx_create_folder',['../pearl-matrix-import_8ipf.html#a893405a122fdf70429f4f75b8877ed7d',1,'pearl-matrix-import.ipf']]], + ['mtrx_5ffile_5fbrickletid_941',['mtrx_file_brickletID',['../pearl-matrix-import_8ipf.html#ad74d5afa71179728a9237d1ec5884482',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fget_5fcycle_5ffolder_942',['mtrx_get_cycle_folder',['../pearl-matrix-import_8ipf.html#a1a46b042e41daffee61706ab2cf54351',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fload_5fall_943',['mtrx_load_all',['../pearl-matrix-import_8ipf.html#a6ac0c685976b0e0c1944fb616a4f3a3c',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fload_5ffile_944',['mtrx_load_file',['../pearl-matrix-import_8ipf.html#a6aeef317fd468c88c99a274338c70ae3',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fload_5finfo_945',['mtrx_load_info',['../pearl-matrix-import_8ipf.html#a3a0ba4a7ad64739303b705d92be53267',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fload_5fpreview_946',['mtrx_load_preview',['../pearl-matrix-import_8ipf.html#abd09594d22038853e1e8021e0f36363d',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fopen_5ffile_947',['mtrx_open_file',['../pearl-matrix-import_8ipf.html#a59e72c849f4314aaa8339fd899665d85',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fparse_5ffilename_948',['mtrx_parse_filename',['../pearl-matrix-import_8ipf.html#a4bfeaf81ac483df0a38b26b6a8cf74a6',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fscale_5fdataset_949',['mtrx_scale_dataset',['../pearl-matrix-import_8ipf.html#ad8532f1473f92539fe88217d5d6e3368',1,'pearl-matrix-import.ipf']]], + ['mtrx_5fsplit_5ffilename_950',['mtrx_split_filename',['../pearl-matrix-import_8ipf.html#a0dc1efa23739e10b7558543b166e95b9',1,'pearl-matrix-import.ipf']]], + ['multidoniachsunjiclinbg_951',['MultiDoniachSunjicLinBG',['../pearl-fitfuncs_8ipf.html#af669aa08d0c32d3647007155f4b7ea3c',1,'pearl-fitfuncs.ipf']]], + ['multigausslinbg_952',['MultiGaussLinBG',['../pearl-fitfuncs_8ipf.html#aad1418e71830c1ec71d7dd62b2ecf9ba',1,'pearl-fitfuncs.ipf']]], + ['multigausslinbg_5fao_953',['MultiGaussLinBG_AO',['../pearl-fitfuncs_8ipf.html#a2c6547164c0b46efecf4d372ea04c263',1,'pearl-fitfuncs.ipf']]], + ['multivoigtlinbg_954',['MultiVoigtLinBG',['../pearl-fitfuncs_8ipf.html#a704de4b170620d07b75f2093fe052272',1,'pearl-fitfuncs.ipf']]], + ['multivoigtlinbg_5fao_955',['MultiVoigtLinBG_AO',['../pearl-fitfuncs_8ipf.html#a81da09e30e2800703dd178248f0c55be',1,'pearl-fitfuncs.ipf']]] ]; diff --git a/doc/html/search/functions_c.html b/doc/html/search/functions_c.html index 99492ba..858bfd6 100644 --- a/doc/html/search/functions_c.html +++ b/doc/html/search/functions_c.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_c.js b/doc/html/search/functions_c.js index 9df2628..9d5f09b 100644 --- a/doc/html/search/functions_c.js +++ b/doc/html/search/functions_c.js @@ -1,10 +1,10 @@ var searchData= [ - ['normalize_5fstrip_5f2d',['normalize_strip_2d',['../pearl-anglescan-process_8ipf.html#ac617c3b400488b656493af8ca08f1791',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5fphi',['normalize_strip_phi',['../pearl-anglescan-process_8ipf.html#aaa734fddecdd75c7cabe20ba777b41b9',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5ftheta',['normalize_strip_theta',['../pearl-anglescan-process_8ipf.html#a9b56897bd92d926d65f4c67bef1d41bb',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5ftheta_5fscans',['normalize_strip_theta_scans',['../pearl-anglescan-process_8ipf.html#a992920d621023e6b483ff51eee68b508',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5fthetaphi',['normalize_strip_thetaphi',['../pearl-anglescan-process_8ipf.html#ad0a93367d2e9b66bb7b81697e87adfaf',1,'pearl-anglescan-process.ipf']]], - ['normalize_5fstrip_5fx',['normalize_strip_x',['../pearl-anglescan-process_8ipf.html#a48b7d774ed8d3f4329e9923e18e580e8',1,'pearl-anglescan-process.ipf']]], - ['notebook_5fadd_5fattributes',['notebook_add_attributes',['../pearl-data-explorer_8ipf.html#a0c162346b59b0f66d34ee26ce5fe1e52',1,'pearl-data-explorer.ipf']]] + ['normalize_5fstrip_5f2d_956',['normalize_strip_2d',['../pearl-anglescan-process_8ipf.html#ac617c3b400488b656493af8ca08f1791',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5fphi_957',['normalize_strip_phi',['../pearl-anglescan-process_8ipf.html#aaa734fddecdd75c7cabe20ba777b41b9',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5ftheta_958',['normalize_strip_theta',['../pearl-anglescan-process_8ipf.html#a9b56897bd92d926d65f4c67bef1d41bb',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5ftheta_5fscans_959',['normalize_strip_theta_scans',['../pearl-anglescan-process_8ipf.html#a992920d621023e6b483ff51eee68b508',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5fthetaphi_960',['normalize_strip_thetaphi',['../pearl-anglescan-process_8ipf.html#ad0a93367d2e9b66bb7b81697e87adfaf',1,'pearl-anglescan-process.ipf']]], + ['normalize_5fstrip_5fx_961',['normalize_strip_x',['../pearl-anglescan-process_8ipf.html#a48b7d774ed8d3f4329e9923e18e580e8',1,'pearl-anglescan-process.ipf']]], + ['notebook_5fadd_5fattributes_962',['notebook_add_attributes',['../pearl-data-explorer_8ipf.html#a0c162346b59b0f66d34ee26ce5fe1e52',1,'pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/functions_d.html b/doc/html/search/functions_d.html index 5be9ecc..2f09f51 100644 --- a/doc/html/search/functions_d.html +++ b/doc/html/search/functions_d.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_d.js b/doc/html/search/functions_d.js index 8a3fda7..568524f 100644 --- a/doc/html/search/functions_d.js +++ b/doc/html/search/functions_d.js @@ -1,12 +1,12 @@ var searchData= [ - ['otf_5fgather_5fbatch',['otf_gather_batch',['../pearl-otf-import_8ipf.html#ad2a83b85030a7d7769d434d6e2e9e557',1,'pearl-otf-import.ipf']]], - ['otf_5fgather_5fiterator',['otf_gather_iterator',['../pearl-otf-import_8ipf.html#a44078e1d8f26e515539acb96973fc630',1,'pearl-otf-import.ipf']]], - ['otf_5finterp',['otf_interp',['../pearl-otf-import_8ipf.html#abd8897317366046dfb97c6ca53813d18',1,'pearl-otf-import.ipf']]], - ['otf_5fload_5fitx',['otf_load_itx',['../pearl-otf-import_8ipf.html#a3632f8a5c0ee32a14a3e589b74a0c496',1,'pearl-otf-import.ipf']]], - ['otf_5fload_5fitx_5fall',['otf_load_itx_all',['../pearl-otf-import_8ipf.html#a603b71176ed838713ec555c440082e22',1,'pearl-otf-import.ipf']]], - ['otf_5fload_5fitx_5fmatch',['otf_load_itx_match',['../pearl-otf-import_8ipf.html#aa47fc4b956ee84a993b6d285b628fe20',1,'pearl-otf-import.ipf']]], - ['otf_5frename_5ffolders',['otf_rename_folders',['../pearl-otf-import_8ipf.html#a715f9cf2d2b1ffb04f2f9a0e344a80ee',1,'pearl-otf-import.ipf']]], - ['otf_5frename_5ffolders_5fiterator',['otf_rename_folders_iterator',['../pearl-otf-import_8ipf.html#a882da254075e8d89f0117e491af90df0',1,'pearl-otf-import.ipf']]], - ['otf_5fsmo_5fint',['otf_smo_int',['../pearl-otf-import_8ipf.html#aba965b854836658aa00e3ec2b361d7c9',1,'pearl-otf-import.ipf']]] + ['otf_5fgather_5fbatch_963',['otf_gather_batch',['../pearl-otf-import_8ipf.html#ad2a83b85030a7d7769d434d6e2e9e557',1,'pearl-otf-import.ipf']]], + ['otf_5fgather_5fiterator_964',['otf_gather_iterator',['../pearl-otf-import_8ipf.html#a44078e1d8f26e515539acb96973fc630',1,'pearl-otf-import.ipf']]], + ['otf_5finterp_965',['otf_interp',['../pearl-otf-import_8ipf.html#abd8897317366046dfb97c6ca53813d18',1,'pearl-otf-import.ipf']]], + ['otf_5fload_5fitx_966',['otf_load_itx',['../pearl-otf-import_8ipf.html#a3632f8a5c0ee32a14a3e589b74a0c496',1,'pearl-otf-import.ipf']]], + ['otf_5fload_5fitx_5fall_967',['otf_load_itx_all',['../pearl-otf-import_8ipf.html#a603b71176ed838713ec555c440082e22',1,'pearl-otf-import.ipf']]], + ['otf_5fload_5fitx_5fmatch_968',['otf_load_itx_match',['../pearl-otf-import_8ipf.html#aa47fc4b956ee84a993b6d285b628fe20',1,'pearl-otf-import.ipf']]], + ['otf_5frename_5ffolders_969',['otf_rename_folders',['../pearl-otf-import_8ipf.html#a715f9cf2d2b1ffb04f2f9a0e344a80ee',1,'pearl-otf-import.ipf']]], + ['otf_5frename_5ffolders_5fiterator_970',['otf_rename_folders_iterator',['../pearl-otf-import_8ipf.html#a882da254075e8d89f0117e491af90df0',1,'pearl-otf-import.ipf']]], + ['otf_5fsmo_5fint_971',['otf_smo_int',['../pearl-otf-import_8ipf.html#aba965b854836658aa00e3ec2b361d7c9',1,'pearl-otf-import.ipf']]] ]; diff --git a/doc/html/search/functions_e.html b/doc/html/search/functions_e.html index e256cb6..ee5afa6 100644 --- a/doc/html/search/functions_e.html +++ b/doc/html/search/functions_e.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_e.js b/doc/html/search/functions_e.js index 2c11d3d..015726a 100644 --- a/doc/html/search/functions_e.js +++ b/doc/html/search/functions_e.js @@ -1,88 +1,91 @@ var searchData= [ - ['parse_5fresult',['parse_result',['../pearl-elog_8ipf.html#a5306514bf7d1a582aec146256ae45a12',1,'pearl-elog.ipf']]], - ['pearl_5fdata_5fexplorer',['pearl_data_explorer',['../pearl-data-explorer_8ipf.html#ab7e3b3a0a901f7559ee9f5affb9a6fca',1,'pearl-data-explorer.ipf']]], - ['pearl_5felog',['pearl_elog',['../pearl-elog_8ipf.html#a4088a48a8428629f120c08a419af62d6',1,'pearl-elog.ipf']]], - ['pearl_5ffile_5ftype',['pearl_file_type',['../pearl-data-explorer_8ipf.html#a8a923d7095071e7e6f99018379807732',1,'pearl-data-explorer.ipf']]], - ['pearlanglescantracker',['PearlAnglescanTracker',['../pearl-menu_8ipf.html#a74bc5da7843ee6c25f2d9c93d22a6ffa',1,'pearl-menu.ipf']]], - ['pearlcameradisplay',['PearlCameraDisplay',['../pearl-menu_8ipf.html#aab4ec7bc68f93029377b7657f40fbd6a',1,'pearl-menu.ipf']]], - ['pearlcleanupname',['PearlCleanupName',['../pearl-compat_8ipf.html#aa1f59acc532c7eee75c83b70ee1feaa9',1,'pearl-compat.ipf']]], - ['pearldataexplorer',['PearlDataExplorer',['../pearl-data-explorer_8ipf.html#a5b824531904179a94e0eaa3ffa09172e',1,'pearl-data-explorer.ipf']]], - ['pearlelogpanel',['PearlElogPanel',['../pearl-elog_8ipf.html#a6da33f1bb2639cb912e9b25af25bf663',1,'pearl-elog.ipf']]], - ['pearllivedisplay',['PearlLiveDisplay',['../pearl-menu_8ipf.html#a61ded60be72959b00f22842afa37c56f',1,'pearl-menu.ipf']]], - ['pearlmenuenablefunc',['PearlMenuEnableFunc',['../pearl-menu_8ipf.html#a3404a53bf13a01c1e811d1af6c35b726',1,'pearl-menu.ipf']]], - ['pearlsampletracker',['PearlSampleTracker',['../pearl-menu_8ipf.html#a1437f6baee0bd6d04bbcd2236c2d1f7f',1,'pearl-menu.ipf']]], - ['pizza_5fservice',['pizza_service',['../pearl-anglescan-process_8ipf.html#afed227ae79873fd32c96afbf606d1965',1,'pearl-anglescan-process.ipf']]], - ['pizza_5fservice_5f2',['pizza_service_2',['../pearl-anglescan-process_8ipf.html#a229770447193d4fd12032b235aab4d28',1,'pearl-anglescan-process.ipf']]], - ['pmp_5fdata',['pmp_data',['../pearl-anglescan-tracker_8ipf.html#a07efc5d6a7121540cc185c251353677c',1,'pearl-anglescan-tracker.ipf']]], - ['pmp_5fdata_5fmouseup',['pmp_data_mouseup',['../pearl-anglescan-tracker_8ipf.html#a4dad34b0481be20234fa5e8d25b262c4',1,'pearl-anglescan-tracker.ipf']]], - ['pmp_5fexport',['pmp_export',['../pearl-area-display_8ipf.html#ac5c7a25e9a8c0b001a429bae23639da9',1,'pearl-area-display.ipf']]], - ['pmp_5fgraph_5fcolortable',['pmp_graph_colortable',['../pearl-anglescan-panel_8ipf.html#ac80c675f6f1a5505e9b6f0349ff5fe92',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fgraph_5fmode',['pmp_graph_mode',['../pearl-anglescan-panel_8ipf.html#a1b41c992729d627445dbba0637b31ece',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fgraph_5fprojection',['pmp_graph_projection',['../pearl-anglescan-panel_8ipf.html#af83bfcf48723e7f6eeb78b4e0d84277d',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fnorm_5falpha_5fmode',['pmp_norm_alpha_mode',['../pearl-anglescan-panel_8ipf.html#acc1028dcd046f441ceaac268ffac9af6',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fnorm_5ftheta_5fdomain',['pmp_norm_theta_domain',['../pearl-anglescan-panel_8ipf.html#a0153f4ed4892dd3b48276af190590e4f',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fnorm_5ftheta_5fmode',['pmp_norm_theta_mode',['../pearl-anglescan-panel_8ipf.html#ae68496dbe344dc8a2c7c99b2d3f4b01c',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fnorm_5fthetaphi_5fmode',['pmp_norm_thetaphi_mode',['../pearl-anglescan-panel_8ipf.html#a289996a12d0ef46af1dac49a67289931',1,'pearl-anglescan-panel.ipf']]], - ['pmp_5fparameters',['pmp_parameters',['../pearl-anglescan-tracker_8ipf.html#a6d484e3bb5f8c18d3b2910e8346b2c17',1,'pearl-anglescan-tracker.ipf']]], - ['pmp_5fparameters_5fmouseup',['pmp_parameters_mouseup',['../pearl-anglescan-tracker_8ipf.html#ad06e1354226f4f617ad0a8d6d7572dca',1,'pearl-anglescan-tracker.ipf']]], - ['pmsco_5fload_5fxyz',['pmsco_load_xyz',['../pearl-pmsco-import_8ipf.html#ab3421c7f54aa64e5e493b267d700c0c8',1,'pearl-pmsco-import.ipf']]], - ['pmsco_5fsave_5fscan',['pmsco_save_scan',['../pearl-pmsco-import_8ipf.html#aa31bbaa2fc77b447e6c6f386b23abdd9',1,'pearl-pmsco-import.ipf']]], - ['polar2cart',['polar2cart',['../pearl-polar-coordinates_8ipf.html#a94ccfa9cf52c55eb1f66c2704478c396',1,'pearl-polar-coordinates.ipf']]], - ['polar2cart_5fwave',['polar2cart_wave',['../pearl-polar-coordinates_8ipf.html#a6a0ffb6b9160413d9694b1fd8e10c858',1,'pearl-polar-coordinates.ipf']]], - ['polar_5fdistance',['polar_distance',['../pearl-polar-coordinates_8ipf.html#a58139e6ebfba242b6b2ba3533b865a9a',1,'pearl-polar-coordinates.ipf']]], - ['polar_5fgraph_5fhook',['polar_graph_hook',['../pearl-anglescan-process_8ipf.html#ac4dbd1ece37b2cf22fa976a153977288',1,'pearl-anglescan-process.ipf']]], - ['prepare_5fcommand_5fline',['prepare_command_line',['../pearl-elog_8ipf.html#abd15431defaec6d770cc8cab2a40e6b0',1,'pearl-elog.ipf']]], - ['prepare_5fgraph_5fattachments',['prepare_graph_attachments',['../pearl-elog_8ipf.html#a4986de01085dc5481500240ef7667419',1,'pearl-elog.ipf']]], - ['prepare_5fhemi_5fscan_5fdisplay',['prepare_hemi_scan_display',['../pearl-anglescan-process_8ipf.html#ac15ebd5a19c558dde666ab36aeb9906f',1,'pearl-anglescan-process.ipf']]], - ['preview_5fattributes',['preview_attributes',['../pearl-data-explorer_8ipf.html#a415e4867be1ee37d84fd609b06f6dcb8',1,'pearl-data-explorer.ipf']]], - ['preview_5fcrop',['preview_crop',['../pearl-anglescan-panel_8ipf.html#a2268cc96a879c1a055c1ff29c1b040ea',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fdatafolder',['preview_datafolder',['../pearl-data-explorer_8ipf.html#a6e8eaf8c092f5da60bd425f9bd8bf178',1,'pearl-data-explorer.ipf']]], - ['preview_5fdataset',['preview_dataset',['../pearl-data-explorer_8ipf.html#a68d38e9464f7d13520ec040cffdf5c3b',1,'pearl-data-explorer.ipf']]], - ['preview_5ffile',['preview_file',['../pearl-data-explorer_8ipf.html#a3232c51a8c19eaf86b9bc67352967a9f',1,'pearl-data-explorer.ipf']]], - ['preview_5fhdf_5ffile',['preview_hdf_file',['../pearl-data-explorer_8ipf.html#a1731f8e1507d90e285885723ae32ba13',1,'pearl-data-explorer.ipf']]], - ['preview_5fitx_5ffile',['preview_itx_file',['../pearl-data-explorer_8ipf.html#a4633885afab755fbc5d262178b9ddcb8',1,'pearl-data-explorer.ipf']]], - ['preview_5fmatrix_5ffile',['preview_matrix_file',['../pearl-matrix-import_8ipf.html#a8acd2b03343ef9bdfecaa75e831392d1',1,'pearl-matrix-import.ipf']]], - ['preview_5fmtrx_5ffile',['preview_mtrx_file',['../pearl-data-explorer_8ipf.html#a340f334c6caa966ee1eb891614e57b5b',1,'pearl-data-explorer.ipf']]], - ['preview_5fnorm_5falpha',['preview_norm_alpha',['../pearl-anglescan-panel_8ipf.html#ad355d06d3b57bb458bd62e6d6f1f2417',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fnorm_5fphi',['preview_norm_phi',['../pearl-anglescan-panel_8ipf.html#a0c228ce2048827dc8161691ec5c425fc',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fnorm_5ftheta',['preview_norm_theta',['../pearl-anglescan-panel_8ipf.html#abe1237d8bf79a2ec3791ad9fe184bc3f',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fnorm_5fthetaphi',['preview_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#a3e798e20a99a03a789dd7914612e4fd2',1,'pearl-anglescan-panel.ipf']]], - ['preview_5fpshell_5ffile',['preview_pshell_file',['../pearl-data-explorer_8ipf.html#a457d2257ffd5880ab858fa583a5d1c99',1,'pearl-data-explorer.ipf']]], - ['preview_5fsetscale_5fx',['preview_setscale_x',['../pearl-data-explorer_8ipf.html#a5a7d3c00360944c00f236900b992694d',1,'pearl-data-explorer.ipf']]], - ['process_5fimage_5fdata',['process_image_data',['../pearl-anglescan-tracker_8ipf.html#a4bc40cded4d4d7676b084f7200ca5e0d',1,'pearl-anglescan-tracker.ipf']]], - ['prompt_5fdefault_5fprocess',['prompt_default_process',['../pearl-data-explorer_8ipf.html#a505ebda6bdecc4120e01766d7aedaf5d',1,'pearl-data-explorer.ipf']]], - ['prompt_5ffunc_5fparams',['prompt_func_params',['../pearl-data-explorer_8ipf.html#a1d7f4ad59b81ecd84bb63cfabd9f24dc',1,'pearl-data-explorer.ipf']]], - ['prompt_5fgauss4_5freduction',['prompt_gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#a1514250704b40aa2614d389a2e250d61',1,'pearl-scienta-preprocess.ipf']]], - ['prompt_5fhdf_5foptions',['prompt_hdf_options',['../pearl-data-explorer_8ipf.html#a200e7ba052fbce4614fb4254701646ab',1,'pearl-data-explorer.ipf']]], - ['prompt_5fint_5flinbg_5freduction',['prompt_int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a145c7275b8809c5e789b932ef46e4811',1,'pearl-scienta-preprocess.ipf']]], - ['prompt_5fint_5fquadbg_5freduction',['prompt_int_quadbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a6d06ea5a11ba79160efeea7fe673af8c',1,'pearl-scienta-preprocess.ipf']]], - ['prompt_5fredim_5flinbg_5freduction',['prompt_redim_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a6e7de6441bbcba217760448babaca827',1,'pearl-scienta-preprocess.ipf']]], - ['ps_5fdetect_5fscale',['ps_detect_scale',['../pearl-pshell-import_8ipf.html#acba7f4b98f67cc112c02dfeefe3e5acd',1,'pearl-pshell-import.ipf']]], - ['ps_5fscale_5fdataset',['ps_scale_dataset',['../pearl-pshell-import_8ipf.html#adc11ea797562b3d99c247f4866618d39',1,'pearl-pshell-import.ipf']]], - ['ps_5fscale_5fdataset_5f2',['ps_scale_dataset_2',['../pearl-pshell-import_8ipf.html#a2c456397c36d4116bfddca452eff5954',1,'pearl-pshell-import.ipf']]], - ['ps_5fscale_5fdatasets',['ps_scale_datasets',['../pearl-pshell-import_8ipf.html#af08a467036c64f70ca3dfe644fcc457c',1,'pearl-pshell-import.ipf']]], - ['ps_5fset_5fdimlabels',['ps_set_dimlabels',['../pearl-pshell-import_8ipf.html#aba25eb98e4c6cc9066c46ef6be1cde15',1,'pearl-pshell-import.ipf']]], - ['ps_5fset_5fdimlabels2',['ps_set_dimlabels2',['../pearl-pshell-import_8ipf.html#a8704627410409bcd27a1adeda4082c47',1,'pearl-pshell-import.ipf']]], - ['psh5_5fclose_5ffile',['psh5_close_file',['../pearl-pshell-import_8ipf.html#a2fc497747287d6fe40c6de997ed4a90d',1,'pearl-pshell-import.ipf']]], - ['psh5_5flist_5fscan_5fdatasets',['psh5_list_scan_datasets',['../pearl-pshell-import_8ipf.html#a4508bd507c4c935bd8463d9b2b84c6fc',1,'pearl-pshell-import.ipf']]], - ['psh5_5flist_5fscan_5fregions',['psh5_list_scan_regions',['../pearl-pshell-import_8ipf.html#acb317b57ef137d4d5da5938013dbe442',1,'pearl-pshell-import.ipf']]], - ['psh5_5flist_5fscans',['psh5_list_scans',['../pearl-pshell-import_8ipf.html#a2152f7c39a187b740cf9890767ffac3f',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fcomplete',['psh5_load_complete',['../pearl-pshell-import_8ipf.html#a8a5ce6c2767607de194b4c148ee98c27',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset',['psh5_load_dataset',['../pearl-pshell-import_8ipf.html#ac4dfb90b951d29b56501e904f5cc38aa',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset_5fmeta',['psh5_load_dataset_meta',['../pearl-pshell-import_8ipf.html#afde787a00a18dc8c63b100d8ac7d992f',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset_5freduced',['psh5_load_dataset_reduced',['../pearl-pshell-import_8ipf.html#a13a45e8618c1ab7406e1aa5e608e21fe',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset_5fslab',['psh5_load_dataset_slab',['../pearl-pshell-import_8ipf.html#a035a4df9f4508144149abdb0b46c87d1',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fdataset_5fslabs',['psh5_load_dataset_slabs',['../pearl-pshell-import_8ipf.html#a2972587ec82cc2a261b8119a582b4215',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5finfo',['psh5_load_info',['../pearl-pshell-import_8ipf.html#aa14b28120a07a8213e5a692930704a4b',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fpreview',['psh5_load_preview',['../pearl-pshell-import_8ipf.html#a1dc6c971120749b378014f1f63cb6668',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5freduced',['psh5_load_reduced',['../pearl-pshell-import_8ipf.html#a3eefc2f84a09f2ce29893c71ef44ae32',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fattrs',['psh5_load_scan_attrs',['../pearl-pshell-import_8ipf.html#aec191d0167bbf606d24396f4658104b5',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fcomplete',['psh5_load_scan_complete',['../pearl-pshell-import_8ipf.html#a0a02f87e19e825964aa17c46ed51df8c',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fdata',['psh5_load_scan_data',['../pearl-pshell-import_8ipf.html#ad26b0b56d7ccd23547535091c9430569',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5finfo',['psh5_load_scan_info',['../pearl-pshell-import_8ipf.html#a79ac37bb666b42c3332e9984196ccfe7',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fmeta',['psh5_load_scan_meta',['../pearl-pshell-import_8ipf.html#aa56c25d64b3e59f74d6dd92a599cce4f',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fpreview',['psh5_load_scan_preview',['../pearl-pshell-import_8ipf.html#ad3b9354b137ba4f1bc3ed2e74f24dc88',1,'pearl-pshell-import.ipf']]], - ['psh5_5fload_5fscan_5fsection',['psh5_load_scan_section',['../pearl-pshell-import_8ipf.html#a83804ba9637debed6ef8b13e7b9b19e0',1,'pearl-pshell-import.ipf']]], - ['psh5_5fopen_5ffile',['psh5_open_file',['../pearl-pshell-import_8ipf.html#accc20b0fc6bda95ba0cd0aea6633086f',1,'pearl-pshell-import.ipf']]] + ['parse_5fresult_972',['parse_result',['../pearl-elog_8ipf.html#a5306514bf7d1a582aec146256ae45a12',1,'pearl-elog.ipf']]], + ['pearl_5fdata_5fexplorer_973',['pearl_data_explorer',['../pearl-data-explorer_8ipf.html#ab7e3b3a0a901f7559ee9f5affb9a6fca',1,'pearl-data-explorer.ipf']]], + ['pearl_5felog_974',['pearl_elog',['../pearl-elog_8ipf.html#a4088a48a8428629f120c08a419af62d6',1,'pearl-elog.ipf']]], + ['pearl_5ffile_5ftype_975',['pearl_file_type',['../pearl-data-explorer_8ipf.html#a8a923d7095071e7e6f99018379807732',1,'pearl-data-explorer.ipf']]], + ['pearlanglescantracker_976',['PearlAnglescanTracker',['../pearl-menu_8ipf.html#a74bc5da7843ee6c25f2d9c93d22a6ffa',1,'pearl-menu.ipf']]], + ['pearlcameradisplay_977',['PearlCameraDisplay',['../pearl-menu_8ipf.html#aab4ec7bc68f93029377b7657f40fbd6a',1,'pearl-menu.ipf']]], + ['pearlcleanupname_978',['PearlCleanupName',['../pearl-compat_8ipf.html#aa1f59acc532c7eee75c83b70ee1feaa9',1,'pearl-compat.ipf']]], + ['pearldataexplorer_979',['PearlDataExplorer',['../pearl-data-explorer_8ipf.html#a5b824531904179a94e0eaa3ffa09172e',1,'pearl-data-explorer.ipf']]], + ['pearlelogpanel_980',['PearlElogPanel',['../pearl-elog_8ipf.html#a6da33f1bb2639cb912e9b25af25bf663',1,'pearl-elog.ipf']]], + ['pearllivedisplay_981',['PearlLiveDisplay',['../pearl-menu_8ipf.html#a61ded60be72959b00f22842afa37c56f',1,'pearl-menu.ipf']]], + ['pearlmenuenablefunc_982',['PearlMenuEnableFunc',['../pearl-menu_8ipf.html#a3404a53bf13a01c1e811d1af6c35b726',1,'pearl-menu.ipf']]], + ['pearlsampletracker_983',['PearlSampleTracker',['../pearl-menu_8ipf.html#a1437f6baee0bd6d04bbcd2236c2d1f7f',1,'pearl-menu.ipf']]], + ['pizza_5fservice_984',['pizza_service',['../pearl-anglescan-process_8ipf.html#afed227ae79873fd32c96afbf606d1965',1,'pearl-anglescan-process.ipf']]], + ['pizza_5fservice_5f2_985',['pizza_service_2',['../pearl-anglescan-process_8ipf.html#a229770447193d4fd12032b235aab4d28',1,'pearl-anglescan-process.ipf']]], + ['pm_5freduction_5fvalues_986',['pm_reduction_values',['../pearl-data-explorer_8ipf.html#a638a13044aede37cabe0c2c7a7c0cb06',1,'pearl-data-explorer.ipf']]], + ['pmp_5fdata_987',['pmp_data',['../pearl-anglescan-tracker_8ipf.html#a07efc5d6a7121540cc185c251353677c',1,'pearl-anglescan-tracker.ipf']]], + ['pmp_5fdata_5fmouseup_988',['pmp_data_mouseup',['../pearl-anglescan-tracker_8ipf.html#a4dad34b0481be20234fa5e8d25b262c4',1,'pearl-anglescan-tracker.ipf']]], + ['pmp_5fexport_989',['pmp_export',['../pearl-area-display_8ipf.html#ac5c7a25e9a8c0b001a429bae23639da9',1,'pearl-area-display.ipf']]], + ['pmp_5fgraph_5fcolortable_990',['pmp_graph_colortable',['../pearl-anglescan-panel_8ipf.html#ac80c675f6f1a5505e9b6f0349ff5fe92',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fgraph_5fmode_991',['pmp_graph_mode',['../pearl-anglescan-panel_8ipf.html#a1b41c992729d627445dbba0637b31ece',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fgraph_5fprojection_992',['pmp_graph_projection',['../pearl-anglescan-panel_8ipf.html#af83bfcf48723e7f6eeb78b4e0d84277d',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fnorm_5falpha_5fmode_993',['pmp_norm_alpha_mode',['../pearl-anglescan-panel_8ipf.html#acc1028dcd046f441ceaac268ffac9af6',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fnorm_5ftheta_5fdomain_994',['pmp_norm_theta_domain',['../pearl-anglescan-panel_8ipf.html#a0153f4ed4892dd3b48276af190590e4f',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fnorm_5ftheta_5fmode_995',['pmp_norm_theta_mode',['../pearl-anglescan-panel_8ipf.html#ae68496dbe344dc8a2c7c99b2d3f4b01c',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fnorm_5fthetaphi_5fmode_996',['pmp_norm_thetaphi_mode',['../pearl-anglescan-panel_8ipf.html#a289996a12d0ef46af1dac49a67289931',1,'pearl-anglescan-panel.ipf']]], + ['pmp_5fparameters_997',['pmp_parameters',['../pearl-anglescan-tracker_8ipf.html#a6d484e3bb5f8c18d3b2910e8346b2c17',1,'pearl-anglescan-tracker.ipf']]], + ['pmp_5fparameters_5fmouseup_998',['pmp_parameters_mouseup',['../pearl-anglescan-tracker_8ipf.html#ad06e1354226f4f617ad0a8d6d7572dca',1,'pearl-anglescan-tracker.ipf']]], + ['pmp_5freduction_5ffunc_999',['pmp_reduction_func',['../pearl-data-explorer_8ipf.html#a166273677188a66c25a84616c6f4baa9',1,'pearl-data-explorer.ipf']]], + ['pmsco_5fload_5fxyz_1000',['pmsco_load_xyz',['../pearl-pmsco-import_8ipf.html#ab3421c7f54aa64e5e493b267d700c0c8',1,'pearl-pmsco-import.ipf']]], + ['pmsco_5fsave_5fscan_1001',['pmsco_save_scan',['../pearl-pmsco-import_8ipf.html#aa31bbaa2fc77b447e6c6f386b23abdd9',1,'pearl-pmsco-import.ipf']]], + ['polar2cart_1002',['polar2cart',['../pearl-polar-coordinates_8ipf.html#a94ccfa9cf52c55eb1f66c2704478c396',1,'pearl-polar-coordinates.ipf']]], + ['polar2cart_5fwave_1003',['polar2cart_wave',['../pearl-polar-coordinates_8ipf.html#a6a0ffb6b9160413d9694b1fd8e10c858',1,'pearl-polar-coordinates.ipf']]], + ['polar_5fdistance_1004',['polar_distance',['../pearl-polar-coordinates_8ipf.html#a58139e6ebfba242b6b2ba3533b865a9a',1,'pearl-polar-coordinates.ipf']]], + ['polar_5fgraph_5fhook_1005',['polar_graph_hook',['../pearl-anglescan-process_8ipf.html#ac4dbd1ece37b2cf22fa976a153977288',1,'pearl-anglescan-process.ipf']]], + ['prepare_5fcommand_5fline_1006',['prepare_command_line',['../pearl-elog_8ipf.html#abd15431defaec6d770cc8cab2a40e6b0',1,'pearl-elog.ipf']]], + ['prepare_5fgraph_5fattachments_1007',['prepare_graph_attachments',['../pearl-elog_8ipf.html#a4986de01085dc5481500240ef7667419',1,'pearl-elog.ipf']]], + ['prepare_5fhemi_5fscan_5fdisplay_1008',['prepare_hemi_scan_display',['../pearl-anglescan-process_8ipf.html#ac15ebd5a19c558dde666ab36aeb9906f',1,'pearl-anglescan-process.ipf']]], + ['preview_5fcrop_1009',['preview_crop',['../pearl-anglescan-panel_8ipf.html#a2268cc96a879c1a055c1ff29c1b040ea',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fdatafolder_1010',['preview_datafolder',['../pearl-data-explorer_8ipf.html#a6e8eaf8c092f5da60bd425f9bd8bf178',1,'pearl-data-explorer.ipf']]], + ['preview_5ffile_1011',['preview_file',['../pearl-data-explorer_8ipf.html#a3232c51a8c19eaf86b9bc67352967a9f',1,'pearl-data-explorer.ipf']]], + ['preview_5fhdf_5ffile_1012',['preview_hdf_file',['../pearl-data-explorer_8ipf.html#a1731f8e1507d90e285885723ae32ba13',1,'pearl-data-explorer.ipf']]], + ['preview_5fitx_5ffile_1013',['preview_itx_file',['../pearl-data-explorer_8ipf.html#a4633885afab755fbc5d262178b9ddcb8',1,'pearl-data-explorer.ipf']]], + ['preview_5fmatrix_5ffile_1014',['preview_matrix_file',['../pearl-matrix-import_8ipf.html#a8acd2b03343ef9bdfecaa75e831392d1',1,'pearl-matrix-import.ipf']]], + ['preview_5fnorm_5falpha_1015',['preview_norm_alpha',['../pearl-anglescan-panel_8ipf.html#ad355d06d3b57bb458bd62e6d6f1f2417',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fnorm_5fphi_1016',['preview_norm_phi',['../pearl-anglescan-panel_8ipf.html#a0c228ce2048827dc8161691ec5c425fc',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fnorm_5ftheta_1017',['preview_norm_theta',['../pearl-anglescan-panel_8ipf.html#abe1237d8bf79a2ec3791ad9fe184bc3f',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fnorm_5fthetaphi_1018',['preview_norm_thetaphi',['../pearl-anglescan-panel_8ipf.html#a3e798e20a99a03a789dd7914612e4fd2',1,'pearl-anglescan-panel.ipf']]], + ['preview_5fpshell_5ffile_1019',['preview_pshell_file',['../pearl-data-explorer_8ipf.html#a457d2257ffd5880ab858fa583a5d1c99',1,'pearl-data-explorer.ipf']]], + ['preview_5fsetscale_5fx_1020',['preview_setscale_x',['../pearl-data-explorer_8ipf.html#a5a7d3c00360944c00f236900b992694d',1,'pearl-data-explorer.ipf']]], + ['process_5fimage_5fdata_1021',['process_image_data',['../pearl-anglescan-tracker_8ipf.html#a4bc40cded4d4d7676b084f7200ca5e0d',1,'pearl-anglescan-tracker.ipf']]], + ['prompt_5fdefault_5fprocess_1022',['prompt_default_process',['../pearl-data-explorer_8ipf.html#a505ebda6bdecc4120e01766d7aedaf5d',1,'pearl-data-explorer.ipf']]], + ['prompt_5ffunc_5fparams_1023',['prompt_func_params',['../pearl-data-explorer_8ipf.html#a1d7f4ad59b81ecd84bb63cfabd9f24dc',1,'pearl-data-explorer.ipf']]], + ['prompt_5fgauss4_5freduction_1024',['prompt_gauss4_reduction',['../pearl-scienta-preprocess_8ipf.html#a1514250704b40aa2614d389a2e250d61',1,'pearl-scienta-preprocess.ipf']]], + ['prompt_5fhdf_5foptions_1025',['prompt_hdf_options',['../pearl-data-explorer_8ipf.html#a200e7ba052fbce4614fb4254701646ab',1,'pearl-data-explorer.ipf']]], + ['prompt_5fint_5flinbg_5freduction_1026',['prompt_int_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a145c7275b8809c5e789b932ef46e4811',1,'pearl-scienta-preprocess.ipf']]], + ['prompt_5fint_5fquadbg_5freduction_1027',['prompt_int_quadbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a6d06ea5a11ba79160efeea7fe673af8c',1,'pearl-scienta-preprocess.ipf']]], + ['prompt_5fredim_5flinbg_5freduction_1028',['prompt_redim_linbg_reduction',['../pearl-scienta-preprocess_8ipf.html#a6e7de6441bbcba217760448babaca827',1,'pearl-scienta-preprocess.ipf']]], + ['ps_5fdetect_5fscale_1029',['ps_detect_scale',['../pearl-pshell-import_8ipf.html#ad2275b0b8a0a1ed05afc50ef50564243',1,'pearl-pshell-import.ipf']]], + ['ps_5ffind_5fattr_5ffolder_1030',['ps_find_attr_folder',['../pearl-pshell-import_8ipf.html#a476f19c72d6e54787535ab6989ee778d',1,'pearl-pshell-import.ipf']]], + ['ps_5ffind_5fscale_5fwave_1031',['ps_find_scale_wave',['../pearl-pshell-import_8ipf.html#a2f39f9379e66ead0d25c33adfbe05ee9',1,'pearl-pshell-import.ipf']]], + ['ps_5ffind_5fscan_5ffolder_1032',['ps_find_scan_folder',['../pearl-pshell-import_8ipf.html#a513091ea9a4e23f76765aa37f1d34055',1,'pearl-pshell-import.ipf']]], + ['ps_5ffix_5ffolder_5fname_1033',['ps_fix_folder_name',['../pearl-pshell-import_8ipf.html#a7d7b67c9f983d3446c5c6f274284b82a',1,'pearl-pshell-import.ipf']]], + ['ps_5fscale_5fdataset_1034',['ps_scale_dataset',['../pearl-pshell-import_8ipf.html#adc11ea797562b3d99c247f4866618d39',1,'pearl-pshell-import.ipf']]], + ['ps_5fscale_5fdataset_5f2_1035',['ps_scale_dataset_2',['../pearl-pshell-import_8ipf.html#a2c456397c36d4116bfddca452eff5954',1,'pearl-pshell-import.ipf']]], + ['ps_5fscale_5fdatasets_1036',['ps_scale_datasets',['../pearl-pshell-import_8ipf.html#a5a1961e05ea900e72d6a886ac5744f2d',1,'pearl-pshell-import.ipf']]], + ['ps_5fset_5fdimlabels_1037',['ps_set_dimlabels',['../pearl-pshell-import_8ipf.html#aba25eb98e4c6cc9066c46ef6be1cde15',1,'pearl-pshell-import.ipf']]], + ['ps_5fset_5fdimlabels2_1038',['ps_set_dimlabels2',['../pearl-pshell-import_8ipf.html#a8704627410409bcd27a1adeda4082c47',1,'pearl-pshell-import.ipf']]], + ['psh5_5fclose_5ffile_1039',['psh5_close_file',['../pearl-pshell-import_8ipf.html#a47513a1db5693f88d64739a5b28926b2',1,'pearl-pshell-import.ipf']]], + ['psh5_5fcreate_5ffolders_1040',['psh5_create_folders',['../pearl-pshell-import_8ipf.html#aa7a48b65e465abde9aad80377605ae59',1,'pearl-pshell-import.ipf']]], + ['psh5_5fdataset_5fto_5ffolder_1041',['psh5_dataset_to_folder',['../pearl-pshell-import_8ipf.html#acda8bf0493a2e8ba1955f12de08e28f2',1,'pearl-pshell-import.ipf']]], + ['psh5_5fextract_5fregion_5fpaths_1042',['psh5_extract_region_paths',['../pearl-pshell-import_8ipf.html#a4f5d11063bd50ded36ca013a2656b539',1,'pearl-pshell-import.ipf']]], + ['psh5_5fextract_5fscan_5fpaths_1043',['psh5_extract_scan_paths',['../pearl-pshell-import_8ipf.html#ab86e42bb6f9ff20f685ad5627b446b77',1,'pearl-pshell-import.ipf']]], + ['psh5_5ffilter_5fdatasets_5frank_1044',['psh5_filter_datasets_rank',['../pearl-pshell-import_8ipf.html#a7c191ea7367f2f328333b9986c7dd538',1,'pearl-pshell-import.ipf']]], + ['psh5_5flist_5fall_5fdatasets_1045',['psh5_list_all_datasets',['../pearl-pshell-import_8ipf.html#a113622ae05611e5051a97d223fae59d0',1,'pearl-pshell-import.ipf']]], + ['psh5_5flist_5fdataset_5finfo_1046',['psh5_list_dataset_info',['../pearl-pshell-import_8ipf.html#ad811542ccfc7c73156c2a107faa93d87',1,'pearl-pshell-import.ipf']]], + ['psh5_5flist_5fscans_1047',['psh5_list_scans',['../pearl-pshell-import_8ipf.html#a85c1fbd2aefff2028e084ea61314dc67',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_1048',['psh5_load',['../pearl-pshell-import_8ipf.html#ab41e955a4ff70f9c78571faad1b43d7b',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdataset_1049',['psh5_load_dataset',['../pearl-pshell-import_8ipf.html#af7a6eefbda58d31336c81a3dda6e9a2d',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdataset_5fmeta_1050',['psh5_load_dataset_meta',['../pearl-pshell-import_8ipf.html#abcf01e205858a512aa713da914eaf966',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdataset_5freduced_1051',['psh5_load_dataset_reduced',['../pearl-pshell-import_8ipf.html#af662500c4f992ef7b956f37ed463513d',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdataset_5fslabs_1052',['psh5_load_dataset_slabs',['../pearl-pshell-import_8ipf.html#afc4fa60c5fbfdb08c2a9d3072d3e16ce',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fdatasets_1053',['psh5_load_datasets',['../pearl-pshell-import_8ipf.html#ae539a7501119cb2349707e2027f0f759',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fgeneral_5fgroup_1054',['psh5_load_general_group',['../pearl-pshell-import_8ipf.html#ac782084655d44d222742e3397051619d',1,'pearl-pshell-import.ipf']]], + ['psh5_5fload_5fscan_5fmeta_1055',['psh5_load_scan_meta',['../pearl-pshell-import_8ipf.html#a23a2e4cb2dc5364bfdbab4367ed6f234',1,'pearl-pshell-import.ipf']]], + ['psh5_5fmatch_5fdataset_5fclasses_1056',['psh5_match_dataset_classes',['../pearl-pshell-import_8ipf.html#af3b5005859915f410ec27a31ac9519ca',1,'pearl-pshell-import.ipf']]], + ['psh5_5fopen_5ffile_1057',['psh5_open_file',['../pearl-pshell-import_8ipf.html#ab684c44d5f0668631e42d9c9c9dfea9e',1,'pearl-pshell-import.ipf']]], + ['psh5_5fpreview_1058',['psh5_preview',['../pearl-pshell-import_8ipf.html#a24afba76ed5323d8cd0abc3c7b0d9912',1,'pearl-pshell-import.ipf']]], + ['psh_5fload_5fgeneral_5fstring_1059',['psh_load_general_string',['../pearl-pshell-import_8ipf.html#a72465006d4e8379fad08d1a1064de2a3',1,'pearl-pshell-import.ipf']]] ]; diff --git a/doc/html/search/functions_f.html b/doc/html/search/functions_f.html index 424126c..f17c412 100644 --- a/doc/html/search/functions_f.html +++ b/doc/html/search/functions_f.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/functions_f.js b/doc/html/search/functions_f.js index 676dec0..c7c9f7b 100644 --- a/doc/html/search/functions_f.js +++ b/doc/html/search/functions_f.js @@ -1,4 +1,4 @@ var searchData= [ - ['quick_5fpizza_5fimage',['quick_pizza_image',['../pearl-anglescan-process_8ipf.html#a0b9e2b025e1d55d2a064edccf6c1c3e3',1,'pearl-anglescan-process.ipf']]] + ['quick_5fpizza_5fimage_1060',['quick_pizza_image',['../pearl-anglescan-process_8ipf.html#a0b9e2b025e1d55d2a064edccf6c1c3e3',1,'pearl-anglescan-process.ipf']]] ]; diff --git a/doc/html/search/groups_0.html b/doc/html/search/groups_0.html index 1ede28d..a2d9335 100644 --- a/doc/html/search/groups_0.html +++ b/doc/html/search/groups_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/groups_0.js b/doc/html/search/groups_0.js index 00ee40e..027c11d 100644 --- a/doc/html/search/groups_0.js +++ b/doc/html/search/groups_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['arpes_20package',['ARPES package',['../group___arpes_package.html',1,'']]] + ['arpes_20package_1201',['ARPES package',['../group___arpes_package.html',1,'']]] ]; diff --git a/doc/html/search/mag_sel.png b/doc/html/search/mag_sel.png index 81f6040a2092402b4d98f9ffa8855d12a0d4ca17..39c0ed52a25dd9d080ee0d42ae6c6042bdfa04d7 100644 GIT binary patch delta 387 zcmdnYa*=t0qy!5C1A|rTQ#&BVlJ4m1$iT3%pZiZD>qIj>9tNf)Z+91l|Ly%}_D@ul zsAn(n^mS!_#KX=lBk2D&{60|65lM6-Px1V)%FZ&RBYX~=GOWPWxZh<9+s(!r~e-Dn&F(J7joYq z)l&8Vdty#vcB0OmiB?q{_kF5^+l}W}R~ek~dmFbhU{|SDOj*f>4|Dl@%X_EZYArBb z&|I6VJJ#f9jJl9)78&qol`;+ E09^HzBLDyZ delta 506 zcmV865@y005ATEwumu010qNS#tmY3ljhU3ljkVnw%JsF)n`rxk*Gp zRCwCtl)H)|K@^6++7>zxx&tqG15pu7)IiiXFflOc2k;dXd>%13GZAy?Rz!q0=|E6a z6vV)&ZBS~G9oe0kbqyw1*gvY`{Pop2oKq#FlzgXt@Xh-7fxh>}`Fxg>$%N%{$!4=5 znM{(;=c!aG1Ofr^Do{u%Ih}t_axfTRS=J{*wOXaoXb=nr#mgB^r&BD;B9%%}DwW7& zGOSiBX0sWS$%IHGLcLypy=2?A0VtQtR4NrTO%tI|NGgiLdcDTBZR+(pqtQtA`~AmZ z!!W4TYT{E~!8ritsi(lkxR<1ql~bQ*wKt@eOE?ecoPmc!wY`F#GRDI5;d>2%O_ zT>y+mqmLK-4)i=v?shvCiv^D3u;1^A$K#~aX>8l(bUG1@MrpU(59rej0X)x>uIu7? z9=F>KpU;P)C|oWVdc9H}$K#P$EJmx-CDR w>wnMinOxVEhr@yU{Z2NUeXZpG=lgma09mNIXv$B;rvLx|07*qoM6N<$g8jzt3IG5A diff --git a/doc/html/search/namespaces_0.html b/doc/html/search/namespaces_0.html index 605ac45..76996d1 100644 --- a/doc/html/search/namespaces_0.html +++ b/doc/html/search/namespaces_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/namespaces_0.js b/doc/html/search/namespaces_0.js index f6de76f..89eabb6 100644 --- a/doc/html/search/namespaces_0.js +++ b/doc/html/search/namespaces_0.js @@ -1,19 +1,18 @@ var searchData= [ - ['pearlanglescanpanel',['PearlAnglescanPanel',['../namespace_pearl_anglescan_panel.html',1,'']]], - ['pearlanglescanprocess',['PearlAnglescanProcess',['../namespace_pearl_anglescan_process.html',1,'']]], - ['pearlareadisplay',['PearlAreaDisplay',['../namespace_pearl_area_display.html',1,'']]], - ['pearlareaimport',['PearlAreaImport',['../namespace_pearl_area_import.html',1,'']]], - ['pearlareaprofiles',['PearlAreaProfiles',['../namespace_pearl_area_profiles.html',1,'']]], - ['pearlarpes',['PearlArpes',['../namespace_pearl_arpes.html',1,'']]], - ['pearlcompat',['PearlCompat',['../namespace_pearl_compat.html',1,'']]], - ['pearldataexplorer',['PearlDataExplorer',['../namespace_pearl_data_explorer.html',1,'']]], - ['pearlelog',['PearlElog',['../namespace_pearl_elog.html',1,'']]], - ['pearlfitfuncs',['PearlFitFuncs',['../namespace_pearl_fit_funcs.html',1,'']]], - ['pearlmatriximport',['PearlMatrixImport',['../namespace_pearl_matrix_import.html',1,'']]], - ['pearlpmscoimport',['PearlPmscoImport',['../namespace_pearl_pmsco_import.html',1,'']]], - ['pearlpshellimport',['PearlPShellImport',['../namespace_pearl_p_shell_import.html',1,'']]], - ['pearlscientacountrate',['PearlScientaCountrate',['../namespace_pearl_scienta_countrate.html',1,'']]], - ['pearlscientapreprocess',['PearlScientaPreprocess',['../namespace_pearl_scienta_preprocess.html',1,'']]], - ['pearlvectoroperations',['PearlVectorOperations',['../namespace_pearl_vector_operations.html',1,'']]] + ['pearlanglescanpanel_605',['PearlAnglescanPanel',['../namespace_pearl_anglescan_panel.html',1,'']]], + ['pearlanglescanprocess_606',['PearlAnglescanProcess',['../namespace_pearl_anglescan_process.html',1,'']]], + ['pearlareadisplay_607',['PearlAreaDisplay',['../namespace_pearl_area_display.html',1,'']]], + ['pearlareaimport_608',['PearlAreaImport',['../namespace_pearl_area_import.html',1,'']]], + ['pearlareaprofiles_609',['PearlAreaProfiles',['../namespace_pearl_area_profiles.html',1,'']]], + ['pearlarpes_610',['PearlArpes',['../namespace_pearl_arpes.html',1,'']]], + ['pearlcompat_611',['PearlCompat',['../namespace_pearl_compat.html',1,'']]], + ['pearlelog_612',['PearlElog',['../namespace_pearl_elog.html',1,'']]], + ['pearlfitfuncs_613',['PearlFitFuncs',['../namespace_pearl_fit_funcs.html',1,'']]], + ['pearlmatriximport_614',['PearlMatrixImport',['../namespace_pearl_matrix_import.html',1,'']]], + ['pearlpmscoimport_615',['PearlPmscoImport',['../namespace_pearl_pmsco_import.html',1,'']]], + ['pearlpshellimport_616',['PearlPShellImport',['../namespace_pearl_p_shell_import.html',1,'']]], + ['pearlscientalive_617',['PearlScientaLive',['../namespace_pearl_scienta_live.html',1,'']]], + ['pearlscientapreprocess_618',['PearlScientaPreprocess',['../namespace_pearl_scienta_preprocess.html',1,'']]], + ['pearlvectoroperations_619',['PearlVectorOperations',['../namespace_pearl_vector_operations.html',1,'']]] ]; diff --git a/doc/html/search/nomatches.html b/doc/html/search/nomatches.html index b1ded27..4377320 100644 --- a/doc/html/search/nomatches.html +++ b/doc/html/search/nomatches.html @@ -1,4 +1,4 @@ - + diff --git a/doc/html/search/pages_0.html b/doc/html/search/pages_0.html index 4955b9e..9a6a29a 100644 --- a/doc/html/search/pages_0.html +++ b/doc/html/search/pages_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/pages_0.js b/doc/html/search/pages_0.js index f1b4aa4..979750b 100644 --- a/doc/html/search/pages_0.js +++ b/doc/html/search/pages_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['angle_2dscan_20processing',['Angle-scan processing',['../pag_anglescan_processing.html',1,'']]] + ['angle_2dscan_20processing_1202',['Angle-scan processing',['../pag_anglescan_processing.html',1,'']]] ]; diff --git a/doc/html/search/pages_1.html b/doc/html/search/pages_1.html index aedb14e..132ee03 100644 --- a/doc/html/search/pages_1.html +++ b/doc/html/search/pages_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/pages_1.js b/doc/html/search/pages_1.js index 7cf7879..d0a9d53 100644 --- a/doc/html/search/pages_1.js +++ b/doc/html/search/pages_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['introduction',['Introduction',['../index.html',1,'']]] + ['introduction_1203',['Introduction',['../index.html',1,'']]] ]; diff --git a/doc/html/search/pages_2.html b/doc/html/search/pages_2.html index bd91593..6109d47 100644 --- a/doc/html/search/pages_2.html +++ b/doc/html/search/pages_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/pages_2.js b/doc/html/search/pages_2.js index cafbcbd..4408398 100644 --- a/doc/html/search/pages_2.js +++ b/doc/html/search/pages_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['projections',['Projections',['../_page_projections.html',1,'']]] + ['projections_1204',['Projections',['../_page_projections.html',1,'']]] ]; diff --git a/doc/html/search/pages_3.html b/doc/html/search/pages_3.html index bc0e37f..54e8ba9 100644 --- a/doc/html/search/pages_3.html +++ b/doc/html/search/pages_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/pages_3.js b/doc/html/search/pages_3.js index 441b2de..8ad3e27 100644 --- a/doc/html/search/pages_3.js +++ b/doc/html/search/pages_3.js @@ -1,4 +1,4 @@ var searchData= [ - ['todo_20list',['Todo List',['../todo.html',1,'']]] + ['todo_20list_1205',['Todo List',['../todo.html',1,'']]] ]; diff --git a/doc/html/search/search.js b/doc/html/search/search.js index dedce3b..a554ab9 100644 --- a/doc/html/search/search.js +++ b/doc/html/search/search.js @@ -1,3 +1,26 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ function convertToId(search) { var result = ''; @@ -788,4 +811,4 @@ function init_search() } searchBox.OnSelectItem(0); } - +/* @license-end */ diff --git a/doc/html/search/search_l.png b/doc/html/search/search_l.png index c872f4da4a01d0754f923e6c94fd8159c0621bd1..fd5f7daa41a4c79b4ae9bea5aa7bdfb94e14084b 100644 GIT binary patch delta 490 zcmcb^vYlmuqy!5C1A|rTQ#&BVlJ4m1$iT3%pZiZD>qIj>9tNf)Z+91l|Ly%}_D@ul zsAn(n^mS!_#KX=lBk2D&{5}H%qn4+OV~EE2-brV@oB~DMzW1v2cBy@1;GO-&?&6Y~ zW{oDf18$B2lAZ#+TwkXx5}KGW%Q0X<<5h);bqD4*s<~D5&%3JN__k|%zOPw(Dc}7@ z-4ptmhf6B&&b!_FjBE9pn*uC5&60xesh+<(kE_1GagvF-8H=anvo~dTmJ2zopr03(~h8~^|S delta 547 zcmV+;0^I$#1l$CW865@y005ATEwumu010qNS#tmY3ljhU3ljkVnw%JsF)n`r;z>k7 zRCwB~R6VQOP#AvB$vH7i{6H{96zot$7cZT<7246EF5Np6N}+$IbiG6Wg#87A+NFaX z+=_^xM1#gCtshC=E{%9^uQX_%?YwXvo{#q&MnpJ8uh(O?ZRc&~_1%^SsPxGh+H0ARIRr6-fgr(&`AvRbVopU=ZE3`i-#IY(T(03h1! zHlI$XuT0Z?QLoowSr&9%hm;bRKr9vulZf8dYBk-mEEt9XAp|Z3_dI{ESuU5KManqm zxCT53f<~cGcyz6@BcYV?X(p55QD*n|()axbFP@uoRaLW*RmK>?FuWV`8P(_JTuM0x za9oSH>v7gH5q0+a{n6^xr4Z4#^?DtIVF)6+o={Pgua4vV-0gPwAK-~Z;>U8i{O&jo zeBVD>zu$Ij!bYR#AUxE%gx1-^Km_jxcFjAyeMMJ1h6Nkljt z4md6I&Tj)?DTMgwd7j(v_urRFrN_}zR8Fdh=h=-k9M$rFl_8(j zC{hPbXF zRCwB?)W514K@j&X?z2*SxFI6-@HT2E2K=9X9%PbEK*!TBw&g( zDMC;|A)uGlRkOS9vd-?zNs%bR4d$w+ox_iFnE8fvIvv7^5<(>Te12Li7C)9srCzmK z{ZcNM{YIl9j{DePFgOWiS%!ZkNe~2q@H}s`*=&ATmUUaJ)!sCl&0hz|_x+QQl=6Uu zVTk2&N#pTY#&P_?w(aMRQc9$0iYSV(SS&Cc4u$Kw?`yT%O{>+4 zG{)E|2aGW&iUJ~nuIn%i1G!udhGD2u%BS=B{Aa)4f2H7o#TWx)44QwYp-?EGQmLR` zuWJBatk>&D4~C9GRaIe{CMuN*Y}>YiAb55*w8!?7RjXAdgm|nRU-P-8>pCpUg0Abk z1Egu%*;6Ts0@E~^VHnGcRy)T2PIh+{L`2}63nKceT!Tm{5r*N0h`wJn(Qdbc=XpI< zRejI}C8Z?JIZY;$MYn(3eL_S~E?G$kf%STwOsCU#LWpkwpzRN{EIZ`sU-={YlWop9 zR;!g54u_wDAb8zwx6^y+C!%`@5g|=eaLy6Ov2fB#XE uB-n1ZVH8E5Ip=Q~W4DguM8|!<2LNApMvO2l*qs0X002ovPDBK*LSTZi=Kr7o diff --git a/doc/html/search/variables_0.html b/doc/html/search/variables_0.html index 74ce807..bf3eba5 100644 --- a/doc/html/search/variables_0.html +++ b/doc/html/search/variables_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_0.js b/doc/html/search/variables_0.js index 3ea3b0e..c93a397 100644 --- a/doc/html/search/variables_0.js +++ b/doc/html/search/variables_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['already_5ffile_5fopen',['ALREADY_FILE_OPEN',['../structerror_code.html#a19dc49bdfb4bd9601f17f907da158026',1,'errorCode']]] + ['already_5ffile_5fopen_1129',['ALREADY_FILE_OPEN',['../structerror_code.html#a19dc49bdfb4bd9601f17f907da158026',1,'errorCode']]] ]; diff --git a/doc/html/search/variables_1.html b/doc/html/search/variables_1.html index 84237b6..49fe59a 100644 --- a/doc/html/search/variables_1.html +++ b/doc/html/search/variables_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_1.js b/doc/html/search/variables_1.js index bb7f2da..cef0e70 100644 --- a/doc/html/search/variables_1.js +++ b/doc/html/search/variables_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['broadening',['broadening',['../struct_doniach_sunjic_struct.html#ac9b18c8b44b43c2ee438f37f8d002a66',1,'DoniachSunjicStruct']]] + ['broadening_1130',['broadening',['../struct_doniach_sunjic_struct.html#ac9b18c8b44b43c2ee438f37f8d002a66',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/variables_10.html b/doc/html/search/variables_10.html index 548ac84..92982ac 100644 --- a/doc/html/search/variables_10.html +++ b/doc/html/search/variables_10.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_10.js b/doc/html/search/variables_10.js index 7ff7b6f..215cdbf 100644 --- a/doc/html/search/variables_10.js +++ b/doc/html/search/variables_10.js @@ -1,5 +1,5 @@ var searchData= [ - ['xdw',['xdw',['../struct_doniach_sunjic_struct.html#a750e7260bf5d4c936dadde714fb2db52',1,'DoniachSunjicStruct']]], - ['xw',['xw',['../struct_doniach_sunjic_struct.html#a45c3a3fa68850032e545907ca65ab982',1,'DoniachSunjicStruct']]] + ['xdw_1198',['xdw',['../struct_doniach_sunjic_struct.html#a750e7260bf5d4c936dadde714fb2db52',1,'DoniachSunjicStruct']]], + ['xw_1199',['xw',['../struct_doniach_sunjic_struct.html#a45c3a3fa68850032e545907ca65ab982',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/variables_11.html b/doc/html/search/variables_11.html index d5be914..94f1a8c 100644 --- a/doc/html/search/variables_11.html +++ b/doc/html/search/variables_11.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_11.js b/doc/html/search/variables_11.js index 246bc4f..9b3ea26 100644 --- a/doc/html/search/variables_11.js +++ b/doc/html/search/variables_11.js @@ -1,4 +1,4 @@ var searchData= [ - ['yw',['yw',['../struct_doniach_sunjic_struct.html#a6cef648ad0cf4be1dd9fbe33ff5df1eb',1,'DoniachSunjicStruct']]] + ['yw_1200',['yw',['../struct_doniach_sunjic_struct.html#a6cef648ad0cf4be1dd9fbe33ff5df1eb',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/variables_2.html b/doc/html/search/variables_2.html index 5c9de1a..0c8a18c 100644 --- a/doc/html/search/variables_2.html +++ b/doc/html/search/variables_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_2.js b/doc/html/search/variables_2.js index a0bbba2..8b2a115 100644 --- a/doc/html/search/variables_2.js +++ b/doc/html/search/variables_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['convolution',['convolution',['../struct_doniach_sunjic_struct.html#a7f05f7827435fea3c986a8d538496955',1,'DoniachSunjicStruct']]] + ['convolution_1131',['convolution',['../struct_doniach_sunjic_struct.html#a7f05f7827435fea3c986a8d538496955',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/variables_3.html b/doc/html/search/variables_3.html index f95e34c..19a31fc 100644 --- a/doc/html/search/variables_3.html +++ b/doc/html/search/variables_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_3.js b/doc/html/search/variables_3.js index 40890e0..9c7d456 100644 --- a/doc/html/search/variables_3.js +++ b/doc/html/search/variables_3.js @@ -1,6 +1,6 @@ var searchData= [ - ['elog_5fparse_5fid',['elog_parse_id',['../pearl-elog_8ipf.html#a6a9923c6465c91b1f9d1d97b090f424b',1,'pearl-elog.ipf']]], - ['elog_5fsuccess_5fmsg',['elog_success_msg',['../pearl-elog_8ipf.html#a63aa38b624b66fe502505040c25bc0c3',1,'pearl-elog.ipf']]], - ['empty_5fresultfile',['EMPTY_RESULTFILE',['../structerror_code.html#ab7f29ef2ba8497c55f2bc55c4b9fc186',1,'errorCode']]] + ['elog_5fparse_5fid_1132',['elog_parse_id',['../pearl-elog_8ipf.html#a6a9923c6465c91b1f9d1d97b090f424b',1,'pearl-elog.ipf']]], + ['elog_5fsuccess_5fmsg_1133',['elog_success_msg',['../pearl-elog_8ipf.html#a63aa38b624b66fe502505040c25bc0c3',1,'pearl-elog.ipf']]], + ['empty_5fresultfile_1134',['EMPTY_RESULTFILE',['../structerror_code.html#ab7f29ef2ba8497c55f2bc55c4b9fc186',1,'errorCode']]] ]; diff --git a/doc/html/search/variables_4.html b/doc/html/search/variables_4.html index d7db285..bdc37be 100644 --- a/doc/html/search/variables_4.html +++ b/doc/html/search/variables_4.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_4.js b/doc/html/search/variables_4.js index 8d1f5fa..59076a7 100644 --- a/doc/html/search/variables_4.js +++ b/doc/html/search/variables_4.js @@ -1,4 +1,4 @@ var searchData= [ - ['file_5fnot_5freadable',['FILE_NOT_READABLE',['../structerror_code.html#a71ce7c0413c44515d9570dab1ffd5ffd',1,'errorCode']]] + ['file_5fnot_5freadable_1135',['FILE_NOT_READABLE',['../structerror_code.html#a71ce7c0413c44515d9570dab1ffd5ffd',1,'errorCode']]] ]; diff --git a/doc/html/search/variables_5.html b/doc/html/search/variables_5.html index 7bbceeb..6aa2249 100644 --- a/doc/html/search/variables_5.html +++ b/doc/html/search/variables_5.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_5.js b/doc/html/search/variables_5.js index 41a5336..8daa63e 100644 --- a/doc/html/search/variables_5.js +++ b/doc/html/search/variables_5.js @@ -1,4 +1,4 @@ var searchData= [ - ['hemi_5fradius_5fmm',['hemi_radius_mm',['../fermi-edge-analysis_8ipf.html#a0cb8da36beae05c79fe5b1da918d3897',1,'fermi-edge-analysis.ipf']]] + ['hemi_5fradius_5fmm_1136',['hemi_radius_mm',['../fermi-edge-analysis_8ipf.html#a0cb8da36beae05c79fe5b1da918d3897',1,'fermi-edge-analysis.ipf']]] ]; diff --git a/doc/html/search/variables_6.html b/doc/html/search/variables_6.html index 4eb162d..ce4a906 100644 --- a/doc/html/search/variables_6.html +++ b/doc/html/search/variables_6.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_6.js b/doc/html/search/variables_6.js index a9f05aa..9379c64 100644 --- a/doc/html/search/variables_6.js +++ b/doc/html/search/variables_6.js @@ -1,5 +1,5 @@ var searchData= [ - ['internal_5ferror_5fconverting_5fdata',['INTERNAL_ERROR_CONVERTING_DATA',['../structerror_code.html#afb49d1cffe8e7590892b018ac9e648cc',1,'errorCode']]], - ['invalid_5frange',['INVALID_RANGE',['../structerror_code.html#a5477920df1edcc7a1af0513d9120947a',1,'errorCode']]] + ['internal_5ferror_5fconverting_5fdata_1137',['INTERNAL_ERROR_CONVERTING_DATA',['../structerror_code.html#afb49d1cffe8e7590892b018ac9e648cc',1,'errorCode']]], + ['invalid_5frange_1138',['INVALID_RANGE',['../structerror_code.html#a5477920df1edcc7a1af0513d9120947a',1,'errorCode']]] ]; diff --git a/doc/html/search/variables_7.html b/doc/html/search/variables_7.html index 0408829..39ffd47 100644 --- a/doc/html/search/variables_7.html +++ b/doc/html/search/variables_7.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_7.js b/doc/html/search/variables_7.js index 821ed85..61f6cb8 100644 --- a/doc/html/search/variables_7.js +++ b/doc/html/search/variables_7.js @@ -1,32 +1,45 @@ var searchData= [ - ['kangledimlabel',['kAngleDimLabel',['../pearl-pshell-import_8ipf.html#a83930d4384b0238fc8416ba03dbc0386',1,'pearl-pshell-import.ipf']]], - ['kattachcolname',['kAttachColName',['../pearl-elog_8ipf.html#addbdec64930e9c1e417b16b25df8c723',1,'pearl-elog.ipf']]], - ['kattachcolsel',['kAttachColSel',['../pearl-elog_8ipf.html#aae61ff4d4a4d83dfc55af45d9ed1cbc3',1,'pearl-elog.ipf']]], - ['kattachcoltitle',['kAttachColTitle',['../pearl-elog_8ipf.html#a5afeb893f92034532341ae51471dc2d2',1,'pearl-elog.ipf']]], - ['kdatadimlabel',['kDataDimLabel',['../pearl-pshell-import_8ipf.html#a277cd450cca7832aa44f8097934e6acb',1,'pearl-pshell-import.ipf']]], - ['kdetectorsensitivity',['kDetectorSensitivity',['../pearl-pshell-import_8ipf.html#a5745428740b64cd66394a7fcd78b86f1',1,'pearl-pshell-import.ipf']]], - ['kdfpersistent',['kdfPersistent',['../pearl-elog_8ipf.html#a3498e65d04de046481170b49d4e3d0d6',1,'pearl-elog.ipf']]], - ['kdfroot',['kdfRoot',['../pearl-elog_8ipf.html#af34e46263aa50843f98f755988f9ab5c',1,'pearl-elog.ipf']]], - ['kdftemplates',['kdfTemplates',['../pearl-elog_8ipf.html#a28eb44739e7d5c7f9899a69afa231b8e',1,'pearl-elog.ipf']]], - ['kdfvolatile',['kdfVolatile',['../pearl-elog_8ipf.html#a915905f2e57d0d9a25c75f39fcce485f',1,'pearl-elog.ipf']]], - ['kenergydimlabel',['kEnergyDimLabel',['../pearl-pshell-import_8ipf.html#a5ad52cb10171572c454f9426d3a9be21',1,'pearl-pshell-import.ipf']]], - ['kpreviewdatasets',['kPreviewDatasets',['../pearl-pshell-import_8ipf.html#a3c72087695969f42ea91c000de47b26e',1,'pearl-pshell-import.ipf']]], - ['kprojarea',['kProjArea',['../pearl-anglescan-process_8ipf.html#a207c56ac03cc18bf1bfde88dbfe2666f',1,'pearl-anglescan-process.ipf']]], - ['kprojdist',['kProjDist',['../pearl-anglescan-process_8ipf.html#aae45cc49d67f79dcedc4420f82acea4c',1,'pearl-anglescan-process.ipf']]], - ['kprojgnom',['kProjGnom',['../pearl-anglescan-process_8ipf.html#a4a40c73c0e03545e0050ea370e9c57d3',1,'pearl-anglescan-process.ipf']]], - ['kprojortho',['kProjOrtho',['../pearl-anglescan-process_8ipf.html#a3b3bd11c35d5f850b34937ab6c45f659',1,'pearl-anglescan-process.ipf']]], - ['kprojscalearea',['kProjScaleArea',['../pearl-anglescan-process_8ipf.html#afa14187803f5b428a96c8234e04ab217',1,'pearl-anglescan-process.ipf']]], - ['kprojscaledist',['kProjScaleDist',['../pearl-anglescan-process_8ipf.html#a04e75675884236b6ed8244d7575d3a13',1,'pearl-anglescan-process.ipf']]], - ['kprojscalegnom',['kProjScaleGnom',['../pearl-anglescan-process_8ipf.html#ab6670abb621d01994c0b9974f58be843',1,'pearl-anglescan-process.ipf']]], - ['kprojscaleortho',['kProjScaleOrtho',['../pearl-anglescan-process_8ipf.html#aa5487fdee22e0da61a511c14239262f5',1,'pearl-anglescan-process.ipf']]], - ['kprojscalestereo',['kProjScaleStereo',['../pearl-anglescan-process_8ipf.html#aed66bda9701d8a69b2174fac974aa665',1,'pearl-anglescan-process.ipf']]], - ['kprojstereo',['kProjStereo',['../pearl-anglescan-process_8ipf.html#ac151c6f989d6a568fdef0acb791f84db',1,'pearl-anglescan-process.ipf']]], - ['ks_5ffilematch_5fadh5',['ks_filematch_adh5',['../pearl-data-explorer_8ipf.html#a181ccce237172811baf3de5a7a06370d',1,'pearl-data-explorer.ipf']]], - ['ks_5ffilematch_5fitx',['ks_filematch_itx',['../pearl-data-explorer_8ipf.html#a53af8689144e3aeb27ca177db5dd0c22',1,'pearl-data-explorer.ipf']]], - ['ks_5ffilematch_5fmtrx',['ks_filematch_mtrx',['../pearl-data-explorer_8ipf.html#ad720655ff881ddecae2e1b8afed58fa0',1,'ks_filematch_mtrx(): pearl-data-explorer.ipf'],['../pearl-matrix-import_8ipf.html#ad720655ff881ddecae2e1b8afed58fa0',1,'ks_filematch_mtrx(): pearl-matrix-import.ipf']]], - ['ks_5ffilematch_5fpshell',['ks_filematch_pshell',['../pearl-data-explorer_8ipf.html#a00bf5267a40b2b3d760c64d73e139878',1,'pearl-data-explorer.ipf']]], - ['kscandimlabel',['kScanDimLabel',['../pearl-pshell-import_8ipf.html#a412b4753ceb753d705a113a26c018b22',1,'pearl-pshell-import.ipf']]], - ['kscientascalingdatasets',['kScientaScalingDatasets',['../pearl-pshell-import_8ipf.html#a03f00b3299bc3df671fcc239f7dd5418',1,'pearl-pshell-import.ipf']]], - ['ktransposeddatasets',['kTransposedDatasets',['../pearl-pshell-import_8ipf.html#a0f2c168c04d075734edb995361aefb82',1,'pearl-pshell-import.ipf']]] + ['kangledimlabel_1139',['kAngleDimLabel',['../pearl-pshell-import_8ipf.html#a83930d4384b0238fc8416ba03dbc0386',1,'pearl-pshell-import.ipf']]], + ['kattachcolname_1140',['kAttachColName',['../pearl-elog_8ipf.html#addbdec64930e9c1e417b16b25df8c723',1,'pearl-elog.ipf']]], + ['kattachcolsel_1141',['kAttachColSel',['../pearl-elog_8ipf.html#aae61ff4d4a4d83dfc55af45d9ed1cbc3',1,'pearl-elog.ipf']]], + ['kattachcoltitle_1142',['kAttachColTitle',['../pearl-elog_8ipf.html#a5afeb893f92034532341ae51471dc2d2',1,'pearl-elog.ipf']]], + ['kdatadimlabel_1143',['kDataDimLabel',['../pearl-pshell-import_8ipf.html#a277cd450cca7832aa44f8097934e6acb',1,'pearl-pshell-import.ipf']]], + ['kdfpersistent_1144',['kdfPersistent',['../pearl-elog_8ipf.html#a3498e65d04de046481170b49d4e3d0d6',1,'pearl-elog.ipf']]], + ['kdfroot_1145',['kdfRoot',['../pearl-elog_8ipf.html#af34e46263aa50843f98f755988f9ab5c',1,'pearl-elog.ipf']]], + ['kdftemplates_1146',['kdfTemplates',['../pearl-elog_8ipf.html#a28eb44739e7d5c7f9899a69afa231b8e',1,'pearl-elog.ipf']]], + ['kdfvolatile_1147',['kdfVolatile',['../pearl-elog_8ipf.html#a915905f2e57d0d9a25c75f39fcce485f',1,'pearl-elog.ipf']]], + ['kdscall_1148',['kDSCAll',['../pearl-pshell-import_8ipf.html#a237e95f14b988f58e2d4c37659f17347',1,'pearl-pshell-import.ipf']]], + ['kdscattrs_1149',['kDSCAttrs',['../pearl-pshell-import_8ipf.html#a10224f615973777a43fefae8eb1a39f2',1,'pearl-pshell-import.ipf']]], + ['kdscdetectors_1150',['kDSCDetectors',['../pearl-pshell-import_8ipf.html#a7c5aaa2f133862ae16ddd735df1ab73d',1,'pearl-pshell-import.ipf']]], + ['kdscdiags_1151',['kDSCDiags',['../pearl-pshell-import_8ipf.html#adf778206fa825ab5006bd553c64a8760',1,'pearl-pshell-import.ipf']]], + ['kdscessentialdiags_1152',['kDSCEssentialDiags',['../pearl-pshell-import_8ipf.html#aebf53e3de392d631b340ee0747b8bbbf',1,'pearl-pshell-import.ipf']]], + ['kdscmeta_1153',['kDSCMeta',['../pearl-pshell-import_8ipf.html#a712ea7a6f18ce4178fd06b07d2d05a9f',1,'pearl-pshell-import.ipf']]], + ['kdscmonitors_1154',['kDSCMonitors',['../pearl-pshell-import_8ipf.html#a300847a8e08161a64a199a6e7ef165c8',1,'pearl-pshell-import.ipf']]], + ['kdscother_1155',['kDSCOther',['../pearl-pshell-import_8ipf.html#ac81d8f4276cf7bb86a74796cc7199e42',1,'pearl-pshell-import.ipf']]], + ['kdscpositioners_1156',['kDSCPositioners',['../pearl-pshell-import_8ipf.html#aeb9a7f56922ff3c862e8b29b5090c01a',1,'pearl-pshell-import.ipf']]], + ['kdscpreview_1157',['kDSCPreview',['../pearl-pshell-import_8ipf.html#a654f0b9fe8770a8bd09a6da4182ca3bc',1,'pearl-pshell-import.ipf']]], + ['kdscregions_1158',['kDSCRegions',['../pearl-pshell-import_8ipf.html#a48f07030482af8315447ac2c598edd0d',1,'pearl-pshell-import.ipf']]], + ['kdscscientascaling_1159',['kDSCScientaScaling',['../pearl-pshell-import_8ipf.html#ab7c2cc8687f6d4550ef90c538b938dad',1,'pearl-pshell-import.ipf']]], + ['kdscsnaps_1160',['kDSCSnaps',['../pearl-pshell-import_8ipf.html#a3236744797a780eb144a684b0bd41d4a',1,'pearl-pshell-import.ipf']]], + ['kenergydimlabel_1161',['kEnergyDimLabel',['../pearl-pshell-import_8ipf.html#a5ad52cb10171572c454f9426d3a9be21',1,'pearl-pshell-import.ipf']]], + ['kessentialdiagnostics_1162',['kEssentialDiagnostics',['../pearl-pshell-import_8ipf.html#ab0bc752ab76659b492cf88c75935336b',1,'pearl-pshell-import.ipf']]], + ['kpreviewdatasets_1163',['kPreviewDatasets',['../pearl-pshell-import_8ipf.html#a3c72087695969f42ea91c000de47b26e',1,'pearl-pshell-import.ipf']]], + ['kprojarea_1164',['kProjArea',['../pearl-anglescan-process_8ipf.html#a207c56ac03cc18bf1bfde88dbfe2666f',1,'pearl-anglescan-process.ipf']]], + ['kprojdist_1165',['kProjDist',['../pearl-anglescan-process_8ipf.html#aae45cc49d67f79dcedc4420f82acea4c',1,'pearl-anglescan-process.ipf']]], + ['kprojgnom_1166',['kProjGnom',['../pearl-anglescan-process_8ipf.html#a4a40c73c0e03545e0050ea370e9c57d3',1,'pearl-anglescan-process.ipf']]], + ['kprojortho_1167',['kProjOrtho',['../pearl-anglescan-process_8ipf.html#a3b3bd11c35d5f850b34937ab6c45f659',1,'pearl-anglescan-process.ipf']]], + ['kprojscalearea_1168',['kProjScaleArea',['../pearl-anglescan-process_8ipf.html#afa14187803f5b428a96c8234e04ab217',1,'pearl-anglescan-process.ipf']]], + ['kprojscaledist_1169',['kProjScaleDist',['../pearl-anglescan-process_8ipf.html#a04e75675884236b6ed8244d7575d3a13',1,'pearl-anglescan-process.ipf']]], + ['kprojscalegnom_1170',['kProjScaleGnom',['../pearl-anglescan-process_8ipf.html#ab6670abb621d01994c0b9974f58be843',1,'pearl-anglescan-process.ipf']]], + ['kprojscaleortho_1171',['kProjScaleOrtho',['../pearl-anglescan-process_8ipf.html#aa5487fdee22e0da61a511c14239262f5',1,'pearl-anglescan-process.ipf']]], + ['kprojscalestereo_1172',['kProjScaleStereo',['../pearl-anglescan-process_8ipf.html#aed66bda9701d8a69b2174fac974aa665',1,'pearl-anglescan-process.ipf']]], + ['kprojstereo_1173',['kProjStereo',['../pearl-anglescan-process_8ipf.html#ac151c6f989d6a568fdef0acb791f84db',1,'pearl-anglescan-process.ipf']]], + ['ks_5ffilematch_5fadh5_1174',['ks_filematch_adh5',['../pearl-data-explorer_8ipf.html#a181ccce237172811baf3de5a7a06370d',1,'pearl-data-explorer.ipf']]], + ['ks_5ffilematch_5fitx_1175',['ks_filematch_itx',['../pearl-data-explorer_8ipf.html#a53af8689144e3aeb27ca177db5dd0c22',1,'pearl-data-explorer.ipf']]], + ['ks_5ffilematch_5fmtrx_1176',['ks_filematch_mtrx',['../pearl-matrix-import_8ipf.html#ad720655ff881ddecae2e1b8afed58fa0',1,'pearl-matrix-import.ipf']]], + ['ks_5ffilematch_5fpshell_1177',['ks_filematch_pshell',['../pearl-data-explorer_8ipf.html#a00bf5267a40b2b3d760c64d73e139878',1,'pearl-data-explorer.ipf']]], + ['kscandimlabel_1178',['kScanDimLabel',['../pearl-pshell-import_8ipf.html#a412b4753ceb753d705a113a26c018b22',1,'pearl-pshell-import.ipf']]], + ['kscientascalingdatasets_1179',['kScientaScalingDatasets',['../pearl-pshell-import_8ipf.html#a03f00b3299bc3df671fcc239f7dd5418',1,'pearl-pshell-import.ipf']]], + ['ktransposeddatasets_1180',['kTransposedDatasets',['../pearl-pshell-import_8ipf.html#a0f2c168c04d075734edb995361aefb82',1,'pearl-pshell-import.ipf']]] ]; diff --git a/doc/html/search/variables_8.html b/doc/html/search/variables_8.html index d54d096..37a2edd 100644 --- a/doc/html/search/variables_8.html +++ b/doc/html/search/variables_8.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_8.js b/doc/html/search/variables_8.js index 2e11c71..24df646 100644 --- a/doc/html/search/variables_8.js +++ b/doc/html/search/variables_8.js @@ -1,7 +1,7 @@ var searchData= [ - ['mcp_5fradius_5fepass',['mcp_radius_epass',['../fermi-edge-analysis_8ipf.html#a4749b9bce3e1d0381bd9daeb97c9754c',1,'fermi-edge-analysis.ipf']]], - ['mcp_5fradius_5fmm',['mcp_radius_mm',['../fermi-edge-analysis_8ipf.html#a4dcc00b93822f1663be2908b10d2ad3e',1,'fermi-edge-analysis.ipf']]], - ['mcp_5fradius_5fpix',['mcp_radius_pix',['../fermi-edge-analysis_8ipf.html#a09f26b0a0fd940a3d8c6f92aa769c8bc',1,'fermi-edge-analysis.ipf']]], - ['model',['model',['../struct_doniach_sunjic_struct.html#a02c13fdcf15e9adfee13464701bb7de2',1,'DoniachSunjicStruct']]] + ['mcp_5fradius_5fepass_1181',['mcp_radius_epass',['../fermi-edge-analysis_8ipf.html#a4749b9bce3e1d0381bd9daeb97c9754c',1,'fermi-edge-analysis.ipf']]], + ['mcp_5fradius_5fmm_1182',['mcp_radius_mm',['../fermi-edge-analysis_8ipf.html#a4dcc00b93822f1663be2908b10d2ad3e',1,'fermi-edge-analysis.ipf']]], + ['mcp_5fradius_5fpix_1183',['mcp_radius_pix',['../fermi-edge-analysis_8ipf.html#a09f26b0a0fd940a3d8c6f92aa769c8bc',1,'fermi-edge-analysis.ipf']]], + ['model_1184',['model',['../struct_doniach_sunjic_struct.html#a02c13fdcf15e9adfee13464701bb7de2',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/variables_9.html b/doc/html/search/variables_9.html index 234dc60..21e5a4f 100644 --- a/doc/html/search/variables_9.html +++ b/doc/html/search/variables_9.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_9.js b/doc/html/search/variables_9.js index 9df99a2..16a5386 100644 --- a/doc/html/search/variables_9.js +++ b/doc/html/search/variables_9.js @@ -1,5 +1,5 @@ var searchData= [ - ['no_5ffile_5fopen',['NO_FILE_OPEN',['../structerror_code.html#affc9a8a46877373b0212d82d867ca5fa',1,'errorCode']]], - ['no_5fnew_5fbricklets',['NO_NEW_BRICKLETS',['../structerror_code.html#a4ec3cbf922809b99b04d324d3a0bbb22',1,'errorCode']]] + ['no_5ffile_5fopen_1185',['NO_FILE_OPEN',['../structerror_code.html#affc9a8a46877373b0212d82d867ca5fa',1,'errorCode']]], + ['no_5fnew_5fbricklets_1186',['NO_NEW_BRICKLETS',['../structerror_code.html#a4ec3cbf922809b99b04d324d3a0bbb22',1,'errorCode']]] ]; diff --git a/doc/html/search/variables_a.html b/doc/html/search/variables_a.html index 0892488..1f65055 100644 --- a/doc/html/search/variables_a.html +++ b/doc/html/search/variables_a.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_a.js b/doc/html/search/variables_a.js index c034cbd..f7d8a18 100644 --- a/doc/html/search/variables_a.js +++ b/doc/html/search/variables_a.js @@ -1,4 +1,4 @@ var searchData= [ - ['oversampling',['oversampling',['../struct_doniach_sunjic_struct.html#ab5a630be50286c3cf04e40d5880506e6',1,'DoniachSunjicStruct']]] + ['oversampling_1187',['oversampling',['../struct_doniach_sunjic_struct.html#ab5a630be50286c3cf04e40d5880506e6',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/variables_b.html b/doc/html/search/variables_b.html index ea46965..c02d066 100644 --- a/doc/html/search/variables_b.html +++ b/doc/html/search/variables_b.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_b.js b/doc/html/search/variables_b.js index f1061a8..e26a98c 100644 --- a/doc/html/search/variables_b.js +++ b/doc/html/search/variables_b.js @@ -1,8 +1,8 @@ var searchData= [ - ['package_5fname',['package_name',['../pearl-anglescan-panel_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-anglescan-panel.ipf'],['../pearl-data-explorer_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-matrix-import.ipf']]], - ['package_5fpath',['package_path',['../pearl-anglescan-panel_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-matrix-import.ipf']]], - ['precision',['precision',['../struct_doniach_sunjic_struct.html#a906e214875392bc470dbd4bb4bdda2db',1,'DoniachSunjicStruct']]], - ['prefs_5fobjects',['prefs_objects',['../pearl-anglescan-tracker_8ipf.html#a20720748c82a7eaa4b02d4084a4219b2',1,'pearl-anglescan-tracker.ipf']]], - ['pw',['pw',['../struct_doniach_sunjic_struct.html#a92bbb374f66840510e7cb8b316057610',1,'DoniachSunjicStruct']]] + ['package_5fname_1188',['package_name',['../pearl-anglescan-panel_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-anglescan-panel.ipf'],['../pearl-elog_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#aca457d1f4414d20a911254b1de13ebbb',1,'package_name(): pearl-matrix-import.ipf']]], + ['package_5fpath_1189',['package_path',['../pearl-anglescan-panel_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-anglescan-panel.ipf'],['../pearl-anglescan-tracker_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-data-explorer.ipf'],['../pearl-elog_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-elog.ipf'],['../pearl-matrix-import_8ipf.html#a75bb92ef5f80843e66a7243bd958ef8b',1,'package_path(): pearl-matrix-import.ipf']]], + ['precision_1190',['precision',['../struct_doniach_sunjic_struct.html#a906e214875392bc470dbd4bb4bdda2db',1,'DoniachSunjicStruct']]], + ['prefs_5fobjects_1191',['prefs_objects',['../pearl-anglescan-tracker_8ipf.html#a20720748c82a7eaa4b02d4084a4219b2',1,'pearl-anglescan-tracker.ipf']]], + ['pw_1192',['pw',['../struct_doniach_sunjic_struct.html#a92bbb374f66840510e7cb8b316057610',1,'DoniachSunjicStruct']]] ]; diff --git a/doc/html/search/variables_c.html b/doc/html/search/variables_c.html index 94bf1a6..4b866c6 100644 --- a/doc/html/search/variables_c.html +++ b/doc/html/search/variables_c.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_c.js b/doc/html/search/variables_c.js index 9ab9270..ef9de86 100644 --- a/doc/html/search/variables_c.js +++ b/doc/html/search/variables_c.js @@ -1,4 +1,4 @@ var searchData= [ - ['success',['SUCCESS',['../structerror_code.html#a36a53ca508600b841a54cfd3a3fd5402',1,'errorCode']]] + ['success_1193',['SUCCESS',['../structerror_code.html#a36a53ca508600b841a54cfd3a3fd5402',1,'errorCode']]] ]; diff --git a/doc/html/search/variables_d.html b/doc/html/search/variables_d.html index b9381e9..84d878b 100644 --- a/doc/html/search/variables_d.html +++ b/doc/html/search/variables_d.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_d.js b/doc/html/search/variables_d.js index 81d5a85..898d8f8 100644 --- a/doc/html/search/variables_d.js +++ b/doc/html/search/variables_d.js @@ -1,4 +1,4 @@ var searchData= [ - ['unknown_5ferror',['UNKNOWN_ERROR',['../structerror_code.html#a11b729058e2f4a2698ddaecf4e61c846',1,'errorCode']]] + ['unknown_5ferror_1194',['UNKNOWN_ERROR',['../structerror_code.html#a11b729058e2f4a2698ddaecf4e61c846',1,'errorCode']]] ]; diff --git a/doc/html/search/variables_e.html b/doc/html/search/variables_e.html index 375ad70..b0d9b7b 100644 --- a/doc/html/search/variables_e.html +++ b/doc/html/search/variables_e.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_e.js b/doc/html/search/variables_e.js index 5666e3b..a95d6d0 100644 --- a/doc/html/search/variables_e.js +++ b/doc/html/search/variables_e.js @@ -1,4 +1,4 @@ var searchData= [ - ['version',['version',['../pearl-anglescan-tracker_8ipf.html#a4c7a521b8f1a0769c09bfa4a1fca7dab',1,'pearl-anglescan-tracker.ipf']]] + ['version_1195',['version',['../pearl-anglescan-tracker_8ipf.html#a4c7a521b8f1a0769c09bfa4a1fca7dab',1,'version(): pearl-anglescan-tracker.ipf'],['../pearl-data-explorer_8ipf.html#a4c7a521b8f1a0769c09bfa4a1fca7dab',1,'version(): pearl-data-explorer.ipf']]] ]; diff --git a/doc/html/search/variables_f.html b/doc/html/search/variables_f.html index d371418..a708dbf 100644 --- a/doc/html/search/variables_f.html +++ b/doc/html/search/variables_f.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,19 @@
    Loading...
    Searching...
    No Matches
    diff --git a/doc/html/search/variables_f.js b/doc/html/search/variables_f.js index 489677e..2b31d42 100644 --- a/doc/html/search/variables_f.js +++ b/doc/html/search/variables_f.js @@ -1,5 +1,5 @@ var searchData= [ - ['wave_5fexist',['WAVE_EXIST',['../structerror_code.html#aa91bd8ef7a635f4575161813ebb09f3b',1,'errorCode']]], - ['wrong_5fparameter',['WRONG_PARAMETER',['../structerror_code.html#aa4279dfdaceed3bd57336cd4e38ed739',1,'errorCode']]] + ['wave_5fexist_1196',['WAVE_EXIST',['../structerror_code.html#aa91bd8ef7a635f4575161813ebb09f3b',1,'errorCode']]], + ['wrong_5fparameter_1197',['WRONG_PARAMETER',['../structerror_code.html#aa4279dfdaceed3bd57336cd4e38ed739',1,'errorCode']]] ]; diff --git a/doc/html/struct_doniach_sunjic_struct.html b/doc/html/struct_doniach_sunjic_struct.html index cbe169c..db0c002 100644 --- a/doc/html/struct_doniach_sunjic_struct.html +++ b/doc/html/struct_doniach_sunjic_struct.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: DoniachSunjicStruct Struct Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -111,7 +113,7 @@ Data Fields

    Detailed Description

    -

    Definition at line 370 of file pearl-fitfuncs.ipf.

    +

    Definition at line 449 of file pearl-fitfuncs.ipf.

    Field Documentation

    ◆ broadening

    @@ -125,7 +127,7 @@ Data Fields
    -

    Definition at line 386 of file pearl-fitfuncs.ipf.

    +

    Definition at line 465 of file pearl-fitfuncs.ipf.

    @@ -141,7 +143,7 @@ Data Fields
    -

    Definition at line 387 of file pearl-fitfuncs.ipf.

    +

    Definition at line 466 of file pearl-fitfuncs.ipf.

    @@ -157,7 +159,7 @@ Data Fields
    -

    Definition at line 385 of file pearl-fitfuncs.ipf.

    +

    Definition at line 464 of file pearl-fitfuncs.ipf.

    @@ -173,7 +175,7 @@ Data Fields
    -

    Definition at line 380 of file pearl-fitfuncs.ipf.

    +

    Definition at line 459 of file pearl-fitfuncs.ipf.

    @@ -189,7 +191,7 @@ Data Fields
    -

    Definition at line 379 of file pearl-fitfuncs.ipf.

    +

    Definition at line 458 of file pearl-fitfuncs.ipf.

    @@ -205,7 +207,7 @@ Data Fields
    -

    Definition at line 370 of file pearl-fitfuncs.ipf.

    +

    Definition at line 449 of file pearl-fitfuncs.ipf.

    @@ -221,7 +223,7 @@ Data Fields
    -

    Definition at line 384 of file pearl-fitfuncs.ipf.

    +

    Definition at line 463 of file pearl-fitfuncs.ipf.

    @@ -237,7 +239,7 @@ Data Fields
    -

    Definition at line 376 of file pearl-fitfuncs.ipf.

    +

    Definition at line 455 of file pearl-fitfuncs.ipf.

    @@ -253,7 +255,7 @@ Data Fields
    -

    Definition at line 375 of file pearl-fitfuncs.ipf.

    +

    Definition at line 454 of file pearl-fitfuncs.ipf.

    @@ -266,9 +268,9 @@ Data Fields diff --git a/doc/html/structerror_code.html b/doc/html/structerror_code.html index 5b320ae..ff88b07 100644 --- a/doc/html/structerror_code.html +++ b/doc/html/structerror_code.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: errorCode Struct Reference @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -119,7 +121,7 @@ Data Fields

    Detailed Description

    from matrixfilereader help

    -

    Definition at line 197 of file pearl-matrix-import.ipf.

    +

    Definition at line 198 of file pearl-matrix-import.ipf.

    Field Documentation

    ◆ ALREADY_FILE_OPEN

    @@ -133,7 +135,7 @@ Data Fields
    -

    Definition at line 200 of file pearl-matrix-import.ipf.

    +

    Definition at line 201 of file pearl-matrix-import.ipf.

    @@ -149,7 +151,7 @@ Data Fields
    -

    Definition at line 201 of file pearl-matrix-import.ipf.

    +

    Definition at line 202 of file pearl-matrix-import.ipf.

    @@ -165,7 +167,7 @@ Data Fields
    -

    Definition at line 202 of file pearl-matrix-import.ipf.

    +

    Definition at line 203 of file pearl-matrix-import.ipf.

    @@ -181,7 +183,7 @@ Data Fields
    -

    Definition at line 205 of file pearl-matrix-import.ipf.

    +

    Definition at line 206 of file pearl-matrix-import.ipf.

    @@ -197,7 +199,7 @@ Data Fields
    -

    Definition at line 207 of file pearl-matrix-import.ipf.

    +

    Definition at line 208 of file pearl-matrix-import.ipf.

    @@ -213,7 +215,7 @@ Data Fields
    -

    Definition at line 206 of file pearl-matrix-import.ipf.

    +

    Definition at line 207 of file pearl-matrix-import.ipf.

    @@ -229,7 +231,7 @@ Data Fields
    -

    Definition at line 203 of file pearl-matrix-import.ipf.

    +

    Definition at line 204 of file pearl-matrix-import.ipf.

    @@ -245,7 +247,7 @@ Data Fields
    -

    Definition at line 197 of file pearl-matrix-import.ipf.

    +

    Definition at line 198 of file pearl-matrix-import.ipf.

    @@ -261,7 +263,7 @@ Data Fields
    -

    Definition at line 199 of file pearl-matrix-import.ipf.

    +

    Definition at line 200 of file pearl-matrix-import.ipf.

    @@ -277,7 +279,7 @@ Data Fields
    -

    Definition at line 208 of file pearl-matrix-import.ipf.

    +

    Definition at line 209 of file pearl-matrix-import.ipf.

    @@ -293,7 +295,7 @@ Data Fields
    -

    Definition at line 204 of file pearl-matrix-import.ipf.

    +

    Definition at line 205 of file pearl-matrix-import.ipf.

    @@ -306,9 +308,9 @@ Data Fields diff --git a/doc/html/tabs.css b/doc/html/tabs.css index bbde11e..7d45d36 100644 --- a/doc/html/tabs.css +++ b/doc/html/tabs.css @@ -1 +1 @@ -.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:transparent}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} diff --git a/doc/html/todo.html b/doc/html/todo.html index 2b90bbd..ddbf7dc 100644 --- a/doc/html/todo.html +++ b/doc/html/todo.html @@ -1,9 +1,9 @@ - + - + PEARL Procedures: Todo List @@ -13,9 +13,6 @@ - @@ -29,7 +26,7 @@
    PEARL Procedures -  rev-distro-2.1.1-1-gf419e92-dirty +  rev-distro-3.0.0-0-gfa24916-dirty
    Igor procedures for the analysis of PEARL data
    @@ -38,18 +35,21 @@ - + +/* @license-end */
    @@ -63,7 +63,9 @@ $(function() {
    @@ -80,31 +82,32 @@ $(document).ready(function(){initNavTree('todo.html','');});
    -
    +
    Todo List
    -
    Global adh5_scale_scan (wave data)
    -
    incomplete
    -
    Global elog_validate_attributes (string logbook, string attributes)
    -
    function currently not implemented, always returns 0
    -
    Global epics_connect ()
    -
    the X03DA channel names are hard-coded.
    -
    Global load_hemi_scan (string nickname, string pathname, string filename)
    -
    function not implemented
    -
    Global mtrx_open_file (string pathName, string fileNameOrPath)
    -
    fix possible cache issues, add an option to override the cache.
    +
    Global adh5_scale_scan (wave data)
    +
    incomplete
    +
    Global elog_validate_attributes (string logbook, string attributes)
    +
    function currently not implemented, always returns 0
    +
    Global epics_connect ()
    +
    the X03DA channel names are hard-coded.
    +
    Global load_hemi_scan (string nickname, string pathname, string filename)
    +
    function not implemented
    +
    Global mtrx_open_file (string pathName, string fileNameOrPath)
    +
    fix possible cache issues, add an option to override the cache.
    +
    diff --git a/doc/latex/refman.pdf b/doc/latex/refman.pdf deleted file mode 100644 index 593f33f8adee56fe286526f4bf8f51eaf9b739dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 713498 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 z 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�${w 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 d`D7e_&mm%g|;o=F{ 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πW2l83F7Pu27Bh7sif#!F>d58JYUqht8jgGrYul3 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%0AssPn~s!mQ4ni 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 z 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

    nYLU_1IcwpGD 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

    7Mg{M%a56RLStdpN&ZnFBrM}3 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