From e3e80f579663367f389c8fcecb05d2978dbfc1f8 Mon Sep 17 00:00:00 2001 From: matthias muntwiler Date: Thu, 9 Sep 2021 12:45:39 +0200 Subject: [PATCH] code changes for release 2.2.0 --- .gitignore | 1 + README.md | 18 +- pearl/electron-binding-energies.itx | 2375 +++++++++++++++++ pearl/fermi-edge-analysis.ipf | 22 +- pearl/pearl-anglescan-panel.ipf | 9 +- pearl/pearl-anglescan-process.ipf | 494 +++- pearl/pearl-anglescan-tracker.ipf | 1 + pearl/pearl-area-display.ipf | 2 + pearl/pearl-area-import.ipf | 7 +- pearl/pearl-area-profiles.ipf | 1 + pearl/pearl-arpes.ipf | 5 +- pearl/pearl-compat.ipf | 1 + pearl/pearl-data-explorer.ipf | 95 +- pearl/pearl-elog.ipf | 15 +- pearl/pearl-fitfuncs.ipf | 83 +- pearl/pearl-gui-tools.ipf | 1 + pearl/pearl-matrix-import.ipf | 1 + pearl/pearl-menu.ipf | 1 + pearl/pearl-pmsco-import.ipf | 132 + pearl/pearl-polar-coordinates.ipf | 1 + pearl/pearl-pshell-import.ipf | 148 +- ...a-countrate.ipf => pearl-scienta-live.ipf} | 38 +- pearl/pearl-scienta-preprocess.ipf | 237 +- pearl/pearl-tools.ipf | 1 + pearl/pearl-vector-operations.ipf | 68 +- 25 files changed, 3519 insertions(+), 238 deletions(-) create mode 100644 pearl/electron-binding-energies.itx rename pearl/{pearl-scienta-countrate.ipf => pearl-scienta-live.ipf} (87%) diff --git a/.gitignore b/.gitignore index 7d3b9a7..302d42c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ ~* *.bak *.ipfT* +doc/html/* doc/latex/* diff --git a/README.md b/README.md index a5e4f78..0f22b1a 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,13 @@ PEARL Procedures should be installed according to the regular Igor Pro guideline - Find the `HDF5.XOP` (`HDF5-64.xop` for Igor 7 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. -PEARL Procedures are compatible with Igor Pro versions 6.37 and 8.04, 32-bit and 64-bit. +PEARL Procedures are tested on Igor 8.04, 64-bit. Please make sure to use the latest release version. + +While most of the code remains compatible with Igor 6.37, it is not tested and not supported. +Importing recent PShell data files may requires Igor 8 due to changes in the HDF5 library. +Igor 7 contains some bugs which affect PEARL Procedures and should not be used. + As long as no Igor 8 specific features are used (long object names), the produced experiment files remain compatible with Igor 6. @@ -34,12 +39,16 @@ Matthias Muntwiler, Copyright --------- -Copyright 2009-2020 by [Paul Scherrer Institut](http://www.psi.ch) +Copyright 2009-2021 by [Paul Scherrer Institut](http://www.psi.ch) Release Notes ============= +## rev-distro-2.2.0 + +- Updates, bugfixes and performance improvements in angle scan processing. + ## rev-distro-2.1.0 - Check compatibility of major features with Igor 8. @@ -53,8 +62,3 @@ Release Notes - The interface of data reduction functions has changed to make data reduction more efficient in multi-peak fits. The supplied reduction functions and dialogs have been refactored. If you want to use your own reduction functions written for pre-2.0, you have to adapt them to the new interface. -## rev-distro-1.1.1 - -- If you have upgraded PEARL Procedures from pre-1.1.1 and Igor breaks in pearl-elog.ipf while opening an experiment, please delete the ELOG preferences file `pearl-elog/preferences.pxp`. (Check the Igor Help to find the package preferences folder on your system.) - - diff --git a/pearl/electron-binding-energies.itx b/pearl/electron-binding-energies.itx new file mode 100644 index 0000000..c353ef7 --- /dev/null +++ b/pearl/electron-binding-energies.itx @@ -0,0 +1,2375 @@ +IGOR + +X // Gwyn Williams' +X // Electron binding energies of the elements +X // (https://userweb.jlab.org/~gwyn/ebindene.html). +X // +X // Adapted for PSI by Matthias Muntwiler. +X // Please refer to the original web page or the x-ray data booklet +X // for sources, definitions and remarks. +X // +X // Adjusted for common (solid) samples with data from: +X // Handbook of X-ray Photolectron Spectroscopy +X // 1995, Physical Electronics, Inc. + +WAVES/D energy number +BEGIN + 13.6 1 + 24.6 2 + 55.6 3 + 111.8 4 + 188 5 + 284.5 6 + 399 7 + 27 7 + 531 8 + 23 8 + 684.9 9 + 30 9 + 863.1 10 + 40.5 10 + 13.7 10 + 13.6 10 + 1071.8 11 + 63.5 11 + 30.65 11 + 30.81 11 + 1303 12 + 88.7 12 + 49.78 12 + 49.5 12 + 1559.6 13 + 117.8 13 + 72.95 13 + 72.55 13 + 1839 14 + 149.7 14 + 99.82 14 + 99.42 14 + 2145.5 15 + 188 15 + 130.7 15 + 129.9 15 + 14 15 + 2469 16 + 228 16 + 165.2 16 + 164 16 + 18 16 + 2822.4 17 + 271 17 + 200.1 17 + 198.5 17 + 17 17 + 6 17 + 3200 18 + 320 18 + 244 18 + 241.9 18 + 24 18 + 10.9 18 + 10.7 18 + 3608.4 19 + 378.6 19 + 297.3 19 + 294.6 19 + 34.8 19 + 18.3 19 + 18.3 19 + 4038.5 20 + 438.4 20 + 349.7 20 + 346.2 20 + 44.3 20 + 25.4 20 + 25.4 20 + 4492 21 + 498 21 + 403.6 21 + 398.7 21 + 51.1 21 + 28.3 21 + 28.3 21 + 4966 22 + 560.9 22 + 460.2 22 + 453.8 22 + 58.7 22 + 32.6 22 + 32.6 22 + 5465 23 + 626.7 23 + 519.8 23 + 512.1 23 + 66.3 23 + 37.2 23 + 37.2 23 + 5989 24 + 696 24 + 583.8 24 + 574.1 24 + 74.1 24 + 42.2 24 + 42.2 24 + 6539 25 + 769.1 25 + 649.9 25 + 638.7 25 + 82.3 25 + 47.2 25 + 47.2 25 + 7112 26 + 844.6 26 + 719.9 26 + 706.8 26 + 91.3 26 + 52.7 26 + 52.7 26 + 7709 27 + 925.1 27 + 793.2 27 + 778.1 27 + 101 27 + 58.9 27 + 59.9 27 + 8333 28 + 1008.6 28 + 870 28 + 852.7 28 + 110.8 28 + 68 28 + 66.2 28 + 8979 29 + 1096.7 29 + 952.3 29 + 932.7 29 + 122.5 29 + 77.3 29 + 75.1 29 + 9659 30 + 1196.2 30 + 1044.9 30 + 1021.8 30 + 139.8 30 + 91.4 30 + 88.6 30 + 10.2 30 + 10.1 30 + 10367 31 + 1299 31 + 1143.2 31 + 1116.4 31 + 159.5 31 + 103.5 31 + 100 31 + 18.7 31 + 18.7 31 + 11103 32 + 1414.6 32 + 1248.1 32 + 1217 32 + 180.1 32 + 124.9 32 + 120.8 32 + 29.8 32 + 29.2 32 + 11867 33 + 1527 33 + 1359.1 33 + 1323.6 33 + 204.7 33 + 146.2 33 + 141.2 33 + 41.7 33 + 41.7 33 + 12658 34 + 1652 34 + 1474.3 34 + 1433.9 34 + 229.6 34 + 166.5 34 + 160.7 34 + 55.5 34 + 54.6 34 + 13474 35 + 1782 35 + 1596 35 + 1550 35 + 257 35 + 189 35 + 182 35 + 70 35 + 69 35 + 14319 36 + 1914.2 36 + 1724.1 36 + 1671.6 36 + 286 36 + 215.4 36 + 207.6 36 + 88.2 36 + 87 36 + 20.7 36 + 7.3 36 + 7.3 36 + 15200 37 + 2065 37 + 1864 37 + 1804 37 + 325 37 + 248.7 37 + 239.1 37 + 113 37 + 111.5 37 + 30.5 37 + 16.3 37 + 15.3 37 + 16105 38 + 2216 38 + 2007 38 + 1940 38 + 358.7 38 + 280.3 38 + 270 38 + 136 38 + 134.2 38 + 38.9 38 + 21.3 38 + 20.1 38 + 17038 39 + 2373 39 + 2156 39 + 2080 39 + 392 39 + 310.6 39 + 298.8 39 + 157.7 39 + 155.8 39 + 43.8 39 + 24.4 39 + 23.1 39 + 17998 40 + 2532 40 + 2307 40 + 2223 40 + 430.3 40 + 343.5 40 + 329.8 40 + 181.1 40 + 178.8 40 + 50.6 40 + 28.5 40 + 27.1 40 + 18986 41 + 2698 41 + 2465 41 + 2371 41 + 466.6 41 + 376.1 41 + 360.6 41 + 205 41 + 202.3 41 + 56.4 41 + 32.6 41 + 30.8 41 + 20000 42 + 2866 42 + 2625 42 + 2520 42 + 506.3 42 + 411.6 42 + 394 42 + 231.1 42 + 227.9 42 + 63.2 42 + 37.6 42 + 35.5 42 + 21044 43 + 3043 43 + 2793 43 + 2677 43 + 544 43 + 447.6 43 + 417.7 43 + 257.6 43 + 253.9 43 + 69.5 43 + 42.3 43 + 39.9 43 + 22117 44 + 3224 44 + 2967 44 + 2838 44 + 586.1 44 + 483.5 44 + 461.4 44 + 284.2 44 + 280 44 + 75 44 + 46.3 44 + 43.2 44 + 23220 45 + 3412 45 + 3146 45 + 3004 45 + 628.1 45 + 521.3 45 + 496.5 45 + 311.9 45 + 307.2 45 + 81.4 45 + 50.5 45 + 47.3 45 + 24350 46 + 3604 46 + 3330 46 + 3173 46 + 671.6 46 + 559.9 46 + 532.3 46 + 340.5 46 + 335.2 46 + 87.1 46 + 55.7 46 + 50.9 46 + 25514 47 + 3806 47 + 3524 47 + 3351 47 + 719 47 + 603.8 47 + 573 47 + 374 47 + 368.3 47 + 97 47 + 63.7 47 + 58.3 47 + 26711 48 + 4018 48 + 3727 48 + 3538 48 + 772 48 + 652.6 48 + 618.4 48 + 411.9 48 + 405.2 48 + 109.8 48 + 63.9 48 + 63.9 48 + 11.7 48 + 10.7 48 + 27940 49 + 4238 49 + 3938 49 + 3730 49 + 827.2 49 + 703.2 49 + 665.3 49 + 451.4 49 + 443.9 49 + 122.9 49 + 73.5 49 + 73.5 49 + 17.7 49 + 16.9 49 + 29200 50 + 4465 50 + 4156 50 + 3929 50 + 884.7 50 + 756.5 50 + 714.6 50 + 493.2 50 + 484.9 50 + 137.1 50 + 83.6 50 + 83.6 50 + 24.9 50 + 23.9 50 + 30491 51 + 4698 51 + 4380 51 + 4132 51 + 946 51 + 812.7 51 + 766.4 51 + 537.5 51 + 528.2 51 + 153.2 51 + 95.6 51 + 95.6 51 + 33.3 51 + 32.1 51 + 31814 52 + 4939 52 + 4612 52 + 4341 52 + 1006 52 + 870.8 52 + 820 52 + 583.4 52 + 573 52 + 169.4 52 + 103.3 52 + 103.3 52 + 41.9 52 + 40.4 52 + 33169 53 + 5188 53 + 4852 53 + 4557 53 + 1072 53 + 931 53 + 875 53 + 630.8 53 + 619.3 53 + 186 53 + 123 53 + 123 53 + 50.6 53 + 48.9 53 + 34554 54 + 5446 54 + 5100 54 + 4779 54 + 1141 54 + 995.4 54 + 933.9 54 + 682.6 54 + 669.7 54 + 207 54 + 139 54 + 139 54 + 63 54 + 61 54 + 17 54 + 7.7 54 + 5.8 54 + 35985 55 + 5714 55 + 5359 55 + 5012 55 + 1211 55 + 1071 55 + 1003 55 + 740.5 55 + 726.6 55 + 232.3 55 + 172.4 55 + 161.3 55 + 79.8 55 + 77.5 55 + 22.7 55 + 14.2 55 + 12.1 55 + 37441 56 + 5989 56 + 5624 56 + 5247 56 + 1293 56 + 1137 56 + 1063 56 + 795.7 56 + 780.5 56 + 253.5 56 + 192 56 + 178.6 56 + 92.6 56 + 89.9 56 + 30.3 56 + 17 56 + 14.8 56 + 38925 57 + 6266 57 + 5891 57 + 5483 57 + 1362 57 + 1209 57 + 1128 57 + 853 57 + 836 57 + 274.7 57 + 205.8 57 + 196 57 + 105.3 57 + 102.5 57 + 34.3 57 + 19.3 57 + 16.8 57 + 40443 58 + 6549 58 + 6164 58 + 5723 58 + 1436 58 + 1274 58 + 1187 58 + 902.4 58 + 883.8 58 + 291 58 + 223.2 58 + 206.5 58 + 109 58 + 0.1 58 + 0.1 58 + 37.8 58 + 19.8 58 + 17 58 + 41991 59 + 6835 59 + 6440 59 + 5964 59 + 1511 59 + 1337 59 + 1242 59 + 948.3 59 + 928.8 59 + 304.5 59 + 236.3 59 + 217.6 59 + 115.1 59 + 115.1 59 + 2 59 + 2 59 + 37.4 59 + 22.3 59 + 22.3 59 + 43569 60 + 7126 60 + 6722 60 + 6208 60 + 1575 60 + 1403 60 + 1297 60 + 1003.3 60 + 980.4 60 + 319.2 60 + 243.3 60 + 224.6 60 + 120.5 60 + 120.5 60 + 1.5 60 + 1.5 60 + 37.5 60 + 21.1 60 + 21.1 60 + 45184 61 + 7428 61 + 7013 61 + 6459 61 + 1471 61 + 1357 61 + 1052 61 + 1027 61 + 242 61 + 242 61 + 120 61 + 120 61 + 46834 62 + 7737 62 + 7312 62 + 6716 62 + 1723 62 + 1541 62 + 1420 62 + 1110.9 62 + 1083.4 62 + 347.2 62 + 265.6 62 + 247.4 62 + 129 62 + 129 62 + 5.2 62 + 5.2 62 + 37.4 62 + 21.3 62 + 21.3 62 + 48519 63 + 8052 63 + 7617 63 + 6977 63 + 1800 63 + 1614 63 + 1481 63 + 1158.6 63 + 1127.5 63 + 360 63 + 284 63 + 257 63 + 133 63 + 127.7 63 + 0 63 + 0 63 + 32 63 + 22 63 + 22 63 + 50239 64 + 8376 64 + 7930 64 + 7243 64 + 1881 64 + 1688 64 + 1544 64 + 1221.9 64 + 1189.6 64 + 378.6 64 + 286 64 + 271 64 + 142.6 64 + 8.6 64 + 8.6 64 + 36 64 + 28 64 + 21 64 + 51996 65 + 8708 65 + 8252 65 + 7514 65 + 1968 65 + 1768 65 + 1611 65 + 1276.9 65 + 1241.1 65 + 396 65 + 322.4 65 + 284.1 65 + 150.5 65 + 150.5 65 + 7.7 65 + 2.4 65 + 45.6 65 + 28.7 65 + 22.6 65 + 53789 66 + 9046 66 + 8581 66 + 7790 66 + 2047 66 + 1842 66 + 1676 66 + 1333 66 + 1292.6 66 + 414.2 66 + 333.5 66 + 293.2 66 + 153.6 66 + 153.6 66 + 8 66 + 4.3 66 + 49.9 66 + 26.3 66 + 26.3 66 + 55618 67 + 9394 67 + 8918 67 + 8071 67 + 2128 67 + 1923 67 + 1741 67 + 1392 67 + 1351 67 + 432.4 67 + 343.5 67 + 308.2 67 + 160 67 + 160 67 + 8.6 67 + 5.2 67 + 49.3 67 + 30.8 67 + 24.1 67 + 57486 68 + 9751 68 + 9264 68 + 8358 68 + 2207 68 + 2006 68 + 1812 68 + 1453 68 + 1409 68 + 449.8 68 + 366.2 68 + 320.2 68 + 167.6 68 + 167.6 68 + 4.7 68 + 50.6 68 + 31.4 68 + 24.7 68 + 59390 69 + 10116 69 + 9617 69 + 8648 69 + 2307 69 + 2090 69 + 1885 69 + 1515 69 + 1468 69 + 470.9 69 + 385.9 69 + 332.6 69 + 175.5 69 + 175.5 69 + 4.6 69 + 54.7 69 + 31.8 69 + 25 69 + 61332 70 + 10486 70 + 9978 70 + 8944 70 + 2398 70 + 2173 70 + 1950 70 + 1576 70 + 1528 70 + 480.5 70 + 388.7 70 + 339.7 70 + 191.2 70 + 182.4 70 + 2.5 70 + 1.3 70 + 52 70 + 30.3 70 + 24.1 70 + 63314 71 + 10870 71 + 10349 71 + 9244 71 + 2491 71 + 2264 71 + 2024 71 + 1639 71 + 1589 71 + 506.8 71 + 412.4 71 + 359.2 71 + 206.1 71 + 196.3 71 + 8.9 71 + 7.5 71 + 57.3 71 + 33.6 71 + 26.7 71 + 65351 72 + 11271 72 + 10739 72 + 9561 72 + 2601 72 + 2365 72 + 2108 72 + 1716 72 + 1662 72 + 538 72 + 438.2 72 + 380.7 72 + 220 72 + 211.5 72 + 15.9 72 + 14.2 72 + 64.2 72 + 38 72 + 29.9 72 + 67416 73 + 11682 73 + 11136 73 + 9881 73 + 2708 73 + 2469 73 + 2194 73 + 1793 73 + 1735 73 + 563.4 73 + 463.4 73 + 400.9 73 + 237.9 73 + 226.4 73 + 23.5 73 + 21.6 73 + 69.7 73 + 42.2 73 + 32.7 73 + 69525 74 + 12100 74 + 11544 74 + 10207 74 + 2820 74 + 2575 74 + 2281 74 + 1872 74 + 1809 74 + 594.1 74 + 490.4 74 + 423.6 74 + 255.9 74 + 243.5 74 + 33.6 74 + 31.4 74 + 75.6 74 + 45.3 74 + 36.8 74 + 71676 75 + 12527 75 + 11959 75 + 10535 75 + 2932 75 + 2682 75 + 2367 75 + 1949 75 + 1883 75 + 625.4 75 + 518.7 75 + 446.8 75 + 273.9 75 + 260.5 75 + 42.9 75 + 40.5 75 + 83 75 + 45.6 75 + 34.6 75 + 73871 76 + 12968 76 + 12385 76 + 10871 76 + 3049 76 + 2792 76 + 2457 76 + 2031 76 + 1960 76 + 658.2 76 + 549.1 76 + 470.7 76 + 293.1 76 + 278.5 76 + 53.4 76 + 50.7 76 + 84 76 + 58 76 + 44.5 76 + 76111 77 + 13419 77 + 12824 77 + 11215 77 + 3174 77 + 2909 77 + 2551 77 + 2116 77 + 2040 77 + 691.1 77 + 577.8 77 + 495.8 77 + 311.9 77 + 296.3 77 + 63.8 77 + 60.8 77 + 95.2 77 + 63 77 + 48 77 + 78395 78 + 13880 78 + 13273 78 + 11564 78 + 3296 78 + 3027 78 + 2645 78 + 2202 78 + 2122 78 + 725.4 78 + 609.1 78 + 519.4 78 + 331.6 78 + 314.6 78 + 74.5 78 + 71.2 78 + 101.7 78 + 65.3 78 + 51.7 78 + 80725 79 + 14353 79 + 13734 79 + 11919 79 + 3425 79 + 3148 79 + 2743 79 + 2291 79 + 2206 79 + 762.1 79 + 642.7 79 + 546.3 79 + 353.2 79 + 335.1 79 + 87.6 79 + 84 79 + 107.2 79 + 74.2 79 + 57.2 79 + 83102 80 + 14839 80 + 14209 80 + 12284 80 + 3562 80 + 3279 80 + 2847 80 + 2385 80 + 2295 80 + 802.2 80 + 680.2 80 + 576.6 80 + 378.2 80 + 358.8 80 + 104 80 + 99.9 80 + 127 80 + 83.1 80 + 64.5 80 + 9.6 80 + 7.8 80 + 85530 81 + 15347 81 + 14698 81 + 12658 81 + 3704 81 + 3416 81 + 2957 81 + 2485 81 + 2389 81 + 846.2 81 + 720.5 81 + 609.5 81 + 405.7 81 + 385 81 + 122.2 81 + 117.8 81 + 136 81 + 94.6 81 + 73.5 81 + 14.7 81 + 12.5 81 + 88005 82 + 15861 82 + 15200 82 + 13035 82 + 3851 82 + 3554 82 + 3066 82 + 2586 82 + 2484 82 + 891.8 82 + 761.9 82 + 643.5 82 + 434.3 82 + 412.2 82 + 141.7 82 + 136.9 82 + 147 82 + 106.4 82 + 83.3 82 + 20.7 82 + 18.1 82 + 90526 83 + 16388 83 + 15711 83 + 13419 83 + 3999 83 + 3696 83 + 3177 83 + 2688 83 + 2580 83 + 939 83 + 805.2 83 + 678.8 83 + 464 83 + 440.1 83 + 162.3 83 + 157 83 + 159.3 83 + 119 83 + 92.6 83 + 26.9 83 + 23.8 83 + 93105 84 + 16939 84 + 16244 84 + 13814 84 + 4149 84 + 3854 84 + 3302 84 + 2798 84 + 2683 84 + 995 84 + 851 84 + 705 84 + 500 84 + 473 84 + 184 84 + 184 84 + 177 84 + 132 84 + 104 84 + 31 84 + 31 84 + 95730 85 + 17493 85 + 16785 85 + 14214 85 + 4317 85 + 4008 85 + 3426 85 + 2909 85 + 2787 85 + 1042 85 + 886 85 + 740 85 + 533 85 + 507 85 + 210 85 + 210 85 + 195 85 + 148 85 + 115 85 + 40 85 + 40 85 + 98404 86 + 18049 86 + 17337 86 + 14619 86 + 4482 86 + 4159 86 + 3538 86 + 3022 86 + 2892 86 + 1097 86 + 929 86 + 768 86 + 567 86 + 541 86 + 238 86 + 238 86 + 214 86 + 164 86 + 127 86 + 48 86 + 48 86 + 26 86 + 101137 87 + 18639 87 + 17907 87 + 15031 87 + 4652 87 + 4327 87 + 3663 87 + 3136 87 + 3000 87 + 1153 87 + 980 87 + 810 87 + 603 87 + 577 87 + 268 87 + 268 87 + 234 87 + 182 87 + 140 87 + 58 87 + 58 87 + 34 87 + 15 87 + 15 87 + 103922 88 + 19237 88 + 18484 88 + 15444 88 + 4822 88 + 4490 88 + 3792 88 + 3248 88 + 3105 88 + 1208 88 + 1058 88 + 879 88 + 636 88 + 603 88 + 299 88 + 299 88 + 254 88 + 200 88 + 153 88 + 68 88 + 68 88 + 44 88 + 19 88 + 19 88 + 106755 89 + 19840 89 + 19083 89 + 15871 89 + 5002 89 + 4656 89 + 3909 89 + 3370 89 + 3219 89 + 1269 89 + 1080 89 + 890 89 + 675 89 + 639 89 + 319 89 + 319 89 + 272 89 + 215 89 + 167 89 + 80 89 + 80 89 + 109651 90 + 20472 90 + 19693 90 + 16300 90 + 5182 90 + 4830 90 + 4046 90 + 3491 90 + 3332 90 + 1330 90 + 1168 90 + 966.4 90 + 712.1 90 + 675.2 90 + 342.4 90 + 333.1 90 + 290 90 + 229 90 + 182 90 + 92.5 90 + 85.4 90 + 41.4 90 + 24.5 90 + 16.6 90 + 112601 91 + 21105 91 + 20314 91 + 16733 91 + 5367 91 + 5001 91 + 4174 91 + 3611 91 + 3442 91 + 1387 91 + 1224 91 + 1007 91 + 743 91 + 708 91 + 371 91 + 360 91 + 310 91 + 232 91 + 232 91 + 94 91 + 94 91 + 115606 92 + 21757 92 + 20948 92 + 17166 92 + 5548 92 + 5182 92 + 4303 92 + 3728 92 + 3552 92 + 1439 92 + 1271 92 + 1043 92 + 778.3 92 + 736.2 92 + 388.2 92 + 377.4 92 + 321 92 + 257 92 + 192 92 + 102.8 92 + 94.2 92 + 43.9 92 + 26.8 92 + 16.8 92 +END +X SetScale/P x 0,1,"", energy; SetScale y 0,0,"", energy; SetScale d 0,0,"eV", energy +X SetScale/P x 0,1,"", number; SetScale y 0,0,"", number + +WAVES/T symbol term +BEGIN + "H" "1s" + "He" "1s" + "Li" "1s" + "Be" "1s" + "B" "1s" + "C" "1s" + "N" "1s" + "N" "2s" + "O" "1s" + "O" "2s" + "F" "1s" + "F" "2s" + "Ne" "1s" + "Ne" "2s" + "Ne" "2p1/2" + "Ne" "2p3/2" + "Na" "1s" + "Na" "2s" + "Na" "2p1/2" + "Na" "2p3/2" + "Mg" "1s" + "Mg" "2s" + "Mg" "2p1/2" + "Mg" "2p3/2" + "Al" "1s" + "Al" "2s" + "Al" "2p1/2" + "Al" "2p3/2" + "Si" "1s" + "Si" "2s" + "Si" "2p1/2" + "Si" "2p3/2" + "P" "1s" + "P" "2s" + "P" "2p1/2" + "P" "2p3/2" + "P" "3s" + "S" "1s" + "S" "2s" + "S" "2p1/2" + "S" "2p3/2" + "S" "3s" + "Cl" "1s" + "Cl" "2s" + "Cl" "2p1/2" + "Cl" "2p3/2" + "Cl" "3s" + "Cl" "3p" + "Ar" "1s" + "Ar" "2s" + "Ar" "2p1/2" + "Ar" "2p3/2" + "Ar" "3s" + "Ar" "3p1/2" + "Ar" "3p3/2" + "K" "1s" + "K" "2s" + "K" "2p1/2" + "K" "2p3/2" + "K" "3s" + "K" "3p1/2" + "K" "3p3/2" + "Ca" "1s" + "Ca" "2s" + "Ca" "2p1/2" + "Ca" "2p3/2" + "Ca" "3s" + "Ca" "3p1/2" + "Ca" "3p3/2" + "Sc" "1s" + "Sc" "2s" + "Sc" "2p1/2" + "Sc" "2p3/2" + "Sc" "3s" + "Sc" "3p1/2" + "Sc" "3p3/2" + "Ti" "1s" + "Ti" "2s" + "Ti" "2p1/2" + "Ti" "2p3/2" + "Ti" "3s" + "Ti" "3p1/2" + "Ti" "3p3/2" + "V" "1s" + "V" "2s" + "V" "2p1/2" + "V" "2p3/2" + "V" "3s" + "V" "3p1/2" + "V" "3p3/2" + "Cr" "1s" + "Cr" "2s" + "Cr" "2p1/2" + "Cr" "2p3/2" + "Cr" "3s" + "Cr" "3p1/2" + "Cr" "3p3/2" + "Mn" "1s" + "Mn" "2s" + "Mn" "2p1/2" + "Mn" "2p3/2" + "Mn" "3s" + "Mn" "3p1/2" + "Mn" "3p3/2" + "Fe" "1s" + "Fe" "2s" + "Fe" "2p1/2" + "Fe" "2p3/2" + "Fe" "3s" + "Fe" "3p1/2" + "Fe" "3p3/2" + "Co" "1s" + "Co" "2s" + "Co" "2p1/2" + "Co" "2p3/2" + "Co" "3s" + "Co" "3p1/2" + "Co" "3p3/2" + "Ni" "1s" + "Ni" "2s" + "Ni" "2p1/2" + "Ni" "2p3/2" + "Ni" "3s" + "Ni" "3p1/2" + "Ni" "3p3/2" + "Cu" "1s" + "Cu" "2s" + "Cu" "2p1/2" + "Cu" "2p3/2" + "Cu" "3s" + "Cu" "3p1/2" + "Cu" "3p3/2" + "Zn" "1s" + "Zn" "2s" + "Zn" "2p1/2" + "Zn" "2p3/2" + "Zn" "3s" + "Zn" "3p1/2" + "Zn" "3p3/2" + "Zn" "3d3/2" + "Zn" "3d5/2" + "Ga" "1s" + "Ga" "2s" + "Ga" "2p1/2" + "Ga" "2p3/2" + "Ga" "3s" + "Ga" "3p1/2" + "Ga" "3p3/2" + "Ga" "3d3/2" + "Ga" "3d5/2" + "Ge" "1s" + "Ge" "2s" + "Ge" "2p1/2" + "Ge" "2p3/2" + "Ge" "3s" + "Ge" "3p1/2" + "Ge" "3p3/2" + "Ge" "3d3/2" + "Ge" "3d5/2" + "As" "1s" + "As" "2s" + "As" "2p1/2" + "As" "2p3/2" + "As" "3s" + "As" "3p1/2" + "As" "3p3/2" + "As" "3d3/2" + "As" "3d5/2" + "Se" "1s" + "Se" "2s" + "Se" "2p1/2" + "Se" "2p3/2" + "Se" "3s" + "Se" "3p1/2" + "Se" "3p3/2" + "Se" "3d3/2" + "Se" "3d5/2" + "Br" "1s" + "Br" "2s" + "Br" "2p1/2" + "Br" "2p3/2" + "Br" "3s" + "Br" "3p1/2" + "Br" "3p3/2" + "Br" "3d3/2" + "Br" "3d5/2" + "Kr" "1s" + "Kr" "2s" + "Kr" "2p1/2" + "Kr" "2p3/2" + "Kr" "3s" + "Kr" "3p1/2" + "Kr" "3p3/2" + "Kr" "3d3/2" + "Kr" "3d5/2" + "Kr" "4s" + "Kr" "4p1/2" + "Kr" "4p3/2" + "Rb" "1s" + "Rb" "2s" + "Rb" "2p1/2" + "Rb" "2p3/2" + "Rb" "3s" + "Rb" "3p1/2" + "Rb" "3p3/2" + "Rb" "3d3/2" + "Rb" "3d5/2" + "Rb" "4s" + "Rb" "4p1/2" + "Rb" "4p3/2" + "Sr" "1s" + "Sr" "2s" + "Sr" "2p1/2" + "Sr" "2p3/2" + "Sr" "3s" + "Sr" "3p1/2" + "Sr" "3p3/2" + "Sr" "3d3/2" + "Sr" "3d5/2" + "Sr" "4s" + "Sr" "4p1/2" + "Sr" "4p3/2" + "Y" "1s" + "Y" "2s" + "Y" "2p1/2" + "Y" "2p3/2" + "Y" "3s" + "Y" "3p1/2" + "Y" "3p3/2" + "Y" "3d3/2" + "Y" "3d5/2" + "Y" "4s" + "Y" "4p1/2" + "Y" "4p3/2" + "Zr" "1s" + "Zr" "2s" + "Zr" "2p1/2" + "Zr" "2p3/2" + "Zr" "3s" + "Zr" "3p1/2" + "Zr" "3p3/2" + "Zr" "3d3/2" + "Zr" "3d5/2" + "Zr" "4s" + "Zr" "4p1/2" + "Zr" "4p3/2" + "Nb" "1s" + "Nb" "2s" + "Nb" "2p1/2" + "Nb" "2p3/2" + "Nb" "3s" + "Nb" "3p1/2" + "Nb" "3p3/2" + "Nb" "3d3/2" + "Nb" "3d5/2" + "Nb" "4s" + "Nb" "4p1/2" + "Nb" "4p3/2" + "Mo" "1s" + "Mo" "2s" + "Mo" "2p1/2" + "Mo" "2p3/2" + "Mo" "3s" + "Mo" "3p1/2" + "Mo" "3p3/2" + "Mo" "3d3/2" + "Mo" "3d5/2" + "Mo" "4s" + "Mo" "4p1/2" + "Mo" "4p3/2" + "Tc" "1s" + "Tc" "2s" + "Tc" "2p1/2" + "Tc" "2p3/2" + "Tc" "3s" + "Tc" "3p1/2" + "Tc" "3p3/2" + "Tc" "3d3/2" + "Tc" "3d5/2" + "Tc" "4s" + "Tc" "4p1/2" + "Tc" "4p3/2" + "Ru" "1s" + "Ru" "2s" + "Ru" "2p1/2" + "Ru" "2p3/2" + "Ru" "3s" + "Ru" "3p1/2" + "Ru" "3p3/2" + "Ru" "3d3/2" + "Ru" "3d5/2" + "Ru" "4s" + "Ru" "4p1/2" + "Ru" "4p3/2" + "Rh" "1s" + "Rh" "2s" + "Rh" "2p1/2" + "Rh" "2p3/2" + "Rh" "3s" + "Rh" "3p1/2" + "Rh" "3p3/2" + "Rh" "3d3/2" + "Rh" "3d5/2" + "Rh" "4s" + "Rh" "4p1/2" + "Rh" "4p3/2" + "Pd" "1s" + "Pd" "2s" + "Pd" "2p1/2" + "Pd" "2p3/2" + "Pd" "3s" + "Pd" "3p1/2" + "Pd" "3p3/2" + "Pd" "3d3/2" + "Pd" "3d5/2" + "Pd" "4s" + "Pd" "4p1/2" + "Pd" "4p3/2" + "Ag" "1s" + "Ag" "2s" + "Ag" "2p1/2" + "Ag" "2p3/2" + "Ag" "3s" + "Ag" "3p1/2" + "Ag" "3p3/2" + "Ag" "3d3/2" + "Ag" "3d5/2" + "Ag" "4s" + "Ag" "4p1/2" + "Ag" "4p3/2" + "Cd" "1s" + "Cd" "2s" + "Cd" "2p1/2" + "Cd" "2p3/2" + "Cd" "3s" + "Cd" "3p1/2" + "Cd" "3p3/2" + "Cd" "3d3/2" + "Cd" "3d5/2" + "Cd" "4s" + "Cd" "4p1/2" + "Cd" "4p3/2" + "Cd" "4d3/2" + "Cd" "4d5/2" + "In" "1s" + "In" "2s" + "In" "2p1/2" + "In" "2p3/2" + "In" "3s" + "In" "3p1/2" + "In" "3p3/2" + "In" "3d3/2" + "In" "3d5/2" + "In" "4s" + "In" "4p1/2" + "In" "4p3/2" + "In" "4d3/2" + "In" "4d5/2" + "Sn" "1s" + "Sn" "2s" + "Sn" "2p1/2" + "Sn" "2p3/2" + "Sn" "3s" + "Sn" "3p1/2" + "Sn" "3p3/2" + "Sn" "3d3/2" + "Sn" "3d5/2" + "Sn" "4s" + "Sn" "4p1/2" + "Sn" "4p3/2" + "Sn" "4d3/2" + "Sn" "4d5/2" + "Sb" "1s" + "Sb" "2s" + "Sb" "2p1/2" + "Sb" "2p3/2" + "Sb" "3s" + "Sb" "3p1/2" + "Sb" "3p3/2" + "Sb" "3d3/2" + "Sb" "3d5/2" + "Sb" "4s" + "Sb" "4p1/2" + "Sb" "4p3/2" + "Sb" "4d3/2" + "Sb" "4d5/2" + "Te" "1s" + "Te" "2s" + "Te" "2p1/2" + "Te" "2p3/2" + "Te" "3s" + "Te" "3p1/2" + "Te" "3p3/2" + "Te" "3d3/2" + "Te" "3d5/2" + "Te" "4s" + "Te" "4p1/2" + "Te" "4p3/2" + "Te" "4d3/2" + "Te" "4d5/2" + "I" "1s" + "I" "2s" + "I" "2p1/2" + "I" "2p3/2" + "I" "3s" + "I" "3p1/2" + "I" "3p3/2" + "I" "3d3/2" + "I" "3d5/2" + "I" "4s" + "I" "4p1/2" + "I" "4p3/2" + "I" "4d3/2" + "I" "4d5/2" + "Xe" "1s" + "Xe" "2s" + "Xe" "2p1/2" + "Xe" "2p3/2" + "Xe" "3s" + "Xe" "3p1/2" + "Xe" "3p3/2" + "Xe" "3d3/2" + "Xe" "3d5/2" + "Xe" "4s" + "Xe" "4p1/2" + "Xe" "4p3/2" + "Xe" "4d3/2" + "Xe" "4d5/2" + "Xe" "5s" + "Xe" "5p1/2" + "Xe" "5p3/2" + "Cs" "1s" + "Cs" "2s" + "Cs" "2p1/2" + "Cs" "2p3/2" + "Cs" "3s" + "Cs" "3p1/2" + "Cs" "3p3/2" + "Cs" "3d3/2" + "Cs" "3d5/2" + "Cs" "4s" + "Cs" "4p1/2" + "Cs" "4p3/2" + "Cs" "4d3/2" + "Cs" "4d5/2" + "Cs" "5s" + "Cs" "5p1/2" + "Cs" "5p3/2" + "Ba" "1s" + "Ba" "2s" + "Ba" "2p1/2" + "Ba" "2p3/2" + "Ba" "3s" + "Ba" "3p1/2" + "Ba" "3p3/2" + "Ba" "3d3/2" + "Ba" "3d5/2" + "Ba" "4s" + "Ba" "4p1/2" + "Ba" "4p3/2" + "Ba" "4d3/2" + "Ba" "4d5/2" + "Ba" "5s" + "Ba" "5p1/2" + "Ba" "5p3/2" + "La" "1s" + "La" "2s" + "La" "2p1/2" + "La" "2p3/2" + "La" "3s" + "La" "3p1/2" + "La" "3p3/2" + "La" "3d3/2" + "La" "3d5/2" + "La" "4s" + "La" "4p1/2" + "La" "4p3/2" + "La" "4d3/2" + "La" "4d5/2" + "La" "5s" + "La" "5p1/2" + "La" "5p3/2" + "Ce" "1s" + "Ce" "2s" + "Ce" "2p1/2" + "Ce" "2p3/2" + "Ce" "3s" + "Ce" "3p1/2" + "Ce" "3p3/2" + "Ce" "3d3/2" + "Ce" "3d5/2" + "Ce" "4s" + "Ce" "4p1/2" + "Ce" "4p3/2" + "Ce" "4d3/2" + "Ce" "4f5/2" + "Ce" "4f7/2" + "Ce" "5s" + "Ce" "5p1/2" + "Ce" "5p3/2" + "Pr" "1s" + "Pr" "2s" + "Pr" "2p1/2" + "Pr" "2p3/2" + "Pr" "3s" + "Pr" "3p1/2" + "Pr" "3p3/2" + "Pr" "3d3/2" + "Pr" "3d5/2" + "Pr" "4s" + "Pr" "4p1/2" + "Pr" "4p3/2" + "Pr" "4d3/2" + "Pr" "4d5/2" + "Pr" "4f5/2" + "Pr" "4f7/2" + "Pr" "5s" + "Pr" "5p1/2" + "Pr" "5p3/2" + "Nd" "1s" + "Nd" "2s" + "Nd" "2p1/2" + "Nd" "2p3/2" + "Nd" "3s" + "Nd" "3p1/2" + "Nd" "3p3/2" + "Nd" "3d3/2" + "Nd" "3d5/2" + "Nd" "4s" + "Nd" "4p1/2" + "Nd" "4p3/2" + "Nd" "4d3/2" + "Nd" "4d5/2" + "Nd" "4f5/2" + "Nd" "4f7/2" + "Nd" "5s" + "Nd" "5p1/2" + "Nd" "5p3/2" + "Pm" "1s" + "Pm" "2s" + "Pm" "2p1/2" + "Pm" "2p3/2" + "Pm" "3p1/2" + "Pm" "3p3/2" + "Pm" "3d3/2" + "Pm" "3d5/2" + "Pm" "4p1/2" + "Pm" "4p3/2" + "Pm" "4d3/2" + "Pm" "4d5/2" + "Sm" "1s" + "Sm" "2s" + "Sm" "2p1/2" + "Sm" "2p3/2" + "Sm" "3s" + "Sm" "3p1/2" + "Sm" "3p3/2" + "Sm" "3d3/2" + "Sm" "3d5/2" + "Sm" "4s" + "Sm" "4p1/2" + "Sm" "4p3/2" + "Sm" "4d3/2" + "Sm" "4d5/2" + "Sm" "4f5/2" + "Sm" "4f7/2" + "Sm" "5s" + "Sm" "5p1/2" + "Sm" "5p3/2" + "Eu" "1s" + "Eu" "2s" + "Eu" "2p1/2" + "Eu" "2p3/2" + "Eu" "3s" + "Eu" "3p1/2" + "Eu" "3p3/2" + "Eu" "3d3/2" + "Eu" "3d5/2" + "Eu" "4s" + "Eu" "4p1/2" + "Eu" "4p3/2" + "Eu" "4d3/2" + "Eu" "4d5/2" + "Eu" "4f5/2" + "Eu" "4f7/2" + "Eu" "5s" + "Eu" "5p1/2" + "Eu" "5p3/2" + "Gd" "1s" + "Gd" "2s" + "Gd" "2p1/2" + "Gd" "2p3/2" + "Gd" "3s" + "Gd" "3p1/2" + "Gd" "3p3/2" + "Gd" "3d3/2" + "Gd" "3d5/2" + "Gd" "4s" + "Gd" "4p1/2" + "Gd" "4p3/2" + "Gd" "4d5/2" + "Gd" "4f5/2" + "Gd" "4f7/2" + "Gd" "5s" + "Gd" "5p1/2" + "Gd" "5p3/2" + "Tb" "1s" + "Tb" "2s" + "Tb" "2p1/2" + "Tb" "2p3/2" + "Tb" "3s" + "Tb" "3p1/2" + "Tb" "3p3/2" + "Tb" "3d3/2" + "Tb" "3d5/2" + "Tb" "4s" + "Tb" "4p1/2" + "Tb" "4p3/2" + "Tb" "4d3/2" + "Tb" "4d5/2" + "Tb" "4f5/2" + "Tb" "4f7/2" + "Tb" "5s" + "Tb" "5p1/2" + "Tb" "5p3/2" + "Dy" "1s" + "Dy" "2s" + "Dy" "2p1/2" + "Dy" "2p3/2" + "Dy" "3s" + "Dy" "3p1/2" + "Dy" "3p3/2" + "Dy" "3d3/2" + "Dy" "3d5/2" + "Dy" "4s" + "Dy" "4p1/2" + "Dy" "4p3/2" + "Dy" "4d3/2" + "Dy" "4d5/2" + "Dy" "4f5/2" + "Dy" "4f7/2" + "Dy" "5s" + "Dy" "5p1/2" + "Dy" "5p3/2" + "Ho" "1s" + "Ho" "2s" + "Ho" "2p1/2" + "Ho" "2p3/2" + "Ho" "3s" + "Ho" "3p1/2" + "Ho" "3p3/2" + "Ho" "3d3/2" + "Ho" "3d5/2" + "Ho" "4s" + "Ho" "4p1/2" + "Ho" "4p3/2" + "Ho" "4d3/2" + "Ho" "4d5/2" + "Ho" "4f5/2" + "Ho" "4f7/2" + "Ho" "5s" + "Ho" "5p1/2" + "Ho" "5p3/2" + "Er" "1s" + "Er" "2s" + "Er" "2p1/2" + "Er" "2p3/2" + "Er" "3s" + "Er" "3p1/2" + "Er" "3p3/2" + "Er" "3d3/2" + "Er" "3d5/2" + "Er" "4s" + "Er" "4p1/2" + "Er" "4p3/2" + "Er" "4d3/2" + "Er" "4d5/2" + "Er" "4f7/2" + "Er" "5s" + "Er" "5p1/2" + "Er" "5p3/2" + "Tm" "1s" + "Tm" "2s" + "Tm" "2p1/2" + "Tm" "2p3/2" + "Tm" "3s" + "Tm" "3p1/2" + "Tm" "3p3/2" + "Tm" "3d3/2" + "Tm" "3d5/2" + "Tm" "4s" + "Tm" "4p1/2" + "Tm" "4p3/2" + "Tm" "4d3/2" + "Tm" "4d5/2" + "Tm" "4f7/2" + "Tm" "5s" + "Tm" "5p1/2" + "Tm" "5p3/2" + "Yb" "1s" + "Yb" "2s" + "Yb" "2p1/2" + "Yb" "2p3/2" + "Yb" "3s" + "Yb" "3p1/2" + "Yb" "3p3/2" + "Yb" "3d3/2" + "Yb" "3d5/2" + "Yb" "4s" + "Yb" "4p1/2" + "Yb" "4p3/2" + "Yb" "4d3/2" + "Yb" "4d5/2" + "Yb" "4f5/2" + "Yb" "4f7/2" + "Yb" "5s" + "Yb" "5p1/2" + "Yb" "5p3/2" + "Lu" "1s" + "Lu" "2s" + "Lu" "2p1/2" + "Lu" "2p3/2" + "Lu" "3s" + "Lu" "3p1/2" + "Lu" "3p3/2" + "Lu" "3d3/2" + "Lu" "3d5/2" + "Lu" "4s" + "Lu" "4p1/2" + "Lu" "4p3/2" + "Lu" "4d3/2" + "Lu" "4d5/2" + "Lu" "4f5/2" + "Lu" "4f7/2" + "Lu" "5s" + "Lu" "5p1/2" + "Lu" "5p3/2" + "Hf" "1s" + "Hf" "2s" + "Hf" "2p1/2" + "Hf" "2p3/2" + "Hf" "3s" + "Hf" "3p1/2" + "Hf" "3p3/2" + "Hf" "3d3/2" + "Hf" "3d5/2" + "Hf" "4s" + "Hf" "4p1/2" + "Hf" "4p3/2" + "Hf" "4d3/2" + "Hf" "4d5/2" + "Hf" "4f5/2" + "Hf" "4f7/2" + "Hf" "5s" + "Hf" "5p1/2" + "Hf" "5p3/2" + "Ta" "1s" + "Ta" "2s" + "Ta" "2p1/2" + "Ta" "2p3/2" + "Ta" "3s" + "Ta" "3p1/2" + "Ta" "3p3/2" + "Ta" "3d3/2" + "Ta" "3d5/2" + "Ta" "4s" + "Ta" "4p1/2" + "Ta" "4p3/2" + "Ta" "4d3/2" + "Ta" "4d5/2" + "Ta" "4f5/2" + "Ta" "4f7/2" + "Ta" "5s" + "Ta" "5p1/2" + "Ta" "5p3/2" + "W" "1s" + "W" "2s" + "W" "2p1/2" + "W" "2p3/2" + "W" "3s" + "W" "3p1/2" + "W" "3p3/2" + "W" "3d3/2" + "W" "3d5/2" + "W" "4s" + "W" "4p1/2" + "W" "4p3/2" + "W" "4d3/2" + "W" "4d5/2" + "W" "4f5/2" + "W" "4f7/2" + "W" "5s" + "W" "5p1/2" + "W" "5p3/2" + "Re" "1s" + "Re" "2s" + "Re" "2p1/2" + "Re" "2p3/2" + "Re" "3s" + "Re" "3p1/2" + "Re" "3p3/2" + "Re" "3d3/2" + "Re" "3d5/2" + "Re" "4s" + "Re" "4p1/2" + "Re" "4p3/2" + "Re" "4d3/2" + "Re" "4d5/2" + "Re" "4f5/2" + "Re" "4f7/2" + "Re" "5s" + "Re" "5p1/2" + "Re" "5p3/2" + "Os" "1s" + "Os" "2s" + "Os" "2p1/2" + "Os" "2p3/2" + "Os" "3s" + "Os" "3p1/2" + "Os" "3p3/2" + "Os" "3d3/2" + "Os" "3d5/2" + "Os" "4s" + "Os" "4p1/2" + "Os" "4p3/2" + "Os" "4d3/2" + "Os" "4d5/2" + "Os" "4f5/2" + "Os" "4f7/2" + "Os" "5s" + "Os" "5p1/2" + "Os" "5p3/2" + "Ir" "1s" + "Ir" "2s" + "Ir" "2p1/2" + "Ir" "2p3/2" + "Ir" "3s" + "Ir" "3p1/2" + "Ir" "3p3/2" + "Ir" "3d3/2" + "Ir" "3d5/2" + "Ir" "4s" + "Ir" "4p1/2" + "Ir" "4p3/2" + "Ir" "4d3/2" + "Ir" "4d5/2" + "Ir" "4f5/2" + "Ir" "4f7/2" + "Ir" "5s" + "Ir" "5p1/2" + "Ir" "5p3/2" + "Pt" "1s" + "Pt" "2s" + "Pt" "2p1/2" + "Pt" "2p3/2" + "Pt" "3s" + "Pt" "3p1/2" + "Pt" "3p3/2" + "Pt" "3d3/2" + "Pt" "3d5/2" + "Pt" "4s" + "Pt" "4p1/2" + "Pt" "4p3/2" + "Pt" "4d3/2" + "Pt" "4d5/2" + "Pt" "4f5/2" + "Pt" "4f7/2" + "Pt" "5s" + "Pt" "5p1/2" + "Pt" "5p3/2" + "Au" "1s" + "Au" "2s" + "Au" "2p1/2" + "Au" "2p3/2" + "Au" "3s" + "Au" "3p1/2" + "Au" "3p3/2" + "Au" "3d3/2" + "Au" "3d5/2" + "Au" "4s" + "Au" "4p1/2" + "Au" "4p3/2" + "Au" "4d3/2" + "Au" "4d5/2" + "Au" "4f5/2" + "Au" "4f7/2" + "Au" "5s" + "Au" "5p1/2" + "Au" "5p3/2" + "Hg" "1s" + "Hg" "2s" + "Hg" "2p1/2" + "Hg" "2p3/2" + "Hg" "3s" + "Hg" "3p1/2" + "Hg" "3p3/2" + "Hg" "3d3/2" + "Hg" "3d5/2" + "Hg" "4s" + "Hg" "4p1/2" + "Hg" "4p3/2" + "Hg" "4d3/2" + "Hg" "4d5/2" + "Hg" "4f5/2" + "Hg" "4f7/2" + "Hg" "5s" + "Hg" "5p1/2" + "Hg" "5p3/2" + "Hg" "5d3/2" + "Hg" "5d5/2" + "Tl" "1s" + "Tl" "2s" + "Tl" "2p1/2" + "Tl" "2p3/2" + "Tl" "3s" + "Tl" "3p1/2" + "Tl" "3p3/2" + "Tl" "3d3/2" + "Tl" "3d5/2" + "Tl" "4s" + "Tl" "4p1/2" + "Tl" "4p3/2" + "Tl" "4d3/2" + "Tl" "4d5/2" + "Tl" "4f5/2" + "Tl" "4f7/2" + "Tl" "5s" + "Tl" "5p1/2" + "Tl" "5p3/2" + "Tl" "5d3/2" + "Tl" "5d5/2" + "Pb" "1s" + "Pb" "2s" + "Pb" "2p1/2" + "Pb" "2p3/2" + "Pb" "3s" + "Pb" "3p1/2" + "Pb" "3p3/2" + "Pb" "3d3/2" + "Pb" "3d5/2" + "Pb" "4s" + "Pb" "4p1/2" + "Pb" "4p3/2" + "Pb" "4d3/2" + "Pb" "4d5/2" + "Pb" "4f5/2" + "Pb" "4f7/2" + "Pb" "5s" + "Pb" "5p1/2" + "Pb" "5p3/2" + "Pb" "5d3/2" + "Pb" "5d5/2" + "Bi" "1s" + "Bi" "2s" + "Bi" "2p1/2" + "Bi" "2p3/2" + "Bi" "3s" + "Bi" "3p1/2" + "Bi" "3p3/2" + "Bi" "3d3/2" + "Bi" "3d5/2" + "Bi" "4s" + "Bi" "4p1/2" + "Bi" "4p3/2" + "Bi" "4d3/2" + "Bi" "4d5/2" + "Bi" "4f5/2" + "Bi" "4f7/2" + "Bi" "5s" + "Bi" "5p1/2" + "Bi" "5p3/2" + "Bi" "5d3/2" + "Bi" "5d5/2" + "Po" "1s" + "Po" "2s" + "Po" "2p1/2" + "Po" "2p3/2" + "Po" "3s" + "Po" "3p1/2" + "Po" "3p3/2" + "Po" "3d3/2" + "Po" "3d5/2" + "Po" "4s" + "Po" "4p1/2" + "Po" "4p3/2" + "Po" "4d3/2" + "Po" "4d5/2" + "Po" "4f5/2" + "Po" "4f7/2" + "Po" "5s" + "Po" "5p1/2" + "Po" "5p3/2" + "Po" "5d3/2" + "Po" "5d5/2" + "At" "1s" + "At" "2s" + "At" "2p1/2" + "At" "2p3/2" + "At" "3s" + "At" "3p1/2" + "At" "3p3/2" + "At" "3d3/2" + "At" "3d5/2" + "At" "4s" + "At" "4p1/2" + "At" "4p3/2" + "At" "4d3/2" + "At" "4d5/2" + "At" "4f5/2" + "At" "4f7/2" + "At" "5s" + "At" "5p1/2" + "At" "5p3/2" + "At" "5d3/2" + "At" "5d5/2" + "Rn" "1s" + "Rn" "2s" + "Rn" "2p1/2" + "Rn" "2p3/2" + "Rn" "3s" + "Rn" "3p1/2" + "Rn" "3p3/2" + "Rn" "3d3/2" + "Rn" "3d5/2" + "Rn" "4s" + "Rn" "4p1/2" + "Rn" "4p3/2" + "Rn" "4d3/2" + "Rn" "4d5/2" + "Rn" "4f5/2" + "Rn" "4f7/2" + "Rn" "5s" + "Rn" "5p1/2" + "Rn" "5p3/2" + "Rn" "5d3/2" + "Rn" "5d5/2" + "Rn" "6s" + "Fr" "1s" + "Fr" "2s" + "Fr" "2p1/2" + "Fr" "2p3/2" + "Fr" "3s" + "Fr" "3p1/2" + "Fr" "3p3/2" + "Fr" "3d3/2" + "Fr" "3d5/2" + "Fr" "4s" + "Fr" "4p1/2" + "Fr" "4p3/2" + "Fr" "4d3/2" + "Fr" "4d5/2" + "Fr" "4f5/2" + "Fr" "4f7/2" + "Fr" "5s" + "Fr" "5p1/2" + "Fr" "5p3/2" + "Fr" "5d3/2" + "Fr" "5d5/2" + "Fr" "6s" + "Fr" "6p1/2" + "Fr" "6p3/2" + "Ra" "1s" + "Ra" "2s" + "Ra" "2p1/2" + "Ra" "2p3/2" + "Ra" "3s" + "Ra" "3p1/2" + "Ra" "3p3/2" + "Ra" "3d3/2" + "Ra" "3d5/2" + "Ra" "4s" + "Ra" "4p1/2" + "Ra" "4p3/2" + "Ra" "4d3/2" + "Ra" "4d5/2" + "Ra" "4f5/2" + "Ra" "4f7/2" + "Ra" "5s" + "Ra" "5p1/2" + "Ra" "5p3/2" + "Ra" "5d3/2" + "Ra" "5d5/2" + "Ra" "6s" + "Ra" "6p1/2" + "Ra" "6p3/2" + "Ac" "1s" + "Ac" "2s" + "Ac" "2p1/2" + "Ac" "2p3/2" + "Ac" "3s" + "Ac" "3p1/2" + "Ac" "3p3/2" + "Ac" "3d3/2" + "Ac" "3d5/2" + "Ac" "4s" + "Ac" "4p1/2" + "Ac" "4p3/2" + "Ac" "4d3/2" + "Ac" "4d5/2" + "Ac" "4f5/2" + "Ac" "4f7/2" + "Ac" "5s" + "Ac" "5p1/2" + "Ac" "5p3/2" + "Ac" "5d3/2" + "Ac" "5d5/2" + "Th" "1s" + "Th" "2s" + "Th" "2p1/2" + "Th" "2p3/2" + "Th" "3s" + "Th" "3p1/2" + "Th" "3p3/2" + "Th" "3d3/2" + "Th" "3d5/2" + "Th" "4s" + "Th" "4p1/2" + "Th" "4p3/2" + "Th" "4d3/2" + "Th" "4d5/2" + "Th" "4f5/2" + "Th" "4f7/2" + "Th" "5s" + "Th" "5p1/2" + "Th" "5p3/2" + "Th" "5d3/2" + "Th" "5d5/2" + "Th" "6s" + "Th" "6p1/2" + "Th" "6p3/2" + "Pa" "1s" + "Pa" "2s" + "Pa" "2p1/2" + "Pa" "2p3/2" + "Pa" "3s" + "Pa" "3p1/2" + "Pa" "3p3/2" + "Pa" "3d3/2" + "Pa" "3d5/2" + "Pa" "4s" + "Pa" "4p1/2" + "Pa" "4p3/2" + "Pa" "4d3/2" + "Pa" "4d5/2" + "Pa" "4f5/2" + "Pa" "4f7/2" + "Pa" "5s" + "Pa" "5p1/2" + "Pa" "5p3/2" + "Pa" "5d3/2" + "Pa" "5d5/2" + "U" "1s" + "U" "2s" + "U" "2p1/2" + "U" "2p3/2" + "U" "3s" + "U" "3p1/2" + "U" "3p3/2" + "U" "3d3/2" + "U" "3d5/2" + "U" "4s" + "U" "4p1/2" + "U" "4p3/2" + "U" "4d3/2" + "U" "4d5/2" + "U" "4f5/2" + "U" "4f7/2" + "U" "5s" + "U" "5p1/2" + "U" "5p3/2" + "U" "5d3/2" + "U" "5d5/2" + "U" "6s" + "U" "6p1/2" + "U" "6p3/2" +END +X SetScale/P x 0,1,"", symbol; SetScale y 0,0,"", symbol +X SetScale/P x 0,1,"", term; SetScale y 0,0,"", term diff --git a/pearl/fermi-edge-analysis.ipf b/pearl/fermi-edge-analysis.ipf index 18fe79d..8f2ba1a 100644 --- a/pearl/fermi-edge-analysis.ipf +++ b/pearl/fermi-edge-analysis.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #include "pearl-area-profiles" @@ -297,24 +298,3 @@ function show_shift(data) shift_x += ecenter end -/// calculate the energy resolution of the analyser -/// -/// @param epass pass energy in eV -/// @param slit analyser entrance slit in mm -/// -/// @return energy resolution (FWHM) -function analyser_energy_resolution(epass, slit) - variable epass - variable slit - - variable respow - if (epass < 4) - respow = 1110 - elseif (epass < 8) - respow = 1400 - else - respow = 1750 - endif - - return epass * max(0.2, slit) / 0.2 / respow -end diff --git a/pearl/pearl-anglescan-panel.ipf b/pearl/pearl-anglescan-panel.ipf index 8c85e02..adfd576 100644 --- a/pearl/pearl-anglescan-panel.ipf +++ b/pearl/pearl-anglescan-panel.ipf @@ -1,9 +1,12 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma version = 1.8 #pragma IgorVersion = 6.2 #pragma ModuleName = PearlAnglescanPanel #include "pearl-anglescan-process" #include "pearl-pmsco-import" +#include "pearl-scienta-preprocess" +#include "pearl-area-display" // copyright (c) 2018-20 Paul Scherrer Institut // @@ -430,9 +433,9 @@ static function delete_rows(rows, data, theta, tilt, phi) extract /free idx, idx, idx >= 0 variable nx = dimsize(data, 0) variable ny = numpnts(idx) - theta = theta[idx] - tilt = tilt[idx] - phi = phi[idx] + theta[0,ny-1] = theta[idx] + tilt[0,ny-1] = tilt[idx] + phi[0,ny-1] = phi[idx] redimension /n=(ny) theta, tilt, phi duplicate /free data, data_copy redimension /n=(nx,ny) data diff --git a/pearl/pearl-anglescan-process.ipf b/pearl/pearl-anglescan-process.ipf index 82852fb..3b78133 100644 --- a/pearl/pearl-anglescan-process.ipf +++ b/pearl/pearl-anglescan-process.ipf @@ -1,12 +1,13 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. -#pragma version = 1.8 +#pragma version = 1.9 #pragma IgorVersion = 6.2 #pragma ModuleName = PearlAnglescanProcess #include "pearl-vector-operations" #include "pearl-polar-coordinates" #include -// copyright (c) 2013-17 Paul Scherrer Institut +// copyright (c) 2013-21 Paul Scherrer Institut // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -64,7 +65,7 @@ /// /// @author matthias muntwiler, matthias.muntwiler@psi.ch /// -/// @copyright 2013-17 Paul Scherrer Institut @n +/// @copyright 2013-21 Paul Scherrer Institut @n /// Licensed under the Apache License, Version 2.0 (the "License"); @n /// you may not use this file except in compliance with the License. @n /// You may obtain a copy of the License at @@ -80,6 +81,70 @@ /// PearlAnglescanProcess is declared in @ref pearl-anglescan-process.ipf. +/// 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)! +/// +/// @param[in,out] strip1 2D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan. +/// this is the first source wave and destination wave. +/// +/// @param[in] strip2 2D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan. +/// this is the second source wave. +/// +/// @return (string) semicolon-separated list of modified wave names (without folder path). +/// +function /s strip_append(strip1, strip2) + wave strip1 + wave strip2 + + dfref df1 = GetWavesDataFolderDFR(strip1) + dfref df2 = GetWavesDataFolderDFR(strip2) + variable ny1 = dimsize(strip1, 1) + variable ny2 = dimsize(strip2, 1) + + concatenate /np=1 {strip2}, strip1 + string modified = AddListItem(NameOfWave(strip1), "") + + variable idf = 0 + do + variable iw = 0 + do + wave /z w1 = WaveRefIndexedDFR(df1, iw) + if (!WaveExists(w1)) + break + endif + + wave /z w2 = df2:$(NameOfWave(w1)) + if (WaveExists(w1) && WaveExists(w2)) + if ((DimSize(w1, 0) == ny1) && (DimSize(w1, 1) == 0) && (DimSize(w2, 0) == ny2) && (DimSize(w2, 1) == 0)) + concatenate /np=0 {w2}, w1 + modified = AddListItem(NameOfWave(w1), modified, "", Inf) + endif + endif + iw += 1 + while(1) + + df1 = df1:attr + df2 = df2:attr + if ((DataFolderRefStatus(df1) != 1) || (DataFolderRefStatus(df2) != 1)) + break + endif + idf += 1 + while(idf < 2) + + return modified +end + /// delete a contiguous range of frames from a strip. /// /// this can be used to remove a region of bad frames due to, e.g., measurement problems. @@ -299,7 +364,9 @@ function normalize_strip_phi(strip, theta, phi, [theta_offset, theta_range, chec endif // average over analyser angles - wave dist = ad_profile_y(strip, -inf, inf, "") + duplicate /free strip, strip_copy + MatrixFilter NanZapMedian strip_copy + wave dist = ad_profile_y(strip_copy, -inf, inf, "") // smooth distribution function duplicate /free dist, dist_smoo @@ -385,7 +452,9 @@ function normalize_strip_theta(strip, theta, [theta_offset, smooth_method, smoot endif // average over analyser angles - wave dist = ad_profile_y(strip, -inf, inf, "") + duplicate /free strip, strip_copy + MatrixFilter NanZapMedian strip_copy + wave dist = ad_profile_y(strip_copy, -inf, inf, "") // smooth distribution function duplicate /free dist, dist_smoo @@ -484,7 +553,9 @@ function normalize_strip_thetaphi(strip, theta, phi, [theta_offset, smooth_metho endif // average over analyser angles - wave dist = ad_profile_y(strip, -inf, inf, "") + duplicate /free strip, strip_copy + MatrixFilter NanZapMedian strip_copy + wave dist = ad_profile_y(strip_copy, -inf, inf, "") // smooth distribution function duplicate /free dist, dist_smoo @@ -542,7 +613,9 @@ function normalize_strip_theta_scans(strip, theta, [theta_offset, smooth_method, endif // average over analyser angles - wave dist = ad_profile_y(strip, -inf, inf, "") + duplicate /free strip, strip_copy + MatrixFilter NanZapMedian strip_copy + wave dist = ad_profile_y(strip_copy, -inf, inf, "") // smooth distribution function duplicate /free dist, dist_smoo @@ -635,6 +708,7 @@ function normalize_strip_2d(strip, theta, [theta_offset, smooth_method, smooth_f variable ny = dimsize(strip, 1) duplicate /free strip, dist, alpha_int, theta_int + MatrixFilter NanZapMedian dist theta_int = theta[q] - theta_offset alpha_int = dimoffset(strip, 0) + p * dimdelta(strip, 0) redimension /n=(nx * ny) dist, alpha_int, theta_int @@ -1955,7 +2029,7 @@ static function /s display_polar_graph(graphname, [angle_offset, do_ticks]) WMPolarGraphSetVar(graphname, "doAngleTickLabelSubRange", 1) WMPolarGraphSetVar(graphname, "angleTickLabelRangeStart", 0) WMPolarGraphSetVar(graphname, "angleTickLabelRangeExtent", 90) - WMPolarGraphSetStr(graphname, "angleTickLabelNotation", "%g°") + WMPolarGraphSetStr(graphname, "angleTickLabelNotation", "%g°") WMPolarGraphSetVar(graphname, "doPolarGrids", 0) WMPolarGraphSetVar(graphname, "doRadiusTickLabels", 0) @@ -2083,9 +2157,9 @@ static function /s draw_hemi_axes(graphname, [do_grids]) SetDrawEnv /W=$graphname textxjust= 1,textyjust= 2 SetDrawEnv /W=$graphname save radi = calc_graph_radius(30, projection=projection) - DrawText /W=$graphname radi, -0.1, "30°" + DrawText /W=$graphname radi, -0.1, "30°" radi = calc_graph_radius(60, projection=projection) - DrawText /W=$graphname radi, -0.1, "60°" + DrawText /W=$graphname radi, -0.1, "60°" endif setdatafolder savedf @@ -2205,7 +2279,7 @@ function /s display_scanlines(nickname, alpha_lo, alpha_hi, m_theta, m_tilt, m_p make /n=1 /d /free d_polar, d_azi variable n_alpha = round(alpha_hi - alpha_lo) + 1 make /n=(n_alpha) /d /free analyser - setscale /i x alpha_lo, alpha_hi, "°", analyser + setscale /i x alpha_lo, alpha_hi, "°", analyser analyser = x convert_angles_ttpa2polar(m_theta, loc_m_tilt, m_phi, analyser, d_polar, d_azi) @@ -2526,50 +2600,78 @@ function set_polar_graph_cursor(nickname, cursorname, polar_angle, azim_angle, [ endif end -/// add an arbitrary angle scan to a hemispherical scan grid. + +/// add arbitrary angle scan 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, -/// 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. +/// 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) wave is calculated as _tot / _wt. +/// the intensity (_i/values) wave is calculated as _tot divided by _wt. +/// +/// @param nickname name prefix of holo waves. +/// empty if waves are in current data folder. +/// @param values counts/intensity values at the positions given in the polara nd azi waves. +/// one- or two-dimensional. +/// NaN values are ignored. +/// @param polar polar angles (in degrees) of each data point. +/// allowed range 0 <= theta <= 90. +/// no specific ordering required. +/// @param azi azimuthal angles (in degrees) of each data point. +/// allowed range -360 <= phi < +360. +/// no specific order required. +/// @param weights weight 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. +/// function hemi_add_anglescan(nickname, values, polar, azi, [weights]) - string nickname // name prefix of holo waves. - // may be empty. - wave values // intensity values - // the wave can be one- or two-dimensional. - // no specific order required, the function sorts the arrays internally - wave polar // polar coordinates. allowed range 0 <= theta <= 90 - // dimensions corresponding to value. - wave azi // azimuthal coordinates. allowed range -360 <= phi < +360 - // dimensions corresponding to value. - wave weights // total accumulation time of each point of values. default = 1 + string nickname + wave values + wave polar + wave azi + wave weights + + dfref savedf = GetDataFolderDFR() if (ParamIsDefault(weights)) duplicate /free values, weights weights = 1 endif - - // quick check whether hemi grid is existing + string s_prefix = "" string s_int = "values" dfref df = find_hemi_data(nickname, s_prefix, s_int) + string s_totals = s_prefix + "tot" + string s_weights = s_prefix + "wt" string s_polar = s_prefix + "pol" string s_azim = s_prefix + "az" + string s_index = s_prefix + "index" string s_theta = s_prefix + "th" - - wave /sdfr=df /z w_values = $s_int - wave /sdfr=df /z w_azim = $s_azim - wave /sdfr=df /z w_polar = $s_polar - wave /sdfr=df /z w_theta = $s_theta - if (!waveexists(w_values) || !waveexists(w_azim) || !waveexists(w_polar)) - abort "Missing hemispherical scan grid. Please call make_hemi_grid() first." - endif + string s_dphi = s_prefix + "dphi" + string s_nphis = s_prefix + "nphis" - // make internal copies, one-dimensional, ordered in theta + wave /sdfr=df w_polar = $s_polar + wave /sdfr=df w_azim = $s_azim + wave /sdfr=df w_values = $s_int + wave /sdfr=df w_totals = $s_totals + wave /sdfr=df w_weights = $s_weights + wave /sdfr=df w_index = $s_index + wave /sdfr=df w_theta = $s_theta + wave /sdfr=df w_dphi = $s_dphi + wave /sdfr=df w_nphis = $s_nphis + + // make internal copies of input, one-dimensional, ordered in theta duplicate /free values, values_copy duplicate /free polar, polar_copy duplicate /free azi, azi_copy @@ -2577,49 +2679,186 @@ function hemi_add_anglescan(nickname, values, polar, azi, [weights]) variable nn = dimsize(values, 0) * max(dimsize(values, 1), 1) redimension /n=(nn) values_copy, polar_copy, azi_copy, weights_copy sort /r polar_copy, polar_copy, azi_copy, values_copy, weights_copy + + make /n=(numpnts(w_theta)) /free /df dfw + // for debugging: remove the MultiThread keyword and the ThreadSafe keywords of sub-functions + 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) + + variable pp + for (pp = 0; pp < numpnts(dfw); pp += 1) + dfref tdf= dfw[pp] + wave df_totals = tdf:w_totals + wave df_weights = tdf:w_weights + w_totals += df_totals + w_weights += df_weights + endfor + w_values = w_weights > 0 ? w_totals / w_weights : nan - variable pol + SetDataFolder savedf +end + +/// thread worker for hemi_add_anglescan +/// +/// this function extracts one azimuthal scan from the input data and adds it to an existing holo scan. +/// it should be considered as a part of hemi_add_anglescan and not used elsewhere, +/// as its interface may change in the future. +/// +/// the function takes as input the entire input data, an existing hemi grid and the index of a polar angle to work on. +/// the results are a w_totals and w_weights wave that can be added to the hemi scan. +/// the two waves are returned in a free data folder referenced by the return value of the function. +/// the function does not change global data. +/// +threadsafe static function /df add_anglescan_worker(ith, values, weights, polar, azi, w_polar, w_azim, w_theta, w_index, w_dphi, w_nphis) + variable ith // index into w_theta + wave values // input data: intensity/counts + wave weights // input data: weights/dwell time + wave polar // input data: polar angles + wave azi // input data: azimuthal angles + wave w_polar // hemi grid + wave w_azim // hemi grid + wave w_theta // hemi grid + wave w_index // hemi grid + wave w_dphi // hemi grid + wave w_nphis // hemi grid + + dfref savedf= GetDataFolderDFR() + dfref freedf= NewFreeDataFolder() + SetDataFolder freedf + make /n=(numpnts(w_polar)) /d w_totals, w_weights + + variable pol = w_theta[ith] variable pol_st = abs(w_theta[1] - w_theta[0]) - variable pol1, pol2 + variable pol1 = pol - pol_st / 2 + variable pol2 = pol + pol_st / 2 + + extract /free /indx polar, sel, (pol1 < polar) && (polar <= pol2) && (numtype(values) == 0) && (weights > 0) + if (numpnts(sel) > 0) + duplicate /free /r=[0, numpnts(sel)-1] azi, azi_slice + duplicate /free /r=[0, numpnts(sel)-1] values, values_slice + duplicate /free /r=[0, numpnts(sel)-1] weights, weights_slice + azi_slice = azi[sel] + values_slice = values[sel] + weights_slice = weights[sel] + add_aziscan_core(values_slice, weights_slice, pol, azi_slice, w_theta, w_azim, w_index, w_dphi, w_totals, w_weights) + endif + + SetDataFolder savedf + return freedf +end + +/// thread worker for hemi_add_anglescan and hemi_add_aziscan +/// +/// this function adds one azimuthal scan to an existing holo scan. +/// it should be considered as a part of hemi_add_anglescan and hemi_add_aziscan and not used elsewhere, +/// as its interface may change in the future. +/// +/// the function takes as input an azimuthal scan and an existing hemi grid. +/// the results are added to w_totals and w_weights waves. +/// +/// @attention the function sorts the input arrays by azimuthal angle! +/// these waves must not refer to global objects if multi-threading is used! +/// +threadsafe static function add_aziscan_core(values, weights, polar, azi, w_theta, w_azim, w_index, w_dphi, w_totals, w_weights) + wave values // input data: intensity/counts + wave weights // input data: weights/dwell time + variable polar // input data: polar angle + wave azi // input data: angle positions of the azimuthal scan + // acceptable range: >= -360 and < +360 + // no specific order required, the function sorts the array in place (!) + wave w_theta // hemi grid + wave w_azim // hemi grid + wave w_index // hemi grid + wave w_dphi // hemi grid + wave w_totals // output data: total counts in hemi grid order + wave w_weights // output data: total weights in hemi grid order - duplicate /free azi_copy, azi_slice - duplicate /free values_copy, values_slice - duplicate /free weights_copy, weights_slice - for (pol = 90; pol >= 0; pol -= pol_st) - pol1 = pol - pol_st / 2 - pol2 = pol + pol_st / 2 - extract /free /indx polar_copy, sel, (pol1 < polar_copy) && (polar_copy <= pol2) - if (numpnts(sel) > 0) - redimension /n=(numpnts(sel)) azi_slice, values_slice, weights_slice - azi_slice = azi_copy[sel] - values_slice = values_copy[sel] - weights_slice = weights_copy[sel] - hemi_add_aziscan(nickname, values_slice, pol, azi_slice, weights=weights_slice) + // destination slice coordinates + variable ipol = BinarySearch(w_theta, polar) + if (ipol < 0) + return -1 + endif + + variable d1, d2 + if (ipol >= 1) + d1 = w_index[ipol - 1] + else + d1 = 0 + endif + d2 = w_index[ipol] - 1 + variable nd = d2 - d1 + 1 + variable dphi = w_dphi[ipol] + make /n=(nd+1) /free bin_index + setscale /i x w_azim[d1] - dphi/2, w_azim[d2] + dphi/2, "deg", bin_index + + // source slice coordinates + // order the slice from -dphi/2 to 360-dphi/2 + azi = azi < 0 ? azi + 360 : azi + azi = azi >= 360 - dphi/2 ? azi - 360 : azi + sort azi, values, weights, azi + setscale /p x 0, 1, "", values, weights, azi + + bin_index = BinarySearch(azi, x) + 1 + bin_index = bin_index == -2 ? 0 : bin_index[p] + bin_index = bin_index == -1 ? numpnts(azi) : bin_index[p] + bin_index[nd] = numpnts(azi) + + // loop over destination + variable id + variable v1, v2, w1, w2 + for (id = 0; id < nd; id += 1) + if (bin_index[id+1] > bin_index[id]) + v1 = w_totals[d1 + id] + w1 = w_weights[d1 + id] + if ((numtype(v1) == 2) || (w1 <= 0)) + v1 = 0 + w1 = 0 + endif + v2 = sum(values, bin_index[id], bin_index[id+1] - 1) + w2 = sum(weights, bin_index[id], bin_index[id+1] - 1) + w_totals[d1 + id] = v1 + v2 + w_weights[d1 + id] = w1 + w2 endif endfor end -/// add an azimuthal scan to a hemispherical scan grid. +/// 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 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. +/// 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). +/// +/// @param nickname name prefix of holo waves. +/// empty if waves are in current data folder. +/// @param values counts/intensity values of the azimuthal scan at the positions given in the azi parameter. +/// @param polar polar angle (in degrees) where to add the azi scan. +/// @param azi angle positions of the azimuthal scan. +/// acceptable range: >= -360 and < +360. +/// no specific order required, the function sorts the array internally. +/// @param weights weight 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(). +/// function hemi_add_aziscan(nickname, values, polar, azi, [weights]) - string nickname // name prefix of holo waves. - // may be empty. - wave values // intensity values of the azimuthal scan at the positions given in the azi parameter - variable polar // polar angle where to add the azi scan - wave azi // angle positions of the azimuthal scan - // acceptable range: >= -360 and < +360 - // no specific order required, the function sorts the array internally - wave weights // total accumulation time of each point of values. default = 1 + string nickname + wave values + variable polar + wave azi + wave weights + dfref savedf = GetDataFolderDFR() + + duplicate /free values, values_copy + duplicate /free azi, azi_copy if (ParamIsDefault(weights)) - duplicate /free values, weights - weights = 1 + duplicate /free values, weights_copy + weights_copy = 1 + else + duplicate /free weights, weights_copy endif - + // hemi grid waves string s_prefix = "" string s_int = "values" @@ -2644,56 +2883,11 @@ function hemi_add_aziscan(nickname, values, polar, azi, [weights]) wave /sdfr=df w_dphi = $s_dphi wave /sdfr=df w_nphis = $s_nphis - // destination slice coordinates - //polar = round(polar) - //variable ipol = 90 - polar - variable ipol = BinarySearch(w_theta, polar) - if (ipol < 0) - abort "assertion failed in hemi_add_aziscan(): polar angle not found in grid." - endif - - variable d1, d2 - if (ipol >= 1) - d1 = w_index[ipol - 1] - else - d1 = 0 - endif - d2 = w_index[ipol] - 1 - variable nd = d2 - d1 + 1 - variable dphi = w_dphi[ipol] - variable az1, az2 - - // source slice coordinates - // order the slice from -dphi/2 to 360-dphi/2 - azi = azi < 0 ? azi + 360 : azi - azi = azi >= 360 - dphi/2 ? azi - 360 : azi - duplicate /free values, sel_values - duplicate /free weights, sel_weights - - // loop over destination - variable id - variable v1, v2, w1, w2 - for (id = 0; id < nd; id += 1) - az1 = (id - 0.5) * dphi - az2 = (id + 0.5) * dphi - extract /free /indx azi, sel, (az1 <= azi) && (azi < az2) - if (numpnts(sel) > 0) - redimension /n=(numpnts(sel)) sel_values, sel_weights - sel_values = values[sel] - sel_weights = weights[sel] - v1 = w_totals[d1 + id] - w1 = w_weights[d1 + id] - if ((numtype(v1) == 2) || (w1 <= 0)) - v1 = 0 - w1 = 0 - endif - v2 = sum(sel_values) - w2 = sum(sel_weights) - w_totals[d1 + id] = v1 + v2 - w_weights[d1 + id] = w1 + w2 - endif - endfor - w_values[d1, d1 + nd - 1] = w_totals[p] / w_weights[p] + add_aziscan_core(values_copy, weights_copy, polar, azi_copy, w_theta, w_azim, w_index, w_dphi, w_totals, w_weights) + + w_values = w_weights > 0 ? w_totals / w_weights : nan + + SetDataFolder savedf end /// interpolate a hemispherical scan onto a rectangular grid @@ -3011,8 +3205,9 @@ function import_tpi_scan(nickname, theta, phi, intensity, [folding, npolar, nogr variable ifold duplicate /free phi, fold_phi for (ifold = 0; ifold < folding; ifold += 1) + fold_phi = fold_phi >= 360 ? fold_phi - 360 : fold_phi hemi_add_anglescan(nickname, intensity, theta, fold_phi) - fold_phi = fold_phi >= 180 ? fold_phi + 360 / folding - fold_phi : fold_phi + 360 / folding + fold_phi += 360 / folding endfor if (nograph==0) @@ -3199,7 +3394,7 @@ function /wave hemi_azi_cut(nickname, pol) make /n=(nsel) /o $s_cut wave w_cut = $s_cut w_cut = w_values[sel] - setscale /i x w_azim[sel[0]], w_azim[sel[nsel-1]], "°", w_cut + setscale /i x w_azim[sel[0]], w_azim[sel[nsel-1]], "°", w_cut setdatafolder savedf return w_cut else @@ -3209,23 +3404,37 @@ function /wave hemi_azi_cut(nickname, pol) setdatafolder savedf end -static function check_contrast(values, pcmin, pcmax, vmin, vmax) +static function check_contrast(values, pcmin, pcmax, vmin, vmax, sym) wave values variable pcmin variable pcmax variable &vmin variable &vmax + variable sym dfref save_df = GetDataFolderDFR() dfref dfr = NewFreeDataFolder() setdatafolder dfr StatsQuantiles /inan /iw /q /z values - wave index = w_quantilesindex - variable imin = round(numpnts(index) * pcmin / 100) - variable imax = round(numpnts(index) * (100 - pcmax) / 100) - vmin = values[index[imin]] - vmax = values[index[imax]] + wave /z index = w_quantilesindex setdatafolder save_df + + if (waveexists(index)) + variable imin = round(numpnts(index) * pcmin / 100) + variable imax = round(numpnts(index) * (100 - pcmax) / 100) + vmin = values[index[imin]] + vmax = values[index[imax]] + if (sym) + variable d = vmax - vmin + if ((vmax >= d/4) && (-vmin >= d/4)) + vmax = min(abs(vmin), abs(vmax)) + vmin = -vmax + endif + endif + else + vmin = wavemin(values) + vmax = wavemax(values) + endif end /// set the pseudocolor contrast by percentile. @@ -3243,12 +3452,21 @@ end /// @param pcmax percentile above the maximum color (0-100). /// @param graphname name of graph. default: top graph. /// @param colortable name of new colortable. default: keep current table. +/// @param reversecolors reverse colors of new colorable. +/// takes effect only if colortable argument is defined. +/// @arg 0 (default) normal colors, +/// @arg 1 reverse color table +/// @param symmetric make scale symmetric about zero (for modulation functions, e.g.). +/// @arg 0 (default) do not enforce symmetry. +/// @arg 1 try symmetric scale if "reasonable". /// -function set_contrast(pcmin, pcmax, [graphname, colortable]) +function set_contrast(pcmin, pcmax, [graphname, colortable, reversecolors, symmetric]) variable pcmin variable pcmax string graphname string colortable + variable reversecolors + variable symmetric if (ParamIsDefault(graphname)) graphname = "" @@ -3256,6 +3474,12 @@ function set_contrast(pcmin, pcmax, [graphname, colortable]) if (ParamIsDefault(colortable)) colortable = "" endif + if (ParamIsDefault(reversecolors)) + reversecolors = 0 + endif + if (ParamIsDefault(symmetric)) + symmetric = 0 + endif dfref save_df = GetDataFolderDFR() @@ -3285,9 +3509,12 @@ function set_contrast(pcmin, pcmax, [graphname, colortable]) rev = str2num("0" + StringFromList(4, info, ",")) if (strlen(colortable) > 0) ctab = colortable + rev = reversecolors + endif + check_contrast(w, pcmin, pcmax, vmin, vmax, symmetric) + if (vmax > vmin) + ModifyGraph /w=$graphname zColor($objname)={w, vmin, vmax, $ctab, rev} endif - check_contrast(w, pcmin, pcmax, vmin, vmax) - ModifyGraph /w=$graphname zColor($objname)={w, vmin, vmax, $ctab, rev} endif endif endfor @@ -3307,9 +3534,12 @@ function set_contrast(pcmin, pcmax, [graphname, colortable]) rev = str2num("0" + StringFromList(3, info, ",")) if (strlen(colortable) > 0) ctab = colortable + rev = reversecolors + endif + check_contrast(w, pcmin, pcmax, vmin, vmax, symmetric) + if (vmax > vmin) + ModifyImage /w=$graphname $objname ctab={vmin, vmax, $ctab, rev} endif - check_contrast(w, pcmin, pcmax, vmin, vmax) - ModifyImage /w=$graphname $objname ctab={vmin, vmax, $ctab, rev} endif endif endfor diff --git a/pearl/pearl-anglescan-tracker.ipf b/pearl/pearl-anglescan-tracker.ipf index 7d7e2e7..18dec8d 100644 --- a/pearl/pearl-anglescan-tracker.ipf +++ b/pearl/pearl-anglescan-tracker.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "Windows-1252" #pragma rtGlobals=3 #pragma version = 1.4 #pragma IgorVersion = 6.2 diff --git a/pearl/pearl-area-display.ipf b/pearl/pearl-area-display.ipf index 5f6794b..36fb96a 100644 --- a/pearl/pearl-area-display.ipf +++ b/pearl/pearl-area-display.ipf @@ -1,8 +1,10 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.2 #pragma ModuleName = PearlAreaDisplay #pragma version = 1.04 #include "pearl-compat" +#include "pearl-area-profiles" /// @file /// @brief visualization tools for 2D and 3D data. diff --git a/pearl/pearl-area-import.ipf b/pearl/pearl-area-import.ipf index c2c8af9..58719ff 100644 --- a/pearl/pearl-area-import.ipf +++ b/pearl/pearl-area-import.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "Windows-1252" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.2 #pragma ModuleName = PearlAreaImport @@ -5,7 +6,7 @@ #include "pearl-compat" #include "pearl-gui-tools" -// copyright (c) 2013-18 Paul Scherrer Institut +// copyright (c) 2013-20 Paul Scherrer Institut // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,7 +27,7 @@ /// /// @author matthias muntwiler, matthias.muntwiler@psi.ch /// -/// @copyright 2013-18 Paul Scherrer Institut @n +/// @copyright 2013-20 Paul Scherrer Institut @n /// Licensed under the Apache License, Version 2.0 (the "License"); @n /// you may not use this file except in compliance with the License. @n /// You may obtain a copy of the License at @@ -1331,7 +1332,7 @@ function adh5_reduce_brick(source, reduction_func, reduction_param, result_prefi for (iw = 0; iw < func_result; iw += 1) sw = "redw_" + num2str(iw) wave profile = dfr:$sw - sw = "ReducedData" + num2str(iw+1) + sw = result_prefix + num2str(iw+1) make /n=(dimsize(profile, 0), nz, nt) /d /o $sw wave data = $sw setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data diff --git a/pearl/pearl-area-profiles.ipf b/pearl/pearl-area-profiles.ipf index d070836..2f3894d 100644 --- a/pearl/pearl-area-profiles.ipf +++ b/pearl/pearl-area-profiles.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.1 #pragma ModuleName = PearlAreaProfiles diff --git a/pearl/pearl-arpes.ipf b/pearl/pearl-arpes.ipf index c77952d..0185cdb 100644 --- a/pearl/pearl-arpes.ipf +++ b/pearl/pearl-arpes.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.1 #pragma ModuleName = PearlArpes @@ -18,7 +19,7 @@ #include "pearl-epics" // EPICS access under Igor #include "pearl-arpes-scans" // run ARPES scans under Igor #include "pearl-sample-tracker" // live tracking and adjustment of sample position -#include "pearl-scienta-countrate" +#include "pearl-scienta-live" #endif /// @file @@ -84,4 +85,4 @@ end function UnloadPearlArpesPackage() execute /p/q/z "DELETEINCLUDE \"pearl-arpes\"" execute /p/q/z "COMPILEPROCEDURES " -end \ No newline at end of file +end diff --git a/pearl/pearl-compat.ipf b/pearl/pearl-compat.ipf index 6264760..f5c0771 100644 --- a/pearl/pearl-compat.ipf +++ b/pearl/pearl-compat.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.1 #pragma ModuleName = PearlCompat diff --git a/pearl/pearl-data-explorer.ipf b/pearl/pearl-data-explorer.ipf index fb7a89b..f2ed939 100644 --- a/pearl/pearl-data-explorer.ipf +++ b/pearl/pearl-data-explorer.ipf @@ -1,7 +1,8 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. -#pragma IgorVersion = 6.1 +#pragma IgorVersion = 6.36 #pragma ModuleName = PearlDataExplorer -#pragma version = 1.50 +#pragma version = 1.60 #include "pearl-area-import" #include "pearl-area-profiles" #include "pearl-area-display" @@ -11,7 +12,7 @@ #include "pearl-matrix-import" #endif -// copyright (c) 2013-16 Paul Scherrer Institut +// copyright (c) 2013-20 Paul Scherrer Institut // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -258,6 +259,9 @@ static function preview_file(filename) string filename dfref saveDF = GetDataFolderDFR() + dfref previewDF = $package_path + + killStrings /z authors, pgroup, proposal, proposer, sample variable ft = pearl_file_type(filename) switch(ft) @@ -288,6 +292,35 @@ static function preview_file(filename) sprintf cmd, "PearlElog#set_panel_graphs(\"\", \"%s\")", graphname execute /Q/Z cmd endif + svar /sdfr=previewDF /z authors + if (svar_Exists(authors)) + if (strlen(authors)>=1) + sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"author=%s\")", authors + execute /Q/Z cmd + endif + endif + svar /sdfr=previewDF /z pgroup + if (svar_Exists(pgroup)) + if (strlen(pgroup)>=1) + sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"p-group=%s\")", pgroup + execute /Q/Z cmd + endif + endif + svar /sdfr=previewDF /z proposal + if (svar_Exists(proposal)) + if (strlen(proposal)>=1) + sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"project=%s\")", proposal + execute /Q/Z cmd + endif + endif + svar /sdfr=previewDF /z proposer + svar /sdfr=previewDF /z sample + if (svar_Exists(sample)) + if (strlen(sample)>=1) + sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"sample=%s\")", sample + execute /Q/Z cmd + endif + endif endif endif @@ -337,6 +370,8 @@ static function /wave preview_pshell_file(filename) if (strlen(s_preview_file) > 0) s_file_info = psh5_load_info("pearl_explorer_filepath", filename) + setdatafolder previewDF + psh5_load_general_group("pearl_explorer_filepath", filename) else s_file_info = "" endif @@ -960,15 +995,22 @@ static function /s display_preview_trace(xtrace, ytrace) lab = "X" endif Label /w=$graphname bottom lab + " (\\U)" - lab = StringByKey("AxisLabelD", labels, "=", "\r") + lab = StringByKey("Dataset", labels, "=", "\r") if (!strlen(lab)) lab = "value" endif Label /w=$graphname left lab + " (\\U)" - + return s_name end +/// 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! +/// static function load_selected_files([options]) string options @@ -981,6 +1023,7 @@ static function load_selected_files([options]) variable ii for (ii = 0; ii < nn; ii += 1) if (wSelectedFiles[ii]) + setdatafolder saveDF if (ParamIsDefault(options)) load_file(wtFiles[ii]) else @@ -990,15 +1033,19 @@ static function load_selected_files([options]) endfor update_datasets() - setdatafolder saveDF end +/// load one file +/// +/// this can be a PShell, HDF5, ITX or MTRX file. +/// (HDF5 and MTRX files require the corresponding XOP to be loaded - cf. file documentation) +/// +/// @note this function may change the current data folder! +/// static function load_file(filename, [options]) string filename string options - dfref saveDF = GetDataFolderDFR() - variable ft = pearl_file_type(filename) switch(ft) case 1: @@ -1024,8 +1071,6 @@ static function load_file(filename, [options]) default: break endswitch - - setdatafolder saveDF end static function prompt_hdf_options(options) @@ -1087,6 +1132,27 @@ function prompt_func_params(func_name, func_param) endif end +/// load a pshell file +/// +/// load a pshell hdf5 file (complete or reduced). +/// +/// if options is not specified, the complete file is loaded. +/// if options is an empty string, the package default options are used. +/// +/// the only supported options is `mode:load_reduced`. +/// in this case, the name of the reduction function must also 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. +/// +/// @param options `key:value;` list of load options. +/// by default, load complete, using psh5_load_complete(). +/// empty string, use options from `s_hdf_options. +/// @arg `mode:load_reduced` load reduced, using psh5_load_reduced(). +/// @arg `reduction_func:...` name of the reduction function. +/// +/// @note after the function returns, +/// the current data folder points to the loaded data (scan1). +/// static function /df load_pshell_file(filename, [options]) string filename string options @@ -1122,7 +1188,7 @@ static function /df load_pshell_file(filename, [options]) print reduction_func, reduction_params psh5_load_reduced(nickname, "pearl_explorer_filepath", filename, $reduction_func, reduction_params) svar s_filepath - loaded_filename = s_filepath + loaded_filename = filename endif break endswitch @@ -1132,10 +1198,12 @@ static function /df load_pshell_file(filename, [options]) if (strlen(loaded_filename) > 0) setdatafolder $("root:" + nickname) dataDF = GetDataFolderDFR() + setdatafolder $(":scan1") string /g pearl_explorer_import = "load_pshell_file" + else + setdatafolder saveDF endif - setdatafolder saveDF return dataDF end @@ -1183,9 +1251,10 @@ static function /df load_hdf_file(filename, [options]) setdatafolder $("root:" + nickname) dataDF = GetDataFolderDFR() string /g pearl_explorer_import = "load_hdf_file" + else + setdatafolder saveDF endif - setdatafolder saveDF return dataDF end diff --git a/pearl/pearl-elog.ipf b/pearl/pearl-elog.ipf index e81934a..cc1ab4c 100644 --- a/pearl/pearl-elog.ipf +++ b/pearl/pearl-elog.ipf @@ -1,10 +1,11 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. -#pragma version = 1.41 -#pragma IgorVersion = 6.2 +#pragma version = 1.50 +#pragma IgorVersion = 6.36 #pragma ModuleName = PearlElog // author: matthias.muntwiler@psi.ch -// Copyright (c) 2013-17 Paul Scherrer Institut +// Copyright (c) 2013-20 Paul Scherrer Institut // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -71,7 +72,7 @@ /// /// @author matthias muntwiler, matthias.muntwiler@psi.ch /// -/// @copyright 2013-17 Paul Scherrer Institut @n +/// @copyright 2013-20 Paul Scherrer Institut @n /// Licensed under the Apache License, Version 2.0 (the "License"); @n /// you may not use this file except in compliance with the License. @n /// You may obtain a copy of the License at @@ -272,14 +273,14 @@ function elog_init_pearl_templates() // attributes (persistent) // available attributes - string /g attributes = "author;project;p-group;sample;source;task;technique;file;valid;" + string /g attributes = "author;project;pgroup;sample;source;task;technique;file;valid;" // controls corresponding to attributes // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box string /g controls = "sv_author;sv_project;sv_pgroup;sv_sample;pm_source;pm_task;pm_technique;sv_file;cb_valid;" // attributes with fixed options, value item declares the options string string /g options = "source=sources;task=tasks;technique=techniques" // attributes which must be defined - string /g required_attributes = "author;project;p-group;sample;source;task;technique;valid" + string /g required_attributes = "author;project;pgroup;sample;source;task;technique;valid" // option lists 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" @@ -292,7 +293,7 @@ function elog_init_pearl_templates() // attributes (persistent) // available attributes - string /g attributes = "author;project;p-group;sample;program;revision;machine;job;experiment;source path;result path;valid" + string /g attributes = "author;project;pgroup;sample;program;revision;machine;job;experiment;source path;result path;valid" // controls corresponding to attributes // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box 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" diff --git a/pearl/pearl-fitfuncs.ipf b/pearl/pearl-fitfuncs.ipf index f623153..9d4a0d1 100644 --- a/pearl/pearl-fitfuncs.ipf +++ b/pearl/pearl-fitfuncs.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.2 #pragma ModuleName = PearlFitFuncs @@ -124,6 +125,51 @@ threadsafe function DoubletGaussLinBG_AO(pw, yw, xw) : FitFunc yw += pw[2] * pw[3] * exp( -( (xw[p] - pw[4] + pw[5] /2) / pw[6] / pw[7] )^2 ) end +/// two doublet gaussian peaks on a linear background fit function (all at once). +/// +/// this fits four gaussian peaks. +/// peak positions are specified by center, splitting and shift rather than individually. +/// amplitudes are specified as absolute values for peaks 1 and 3, +/// and relative values for peaks 2 and 4. +/// +/// can be used if a spin-orbit doublet is split by a chemical shift +/// which affects both spin-orbit peaks equally. +/// +/// @note FWHM = width * 2 * sqrt(ln(2)) = width * 1.665 +/// +/// @param pw shape parameters. +/// @arg pw[0] = constant coefficient of background +/// @arg pw[1] = linear coefficient of background +/// @arg pw[2] = amplitude of peak 1 +/// @arg pw[3] = amplitude of peak 2 +/// @arg pw[4] = amplitude of peak 3, relative to peak 1 +/// @arg pw[5] = amplitude of peak 4, relative to peak 2 +/// @arg pw[6] = position of peak 1 +/// @arg pw[7] = splitting (distance between peaks 1 and 3) +/// @arg pw[8] = shift (distance between peaks 1 and 2) +/// @arg pw[9] = width of peaks 1 and 3 +/// @arg pw[10] = width of peaks 2 and 4 +/// +/// @param yw y (dependent) values. +/// +/// @param xw x (independent) independent values. +/// +threadsafe function DblDoubletGaussLinBG_AO(pw, yw, xw) : FitFunc + wave pw + wave yw + wave xw + + yw = pw[0] + xw[p] * pw[1] + // peak 1 + yw += pw[2] * exp( -( (xw[p] - pw[6]) / pw[9] )^2 ) + // peak 2 + yw += pw[3] * exp( -( (xw[p] - pw[6] - pw[8]) / pw[10] )^2 ) + // peak 3 + yw += pw[2] * pw[4] * exp( -( (xw[p] - pw[6] - pw[7]) / pw[9] )^2 ) + // peak 4 + yw += pw[3] * pw[5] * exp( -( (xw[p] - pw[6] - pw[7] - pw[8]) / pw[10] )^2 ) +end + //------------------------------------------------------------------------------ // Voigt shapes //------------------------------------------------------------------------------ @@ -141,7 +187,7 @@ end /// @arg w[5 + (i-1) * 4] = shape of peak i /// @param x independent variable /// -function MultiVoigtLinBG(w,x) : FitFunc +threadsafe function MultiVoigtLinBG(w,x) : FitFunc wave w variable x @@ -156,6 +202,39 @@ function MultiVoigtLinBG(w,x) : FitFunc return v end +/// multiple voigt peaks on a linear background fit function. +/// +/// +/// this is the all-at-once version of @ref MultiVoigtLinBG. +/// it runs slightly faster compared to the point-by-point function. +/// +/// @param pw shape parameters. +/// the length of the wave defines the number of peaks. +/// @arg pw[0] = constant coefficient of background +/// @arg pw[1] = linear coefficient of background +/// @arg pw[2 + (i-1) * 4] = amplitude of peak i +/// @arg pw[3 + (i-1) * 4] = position of peak i +/// @arg pw[4 + (i-1) * 4] = width of peak i +/// @arg pw[5 + (i-1) * 4] = shape of peak i +/// +/// @param yw y (dependent) values. +/// +/// @param xw x (independent) independent values. +/// +threadsafe function MultiVoigtLinBG_AO(pw, yw, xw) : FitFunc + wave pw + wave yw + wave xw + + variable np = numpnts(pw) + variable ip + + yw = pw[0] + xw[p] * pw[1] + for (ip = 2; ip < np; ip += 4) + yw += pw[ip] * VoigtFunc((xw[p] - pw[ip+1]) / pw[ip+2], pw[ip+3]) + endfor +end + //------------------------------------------------------------------------------ // Doniach-Sunjic shapes @@ -198,7 +277,7 @@ end /// @arg w[5 + (i-1) * 4] = singularity index (0...1) of peak i /// @param x independent variable /// -function MultiDoniachSunjicLinBG(w,x) : FitFunc +threadsafe function MultiDoniachSunjicLinBG(w,x) : FitFunc wave w variable x diff --git a/pearl/pearl-gui-tools.ipf b/pearl/pearl-gui-tools.ipf index 102896a..65e2b86 100644 --- a/pearl/pearl-gui-tools.ipf +++ b/pearl/pearl-gui-tools.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.1 #pragma ModuleName = PearlGuiTools diff --git a/pearl/pearl-matrix-import.ipf b/pearl/pearl-matrix-import.ipf index 82294a8..7f53c7d 100644 --- a/pearl/pearl-matrix-import.ipf +++ b/pearl/pearl-matrix-import.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 #pragma version = 1.00 #pragma IgorVersion = 6.36 diff --git a/pearl/pearl-menu.ipf b/pearl/pearl-menu.ipf index e90ddaa..998e5e5 100644 --- a/pearl/pearl-menu.ipf +++ b/pearl/pearl-menu.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=1 // Use modern global access method. #pragma ModuleName = PearlMenu #pragma version = 1.02 diff --git a/pearl/pearl-pmsco-import.ipf b/pearl/pearl-pmsco-import.ipf index c00270a..92d9f67 100644 --- a/pearl/pearl-pmsco-import.ipf +++ b/pearl/pearl-pmsco-import.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.2 #pragma ModuleName = PearlPmscoImport @@ -174,6 +175,137 @@ static function /s save_scan_helper(destname, value, template, destdfr, wavename return wavenames end +/// load a PMSCO scan file into the current data folder. +/// +/// the function loads all columns from the file. +/// the waves are named with two-letter names according to the file extension. +/// existing waves are overwritten. +/// +/// the file extension must be `etpais` or a subset of it, e.g., `etpi`. +/// the wave names will be `en` (energy), `th` (theta), `ph` (phi), `al` (alpha), +/// `in` (intensity) or `mo` (modulation), and `si` (sigma). +/// +/// @param pathname name of igor symbolic path to destination folder. +/// prompt user if empty. +/// +/// @param filename requested file name. +/// prompt user if empty. +/// the extension must be a string of characters indicating the data of each column. +/// it must be "etpais" or any substring of it, and the columns must be ordered accordingly. +/// if the name contains `.modf`, the intensity wave is named as `mo` rather than `in`. +/// this behaviour can be overridden by the `is_modulation` flag. +/// +/// @param is_modulation select whether the intensity column is named `mo` rather than `in`. +/// @arg 0 (default) decide based on existens of `.modf` in the file name. +/// @arg > 0 use `mo` regardless of file name. +/// @arg < 0 use `in` regardless of file name. +/// +/// @param quiet (optional) +/// @arg 0 (default) print the file name and wave names to the history. +/// @arg 1 do not print messages to the history. +/// +function /s load_pmsco_scan(pathname, filename, [is_modulation, quiet]) + string pathname // name of a symbolic path + string filename + variable is_modulation + variable quiet + + if (ParamIsDefault(quiet)) + quiet = 0 + endif + + loadwave /p=$pathname /a /g /o /q filename + + if (ParamIsDefault(is_modulation)) + is_modulation = StringMatch(s_filename, "*.modf.*") + else + is_modulation = is_modulation > 0 + endif + + string fileext + string waves = "" + if (v_flag > 0) + fileext = StringFromList(ItemsInList(s_filename, ".") - 1, s_filename, ".") + variable nw = ItemsInList(s_wavenames) + variable iw + string sw1, sw2 + for (iw = 0; iw < nw; iw += 1) + sw1 = StringFromlist(iw, s_wavenames) + strswitch(fileext[iw]) + case "e": + sw2 = "en" + break + case "t": + sw2 = "th" + break + case "p": + sw2 = "ph" + break + case "a": + sw2 = "al" + break + case "i": + if (is_modulation) + sw2 = "mo" + else + sw2 = "in" + endif + break + case "s": + sw2 = "si" + break + endswitch + duplicate /o $sw1, $sw2 + killwaves /z $sw1 + waves = AddListItem(sw2, waves, ",", inf) + endfor + + // Sort {en,th,ph, al} en,th,ph,al,int,sig + + if (!quiet) + print "load_pmsco_scan ", s_filename, ": ", waves + endif + + return s_filename + else + return "" + endif +end + +/// load a PMSCO result file into the current data folder. +/// +/// result files have the extension dat or tasks.dat. +/// this will overwrite existing waves. +/// the function loads all columns. +/// +/// @param pathname name of a symbolic path +/// @param filename file name +/// @param quiet (optional) @arg 0 (default) print the file name and wave names to the history. +/// @arg 1 do not print messages to the history. +/// +function /s load_pmsco_result(pathname, filename, [quiet]) + string pathname // name of a symbolic path + string filename + variable quiet + + if (ParamIsDefault(quiet)) + quiet = 0 + endif + + if (quiet) + loadwave /p=$pathname /a /w /g /o /q filename + else + loadwave /p=$pathname /a /w /g /o filename + endif + + if (v_flag > 0) + return s_filename + else + return "" + endif +end + + /// load an xyz cluster file /// /// load an xyz cluster file into the current data folder diff --git a/pearl/pearl-polar-coordinates.ipf b/pearl/pearl-polar-coordinates.ipf index 0e67e3e..a12092a 100644 --- a/pearl/pearl-polar-coordinates.ipf +++ b/pearl/pearl-polar-coordinates.ipf @@ -1,3 +1,4 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 #pragma version = 1.1 #pragma IgorVersion = 6.1 diff --git a/pearl/pearl-pshell-import.ipf b/pearl/pearl-pshell-import.ipf index 280d3c4..1b2482b 100644 --- a/pearl/pearl-pshell-import.ipf +++ b/pearl/pearl-pshell-import.ipf @@ -1,12 +1,14 @@ +#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.36 #pragma ModuleName = PearlPShellImport +#pragma version = 1.11 #include #include "pearl-compat" #include "pearl-gui-tools" #include "pearl-area-import" -// copyright (c) 2013-18 Paul Scherrer Institut +// copyright (c) 2013-21 Paul Scherrer Institut // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -50,7 +52,7 @@ /// /// @author matthias muntwiler, matthias.muntwiler@psi.ch /// -/// @copyright 2013-18 Paul Scherrer Institut @n +/// @copyright 2013-21 Paul Scherrer Institut @n /// Licensed under the Apache License, Version 2.0 (the "License"); @n /// you may not use this file except in compliance with the License. @n /// You may obtain a copy of the License at @@ -75,7 +77,7 @@ strconstant kScanDimLabel = "scan" strconstant kDataDimLabel = "data" /// List of preferred datasets to load for preview -strconstant kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;" +strconstant kPreviewDatasets = "ImageEnergyDistribution;ScientaSpectrum;ScientaImage;Counts;SampleCurrent;" /// List of datasets that must be loaded to determine the axis scaling of a Scienta image strconstant kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;" @@ -336,6 +338,81 @@ function /s psh5_load_preview(APathName, AFileName, [load_data, load_attr, pref_ return dataname end +/// load organizational metadata from the general group. +/// +/// the general group contains the following datasets: +/// authors, pgroup, proposal, proposer, sample. +/// +/// data is loaded into the current data folder. +/// all items are loaded into strings, authors is a comma-separated list. +/// missing items default to empty strings. +/// +/// @param APathName igor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed +/// +/// @param AFileName if empty a dialog box shows up +/// +/// @return semicolon-separated list of the objects. +/// +function /s psh5_load_general_group(APathName, AFileName) + string APathName + string AFileName + + variable fileID + + HDF5OpenFile /P=$APathName /R /Z fileID as AFileName + if (v_flag == 0) + string obj_names = "authors;pgroup;proposal;proposer;sample;" + variable nn = ItemsInList(obj_names, ";") + variable ii + string name + + for (ii = 0; ii < nn; ii += 1) + name = StringFromList(ii, obj_names, ";") + psh_load_general_string(fileID, name) + endfor + + return obj_names + else + return "" + endif +end + +/// load a string from the general group. +/// +/// the general group contains the following datasets: +/// authors, pgroup, proposal, proposer, sample. +/// +/// data is loaded into a global string in the current data folder. +/// arrays with multiple items are loaded into a comma-separated list. +/// a missing item defaults to the empty string. +/// +/// @param fileID ID of open HDF5 file from psh5_open_file(). +/// +/// @return comma-separated list of values. +/// +function /s psh_load_general_string(fileID, name) + variable fileID + string name + + string path = "/general/" + name + HDF5LoadData /O /Q /Z /N=wt_load_general /TYPE=1 fileID, path + string values = "" + if (!v_flag) + wave /t wt_load_general + variable nn = numpnts(wt_load_general) + variable ii + for (ii = 0; ii < nn; ii += 1) + values = AddListItem(wt_load_general[ii], values, ",", inf) + endfor + killwaves /z wt_load_general + if (strlen(values) >= 1) + values = values[0,strlen(values)-2] + endif + endif + string /g $name = values + return values +end + /// load all data of a selected scan from a PShell data file. /// /// data is loaded into the current data folder. @@ -1667,13 +1744,13 @@ function ps_detect_scale(ax, lo, hi, un) case "Angular45": lo[%$kAngleDimLabel] = -45/2 hi[%$kAngleDimLabel] = +45/2 - un[%$kAngleDimLabel] = "°" + un[%$kAngleDimLabel] = "°" ax[%$kAngleDimLabel] = "angle" break case "Angular60": lo[%$kAngleDimLabel] = -60/2 hi[%$kAngleDimLabel] = +60/2 - un[%$kAngleDimLabel] = "°" + un[%$kAngleDimLabel] = "°" ax[%$kAngleDimLabel] = "angle" break case "Transmission": @@ -1719,12 +1796,12 @@ function ps_detect_scale(ax, lo, hi, un) un[%$kScanDimLabel] = "mm" break case "ExitSlit": - un[%$kScanDimLabel] = "µm" + un[%$kScanDimLabel] = "µm" break case "ManipulatorTheta": case "ManipulatorTilt": case "ManipulatorPhi": - un[%$kScanDimLabel] = "°" + un[%$kScanDimLabel] = "°" break case "FocusXRot": case "FocusYRot": @@ -1890,6 +1967,11 @@ end /// /// @param reduction_param parameter string for the reduction function. /// +/// @param dataset name of dataset to load, optionally including group path relative to scan (scan 1). +/// by default, the function looks for a ScientaImage dataset. +/// in a multi-region scan, this will be region 1. +/// to select region 2, e.g., use `dataset="region2/ScientaImage"`. +/// /// @param progress progress window. /// @arg 1 (default) show progress window /// @arg 0 do not show progress window @@ -1908,12 +1990,13 @@ end /// /// @return global string s_scanpaths in new data folder contains a list of scan groups inside the file. /// -function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [progress, nthreads]) +function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [dataset, progress, nthreads]) string ANickName string APathName string AFileName funcref adh5_default_reduction reduction_func string reduction_param + string dataset variable progress variable nthreads @@ -1972,7 +2055,9 @@ function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, r setdatafolder dataDF string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1) - string dataset = select_dataset(datasets, "ScientaImage") + if (ParamIsDefault(dataset)) + dataset = select_dataset(datasets, "ScientaImage") + endif wavenames = psh5_load_dataset_reduced(fileID, scanpath, dataset, reduction_func, reduction_param, progress=progress, nthreads=nthreads) psh5_close_file(fileID) @@ -2503,3 +2588,48 @@ static function /s wave2list(w, format, sep) return list end + +/// kill any waves matching a pattern in the experiment +/// +/// this may be used to kill big waves of original data before saving +/// +function /s kill_matching_waves(dfr, pattern, recurse, [killed]) + DFREF dfr + string pattern + variable recurse + string killed + + if (ParamIsDefault(killed)) + killed = "" + endif + + string s + string r + variable index = 0 + do + Wave/Z w = WaveRefIndexedDFR(dfr, index) + if (!WaveExists(w)) + break + endif + + s = NameOfWave(w) + if (stringmatch(s, pattern)) + killwaves /z w + killed = AddListItem(s, killed, ";", Inf) + endif + + index += 1 + while(1) + + if (recurse) + Variable numChildDataFolders = CountObjectsDFR(dfr, 4) + Variable i + for(i=0; i