diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fl-add-zlp-crop.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fl-add-zlp-crop.f64 new file mode 100644 index 0000000..a66be0e Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fl-add-zlp-crop.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fl-add-zlp.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fl-add-zlp.f64 new file mode 100644 index 0000000..0c251d8 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fl-add-zlp.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fl-crop.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fl-crop.f64 new file mode 100644 index 0000000..2274bc9 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fl-crop.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fl-default.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fl-default.f64 new file mode 100644 index 0000000..84130d7 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fl-default.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fr-default.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fr-default.f64 new file mode 100644 index 0000000..84859af Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fr-default.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fr-fixed-threshold-6.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fr-fixed-threshold-6.f64 new file mode 100644 index 0000000..8afc483 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fr-fixed-threshold-6.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fr-fwhm-1.5.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fr-fwhm-1.5.f64 new file mode 100644 index 0000000..d3fa536 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fr-fwhm-1.5.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap-cl.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap-cl.f64 new file mode 100644 index 0000000..98b5cbc Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap-cl.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap-ll.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap-ll.f64 new file mode 100644 index 0000000..a9612bc Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap-ll.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap.f64 new file mode 100644 index 0000000..5680084 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-fr-no-extrap.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pins.json b/Tests/SpectroEELSTests/Fixtures/eels16-pins.json new file mode 100644 index 0000000..0fba27a --- /dev/null +++ b/Tests/SpectroEELSTests/Fixtures/eels16-pins.json @@ -0,0 +1,6675 @@ +{ + "environment": { + "command": "python -I -B tools/eels-task16/pins.py", + "exspy": "0.3.2", + "hyperspy": "2.4.0", + "note": "spectra are synthetic and deterministic; HyperSpy ran without numba (non-accelerated paths, identical results)", + "numpy": "2.5.4", + "python": "3.13.16", + "scipy": "1.18.1", + "scriptSha256": "192d72478088a4edf94040f88b1da1d1254bd844f11309de7aabd7491ff72b11" + }, + "files": { + "fl-add-zlp": { + "sha256": "bc952a500e916dfd35978784d0c4ed86d453a1974dcf42618cbfcea160434755", + "shape": [ + 3, + 4, + 1600 + ] + }, + "fl-add-zlp-crop": { + "sha256": "5e09b1c72919a4ce0f190bb27c59866834b76526faf29c608395eb5828bdecb1", + "shape": [ + 3, + 4, + 1568 + ] + }, + "fl-crop": { + "sha256": "d2fd726d9e417d62013c76a294a1270e666e858d931193a894fd5b5821719b1b", + "shape": [ + 3, + 4, + 1568 + ] + }, + "fl-default": { + "sha256": "d94bb835d368e802d7a20dba0fce67ef2710f75df5396fda88f79fb6ddf6accc", + "shape": [ + 3, + 4, + 1600 + ] + }, + "fr-default": { + "sha256": "e07378f4769e278a317cf00701663fa7a27e93b1ff0cf0caa987c114e35f9860", + "shape": [ + 3, + 4, + 300 + ] + }, + "fr-fixed-threshold-6": { + "sha256": "44d3d9c47d9c63980d75f1837b8be9d9c55ae0b344b9598f6c300ac9e804f50f", + "shape": [ + 3, + 4, + 300 + ] + }, + "fr-fwhm-1.5": { + "sha256": "86b609b53f16f2ceb414b06417a636f76cc6ffab194b495d5ee178625ac0201b", + "shape": [ + 3, + 4, + 300 + ] + }, + "fr-no-extrap": { + "sha256": "8b53af8a778134380573e017d2faa46a1b36e4343464ab3458eaf476a4c7c32d", + "shape": [ + 3, + 4, + 300 + ] + }, + "fr-no-extrap-cl": { + "sha256": "2c5c79718baea7d0161fe9b54f7183fedbf5e10c7c4df458f4c3fecf74673be2", + "shape": [ + 3, + 4, + 300 + ] + }, + "fr-no-extrap-ll": { + "sha256": "1ad3e218640f770afb635f3742c4e8e2a0b33e5e7dae2d9c6ebaa01e12c34a21", + "shape": [ + 3, + 4, + 300 + ] + }, + "pl-binned-w20-e100": { + "sha256": "c02dc15a74d51c004906c6fa08cd573e37cf05e96e62011f6789ee2994c5442f", + "shape": [ + 2, + 3, + 300 + ] + }, + "pl-binned-w20-e100-fixneg": { + "sha256": "83fb417d87b9613a66466f4bdd1e5443936638b0cf1af92f85ae79ab6802428f", + "shape": [ + 2, + 3, + 300 + ] + }, + "pl-binned-w20-e1024": { + "sha256": "2e781b7ce612dac4a934f91e448d4dc0457f629894c49615751ef7d8ea4c175a", + "shape": [ + 2, + 3, + 1224 + ] + }, + "pl-binned-w50-e100": { + "sha256": "f9df3e938eecf263d5d3f8b5d4fec117ad8cdf346c521db057218e6dd8c35e28", + "shape": [ + 2, + 3, + 300 + ] + }, + "pl-exact-binned-w20-e100": { + "sha256": "ee6c1345f380eb9919b8202f3203b8d5f19b61c025a975ad4e3e335b6a659bac", + "shape": [ + 2, + 3, + 100 + ] + }, + "pl-exact-binned-w20-e100-fixneg": { + "sha256": "ee6c1345f380eb9919b8202f3203b8d5f19b61c025a975ad4e3e335b6a659bac", + "shape": [ + 2, + 3, + 100 + ] + }, + "pl-exact-binned-w20-e1024": { + "sha256": "184b4a58be5b5049fde2ca44f965c1291fa4fd0fbdb9f11de5f3c8651ef218d5", + "shape": [ + 2, + 3, + 1024 + ] + }, + "pl-exact-binned-w50-e100": { + "sha256": "ee6c1345f380eb9919b8202f3203b8d5f19b61c025a975ad4e3e335b6a659bac", + "shape": [ + 2, + 3, + 100 + ] + }, + "pl-exact-unbinned-w20-e100": { + "sha256": "18787dc729fd94e0f482ee356c5caffe2c4e4555fe77eeafd3e7515c118cdffe", + "shape": [ + 2, + 3, + 100 + ] + }, + "pl-exact-unbinned-w20-e100-fixneg": { + "sha256": "18787dc729fd94e0f482ee356c5caffe2c4e4555fe77eeafd3e7515c118cdffe", + "shape": [ + 2, + 3, + 100 + ] + }, + "pl-exact-unbinned-w20-e1024": { + "sha256": "7bdd8360d4cfc8c8d8f3f9c58de25435ca626bd9315888826dbd7fbe33c9b4df", + "shape": [ + 2, + 3, + 1024 + ] + }, + "pl-exact-unbinned-w50-e100": { + "sha256": "18787dc729fd94e0f482ee356c5caffe2c4e4555fe77eeafd3e7515c118cdffe", + "shape": [ + 2, + 3, + 100 + ] + }, + "pl-input-binned": { + "sha256": "bbf261db156e4cd6f8f53f40f993e5b976ddd794315f31cea20aafad63d9ee3a", + "shape": [ + 2, + 3, + 200 + ] + }, + "pl-input-unbinned": { + "sha256": "3edaf42373bd475e4a3fe23526be62bf7e878192ee6c4d23fd3d19107e4327ca", + "shape": [ + 2, + 3, + 200 + ] + }, + "pl-unbinned-w20-e100": { + "sha256": "14506607e268bde7e59485a8577c05c362a3bd32ab3eff3908ffb04d0217e212", + "shape": [ + 2, + 3, + 300 + ] + }, + "pl-unbinned-w20-e100-fixneg": { + "sha256": "8583f82727a82fbaccb4fcc87d7560429710a4d3678e3ab3e2152ae37a254b11", + "shape": [ + 2, + 3, + 300 + ] + }, + "pl-unbinned-w20-e1024": { + "sha256": "3f7e3cfc38b37d5c94ddc872935746546943f60b75dbf246d5e4a7389ab9574e", + "shape": [ + 2, + 3, + 1224 + ] + }, + "pl-unbinned-w50-e100": { + "sha256": "3d8a0fbcf077233ad90a673b64743505bd6afa145a71830c9367ea438c687058", + "shape": [ + 2, + 3, + 300 + ] + }, + "plural-core": { + "sha256": "756681c15387877a8a7fa43e4cac556f2ad1f054e1eeb92f8714afdfca723db3", + "shape": [ + 3, + 4, + 300 + ] + }, + "plural-edge": { + "sha256": "b702730df266d35d56b8c4c3b6622dc0f88298b0581080543dedb8ffb60eaa02", + "shape": [ + 3, + 4, + 300 + ] + }, + "plural-ll": { + "sha256": "6cc74eb1736f0148a8f8df9c526cdf0b342aa2f0c2ee221992d82ed5e0914b54", + "shape": [ + 3, + 4, + 1600 + ] + }, + "plural-single": { + "sha256": "0c9bffe3ff6a94cb4177c795a085bcdcb2963e1274b5a653ea4684c8efcae954", + "shape": [ + 3, + 4, + 1600 + ] + }, + "plural-single-broadened": { + "sha256": "8160859360fe9853fa7b51202cf858322d1eeee20bb0e95aedcf2934d47b2a95", + "shape": [ + 3, + 4, + 1600 + ] + }, + "plural-zlp": { + "sha256": "90f9a262ffdb11571ab2338c585fd62c891247561e8f00f2c2fd40c4f6e17f49", + "shape": [ + 3, + 4, + 1600 + ] + }, + "taper-both": { + "sha256": "77f9ea9f71d7a0bdbc75cbc5babe02991996aa9e7921ff045979e1988a8cb0a5", + "shape": [ + 2, + 300 + ] + }, + "taper-channels25": { + "sha256": "91164d075312f35766a7619f7261d03570d8aa042260a52ae89615e48ae64632", + "shape": [ + 2, + 300 + ] + }, + "taper-input": { + "sha256": "b644645c75d29dff39e23daac2cce406b14773dbb538826829e90857a4fb04fa", + "shape": [ + 2, + 300 + ] + }, + "taper-left": { + "sha256": "06bab672cf9c156964768eb39983321d9afb7d07e91c98e622fcb67516cb6680", + "shape": [ + 2, + 300 + ] + }, + "taper-left-ch40-off5": { + "sha256": "cc7406fd2df82ab1760a7a61e689dccb917b524e8f3cba5470b72df5b345368f", + "shape": [ + 2, + 300 + ] + }, + "taper-offset10": { + "sha256": "589d59ea09758005741f1791bf9c3b0a0f4be239fd30b59874c27a9dc94b5492", + "shape": [ + 2, + 300 + ] + }, + "taper-right": { + "sha256": "f3b89b56c0ab8d973e2bb9df8bf14cdbe89a085dc28184381d9bad6db73508f3", + "shape": [ + 2, + 300 + ] + }, + "zlp-align-also-align": { + "sha256": "1169495f9563fcaeb530b70e7e26a008e276548200f00c6def41600072a417d1", + "shape": [ + 3, + 4, + 568 + ] + }, + "zlp-align-also-align-core": { + "sha256": "85e070a493f34ff5a2204dd7130d360693953232b15b8c36510660bbd9aa524b", + "shape": [ + 3, + 4, + 292 + ] + }, + "zlp-align-default": { + "sha256": "1169495f9563fcaeb530b70e7e26a008e276548200f00c6def41600072a417d1", + "shape": [ + 3, + 4, + 568 + ] + }, + "zlp-align-interp-ip3": { + "sha256": "e83d298c8c27d61cbafc65cd9f624c1ffef2cc6579a2abf91a8689925c58a98d", + "shape": [ + 3, + 4, + 568 + ] + }, + "zlp-align-mask": { + "sha256": "a66ab8ee4ac2b17fc0be8100a031bb02c3dfdf8a597141cc20dd8622ba19ecf4", + "shape": [ + 3, + 4, + 568 + ] + }, + "zlp-align-no-calibrate": { + "sha256": "d59adca81ae0f94ff56937beb8146018487d6c97e042d4c594aec48de1df33e8", + "shape": [ + 3, + 4, + 568 + ] + }, + "zlp-align-no-crop": { + "sha256": "86ed94046fefa052e7ef1fa5e8d1df8aa594a94da8c67522fd638b9c3465e419", + "shape": [ + 3, + 4, + 600 + ] + }, + "zlp-align-no-crop-no-calibrate": { + "sha256": "22eea3e1daffcf196e2ca8ed3decd47c1a855b61b5e5bdbc585814d16a7d1797", + "shape": [ + 3, + 4, + 600 + ] + }, + "zlp-align-no-subpixel": { + "sha256": "95aacabd1a1cebbe79afd234abffba6bb1ebc1d002b7846eae56024ff0d287ac", + "shape": [ + 3, + 4, + 570 + ] + }, + "zlp-align-signal-range": { + "sha256": "fadaa2445019dbc3e4de6105d564b730294a9d4bddac0bdb15cc7908dd7a0d15", + "shape": [ + 3, + 4, + 568 + ] + }, + "zlp-align-spike-no-range": { + "sha256": "5314bcb648057222be97a5773f541f084172d0469982a9601cac69cabd4237ae", + "shape": [ + 3, + 4, + 600 + ] + }, + "zlp-align-spike-range": { + "sha256": "68189d07c199500306ce547235518a4044154d3965e5bb211ae1db8381d7c2f0", + "shape": [ + 3, + 4, + 568 + ] + }, + "zlp-core": { + "sha256": "a4f1cb43a63bdab1a8d63ce8c22b1a26d81c1dbd7a3f56f51ab1e318470819a1", + "shape": [ + 3, + 4, + 300 + ] + }, + "zlp-ll": { + "sha256": "be519027ae835425a66e15d257068147264dd0cf720ac976e11ca5f3d1c81bdd", + "shape": [ + 3, + 4, + 600 + ] + }, + "zlp-ll-spike": { + "sha256": "5314bcb648057222be97a5773f541f084172d0469982a9601cac69cabd4237ae", + "shape": [ + 3, + 4, + 600 + ] + }, + "zlp-shift1d-crop": { + "sha256": "de1ceda8c2e72bb5e20d67b2c26b76637e6d8a74b64d1a367b2cf8f3b6c49c2b", + "shape": [ + 4, + 34 + ] + }, + "zlp-shift1d-input": { + "sha256": "e43e0ae35a3d573253cbd6239affeca15591f47f68f7b736d5fb411d6e7ebdf7", + "shape": [ + 4, + 40 + ] + }, + "zlp-shift1d-nocrop": { + "sha256": "5a70cb49cf37f828d3166760d48d7305826361196e570ada46760c1077670031", + "shape": [ + 4, + 40 + ] + } + }, + "fourierLog": { + "cases": { + "add-zlp": { + "channels": 1600, + "fftSize": 3200, + "file": "fl-add-zlp", + "kwargs": { + "add_zlp": true + }, + "offsetEV": -20.0, + "taperedChannels": 32 + }, + "add-zlp-crop": { + "channels": 1568, + "fftSize": 3200, + "file": "fl-add-zlp-crop", + "kwargs": { + "add_zlp": true, + "crop": true + }, + "offsetEV": -20.0, + "taperedChannels": 32 + }, + "crop": { + "channels": 1568, + "fftSize": 3200, + "file": "fl-crop", + "kwargs": { + "crop": true + }, + "offsetEV": -20.0, + "taperedChannels": 32 + }, + "default": { + "channels": 1600, + "fftSize": 3200, + "file": "fl-default", + "kwargs": {}, + "offsetEV": -20.0, + "taperedChannels": 32 + } + }, + "plural": { + "channels": 1600, + "i0": 1000000.0, + "lowLossFile": "plural-ll", + "note": "J = I0 ifft(fft(Z/I0) exp(fft(S)/I0)) on a 8192 circular grid, cropped; truth S is the single-scattering counts, S x Z/I0 is what Fourier-log returns", + "nx": 4, + "ny": 3, + "offsetEV": -20.0, + "scaleEV": 0.1, + "singleScatteringBroadenedFile": "plural-single-broadened", + "singleScatteringFile": "plural-single", + "tauOverLambda": [ + [ + 0.2, + 0.4, + 0.6, + 0.8 + ], + [ + 1.0, + 1.2, + 0.1, + 0.3 + ], + [ + 0.5, + 0.7, + 0.9, + 1.1 + ] + ], + "zlpFile": "plural-zlp" + } + }, + "fourierRatio": { + "cases": { + "default": { + "channels": 300, + "coreLossChannelsAfterExtrapolation": 400, + "fftSize": 2100, + "file": "fr-default", + "fwhmEV": 0.900029897766919, + "i0": [ + [ + 1000000.0, + 1000000.0, + 1000000.0000000001, + 1000000.0 + ], + [ + 1000000.0000000001, + 1000000.0000000001, + 1000000.0000000002, + 1000000.0000000001 + ], + [ + 1000000.0000000001, + 1000000.0000000001, + 1000000.0000000001, + 1000000.0000000001 + ] + ], + "kwargs": {}, + "lowLossChannelsAfterExtrapolation": 1700, + "offsetEV": 280.0, + "taperedChannelsCoreLoss": 20, + "taperedChannelsLowLoss": 34, + "thresholdEV": [ + [ + 6.2, + 4.7, + 8.8, + 4.7 + ], + [ + 3.9000000000000004, + 5.0, + 4.6, + 5.6000000000000005 + ], + [ + 4.9, + 10.700000000000001, + 4.6, + 3.7 + ] + ] + }, + "fixed-threshold-6": { + "channels": 300, + "coreLossChannelsAfterExtrapolation": 400, + "fftSize": 2100, + "file": "fr-fixed-threshold-6", + "fwhmEV": 0.900029897766919, + "i0": [ + [ + 1000000.0, + 1000000.0000000001, + 1000000.0, + 1000000.0000000001 + ], + [ + 1000000.0000000001, + 1000000.0, + 1000000.0000000001, + 1000000.0 + ], + [ + 1000000.0000000001, + 1000000.0000000001, + 1000000.0000000001, + 1000000.0 + ] + ], + "kwargs": { + "threshold": 6.0 + }, + "lowLossChannelsAfterExtrapolation": 1700, + "offsetEV": 280.0, + "taperedChannelsCoreLoss": 20, + "taperedChannelsLowLoss": 34, + "thresholdEV": null + }, + "fwhm-1.5": { + "channels": 300, + "coreLossChannelsAfterExtrapolation": 400, + "fftSize": 2100, + "file": "fr-fwhm-1.5", + "fwhmEV": 1.5, + "i0": [ + [ + 1000000.0, + 1000000.0000000001, + 1000000.0, + 1000000.0000000001 + ], + [ + 1000000.0000000001, + 1000000.0, + 1000000.0000000001, + 1000000.0 + ], + [ + 1000000.0000000001, + 1000000.0000000001, + 1000000.0000000001, + 1000000.0 + ] + ], + "kwargs": { + "fwhm": 1.5, + "threshold": 6.0 + }, + "lowLossChannelsAfterExtrapolation": 1700, + "offsetEV": 280.0, + "taperedChannelsCoreLoss": 20, + "taperedChannelsLowLoss": 34, + "thresholdEV": null + }, + "no-extrap": { + "channels": 300, + "coreLossChannelsAfterExtrapolation": 300, + "fftSize": 1920, + "file": "fr-no-extrap", + "fwhmEV": 0.900029897766919, + "i0": [ + [ + 1000000.0, + 1000000.0000000001, + 1000000.0, + 1000000.0000000001 + ], + [ + 1000000.0000000001, + 1000000.0, + 1000000.0000000001, + 1000000.0 + ], + [ + 1000000.0000000001, + 1000000.0000000001, + 1000000.0000000001, + 1000000.0 + ] + ], + "kwargs": { + "extrapolate_coreloss": false, + "extrapolate_lowloss": false, + "threshold": 6.0 + }, + "lowLossChannelsAfterExtrapolation": 1600, + "offsetEV": 280.0, + "taperedChannelsCoreLoss": 20, + "taperedChannelsLowLoss": 32, + "thresholdEV": null + }, + "no-extrap-cl": { + "channels": 300, + "coreLossChannelsAfterExtrapolation": 300, + "fftSize": 2000, + "file": "fr-no-extrap-cl", + "fwhmEV": 0.900029897766919, + "i0": [ + [ + 1000000.0, + 1000000.0000000001, + 1000000.0, + 1000000.0000000001 + ], + [ + 1000000.0000000001, + 1000000.0, + 1000000.0000000001, + 1000000.0 + ], + [ + 1000000.0000000001, + 1000000.0000000001, + 1000000.0000000001, + 1000000.0 + ] + ], + "kwargs": { + "extrapolate_coreloss": false, + "threshold": 6.0 + }, + "lowLossChannelsAfterExtrapolation": 1700, + "offsetEV": 280.0, + "taperedChannelsCoreLoss": 20, + "taperedChannelsLowLoss": 34, + "thresholdEV": null + }, + "no-extrap-ll": { + "channels": 300, + "coreLossChannelsAfterExtrapolation": 400, + "fftSize": 2000, + "file": "fr-no-extrap-ll", + "fwhmEV": 0.900029897766919, + "i0": [ + [ + 1000000.0, + 1000000.0000000001, + 1000000.0, + 1000000.0000000001 + ], + [ + 1000000.0000000001, + 1000000.0, + 1000000.0000000001, + 1000000.0 + ], + [ + 1000000.0000000001, + 1000000.0000000001, + 1000000.0000000001, + 1000000.0 + ] + ], + "kwargs": { + "extrapolate_lowloss": false, + "threshold": 6.0 + }, + "lowLossChannelsAfterExtrapolation": 1600, + "offsetEV": 280.0, + "taperedChannelsCoreLoss": 20, + "taperedChannelsLowLoss": 32, + "thresholdEV": null + } + }, + "core": { + "channels": 300, + "file": "plural-core", + "offsetEV": 280.0, + "scaleEV": 0.1, + "truthEdgeFile": "plural-edge", + "zeroLossChannel": 200 + }, + "fwhmAllPixelsEV": [ + [ + 0.900029897766919, + 0.900029897766919, + 0.900029897766919, + 0.900029897766919 + ], + [ + 0.900029897766919, + 0.900029897766919, + 0.900029897766919, + 0.900029897766919 + ], + [ + 0.900029897766919, + 0.900029897766919, + 0.900029897766919, + 0.900029897766919 + ] + ], + "note": "exSpy's Gaussian is a density per eV (A=1, sum over channels = 1/scale), so the result is the planted edge smoothed by the Gaussian AND multiplied by 1/scale: interior of fr-fixed-threshold-6 equals smoothed truth / scale to 3 %", + "plural": { + "channels": 1600, + "i0": 1000000.0, + "lowLossFile": "plural-ll", + "note": "J = I0 ifft(fft(Z/I0) exp(fft(S)/I0)) on a 8192 circular grid, cropped; truth S is the single-scattering counts, S x Z/I0 is what Fourier-log returns", + "nx": 4, + "ny": 3, + "offsetEV": -20.0, + "scaleEV": 0.1, + "singleScatteringBroadenedFile": "plural-single-broadened", + "singleScatteringFile": "plural-single", + "tauOverLambda": [ + [ + 0.2, + 0.4, + 0.6, + 0.8 + ], + [ + 1.0, + 1.2, + 0.1, + 0.3 + ], + [ + 0.5, + 0.7, + 0.9, + 1.1 + ] + ], + "zlpFile": "plural-zlp" + } + }, + "optimalFFTSize": { + "complex": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 14, + 15, + 16, + 18, + 18, + 20, + 20, + 21, + 22, + 24, + 24, + 25, + 27, + 27, + 28, + 30, + 30, + 32, + 32, + 33, + 35, + 35, + 36, + 40, + 40, + 40, + 40, + 42, + 42, + 44, + 44, + 45, + 48, + 48, + 48, + 49, + 50, + 54, + 54, + 54, + 54, + 55, + 56, + 60, + 60, + 60, + 60, + 63, + 63, + 63, + 64, + 66, + 66, + 70, + 70, + 70, + 70, + 72, + 72, + 75, + 75, + 75, + 77, + 77, + 80, + 80, + 80, + 81, + 84, + 84, + 84, + 88, + 88, + 88, + 88, + 90, + 90, + 96, + 96, + 96, + 96, + 96, + 96, + 98, + 98, + 99, + 100, + 105, + 105, + 105, + 105, + 105, + 108, + 108, + 108, + 110, + 110, + 112, + 112, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 121, + 125, + 125, + 125, + 125, + 126, + 128, + 128, + 132, + 132, + 132, + 132, + 135, + 135, + 135, + 140, + 140, + 140, + 140, + 140, + 144, + 144, + 144, + 144, + 147, + 147, + 147, + 150, + 150, + 150, + 154, + 154, + 154, + 154, + 160, + 160, + 160, + 160, + 160, + 160, + 162, + 162, + 165, + 165, + 165, + 168, + 168, + 168, + 175, + 175, + 175, + 175, + 175, + 175, + 175, + 176, + 180, + 180, + 180, + 180, + 189, + 189, + 189, + 189, + 189, + 189, + 189, + 189, + 189, + 192, + 192, + 192, + 196, + 196, + 196, + 196, + 198, + 198, + 200, + 200, + 256, + 256, + 264, + 512, + 1000, + 1024, + 1024, + 1029, + 1500, + 2048, + 2048, + 2058, + 2200, + 4096, + 4116, + 10080, + 65610 + ], + "ns": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 255, + 256, + 257, + 511, + 1000, + 1023, + 1024, + 1025, + 1500, + 2047, + 2048, + 2049, + 2200, + 4093, + 4097, + 10007, + 65537 + ], + "real": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 8, + 9, + 10, + 12, + 12, + 15, + 15, + 15, + 16, + 18, + 18, + 20, + 20, + 24, + 24, + 24, + 24, + 25, + 27, + 27, + 30, + 30, + 30, + 32, + 32, + 36, + 36, + 36, + 36, + 40, + 40, + 40, + 40, + 45, + 45, + 45, + 45, + 45, + 48, + 48, + 48, + 50, + 50, + 54, + 54, + 54, + 54, + 60, + 60, + 60, + 60, + 60, + 60, + 64, + 64, + 64, + 64, + 72, + 72, + 72, + 72, + 72, + 72, + 72, + 72, + 75, + 75, + 75, + 80, + 80, + 80, + 80, + 80, + 81, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 90, + 96, + 96, + 96, + 96, + 96, + 96, + 100, + 100, + 100, + 100, + 108, + 108, + 108, + 108, + 108, + 108, + 108, + 108, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 125, + 125, + 125, + 125, + 125, + 128, + 128, + 128, + 135, + 135, + 135, + 135, + 135, + 135, + 135, + 144, + 144, + 144, + 144, + 144, + 144, + 144, + 144, + 144, + 150, + 150, + 150, + 150, + 150, + 150, + 160, + 160, + 160, + 160, + 160, + 160, + 160, + 160, + 160, + 160, + 162, + 162, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 180, + 192, + 192, + 192, + 192, + 192, + 192, + 192, + 192, + 192, + 192, + 192, + 192, + 200, + 200, + 200, + 200, + 200, + 200, + 200, + 200, + 256, + 256, + 270, + 512, + 1000, + 1024, + 1024, + 1080, + 1500, + 2048, + 2048, + 2160, + 2250, + 4096, + 4320, + 10125, + 65610 + ] + }, + "powerLaw": { + "cases": { + "binned-w20-e100": { + "A": [ + [ + 1013549835.6003592, + 505598888.8448781, + 20318798813.413185 + ], + [ + 3055105005003.2607, + 80601042.4252562, + 399317.666438425 + ] + ], + "AUsed": [ + [ + 1013549835.6003592, + 505598888.8448781, + 20318798813.413185 + ], + [ + 3055105005003.2607, + 80601042.4252562, + 399317.666438425 + ] + ], + "binned": true, + "channels": 300, + "exactFile": "pl-exact-binned-w20-e100", + "extrapolationChannels": 100, + "file": "pl-binned-w20-e100", + "fixNegativeR": false, + "inputFile": "pl-input-binned", + "r": [ + [ + 3.0019334943590765, + 2.501597832763087, + 3.5022745207529895 + ], + [ + 4.002620911781475, + 1.701071933295958, + -0.40024320628350213 + ] + ], + "windowChannels": 20 + }, + "binned-w20-e100-fixneg": { + "A": [ + [ + 1013549835.6003592, + 505598888.8448781, + 20318798813.413185 + ], + [ + 3055105005003.2607, + 80601042.4252562, + 399317.666438425 + ] + ], + "AUsed": [ + [ + 1013549835.6003592, + 505598888.8448781, + 20318798813.413185 + ], + [ + 3055105005003.2607, + 80601042.4252562, + 0.0 + ] + ], + "binned": true, + "channels": 300, + "exactFile": "pl-exact-binned-w20-e100-fixneg", + "extrapolationChannels": 100, + "file": "pl-binned-w20-e100-fixneg", + "fixNegativeR": true, + "inputFile": "pl-input-binned", + "r": [ + [ + 3.0019334943590765, + 2.501597832763087, + 3.5022745207529895 + ], + [ + 4.002620911781475, + 1.701071933295958, + -0.40024320628350213 + ] + ], + "windowChannels": 20 + }, + "binned-w20-e1024": { + "A": [ + [ + 1013549835.6003592, + 505598888.8448781, + 20318798813.413185 + ], + [ + 3055105005003.2607, + 80601042.4252562, + 399317.666438425 + ] + ], + "AUsed": [ + [ + 1013549835.6003592, + 505598888.8448781, + 20318798813.413185 + ], + [ + 3055105005003.2607, + 80601042.4252562, + 399317.666438425 + ] + ], + "binned": true, + "channels": 1224, + "exactFile": "pl-exact-binned-w20-e1024", + "extrapolationChannels": 1024, + "file": "pl-binned-w20-e1024", + "fixNegativeR": false, + "inputFile": "pl-input-binned", + "r": [ + [ + 3.0019334943590765, + 2.501597832763087, + 3.5022745207529895 + ], + [ + 4.002620911781475, + 1.701071933295958, + -0.40024320628350213 + ] + ], + "windowChannels": 20 + }, + "binned-w50-e100": { + "A": [ + [ + 1015041552.4904635, + 505956583.8907303, + 20368466419.14543 + ], + [ + 3066182642641.394, + 80594343.08396533, + 399464.6185876928 + ] + ], + "AUsed": [ + [ + 1015041552.4904635, + 505956583.8907303, + 20368466419.14543 + ], + [ + 3066182642641.394, + 80594343.08396533, + 399464.6185876928 + ] + ], + "binned": true, + "channels": 300, + "exactFile": "pl-exact-binned-w50-e100", + "extrapolationChannels": 100, + "file": "pl-binned-w50-e100", + "fixNegativeR": false, + "inputFile": "pl-input-binned", + "r": [ + [ + 3.002179740707045, + 2.5017162392001264, + 3.5026833154083343 + ], + [ + 4.00322695456919, + 1.7010580052893283, + -0.40018159633164135 + ] + ], + "windowChannels": 50 + }, + "unbinned-w20-e100": { + "A": [ + [ + 2027099671.2007184, + 1011197777.6897562, + 40637597626.82637 + ], + [ + 6110210010006.521, + 161202084.8505124, + 798635.33287685 + ] + ], + "AUsed": [ + [ + 2027099671.2007184, + 1011197777.6897562, + 40637597626.82637 + ], + [ + 6110210010006.521, + 161202084.8505124, + 798635.33287685 + ] + ], + "binned": false, + "channels": 300, + "exactFile": "pl-exact-unbinned-w20-e100", + "extrapolationChannels": 100, + "file": "pl-unbinned-w20-e100", + "fixNegativeR": false, + "inputFile": "pl-input-unbinned", + "r": [ + [ + 3.0019334943590765, + 2.501597832763087, + 3.5022745207529895 + ], + [ + 4.002620911781475, + 1.701071933295958, + -0.40024320628350213 + ] + ], + "windowChannels": 20 + }, + "unbinned-w20-e100-fixneg": { + "A": [ + [ + 2027099671.2007184, + 1011197777.6897562, + 40637597626.82637 + ], + [ + 6110210010006.521, + 161202084.8505124, + 798635.33287685 + ] + ], + "AUsed": [ + [ + 2027099671.2007184, + 1011197777.6897562, + 40637597626.82637 + ], + [ + 6110210010006.521, + 161202084.8505124, + 0.0 + ] + ], + "binned": false, + "channels": 300, + "exactFile": "pl-exact-unbinned-w20-e100-fixneg", + "extrapolationChannels": 100, + "file": "pl-unbinned-w20-e100-fixneg", + "fixNegativeR": true, + "inputFile": "pl-input-unbinned", + "r": [ + [ + 3.0019334943590765, + 2.501597832763087, + 3.5022745207529895 + ], + [ + 4.002620911781475, + 1.701071933295958, + -0.40024320628350213 + ] + ], + "windowChannels": 20 + }, + "unbinned-w20-e1024": { + "A": [ + [ + 2027099671.2007184, + 1011197777.6897562, + 40637597626.82637 + ], + [ + 6110210010006.521, + 161202084.8505124, + 798635.33287685 + ] + ], + "AUsed": [ + [ + 2027099671.2007184, + 1011197777.6897562, + 40637597626.82637 + ], + [ + 6110210010006.521, + 161202084.8505124, + 798635.33287685 + ] + ], + "binned": false, + "channels": 1224, + "exactFile": "pl-exact-unbinned-w20-e1024", + "extrapolationChannels": 1024, + "file": "pl-unbinned-w20-e1024", + "fixNegativeR": false, + "inputFile": "pl-input-unbinned", + "r": [ + [ + 3.0019334943590765, + 2.501597832763087, + 3.5022745207529895 + ], + [ + 4.002620911781475, + 1.701071933295958, + -0.40024320628350213 + ] + ], + "windowChannels": 20 + }, + "unbinned-w50-e100": { + "A": [ + [ + 2030083104.980927, + 1011913167.7818099, + 40736932838.29086 + ], + [ + 6132365285283.832, + 161188686.16793066, + 798929.2371759301 + ] + ], + "AUsed": [ + [ + 2030083104.980927, + 1011913167.7818099, + 40736932838.29086 + ], + [ + 6132365285283.832, + 161188686.16793066, + 798929.2371759301 + ] + ], + "binned": false, + "channels": 300, + "exactFile": "pl-exact-unbinned-w50-e100", + "extrapolationChannels": 100, + "file": "pl-unbinned-w50-e100", + "fixNegativeR": false, + "inputFile": "pl-input-unbinned", + "r": [ + [ + 3.002179740707045, + 2.5017162392001837, + 3.5026833154083343 + ], + [ + 4.003226954569218, + 1.7010580052893283, + -0.40018159633152683 + ] + ], + "windowChannels": 50 + } + }, + "channels": 200, + "offsetEV": 300.0, + "scaleEV": 0.5, + "truthA": [ + [ + 1000000000.0, + 500000000.0, + 20000000000.0 + ], + [ + 3000000000000.0, + 80000000.0, + 400000.0 + ] + ], + "truthR": [ + [ + 3.0, + 2.5, + 3.5 + ], + [ + 4.0, + 1.7, + -0.4 + ] + ] + }, + "taper": { + "cases": { + "both": { + "file": "taper-both", + "kwargs": {}, + "taperedChannels": 20 + }, + "channels25": { + "file": "taper-channels25", + "kwargs": { + "channels": 25 + }, + "taperedChannels": 25 + }, + "default-n100": { + "kwargs": {}, + "n": 100, + "taperedChannels": 20 + }, + "default-n1024": { + "kwargs": {}, + "n": 1024, + "taperedChannels": 20 + }, + "default-n2000": { + "kwargs": {}, + "n": 2000, + "taperedChannels": 40 + }, + "default-n50": { + "kwargs": {}, + "n": 50, + "taperedChannels": 20 + }, + "default-n5000": { + "kwargs": {}, + "n": 5000, + "taperedChannels": 100 + }, + "default-n999": { + "kwargs": {}, + "n": 999, + "taperedChannels": 20 + }, + "left": { + "file": "taper-left", + "kwargs": { + "side": "left" + }, + "taperedChannels": 20 + }, + "left-ch40-off5": { + "file": "taper-left-ch40-off5", + "kwargs": { + "channels": 40, + "offset": 5, + "side": "left" + }, + "taperedChannels": 40 + }, + "offset10": { + "file": "taper-offset10", + "kwargs": { + "offset": 10 + }, + "taperedChannels": 20 + }, + "right": { + "file": "taper-right", + "kwargs": { + "side": "right" + }, + "taperedChannels": 20 + } + }, + "input": { + "channels": 300, + "file": "taper-input", + "rows": 2 + } + }, + "zlp": { + "align": { + "also-align": { + "alsoAligned": { + "channels": 292, + "file": "zlp-align-also-align-core", + "offsetEV": 101.6 + }, + "channels": 568, + "file": "zlp-align-also-align", + "kind": "ll", + "kwargs": {}, + "maskUsed": false, + "offsetEV": -18.8, + "reestimatedCentreEV": [ + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000008, + 0.47499999999999937, + -0.025000000000000633, + -0.5250000000000006 + ], + [ + -0.9249999999999992, + -1.4249999999999992, + 1.4749999999999994, + -0.22499999999999992 + ], + [ + 0.7750000000000001, + -0.1249999999999985, + -0.7249999999999999, + 0.17499999999999866 + ] + ], + [ + [ + 1.0750000000000008, + 0.47499999999999937, + -0.025000000000000633, + -0.5250000000000006 + ], + [ + -0.9249999999999992, + -1.4249999999999992, + 1.4749999999999994, + -0.22499999999999992 + ], + [ + 0.7750000000000001, + -0.1249999999999985, + -0.7249999999999999, + 0.17499999999999866 + ] + ], + [ + [ + 0.0, + -0.03333333333333333, + 0.016666666666666666, + -0.03333333333333333 + ], + [ + 0.0, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + -0.03333333333333333, + 0.016666666666666666, + -0.03333333333333333 + ], + [ + 0.0, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + "default": { + "channels": 568, + "file": "zlp-align-default", + "kind": "ll", + "kwargs": {}, + "maskUsed": false, + "offsetEV": -18.8, + "reestimatedCentreEV": [ + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000008, + 0.47499999999999937, + -0.025000000000000633, + -0.5250000000000006 + ], + [ + -0.9249999999999992, + -1.4249999999999992, + 1.4749999999999994, + -0.22499999999999992 + ], + [ + 0.7750000000000001, + -0.1249999999999985, + -0.7249999999999999, + 0.17499999999999866 + ] + ], + [ + [ + 0.0, + -0.03333333333333333, + 0.016666666666666666, + -0.03333333333333333 + ], + [ + 0.0, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + "interp-ip3": { + "channels": 568, + "file": "zlp-align-interp-ip3", + "kind": "ll", + "kwargs": { + "number_of_interpolation_points": 3 + }, + "maskUsed": false, + "offsetEV": -18.8, + "reestimatedCentreEV": [ + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000008, + 0.47499999999999937, + -0.025000000000000633, + -0.5250000000000006 + ], + [ + -0.9249999999999992, + -1.4249999999999992, + 1.4749999999999994, + -0.22499999999999992 + ], + [ + 0.7750000000000001, + -0.1249999999999985, + -0.7249999999999999, + 0.17499999999999866 + ] + ], + [ + [ + 0.0, + -0.025, + 0.025, + -0.05 + ], + [ + 0.0, + 0.0, + 0.0, + -0.025 + ], + [ + 0.025, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + "mask": { + "channels": 568, + "file": "zlp-align-mask", + "kind": "ll", + "kwargs": { + "mask": null + }, + "maskUsed": true, + "offsetEV": -18.74, + "reestimatedCentreEV": [ + [ + -0.03999999999999915, + null, + -0.03999999999999915, + 0.060000000000002274 + ], + [ + -0.03999999999999915, + 0.060000000000002274, + 0.060000000000002274, + 0.060000000000002274 + ], + [ + -0.03999999999999915, + -0.03999999999999915, + null, + -0.03999999999999915 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0500000000000007, + null, + -0.05000000000000071, + -0.5500000000000007 + ], + [ + -0.9499999999999993, + -1.4499999999999993, + 1.4499999999999993, + -0.25 + ], + [ + 0.75, + -0.14999999999999858, + null, + 0.14999999999999858 + ] + ], + [ + [ + 0.0, + null, + 0.016666666666666666, + -0.03333333333333333 + ], + [ + 0.0, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + null, + 0.0 + ] + ] + ] + }, + "no-calibrate": { + "channels": 568, + "file": "zlp-align-no-calibrate", + "kind": "ll", + "kwargs": { + "calibrate": false + }, + "maskUsed": false, + "offsetEV": -18.4, + "reestimatedCentreEV": [ + [ + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213 + ], + [ + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213 + ], + [ + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000008, + 0.47499999999999937, + -0.025000000000000633, + -0.5250000000000006 + ], + [ + -0.9249999999999992, + -1.4249999999999992, + 1.4749999999999994, + -0.22499999999999992 + ], + [ + 0.7750000000000001, + -0.1249999999999985, + -0.7249999999999999, + 0.17499999999999866 + ] + ], + [ + [ + 0.0, + -0.03333333333333333, + 0.016666666666666666, + -0.03333333333333333 + ], + [ + 0.0, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + "no-crop": { + "channels": 600, + "file": "zlp-align-no-crop", + "kind": "ll", + "kwargs": { + "crop": false + }, + "maskUsed": false, + "offsetEV": -20.400000000000002, + "reestimatedCentreEV": [ + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000008, + 0.47499999999999937, + -0.025000000000000633, + -0.5250000000000006 + ], + [ + -0.9249999999999992, + -1.4249999999999992, + 1.4749999999999994, + -0.22499999999999992 + ], + [ + 0.7750000000000001, + -0.1249999999999985, + -0.7249999999999999, + 0.17499999999999866 + ] + ], + [ + [ + 0.0, + -0.03333333333333333, + 0.016666666666666666, + -0.03333333333333333 + ], + [ + 0.0, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + "no-crop-no-calibrate": { + "channels": 600, + "file": "zlp-align-no-crop-no-calibrate", + "kind": "ll", + "kwargs": { + "calibrate": false, + "crop": false + }, + "maskUsed": false, + "offsetEV": -20.0, + "reestimatedCentreEV": [ + [ + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213 + ], + [ + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213 + ], + [ + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213, + 0.40000000000000213 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000008, + 0.47499999999999937, + -0.025000000000000633, + -0.5250000000000006 + ], + [ + -0.9249999999999992, + -1.4249999999999992, + 1.4749999999999994, + -0.22499999999999992 + ], + [ + 0.7750000000000001, + -0.1249999999999985, + -0.7249999999999999, + 0.17499999999999866 + ] + ], + [ + [ + 0.0, + -0.03333333333333333, + 0.016666666666666666, + -0.03333333333333333 + ], + [ + 0.0, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + "no-subpixel": { + "channels": 570, + "file": "zlp-align-no-subpixel", + "kind": "ll", + "kwargs": { + "subpixel": false + }, + "maskUsed": false, + "offsetEV": -18.883333333333336, + "reestimatedCentreEV": [ + [ + 0.01666666666666572, + 0.01666666666666572, + -0.0833333333333357, + 0.01666666666666572 + ], + [ + 0.01666666666666572, + 0.01666666666666572, + 0.01666666666666572, + 0.01666666666666572 + ], + [ + -0.0833333333333357, + 0.01666666666666572, + 0.01666666666666572, + 0.01666666666666572 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000008, + 0.47499999999999937, + -0.025000000000000633, + -0.5250000000000006 + ], + [ + -0.9249999999999992, + -1.4249999999999992, + 1.4749999999999994, + -0.22499999999999992 + ], + [ + 0.7750000000000001, + -0.1249999999999985, + -0.7249999999999999, + 0.17499999999999866 + ] + ] + ] + }, + "signal-range": { + "channels": 568, + "file": "zlp-align-signal-range", + "kind": "ll", + "kwargs": { + "signal_range": [ + -5.0, + 5.0 + ] + }, + "maskUsed": false, + "offsetEV": -18.8, + "reestimatedCentreEV": [ + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000006, + 0.47500000000000003, + -0.024999999999999967, + -0.5249999999999999 + ], + [ + -0.9250000000000003, + -1.4250000000000003, + 1.475, + -0.22500000000000014 + ], + [ + 0.7749999999999999, + -0.12499999999999961, + -0.7250000000000001, + 0.1750000000000002 + ] + ], + [ + [ + 0.0, + -0.03333333333333333, + 0.03333333333333333, + -0.05 + ], + [ + 0.016666666666666666, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + 0.0, + 0.016666666666666666 + ] + ] + ] + }, + "spike-no-range": { + "channels": 600, + "file": "zlp-align-spike-no-range", + "kind": "llSpike", + "kwargs": {}, + "maskUsed": false, + "offsetEV": -32.0, + "reestimatedCentreEV": [ + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + "spike-range": { + "channels": 568, + "file": "zlp-align-spike-range", + "kind": "llSpike", + "kwargs": { + "signal_range": [ + -5.0, + 5.0 + ] + }, + "maskUsed": false, + "offsetEV": -18.8, + "reestimatedCentreEV": [ + [ + 12.7, + 12.100000000000001, + 11.600000000000001, + 11.0 + ], + [ + 10.7, + 10.2, + 13.100000000000001, + 11.400000000000002 + ], + [ + 12.400000000000002, + 11.5, + 10.900000000000002, + 11.8 + ] + ], + "scaleEV": 0.1, + "shiftPasses": [ + [ + [ + 1.0750000000000006, + 0.47500000000000003, + -0.024999999999999967, + -0.5249999999999999 + ], + [ + -0.9250000000000003, + -1.4250000000000003, + 1.475, + -0.22500000000000014 + ], + [ + 0.7749999999999999, + -0.12499999999999961, + -0.7250000000000001, + 0.1750000000000002 + ] + ], + [ + [ + 0.0, + -0.03333333333333333, + 0.03333333333333333, + -0.05 + ], + [ + 0.016666666666666666, + 0.0, + 0.0, + -0.03333333333333333 + ], + [ + 0.03333333333333333, + 0.0, + 0.0, + 0.016666666666666666 + ] + ] + ] + } + }, + "centre": { + "masked": [ + [ + -0.6999999999999993, + null, + 0.40000000000000213, + 0.9000000000000021 + ], + [ + 1.3000000000000007, + 1.8000000000000007, + -1.0999999999999979, + 0.6000000000000014 + ], + [ + -0.3999999999999986, + 0.5, + null, + 0.20000000000000284 + ] + ], + "plain": [ + [ + -0.6999999999999993, + -0.09999999999999787, + 0.40000000000000213, + 0.9000000000000021 + ], + [ + 1.3000000000000007, + 1.8000000000000007, + -1.0999999999999979, + 0.6000000000000014 + ], + [ + -0.3999999999999986, + 0.5, + 1.1000000000000014, + 0.20000000000000284 + ] + ], + "spike": [ + [ + 12.0, + 12.0, + 12.0, + 12.0 + ], + [ + 12.0, + 12.0, + 12.0, + 12.0 + ], + [ + 12.0, + 12.0, + 12.0, + 12.0 + ] + ] + }, + "core": { + "channels": 300, + "file": "zlp-core", + "offsetEV": 100.0, + "scaleEV": 0.5 + }, + "estimateShift": { + "default": { + "fromEV": -3.0, + "interpolationPoints": 5, + "shiftEV": [ + [ + 0.0, + -0.6333333333333333, + -1.0666666666666667, + -1.6333333333333333 + ], + [ + -1.9666666666666668, + -2.5, + 0.38333333333333336, + -1.3333333333333335 + ], + [ + -0.25, + -1.1833333333333333, + -1.7833333333333332, + -0.8666666666666667 + ] + ], + "toEV": 3.0 + }, + "ip0": { + "fromEV": -3.0, + "interpolationPoints": 0, + "shiftEV": [ + [ + 0.0, + -0.6000000000000001, + -1.1, + -1.6 + ], + [ + -2.0, + -2.5, + 0.4, + -1.3 + ], + [ + -0.2, + -1.2000000000000002, + -1.8, + -0.9 + ] + ], + "toEV": 3.0 + }, + "ip9": { + "fromEV": -3.0, + "interpolationPoints": 9, + "shiftEV": [ + [ + 0.0, + -0.63, + -1.06, + -1.64 + ], + [ + -1.97, + -2.49, + 0.38, + -1.33 + ], + [ + -0.25, + -1.1800000000000002, + -1.79, + -0.87 + ] + ], + "toEV": 3.0 + }, + "wide": { + "fromEV": -4.0, + "interpolationPoints": 5, + "shiftEV": [ + [ + 0.0, + -0.6333333333333333, + -1.0666666666666667, + -1.6500000000000001 + ], + [ + -1.9666666666666668, + -2.5, + 0.38333333333333336, + -1.3333333333333335 + ], + [ + -0.25, + -1.1833333333333333, + -1.8, + -0.8666666666666667 + ] + ], + "toEV": 4.0 + } + }, + "ll": { + "channels": 600, + "file": "zlp-ll", + "nx": 4, + "ny": 3, + "offsetEV": -20.0, + "scaleEV": 0.1 + }, + "llSpike": { + "file": "zlp-ll-spike", + "spikeEV": 12.0 + }, + "mask": { + "w2.0-none": { + "mask": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ], + "signalMask": null + }, + "w2.0-signal": { + "mask": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ], + "signalMask": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ] + }, + "w5.0-none": { + "mask": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ], + "signalMask": null + }, + "w5.0-signal": { + "mask": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ], + "signalMask": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ] + } + }, + "shift1D": { + "cases": { + "crop": { + "channels": 34, + "file": "zlp-shift1d-crop", + "offsetEV": 7.0 + }, + "nocrop": { + "channels": 40, + "file": "zlp-shift1d-nocrop", + "offsetEV": 5.0 + } + }, + "inputFile": "zlp-shift1d-input", + "offsetEV": 5.0, + "scaleEV": 0.5, + "shiftEV": [ + 0.0, + 0.35, + -0.72, + 1.6 + ] + }, + "truth": { + "globalOffsetEV": 0.37, + "zlpCentreEV": [ + [ + -0.7000000000000001, + -0.06, + 0.37, + 0.95 + ], + [ + 1.28, + 1.7999999999999998, + -1.0899999999999999, + 0.64 + ], + [ + -0.44000000000000006, + 0.49, + 1.1, + 0.18 + ] + ], + "zlpFWHMEV": 0.9 + } + } +} diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e100-fixneg.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e100-fixneg.f64 new file mode 100644 index 0000000..c06b6d0 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e100-fixneg.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e100.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e100.f64 new file mode 100644 index 0000000..9b4a405 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e100.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e1024.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e1024.f64 new file mode 100644 index 0000000..a946654 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w20-e1024.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w50-e100.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w50-e100.f64 new file mode 100644 index 0000000..f687068 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-binned-w50-e100.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e100-fixneg.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e100-fixneg.f64 new file mode 100644 index 0000000..0970eaf Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e100-fixneg.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e100.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e100.f64 new file mode 100644 index 0000000..0970eaf Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e100.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e1024.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e1024.f64 new file mode 100644 index 0000000..049f051 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w20-e1024.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w50-e100.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w50-e100.f64 new file mode 100644 index 0000000..0970eaf Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-binned-w50-e100.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e100-fixneg.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e100-fixneg.f64 new file mode 100644 index 0000000..566856f Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e100-fixneg.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e100.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e100.f64 new file mode 100644 index 0000000..566856f Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e100.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e1024.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e1024.f64 new file mode 100644 index 0000000..1d77dd4 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w20-e1024.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w50-e100.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w50-e100.f64 new file mode 100644 index 0000000..566856f Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-exact-unbinned-w50-e100.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-input-binned.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-input-binned.f64 new file mode 100644 index 0000000..6c114de Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-input-binned.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-input-unbinned.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-input-unbinned.f64 new file mode 100644 index 0000000..e739232 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-input-unbinned.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e100-fixneg.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e100-fixneg.f64 new file mode 100644 index 0000000..6b723df Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e100-fixneg.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e100.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e100.f64 new file mode 100644 index 0000000..f3766fa Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e100.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e1024.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e1024.f64 new file mode 100644 index 0000000..f09179e Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w20-e1024.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w50-e100.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w50-e100.f64 new file mode 100644 index 0000000..ca13898 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-pl-unbinned-w50-e100.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-plural-core.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-plural-core.f64 new file mode 100644 index 0000000..1e13cd8 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-plural-core.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-plural-edge.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-plural-edge.f64 new file mode 100644 index 0000000..625032a Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-plural-edge.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-plural-ll.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-plural-ll.f64 new file mode 100644 index 0000000..ac58533 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-plural-ll.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-plural-single-broadened.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-plural-single-broadened.f64 new file mode 100644 index 0000000..27dda1c Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-plural-single-broadened.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-plural-single.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-plural-single.f64 new file mode 100644 index 0000000..8b65c55 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-plural-single.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-plural-zlp.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-plural-zlp.f64 new file mode 100644 index 0000000..57231b1 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-plural-zlp.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-taper-both.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-taper-both.f64 new file mode 100644 index 0000000..063568a Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-taper-both.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-taper-channels25.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-taper-channels25.f64 new file mode 100644 index 0000000..b4c61c8 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-taper-channels25.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-taper-input.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-taper-input.f64 new file mode 100644 index 0000000..003116b Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-taper-input.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-taper-left-ch40-off5.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-taper-left-ch40-off5.f64 new file mode 100644 index 0000000..ae4b7d3 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-taper-left-ch40-off5.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-taper-left.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-taper-left.f64 new file mode 100644 index 0000000..db812dc Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-taper-left.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-taper-offset10.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-taper-offset10.f64 new file mode 100644 index 0000000..0ab76ef Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-taper-offset10.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-taper-right.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-taper-right.f64 new file mode 100644 index 0000000..bb18f14 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-taper-right.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-also-align-core.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-also-align-core.f64 new file mode 100644 index 0000000..dee40d4 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-also-align-core.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-also-align.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-also-align.f64 new file mode 100644 index 0000000..2590c36 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-also-align.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-default.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-default.f64 new file mode 100644 index 0000000..2590c36 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-default.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-interp-ip3.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-interp-ip3.f64 new file mode 100644 index 0000000..c3e45cd Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-interp-ip3.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-mask.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-mask.f64 new file mode 100644 index 0000000..fad537c Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-mask.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-calibrate.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-calibrate.f64 new file mode 100644 index 0000000..797d07e Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-calibrate.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-crop-no-calibrate.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-crop-no-calibrate.f64 new file mode 100644 index 0000000..0b55314 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-crop-no-calibrate.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-crop.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-crop.f64 new file mode 100644 index 0000000..62905d0 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-crop.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-subpixel.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-subpixel.f64 new file mode 100644 index 0000000..7a3ed32 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-no-subpixel.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-signal-range.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-signal-range.f64 new file mode 100644 index 0000000..27d0c08 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-signal-range.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-spike-no-range.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-spike-no-range.f64 new file mode 100644 index 0000000..283155d Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-spike-no-range.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-spike-range.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-spike-range.f64 new file mode 100644 index 0000000..5157b6a Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-align-spike-range.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-core.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-core.f64 new file mode 100644 index 0000000..597afe0 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-core.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-ll-spike.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-ll-spike.f64 new file mode 100644 index 0000000..283155d Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-ll-spike.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-ll.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-ll.f64 new file mode 100644 index 0000000..36483ce Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-ll.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-crop.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-crop.f64 new file mode 100644 index 0000000..051cab0 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-crop.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-input.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-input.f64 new file mode 100644 index 0000000..3dc2593 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-input.f64 differ diff --git a/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-nocrop.f64 b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-nocrop.f64 new file mode 100644 index 0000000..27c7248 Binary files /dev/null and b/Tests/SpectroEELSTests/Fixtures/eels16-zlp-shift1d-nocrop.f64 differ diff --git a/tools/eels-task16/README.md b/tools/eels-task16/README.md new file mode 100644 index 0000000..6072e8f --- /dev/null +++ b/tools/eels-task16/README.md @@ -0,0 +1,51 @@ +# tools/eels-task16: exSpy / HyperSpy pins for EELS task 16, sections 2, 3 and 4 + +Written before the Swift code, so the Mac session that implements `docs/design/eels-task-16.md` starts with numbers. +Covers zero-loss alignment and mask (design section 2), power-law extrapolation and Hanning taper (section 3), Fourier-log, +Fourier-ratio and `optimal_fft_size` (section 4). Not covered: GOS tables, the edge model fit (section 6), Richardson-Lucy. + +``` +python -m venv v && v/bin/pip install hyperspy==2.4.0 exspy==0.3.2 # the design's pins; NumPy 2.5.4, SciPy 1.18.1 were used +v/bin/python -I -B tools/eels-task16/pins.py # --out DIR to write elsewhere +``` +The script asserts the two versions. Output: `Tests/SpectroEELSTests/Fixtures/eels16-pins.json` (the layout is the script's +docstring) and 58 `eels16-*.f64` arrays (float64 little-endian, C order, NaN kept; shape and sha256 under `files` in the JSON), 2.8 MB. +A second run is byte-identical (sha256 over all files checked). HyperSpy ran without numba (non-accelerated paths). +The pins use exSpy 0.3.2 from PyPI, not the `7185a4d1` checkout the older EELS pins use; the design note names 0.3.2. + +## Inputs (all synthetic, deterministic, images are 3 x 4 pixels, pixel p = row * 4 + col) + +- **Alignment**: low loss 600 ch, -20 eV + 0.1 k; ZLP FWHM 0.9 eV at a per-pixel centre (global 0.37 eV plus -1.46 .. +1.43 eV, + none on a channel), plasmon at 15 eV, power-law tail. A second image with a spike larger than the ZLP at 12 eV, and a core-loss-like + image (300 ch, 100 eV + 0.5 k) for `also_align`. Truth: the planted centres. +- **Power law**: A in 4e5 .. 3e12, r in -0.4 .. 4 (one pixel r < 0 for `fix_neg_r`), 200 ch from 300 eV at 0.5 eV, binned and unbinned. +- **Plural scattering**: ZLP at 0 eV (FWHM 0.9), single-scattering shape S (peaks 12 and 24 eV), t/lambda 0.1 .. 1.1 per pixel, + I0 = 1e6, 1600 ch from -20 eV at 0.1 eV: J = I0 ifft(fft(Z/I0) exp(fft(S)/I0)) on an 8192 circular grid, cropped. Core loss: a + step-plus-exponential edge convolved with J/I0, 300 ch from 280 eV. Truth: S, S broadened by the ZLP, the edge. + +## Findings the port must know + +1. **`max_shift` is not tested here** (a no-op in `estimate_shift1D`, as the design says). `estimateShift` pins `estimate_shift1D` + with reference pixel 0, `number_of_interpolation_points` 0, 5 and 9, two windows. +2. **A navigation mask given as an ndarray must have shape (nx, ny)**, the reverse of the data's (ny, nx), or exSpy raises; the pins pass it + as a signal (`BaseSignal(mask).T`), which is what the kit's `PixelMask` (row-major ny x nx) means. Masked pixels give NaN centres. +3. **`align_zero_loss_peak` without `signal_range` on a spectrum with a spike** above the ZLP aligns on the spike (offset -32.0 eV, case + `spike-no-range`); with `signal_range=(-5, 5)` it does not. Both are pinned as exSpy behaves. +4. **`shiftPasses`** hold the shift arrays `shift1D` received, in order: pass 1 is the coarse shift (`mean(zlpc) - zlpc`), pass 2 the + `align1D` subpixel shift (absent with `subpixel=False`; four entries with `also_align`, one per signal per pass). +5. **Fourier-log returns S x Z/I0, not S**: `z * log(j/z)` is the single-scattering distribution broadened by the ZLP. Against that + truth the interior (outside the tapered channels) agrees to 5.6e-4 of the peak; the planted-truth test must compare with `plural-single-broadened`. + It needs the spectrum to decay inside the axis: with a truncated plural tail (first try) the error was 20 %. +6. **Fourier-ratio carries a factor 1/scale**: exSpy's Gaussian is a density per eV (A = 1), so the result is the edge smoothed by the + Gaussian times 1/scale (10 here). The interior of `fr-fixed-threshold-6` equals smoothed truth / scale to 3 %. The port reproduces + exSpy, not the physics (parity row note). +7. **Taper default**: `channels = max(20, round(0.02 n))`: 20 for every n < 1250, 40 at n = 2000, 100 at n = 5000 (cases `default-n*`). +8. **`power_law_extrapolation` `fix_neg_r`** zeroes A where r <= 0: the JSON has `A` (estimate) and `AUsed`. A, r come from + `PowerLaw.estimate_parameters` on the zero-extended signal, so they depend on the window only, not on the extrapolation size (checked). + +## Not pinned here (left to the implementing session) + +`estimate_peak_width` on pathological spectra (not exactly two roots gives NaN; only the planted ZLP is pinned, in `fwhmAllPixelsEV` +and each Fourier-ratio case's `fwhmEV`); `richardson_lucy_deconvolution`; the lazy (dask) code paths; Poisson-noisy inputs (the old +slices' noisy pins hold counting statistics; deconvolution of noisy data is dominated by the `log`/division in Fourier space and is +not a useful agreement test). diff --git a/tools/eels-task16/parity-rows-draft.md b/tools/eels-task16/parity-rows-draft.md new file mode 100644 index 0000000..62cb555 --- /dev/null +++ b/tools/eels-task16/parity-rows-draft.md @@ -0,0 +1,19 @@ +# Draft `docs/parity.md` rows for task 16 sections 2, 3, 4 + +For the implementing session to move into `docs/parity.md` (design section 9) when the code lands; state stays "missing" until then. +Columns as in parity.md. Fixture: `Tests/SpectroEELSTests/Fixtures/eels16-pins.json` (+ `eels16-*.f64`), generated by `tools/eels-task16/pins.py` +(exSpy 0.3.2 / HyperSpy 2.4.0). "kit" = the tolerance the pins are to be held at; upstream = what exSpy's own test uses. + +| exSpy / HyperSpy | SpectroKit | state | code | priority | upstream tolerance (test file) | evidence (to write) | +|---|---|---|---|---|---|---| +| `estimate_zero_loss_peak_centre` (with `mask`, `signal_range`) | `EELSAlignment.zeroLossPeakCentre` | missing | TOL | study | `test_eels.py::test_estimate_zero_loss_peak_centre` defaults (rtol 1e-7); kit: exact eV (first argmax of a grid value) | `AlignPinsTests`: `zlp.centre.{plain,masked,spike}` | +| `get_zero_loss_peak_mask` | `EELSAlignment.zeroLossPeakMask` | missing | exact | study | `test_eels.py::test_get_zero_loss_peak_mask*` exact | `zlp.mask` (widths 5.0, 2.0; with and without `signal_mask`) | +| `Signal1D.estimate_shift1D` | `EELSAlignment.estimateShift` | missing | TOL | study | `test_1D_tools.py::TestAlignTools::test_estimate_shift` atol 1e-3 (eV); `max_shift` is a no-op upstream and is not offered | `zlp.estimateShift.{default,wide,ip0,ip9}` at atol 1e-3 eV | +| `Signal1D.shift1D` | `EELSAlignment.shift` | missing | TOL | study | `test_1D_tools.py::TestAlignTools::test_shift1D` defaults; new offset exact | `zlp.shift1D.cases.{crop,nocrop}`: data at rtol 1e-7 atol 1e-12, offset and size exact, NaN where undefined | +| `align_zero_loss_peak` (calibrate, subpixel, crop, mask, signal_range, also_align) | `EELSAlignment.alignZeroLossPeak` | missing | TOL | study | `test_eels.py::TestAlignZLP` mean/std of re-estimated centre defaults (rtol 1e-7; with mask atol eps); `calibrate=False` std atol 1e-2; `crop=False` size kept; spike signal_range max 8 | `zlp.align.*` (11 variants): offset, size, scale exact to 1e-12; data rtol 1e-7 atol 1e-9 x max; shift passes atol 1e-9 eV; truth: planted centres within 0.5 channel coarse, 1e-3 eV subpixel | +| `Signal1D.hanning_taper` (side, channels, offset) | `EELSSpectrumOps.hanningTaper` | missing | exact | useful | no numeric test upstream; exact by construction (`np.hanning`) | `taper.cases.*`: returned channels exact, data to 1e-15 relative; default-channel rule `default-n*` | +| `power_law_extrapolation` (window, size, `fix_neg_r`, binned) | `EELSSpectrumOps.powerLawExtrapolation` | missing | TOL | study | `test_eels.py::TestPowerLawExtrapolation` atol 1e-2 against the exact power law (`atol=10e-3`); `test_power_law.py` A, r defaults | `powerLaw.cases.*`: A, r rtol 1e-7; data rtol 1e-9; vs `exactFile` atol 1e-2 (binned and unbinned) | +| `utils.math_tools.optimal_fft_size` / `scipy.fft.next_fast_len` | `EELSDeconvolution.optimalFFTSize` | missing | exact | useful | none upstream; exact integers | `optimalFFTSize` (217 values, real and complex) | +| `fourier_log_deconvolution` (`add_zlp`, `crop`) | `EELSDeconvolution.fourierLog` | missing | TOL | study | none upstream (kit decision, design section 4): rtol 1e-7 + atol 1e-7 x max abs of the pinned result per pixel; `fftSize`, `taperedChannels` exact | `fourierLog.cases.*` (4); planted truth: interior vs S x Z/I0 within 6e-4 of the peak (exSpy's own number, finding 5) | +| `fourier_ratio_deconvolution` (fwhm, threshold, extrapolate_*) | `EELSDeconvolution.fourierRatio` | missing | TOL | study | none upstream (`test_running` only runs): same rule; `fftSize`, tapered channels exact; FWHM to 1e-9 eV; I0 rtol 1e-12 | `fourierRatio.cases.*` (6); output carries exSpy's 1/scale factor (finding 6); planted truth: interior vs smoothed edge / scale within 3 % | +| `estimate_peak_width` (`factor=0.5`) | part of `fourierRatio` (`FourierRatioOptions.fwhmEV == nil`) | missing | TOL | useful | `test_signal1d.py` peak-width tests (kit reads the roots as cubic-spline roots) | `fourierRatio.fwhmAllPixelsEV` at 1e-9 eV; NaN when not exactly two roots | diff --git a/tools/eels-task16/pins.py b/tools/eels-task16/pins.py new file mode 100644 index 0000000..a0b8666 --- /dev/null +++ b/tools/eels-task16/pins.py @@ -0,0 +1,408 @@ +#!/usr/bin/env python3 +"""exSpy / HyperSpy pins for SpectroKit EELS task 16, sections 2, 3 and 4 of docs/design/eels-task-16.md. + +Written before the Swift code. Pins what exSpy 0.3.2 / HyperSpy 2.4.0 answer on deterministic synthetic spectrum images with +known shifts: zero-loss alignment and mask (section 2), power-law extrapolation and Hanning taper (section 3), +Fourier-log and Fourier-ratio deconvolution and `optimal_fft_size` (section 4). Not covered: GOS tables, the edge model fit, +Richardson-Lucy. Agreement with exSpy is agreement, not truth; the planted truth (shifts, edge shape) is stored beside each case. + +Run (any venv with `pip install hyperspy==2.4.0 exspy==0.3.2`; NumPy 2.5.4, SciPy 1.18.1 were used): + + python -I -B tools/eels-task16/pins.py [--out DIR] + +Writes into --out (default Tests/SpectroEELSTests/Fixtures/): + + eels16-.f64 float64 little-endian, C order, NaN kept (named in eels16-pins.json under "files" with shape and sha256) + eels16-pins.json everything else; floats are Python reprs (they round-trip exactly), NaN is null + +Images are (ny, nx, channels) = (3, 4, n), pixel p = row * 4 + col. Axis of channel k: offset + scale * k. +Every output is byte-identical on a second run (default_rng(20261021); no other randomness). + +Layout of eels16-pins.json: + environment versions, sha256 of this script, the generator command + files name -> {shape, sha256} for every .f64 + zlp.* section 2. inputs: "ll" (shifted ZLP + plasmon + tail), "llSpike" (a spike larger than the ZLP at 12 eV), + "core" (a second image carrying the same shifts, for also_align); truth: per-pixel ZLP centre in eV. + centre estimate_zero_loss_peak_centre, with and without mask (masked -> null) + mask get_zero_loss_peak_mask for widths 5.0 and 2.0, with and without signal_mask + estimateShift estimate_shift1D(start, end, reference_indices=(0,0), number_of_interpolation_points=5) in eV + align one record per align_zero_loss_peak variant: kwargs, offset, size, scale, the re-estimated centre of the + aligned image, the shift arrays shift1D received in order (pass 1 coarse, pass 2 align1D subpixel), the + aligned image file, the also_align image file where used + shift1D shift1D on a ramp with fractional shifts, crop True and False: offset, size, data + taper hanning_taper cases: side, channels, offset -> returned channels and tapered data + powerLaw power_law_extrapolation cases (binned/unbinned, window, size, fix_neg_r): A, r from PowerLaw.estimate_parameters + on the zero-extended signal, the extrapolated data, the exact power law at the new channels (truth) + optimalFFTSize hyperspy.misc.math_tools.optimal_fft_size(n, real) for n in 1..200 plus selected larger n + fourierLog cases: size, taperedChannels, result with add_zlp / crop False/True; planted truth (single scattering S) + fourierRatio cases: size, fwhm (estimate_peak_width), thresholds, I0, taperedChannels, result; planted truth (edge) +""" +import argparse +import hashlib +import json +import logging +import math +import os +import platform +import sys +import warnings + +HERE = os.path.dirname(os.path.abspath(__file__)) +REPO = os.path.normpath(os.path.join(HERE, "..", "..")) + +ap = argparse.ArgumentParser(description=__doc__.split("\n")[0]) +ap.add_argument("--out", default=os.path.join(REPO, "Tests", "SpectroEELSTests", "Fixtures")) +ARGS = ap.parse_args() +OUT = ARGS.out +os.makedirs(OUT, exist_ok=True) + +logging.disable(logging.CRITICAL) +warnings.simplefilter("ignore") + +import numpy as np # noqa: E402 +import scipy # noqa: E402 +import hyperspy # noqa: E402 +import hyperspy.api as hs # noqa: E402 +import exspy # noqa: E402 +from hyperspy.misc.math_tools import optimal_fft_size # noqa: E402 +from hyperspy._signals.signal1d import Signal1D # noqa: E402 + +assert hyperspy.__version__ == "2.4.0" and exspy.__version__ == "0.3.2", (hyperspy.__version__, exspy.__version__) + +NY, NX = 3, 4 +RNG = np.random.default_rng(20261021) +FILES = {} +PINS = {} + + +def jnum(x): + """float (or None) for JSON: NaN -> null.""" + if x is None: + return None + x = float(x) + return None if math.isnan(x) else x + + +def jlist(a): + a = np.asarray(a, dtype=np.float64) + if a.ndim == 0: + return jnum(a) + return [jlist(v) for v in a] + + +def write(name, arr): + """Write eels16-.f64 and record it; returns the array as float64 C-order.""" + a = np.ascontiguousarray(np.asarray(arr, dtype="= 2, 5e4 * np.maximum(E_LL, 2) ** -2.5, 0)) + if spike: + d[i, j, int(round((12.0 - OFF_LL) / SC_LL))] = 3.0 * d[i, j].max() + return d + + +ll = write("zlp-ll", lowloss_shifted()) +llspike = write("zlp-ll-spike", lowloss_shifted(spike=True)) +# A core-loss-like second image that carries the same shifts (also_align): 300 channels at 0.5 eV from 100 eV. +N_CO, OFF_CO, SC_CO = 300, 100.0, 0.5 +core = np.stack([np.stack([1e4 * np.maximum(OFF_CO + SC_CO * np.arange(N_CO), 1) ** -1.5 * (1 + 0.1 * (i * NX + j)) for j in range(NX)]) for i in range(NY)]) +write("zlp-core", core) +PINS["zlp"] = { + "ll": {"file": "zlp-ll", "nx": NX, "ny": NY, "channels": N_LL, "offsetEV": OFF_LL, "scaleEV": SC_LL}, + "llSpike": {"file": "zlp-ll-spike", "spikeEV": 12.0}, + "core": {"file": "zlp-core", "channels": N_CO, "offsetEV": OFF_CO, "scaleEV": SC_CO}, + "truth": {"zlpCentreEV": jlist(CENTRES), "globalOffsetEV": GLOBAL, "zlpFWHMEV": 0.9}, +} + +MASK = np.zeros((NY, NX), dtype=bool) +MASK[0, 1] = MASK[2, 2] = True + + +def nav_mask(m): + """exSpy wants a navigation mask as a signal with signal dimension 0 (an ndarray is compared with (nx, ny)).""" + return None if m is None else hs.signals.BaseSignal(np.asarray(m)).T + + +def fresh(kind="ll"): + d = {"ll": ll, "llSpike": llspike}[kind] + return eels(d, OFF_LL, SC_LL, title=kind) + + +centre = {} +for name, kind, mask in [("plain", "ll", None), ("masked", "ll", MASK), ("spike", "llSpike", None)]: + c = fresh(kind).estimate_zero_loss_peak_centre(mask=nav_mask(mask)) + centre[name] = jlist(c.data) +PINS["zlp"]["centre"] = centre + +zmask = {} +for width in (5.0, 2.0): + for sm_name, sm in [("none", None), ("signal", (E_LL > 30))]: + m = fresh().get_zero_loss_peak_mask(zero_loss_peak_mask_width=width, signal_mask=sm) + zmask["w%.1f-%s" % (width, sm_name)] = {"mask": [bool(v) for v in m], "signalMask": None if sm is None else [bool(v) for v in sm]} +PINS["zlp"]["mask"] = zmask + +est = {} +for name, (a, b, ip) in {"default": (-3.0, 3.0, 5), "wide": (-4.0, 4.0, 5), "ip0": (-3.0, 3.0, 0), "ip9": (-3.0, 3.0, 9)}.items(): + s = fresh() + ref = s.estimate_shift1D(a, b, reference_indices=(0, 0), number_of_interpolation_points=ip, show_progressbar=False) + est[name] = {"fromEV": a, "toEV": b, "interpolationPoints": ip, "shiftEV": jlist(ref)} +PINS["zlp"]["estimateShift"] = est + +# align_zero_loss_peak variants. shift1D is wrapped to record the shift arrays it receives, in order. +RECORD = [] +_orig_shift = Signal1D.shift1D + + +def _wrapped(self, shift_array, *a, **k): + RECORD.append(np.array(shift_array, dtype=np.float64).copy()) + return _orig_shift(self, shift_array, *a, **k) + + +Signal1D.shift1D = _wrapped +VARIANTS = { + "default": dict(kind="ll", kw={}), + "no-subpixel": dict(kind="ll", kw=dict(subpixel=False)), + "no-calibrate": dict(kind="ll", kw=dict(calibrate=False)), + "no-crop": dict(kind="ll", kw=dict(crop=False)), + "no-crop-no-calibrate": dict(kind="ll", kw=dict(crop=False, calibrate=False)), + "mask": dict(kind="ll", kw=dict(mask=MASK)), + "signal-range": dict(kind="ll", kw=dict(signal_range=(-5.0, 5.0))), + "spike-no-range": dict(kind="llSpike", kw={}), + "spike-range": dict(kind="llSpike", kw=dict(signal_range=(-5.0, 5.0))), + "also-align": dict(kind="ll", kw={}, also=True), + "interp-ip3": dict(kind="ll", kw=dict(number_of_interpolation_points=3)), +} +align = {} +for name, v in VARIANTS.items(): + s = fresh(v["kind"]) + also = [eels(core, OFF_CO, SC_CO, title="core")] if v.get("also") else [] + RECORD.clear() + kw = dict(v["kw"]) + if "mask" in kw: + kw["mask"] = nav_mask(kw["mask"]) + s.align_zero_loss_peak(also_align=also, print_stats=False, show_progressbar=False, **kw) + ax = s.axes_manager.signal_axes[0] + rec = {"kind": v["kind"], "kwargs": {k: (None if k == "mask" else (list(x) if isinstance(x, tuple) else x)) for k, x in v["kw"].items()}, + "maskUsed": "mask" in v["kw"], + "offsetEV": float(ax.offset), "scaleEV": float(ax.scale), "channels": int(ax.size), + "reestimatedCentreEV": jlist(s.estimate_zero_loss_peak_centre(mask=kw.get("mask")).data), + "shiftPasses": [jlist(r) for r in RECORD], + "file": "zlp-align-%s" % name} + write(rec["file"], s.data) + if also: + cax = also[0].axes_manager.signal_axes[0] + rec["alsoAligned"] = {"file": "zlp-align-%s-core" % name, "offsetEV": float(cax.offset), "channels": int(cax.size)} + write(rec["alsoAligned"]["file"], also[0].data) + align[name] = rec +Signal1D.shift1D = _orig_shift +PINS["zlp"]["align"] = align + +# shift1D alone: a ramp-plus-bump signal, fractional shifts in channels * scale (eV). +ramp = np.array([np.sin(np.arange(40) / 5.0) + 0.05 * np.arange(40) * (k + 1) for k in range(4)]) # (4, 40) +sh = np.array([0.0, 0.35, -0.72, 1.6]) # eV, scale 0.5 -> 0, 0.7, -1.44, 3.2 channels +shift = {} +for crop in (True, False): + s = eels(ramp, 5.0, 0.5, binned=False) + s.shift1D(sh, crop=crop, show_progressbar=False) + ax = s.axes_manager.signal_axes[0] + shift["crop" if crop else "nocrop"] = {"offsetEV": float(ax.offset), "channels": int(ax.size), "file": "zlp-shift1d-%s" % ("crop" if crop else "nocrop")} + write(shift["crop" if crop else "nocrop"]["file"], s.data) +write("zlp-shift1d-input", ramp) +PINS["zlp"]["shift1D"] = {"inputFile": "zlp-shift1d-input", "offsetEV": 5.0, "scaleEV": 0.5, "shiftEV": jlist(sh), "cases": shift} + +# --------------------------------------------------------------------------------------------------------------- section 3 +# Hanning taper (HyperSpy Signal1D.hanning_taper). +taper = {} +tdata = 1.0 + np.arange(2 * 300).reshape(2, 300) * 0.01 + 5.0 +write("taper-input", tdata) +for name, kw in {"both": {}, "left": dict(side="left"), "right": dict(side="right"), "channels25": dict(channels=25), + "offset10": dict(offset=10), "left-ch40-off5": dict(side="left", channels=40, offset=5)}.items(): + s = eels(tdata, 0.0, 1.0) + n = s.hanning_taper(**kw) + taper[name] = {"kwargs": kw, "taperedChannels": int(n), "file": "taper-%s" % name} + write(taper[name]["file"], s.data) +for n in (50, 100, 999, 1024, 2000, 5000): # default channels = max(20, round(0.02 n)) + s = eels(np.ones((1, n)), 0.0, 1.0) + taper["default-n%d" % n] = {"kwargs": {}, "n": n, "taperedChannels": int(s.hanning_taper())} +PINS["taper"] = {"input": {"file": "taper-input", "channels": 300, "rows": 2}, "cases": taper} + +# Power-law extrapolation (exSpy power_law_extrapolation). +N_PL, OFF_PL, SC_PL = 200, 300.0, 0.5 +E_PL = OFF_PL + SC_PL * np.arange(N_PL) +A_PL = np.array([[1e9, 5e8, 2e10], [3e12, 8e7, 4e5]]) +R_PL = np.array([[3.0, 2.5, 3.5], [4.0, 1.7, -0.4]]) # last pixel: r < 0 (rising) for fix_neg_r +pl = {} +for binned in (True, False): + d = A_PL[..., None] * E_PL ** (-R_PL[..., None]) * (SC_PL if binned else 1.0) + write("pl-input-%s" % ("binned" if binned else "unbinned"), d) + for ws, es, fix in [(20, 1024, False), (20, 100, True), (50, 100, False), (20, 100, False)]: + s = eels(d, OFF_PL, SC_PL, binned=binned) + out = s.power_law_extrapolation(window_size=ws, extrapolation_size=es, fix_neg_r=fix) + # A, r exactly as exSpy gets them: PowerLaw.estimate_parameters on the zero-extended copy over the last window + ext = s.deepcopy() + ext.data = np.zeros(list(d.shape[:-1]) + [N_PL + es]) + ext.data[..., :N_PL] = d + ext.get_dimensions_from_data() + comp = hs.model.components1D.PowerLaw() + comp._axes_manager = s.axes_manager + ax = s.axes_manager.signal_axes[0] + A, r = comp.estimate_parameters(ext, ax.index2value(ax.size - ws), ax.index2value(ax.size - 1), out=True) + name = "%s-w%d-e%d%s" % ("binned" if binned else "unbinned", ws, es, "-fixneg" if fix else "") + e_new = OFF_PL + SC_PL * np.arange(N_PL, N_PL + es) + exact = A_PL[..., None] * e_new ** (-R_PL[..., None]) * (SC_PL if binned else 1.0) + pl[name] = {"binned": binned, "windowChannels": ws, "extrapolationChannels": es, "fixNegativeR": fix, + "A": jlist(A), "AUsed": jlist(np.where(r <= 0, 0, A) if fix else A), "r": jlist(r), "inputFile": "pl-input-%s" % ("binned" if binned else "unbinned"), + "file": "pl-%s" % name, "exactFile": "pl-exact-%s" % name, "channels": int(out.axes_manager.signal_axes[0].size)} + write(pl[name]["file"], out.data) + write(pl[name]["exactFile"], exact) +PINS["powerLaw"] = {"offsetEV": OFF_PL, "scaleEV": SC_PL, "channels": N_PL, "truthA": jlist(A_PL), "truthR": jlist(R_PL), "cases": pl} + +# --------------------------------------------------------------------------------------------------------------- section 4 +PINS["optimalFFTSize"] = { + "ns": [int(n) for n in list(range(1, 201)) + [255, 256, 257, 511, 1000, 1023, 1024, 1025, 1500, 2047, 2048, 2049, 2200, 4093, 4097, 10007, 65537]], +} +PINS["optimalFFTSize"]["real"] = [int(optimal_fft_size(n, True)) for n in PINS["optimalFFTSize"]["ns"]] +PINS["optimalFFTSize"]["complex"] = [int(optimal_fft_size(n, False)) for n in PINS["optimalFFTSize"]["ns"]] + +# Planted plural-scattering low loss: ZLP at 0 eV for every pixel, thickness t/lambda per pixel, J = I0 ifft(Z' exp(fft S / I0)). +N_P, OFF_P, SC_P = 1600, -20.0, 0.1 # -20 .. 139.9 eV, long enough that the plural tail has decayed +E_P = OFF_P + SC_P * np.arange(N_P) +TAU = np.array([[0.2, 0.4, 0.6, 0.8], [1.0, 1.2, 0.1, 0.3], [0.5, 0.7, 0.9, 1.1]]) +I0_P = 1e6 +PAD = 8192 # circular grid long enough that nothing wraps +z1 = gauss(E_P, 0.0, 0.9, 1.0) # unit-area ZLP per eV +S1 = gauss(E_P, 12.0, 4.0, 1.0) + gauss(E_P, 24.0, 7.0, 0.5) # single-scattering shape (unit area 1.5) +S1 = np.where(E_P > 2.0, S1, 0.0) +zl = np.zeros((NY, NX, N_P)) +jl = np.zeros((NY, NX, N_P)) +ss = np.zeros((NY, NX, N_P)) +for i in range(NY): + for j in range(NX): + tau = TAU[i, j] + S = tau * I0_P * S1 / S1.sum() * 1.0 # counts: area tau * I0 over the channels + Z = I0_P * z1 / z1.sum() # counts: area I0 + Zf, Sf = np.fft.rfft(Z, PAD), np.fft.rfft(S, PAD) + J = np.fft.irfft(Zf * np.exp(Sf / I0_P), PAD)[:N_P] + zl[i, j], jl[i, j], ss[i, j] = Z, J, S +write("plural-zlp", zl) +write("plural-ll", jl) +write("plural-single", ss) +# Fourier-log returns Z (x) S / I0 (the single-scattering distribution broadened by the ZLP), not S: that is the truth to compare with +ssb = np.stack([np.stack([np.convolve(ss[i, j], zl[i, j] / zl[i, j].sum())[:N_P] for j in range(NX)]) for i in range(NY)]) +write("plural-single-broadened", ssb) +plural = {"nx": NX, "ny": NY, "channels": N_P, "offsetEV": OFF_P, "scaleEV": SC_P, "tauOverLambda": jlist(TAU), "i0": I0_P, + "zlpFile": "plural-zlp", "lowLossFile": "plural-ll", "singleScatteringFile": "plural-single", "singleScatteringBroadenedFile": "plural-single-broadened", + "note": "J = I0 ifft(fft(Z/I0) exp(fft(S)/I0)) on a 8192 circular grid, cropped; truth S is the single-scattering counts, S x Z/I0 is what Fourier-log returns"} + +fl = {} +for name, kw in {"default": {}, "add-zlp": dict(add_zlp=True), "crop": dict(crop=True), "add-zlp-crop": dict(add_zlp=True, crop=True)}.items(): + j = eels(jl, OFF_P, SC_P, title="J") + z = eels(zl, OFF_P, SC_P, title="Z") + tapped = j.deepcopy().hanning_taper() + out = j.fourier_log_deconvolution(z, **kw) + size = optimal_fft_size(N_P + N_P - 1, True) + ax = out.axes_manager.signal_axes[0] + fl[name] = {"kwargs": kw, "fftSize": int(size), "taperedChannels": int(tapped), "channels": int(ax.size), + "offsetEV": float(ax.offset), "file": "fl-%s" % name} + write(fl[name]["file"], out.data) +# zlp shorter than the spectrum and longer than it (sizes differ; zlp.data is broadcast against j only when sizes match, +# so the shapes here keep the channel counts equal and the case documents that exSpy requires it) +PINS["fourierLog"] = {"plural": plural, "cases": fl} + +# Fourier ratio: core loss = edge (single scattering, background removed) convolved with J/I0 (ZLP weight 1), 300 channels at 0.1 eV from 280 eV. +N_C, OFF_C = 300, 280.0 +e = np.arange(N_C) * SC_P +edge = np.where(e >= 4.0, 2e3 * np.exp(-(e - 4.0) / 25.0), 0.0) # a smooth step with an exponential tail, counts per channel +core_p = np.zeros((NY, NX, N_C)) +edge_p = np.zeros((NY, NX, N_C)) +ZERO = int(round(-OFF_P / SC_P)) # channel of 0 eV in the low loss +for i in range(NY): + for j in range(NX): + ed = edge * (1.0 + 0.2 * (i * NX + j)) + full = np.convolve(ed, jl[i, j] / I0_P) + core_p[i, j] = full[ZERO:ZERO + N_C] + edge_p[i, j] = ed +write("plural-core", core_p) +write("plural-edge", edge_p) +fr = {} +for name, kw in {"default": {}, "fixed-threshold-6": dict(threshold=6.0), "fwhm-1.5": dict(fwhm=1.5, threshold=6.0), + "no-extrap-ll": dict(threshold=6.0, extrapolate_lowloss=False), + "no-extrap-cl": dict(threshold=6.0, extrapolate_coreloss=False), + "no-extrap": dict(threshold=6.0, extrapolate_lowloss=False, extrapolate_coreloss=False)}.items(): + c = eels(core_p, OFF_C, SC_P, title="core") + l = eels(jl, OFF_P, SC_P, title="J") + kws = dict(kw) + ctx = {} + # the pieces exSpy computes internally, recomputed with the same calls + ll2 = l.power_law_extrapolation(window_size=100, extrapolation_size=100) if kw.get("extrapolate_lowloss", True) else l.deepcopy() + cl2 = c.power_law_extrapolation(window_size=20, extrapolation_size=100) if kw.get("extrapolate_coreloss", True) else c.deepcopy() + tap_ll, tap_cl = ll2.hanning_taper(), cl2.hanning_taper() + size = optimal_fft_size(ll2.axes_manager.signal_axes[0].size + cl2.axes_manager.signal_axes[0].size - 1) + thr = kw.get("threshold") + thr_used = l.estimate_elastic_scattering_threshold() if thr is None else None + I0 = ll2.estimate_elastic_scattering_intensity(threshold=thr_used if thr is None else thr) + fwhm_ref = float(l.get_current_signal().estimate_peak_width()._get_current_data()[0]) if kw.get("fwhm") is None else kw["fwhm"] + out = c.fourier_ratio_deconvolution(l, **kws) + fr[name] = {"kwargs": kw, "fftSize": int(size), "lowLossChannelsAfterExtrapolation": int(ll2.axes_manager.signal_axes[0].size), + "coreLossChannelsAfterExtrapolation": int(cl2.axes_manager.signal_axes[0].size), + "taperedChannelsLowLoss": int(tap_ll), "taperedChannelsCoreLoss": int(tap_cl), + "fwhmEV": jnum(fwhm_ref), "thresholdEV": None if thr_used is None else jlist(thr_used.data), + "i0": jlist(I0.data), "channels": int(out.axes_manager.signal_axes[0].size), "offsetEV": float(out.axes_manager.signal_axes[0].offset), + "file": "fr-%s" % name} + write(fr[name]["file"], out.data) +# FWHM of every pixel's ZLP (estimate_peak_width on the whole image; NaN where the cubic spline does not have exactly two roots) +fw = eels(jl, OFF_P, SC_P).estimate_peak_width() +fwhm_all = jlist(fw.data) +PINS["fourierRatio"] = {"note": "exSpy's Gaussian is a density per eV (A=1, sum over channels = 1/scale), so the result is the planted edge " + "smoothed by the Gaussian AND multiplied by 1/scale: interior of fr-fixed-threshold-6 equals smoothed truth / scale to 3 %", + "plural": plural, "core": {"file": "plural-core", "channels": N_C, "offsetEV": OFF_C, "scaleEV": SC_P, + "truthEdgeFile": "plural-edge", "zeroLossChannel": ZERO}, + "fwhmAllPixelsEV": fwhm_all, "cases": fr} + +# ----------------------------------------------------------------------------------------------------------------- environment +with open(__file__, "rb") as fh: + PINS["environment"] = { + "exspy": exspy.__version__, "hyperspy": hyperspy.__version__, "numpy": np.__version__, "scipy": scipy.__version__, + "python": platform.python_version(), "scriptSha256": hashlib.sha256(fh.read()).hexdigest(), + "command": "python -I -B tools/eels-task16/pins.py", + "note": "spectra are synthetic and deterministic; HyperSpy ran without numba (non-accelerated paths, identical results)", + } +PINS["files"] = FILES +with open(os.path.join(OUT, "eels16-pins.json"), "w") as fh: + json.dump(PINS, fh, indent=1, sort_keys=True, allow_nan=False) + fh.write("\n") +print("wrote", len(FILES), "arrays")