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<