MNeuEventLib 0.2.1__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mneueventlib-0.3.0/.github/workflows/push.yml +111 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/Cargo.lock +26 -18
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/Cargo.toml +3 -1
- mneueventlib-0.3.0/MNeuEventLib/test_helpers.py +40 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/PKG-INFO +1 -1
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/README.md +8 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/how-to/filtering.ipynb +3 -3
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/tutorials/getting_started.ipynb +3 -1
- mneueventlib-0.3.0/files/README.md +1 -0
- mneueventlib-0.3.0/files/muon_ref.nxs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/pyproject.toml +1 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/batch_interface.rs +71 -8
- mneueventlib-0.3.0/src/consts.rs +15 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/mod.rs +1 -1
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/nexus_data.rs +8 -6
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/save/instrument.rs +16 -10
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/save/mod.rs +1 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/save/periods.rs +1 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/save/sample_logs.rs +4 -0
- mneueventlib-0.3.0/src/data/save/sanitise/mod.rs +8 -0
- mneueventlib-0.3.0/src/data/save/sanitise/nexus_data.rs +707 -0
- mneueventlib-0.3.0/src/data/save/sanitise/utils.rs +426 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/save/utils.rs +13 -12
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/save/wimda.rs +5 -2
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/interface.rs +19 -4
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/stats.rs +52 -103
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/test_utils.rs +10 -0
- mneueventlib-0.3.0/tests/integration/test_mantid.py +352 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/tests/test_data/HIFI00195790.nxs +0 -0
- mneueventlib-0.3.0/tools/make_default.py +156 -0
- mneueventlib-0.2.1/.github/workflows/push.yml +0 -41
- mneueventlib-0.2.1/src/consts.rs +0 -3
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/.github/workflows/label_merge_conflicts.yml +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/.github/workflows/release.yml +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/.gitignore +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/.readthedocs.yaml +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/LICENSE +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/MNeuEventLib/__init__.py +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/MNeuEventLib/plotting.py +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/bench.py +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/Makefile +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/make.bat +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/_static/HIFI00195790.nxs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/_static/api/README.md +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/api.rst +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/conf.py +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/how-to/create_plots.ipynb +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/how-to/index.rst +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/index.rst +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/install.rst +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/tutorials/batch_processing.ipynb +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/docs/source/tutorials/index.rst +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/frame_data.rs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/data/sample_logs.rs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/filters/api.rs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/filters/filtering.rs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/filters/mod.rs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/filters/weights.rs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/lib.rs +0 -0
- {mneueventlib-0.2.1 → mneueventlib-0.3.0}/src/utils.rs +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
name:
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
|
|
6
|
+
env:
|
|
7
|
+
CARGO_TERM_COLOR: always
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
format:
|
|
11
|
+
name: Check formatting
|
|
12
|
+
runs-on: ubuntu-slim
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v7
|
|
15
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
16
|
+
with:
|
|
17
|
+
components: rustfmt
|
|
18
|
+
- run: cargo fmt --check
|
|
19
|
+
|
|
20
|
+
lint:
|
|
21
|
+
name: Lint
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v7
|
|
25
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
26
|
+
with:
|
|
27
|
+
components: clippy
|
|
28
|
+
- run: cargo clippy --all-targets --all-features -- -D warnings
|
|
29
|
+
|
|
30
|
+
linux:
|
|
31
|
+
name: Run unit tests
|
|
32
|
+
needs: [lint, format]
|
|
33
|
+
strategy:
|
|
34
|
+
matrix:
|
|
35
|
+
os: [windows-latest, ubuntu-latest, macOS-latest]
|
|
36
|
+
runs-on: ${{ matrix.os }}
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v7
|
|
39
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
40
|
+
- run: cargo test --verbose
|
|
41
|
+
|
|
42
|
+
run_integration_tests:
|
|
43
|
+
name: Integration tests
|
|
44
|
+
needs: [lint, format]
|
|
45
|
+
strategy:
|
|
46
|
+
fail-fast: false
|
|
47
|
+
matrix:
|
|
48
|
+
os: [windows-latest, ubuntu-latest, macos-latest]
|
|
49
|
+
build: [stable, nightly]
|
|
50
|
+
include:
|
|
51
|
+
- build: stable
|
|
52
|
+
mantid_channel: 'mantid'
|
|
53
|
+
- build: nightly
|
|
54
|
+
mantid_channel: 'mantid/label/nightly'
|
|
55
|
+
runs-on: ${{ matrix.os }}
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v7
|
|
58
|
+
with:
|
|
59
|
+
fetch-depth: "0"
|
|
60
|
+
|
|
61
|
+
- name: Setup Conda
|
|
62
|
+
uses: conda-incubator/setup-miniconda@v4
|
|
63
|
+
with:
|
|
64
|
+
miniconda-version: "latest"
|
|
65
|
+
mamba-version: "*"
|
|
66
|
+
channels: ${{ matrix.mantid_channel }},conda-forge
|
|
67
|
+
channel-priority: flexible
|
|
68
|
+
conda-remove-defaults: true
|
|
69
|
+
activate-environment: mantid-env
|
|
70
|
+
auto-activate-base: false
|
|
71
|
+
|
|
72
|
+
- name: Install Mantid and test deps
|
|
73
|
+
shell: bash -el {0}
|
|
74
|
+
env:
|
|
75
|
+
MSYS_NO_PATHCONV: 1
|
|
76
|
+
run: mamba install -y -n mantid-env mantid pytest pip
|
|
77
|
+
|
|
78
|
+
- name: Show resolved python version
|
|
79
|
+
shell: bash -el {0}
|
|
80
|
+
run: |
|
|
81
|
+
conda activate mantid-env
|
|
82
|
+
python --version
|
|
83
|
+
|
|
84
|
+
- name: Install maturin into mantid-env
|
|
85
|
+
shell: bash -el {0}
|
|
86
|
+
run: |
|
|
87
|
+
conda activate mantid-env
|
|
88
|
+
python -m pip install maturin
|
|
89
|
+
|
|
90
|
+
- name: Verify test deps installed
|
|
91
|
+
shell: bash -el {0}
|
|
92
|
+
run: |
|
|
93
|
+
mamba list -n mantid-env pytest
|
|
94
|
+
conda activate mantid-env
|
|
95
|
+
python -c "import pytest; print(pytest.__version__)"
|
|
96
|
+
|
|
97
|
+
- name: Install Rust toolchain
|
|
98
|
+
uses: dtolnay/rust-toolchain@stable
|
|
99
|
+
|
|
100
|
+
- name: Build and install Rust extension into conda env
|
|
101
|
+
shell: bash -el {0}
|
|
102
|
+
run: |
|
|
103
|
+
conda activate mantid-env
|
|
104
|
+
python -m maturin develop --release
|
|
105
|
+
|
|
106
|
+
- name: Run integration tests
|
|
107
|
+
shell: bash -el {0}
|
|
108
|
+
run: |
|
|
109
|
+
conda activate mantid-env
|
|
110
|
+
python -m pytest tests/integration/
|
|
111
|
+
|
|
@@ -4,15 +4,17 @@ version = 4
|
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "MNeuEventLib"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
dependencies = [
|
|
9
9
|
"anyhow",
|
|
10
10
|
"chrono",
|
|
11
11
|
"hdf5-metno",
|
|
12
|
+
"hdf5-metno-sys",
|
|
12
13
|
"ndarray",
|
|
13
14
|
"numpy",
|
|
14
15
|
"pyo3",
|
|
15
16
|
"rayon",
|
|
17
|
+
"seq-macro",
|
|
16
18
|
"serde",
|
|
17
19
|
"serde_json",
|
|
18
20
|
"tabled",
|
|
@@ -75,9 +77,9 @@ checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e"
|
|
|
75
77
|
|
|
76
78
|
[[package]]
|
|
77
79
|
name = "cc"
|
|
78
|
-
version = "1.4.
|
|
80
|
+
version = "1.4.7"
|
|
79
81
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
80
|
-
checksum = "
|
|
82
|
+
checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313"
|
|
81
83
|
dependencies = [
|
|
82
84
|
"find-msvc-tools",
|
|
83
85
|
"shlex",
|
|
@@ -85,9 +87,9 @@ dependencies = [
|
|
|
85
87
|
|
|
86
88
|
[[package]]
|
|
87
89
|
name = "cfg-if"
|
|
88
|
-
version = "1.0.
|
|
90
|
+
version = "1.0.5"
|
|
89
91
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
90
|
-
checksum = "
|
|
92
|
+
checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
|
|
91
93
|
|
|
92
94
|
[[package]]
|
|
93
95
|
name = "chrono"
|
|
@@ -172,9 +174,9 @@ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
|
|
|
172
174
|
|
|
173
175
|
[[package]]
|
|
174
176
|
name = "find-msvc-tools"
|
|
175
|
-
version = "0.1.
|
|
177
|
+
version = "0.1.13"
|
|
176
178
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
177
|
-
checksum = "
|
|
179
|
+
checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b"
|
|
178
180
|
|
|
179
181
|
[[package]]
|
|
180
182
|
name = "fnv"
|
|
@@ -248,7 +250,7 @@ dependencies = [
|
|
|
248
250
|
"proc-macro-crate",
|
|
249
251
|
"proc-macro2",
|
|
250
252
|
"quote",
|
|
251
|
-
"syn 3.0.
|
|
253
|
+
"syn 3.0.6",
|
|
252
254
|
]
|
|
253
255
|
|
|
254
256
|
[[package]]
|
|
@@ -262,9 +264,9 @@ dependencies = [
|
|
|
262
264
|
|
|
263
265
|
[[package]]
|
|
264
266
|
name = "hdf5-metno-sys"
|
|
265
|
-
version = "0.12.
|
|
267
|
+
version = "0.12.4"
|
|
266
268
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
267
|
-
checksum = "
|
|
269
|
+
checksum = "567a57ee34c38263f551f2cf02b95675def6b91d0e321c5e70f8c6d5ef9cee87"
|
|
268
270
|
dependencies = [
|
|
269
271
|
"hdf5-metno-src",
|
|
270
272
|
"libc",
|
|
@@ -716,9 +718,9 @@ checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
|
|
|
716
718
|
|
|
717
719
|
[[package]]
|
|
718
720
|
name = "rustix"
|
|
719
|
-
version = "1.1.
|
|
721
|
+
version = "1.1.5"
|
|
720
722
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
721
|
-
checksum = "
|
|
723
|
+
checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d"
|
|
722
724
|
dependencies = [
|
|
723
725
|
"bitflags",
|
|
724
726
|
"errno",
|
|
@@ -739,6 +741,12 @@ version = "1.2.0"
|
|
|
739
741
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
740
742
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|
741
743
|
|
|
744
|
+
[[package]]
|
|
745
|
+
name = "seq-macro"
|
|
746
|
+
version = "0.3.6"
|
|
747
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
748
|
+
checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
|
749
|
+
|
|
742
750
|
[[package]]
|
|
743
751
|
name = "serde"
|
|
744
752
|
version = "1.0.229"
|
|
@@ -766,7 +774,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
|
|
766
774
|
dependencies = [
|
|
767
775
|
"proc-macro2",
|
|
768
776
|
"quote",
|
|
769
|
-
"syn 3.0.
|
|
777
|
+
"syn 3.0.6",
|
|
770
778
|
]
|
|
771
779
|
|
|
772
780
|
[[package]]
|
|
@@ -813,9 +821,9 @@ dependencies = [
|
|
|
813
821
|
|
|
814
822
|
[[package]]
|
|
815
823
|
name = "syn"
|
|
816
|
-
version = "3.0.
|
|
824
|
+
version = "3.0.6"
|
|
817
825
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
818
|
-
checksum = "
|
|
826
|
+
checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
|
|
819
827
|
dependencies = [
|
|
820
828
|
"proc-macro2",
|
|
821
829
|
"quote",
|
|
@@ -906,9 +914,9 @@ dependencies = [
|
|
|
906
914
|
|
|
907
915
|
[[package]]
|
|
908
916
|
name = "unicode-ident"
|
|
909
|
-
version = "1.0.
|
|
917
|
+
version = "1.0.26"
|
|
910
918
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
911
|
-
checksum = "
|
|
919
|
+
checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
|
|
912
920
|
|
|
913
921
|
[[package]]
|
|
914
922
|
name = "unicode-width"
|
|
@@ -948,7 +956,7 @@ dependencies = [
|
|
|
948
956
|
"bumpalo",
|
|
949
957
|
"proc-macro2",
|
|
950
958
|
"quote",
|
|
951
|
-
"syn 3.0.
|
|
959
|
+
"syn 3.0.6",
|
|
952
960
|
"wasm-bindgen-shared",
|
|
953
961
|
]
|
|
954
962
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "MNeuEventLib"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
license = "BSD-3-Clause"
|
|
6
6
|
readme = "README.md"
|
|
@@ -12,6 +12,7 @@ crate-type = ["cdylib"]
|
|
|
12
12
|
|
|
13
13
|
[dependencies]
|
|
14
14
|
hdf5 = { package = "hdf5-metno", version = "0.14.1", features = ["static"] }
|
|
15
|
+
hdf5-metno-sys = "0.12.3"
|
|
15
16
|
ndarray = "0.17.2"
|
|
16
17
|
rayon = "1.12.0"
|
|
17
18
|
anyhow = "1.0.102"
|
|
@@ -21,6 +22,7 @@ serde = { version = "1.0.228", features = ["derive"] }
|
|
|
21
22
|
serde_json = "1.0.150"
|
|
22
23
|
chrono = { version = "0.4.45", features = ["std"] }
|
|
23
24
|
tabled = "0.21.0"
|
|
25
|
+
seq-macro = "0.3"
|
|
24
26
|
|
|
25
27
|
[dev-dependencies]
|
|
26
28
|
tempfile = "3.27.0"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import h5py
|
|
2
|
+
import numpy as np
|
|
3
|
+
import shutil
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def replace(f, key, values, dtype):
|
|
7
|
+
"""
|
|
8
|
+
A simple helper method to replace
|
|
9
|
+
a dataset (without attributes)
|
|
10
|
+
"""
|
|
11
|
+
del f[key]
|
|
12
|
+
f.create_dataset(key, data=values, dtype=dtype)
|
|
13
|
+
|
|
14
|
+
def make_single_period_data(multi_period,
|
|
15
|
+
single_period):
|
|
16
|
+
"""
|
|
17
|
+
This is a simple method to convert
|
|
18
|
+
multi-period data into single
|
|
19
|
+
period.
|
|
20
|
+
:param multi_period: the file path
|
|
21
|
+
to the multi-period data.
|
|
22
|
+
:param single_period: the file path
|
|
23
|
+
to write the single period data to
|
|
24
|
+
"""
|
|
25
|
+
shutil.copy(multi_period,
|
|
26
|
+
single_period)
|
|
27
|
+
f = h5py.File(single_period, 'a')
|
|
28
|
+
data = f['raw_data_1']
|
|
29
|
+
tmp = data['detector_1_events']
|
|
30
|
+
N = tmp['period_number'].len()
|
|
31
|
+
zeros = np.zeros(N)
|
|
32
|
+
replace(tmp, 'period_number', zeros, 'int64')
|
|
33
|
+
|
|
34
|
+
tmp = data['periods']
|
|
35
|
+
replace(tmp, 'labels', 'period_1', 'S8')
|
|
36
|
+
|
|
37
|
+
replace(tmp, 'number', 1, 'int32')
|
|
38
|
+
replace(tmp, 'type', [1], 'int32')
|
|
39
|
+
f.close()
|
|
40
|
+
return
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
# MNeuEventLib
|
|
2
|
+
MNeuEventLib is an event data filtering library for ISIS Neutron and Muon Source.
|
|
3
|
+
|
|
4
|
+
## Install from PyPI
|
|
5
|
+
MNeuEventLib can be installed as a pre-compiled binary [from PyPI](https://pypi.org/project/MNeuEventLib/) using
|
|
6
|
+
```
|
|
7
|
+
pip install MNeuEventLib
|
|
8
|
+
```
|
|
9
|
+
|
|
2
10
|
|
|
3
11
|
## Build from source
|
|
4
12
|
MNeuEventLib is built with [`maturin`](https://www.maturin.rs/). Compilation also requires the [`rustup` toolchain](https://rustup.rs/).
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"id": "0ca97a00-642c-47c1-b0fd-e2929d3a56a6",
|
|
89
89
|
"metadata": {},
|
|
90
90
|
"source": [
|
|
91
|
-
"Now, if we calculate our data, we will see in the histogram section of our data that some events have been removed. The full dataset contains
|
|
91
|
+
"Now, if we calculate our data, we will see in the histogram section of our data that some events have been removed. The full dataset contains 64147 events."
|
|
92
92
|
]
|
|
93
93
|
},
|
|
94
94
|
{
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"id": "f76da006-458a-424c-a202-c063407ff1e0",
|
|
107
107
|
"metadata": {},
|
|
108
108
|
"source": [
|
|
109
|
-
"Now if we change the time filter type to `include` and calculate again, we will exclude all data _except_ that between 0.5 and 1.5 seconds. We'd expect our output histogram to have `
|
|
109
|
+
"Now if we change the time filter type to `include` and calculate again, we will exclude all data _except_ that between 0.5 and 1.5 seconds. We'd expect our output histogram to have `64147 - 49048 =` 15099 events, which it does:"
|
|
110
110
|
]
|
|
111
111
|
},
|
|
112
112
|
{
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"id": "2a2ab3f5-0e76-4cba-a9d5-8949334914d3",
|
|
182
182
|
"metadata": {},
|
|
183
183
|
"source": [
|
|
184
|
-
"We can see from the output here that this filtered data has
|
|
184
|
+
"We can see from the output here that this filtered data has 50804 events, as opposed to the full data which had 64147.\n",
|
|
185
185
|
"\n",
|
|
186
186
|
"Note that there are also log filter functions for when you want an unbounded range on one side: \n",
|
|
187
187
|
"- `add_log_filter_above(name, log, lower)` for above;\n",
|
|
@@ -73,6 +73,8 @@
|
|
|
73
73
|
"id": "74f13f07-7b5f-42fa-9082-c6976fceb2d1",
|
|
74
74
|
"metadata": {},
|
|
75
75
|
"source": [
|
|
76
|
+
" The save method will automatically add any missing meta-data to the file with some default values (typically zero). This will produce a file that is compatable with Mantid. To only use the meta-data in the original event file (i.e. not add any missing data) by setting `autofill=False` as an argument to the save method. This may not load correctly into Mantid. \n",
|
|
77
|
+
"\n",
|
|
76
78
|
"## Sample log filtering\n",
|
|
77
79
|
"Converting our event data to a histogram directly is good, but where the event data format really shines is its ability to let us filter out parts of the data that we do not see as relevant. MNeuEventLib allows multiple kinds of filter:\n",
|
|
78
80
|
"- Filters over **time ranges** ('time filters')\n",
|
|
@@ -160,7 +162,7 @@
|
|
|
160
162
|
"id": "5793c76f-0513-4d74-b06b-4c87bb3b73d3",
|
|
161
163
|
"metadata": {},
|
|
162
164
|
"source": [
|
|
163
|
-
"We can see from the output here that this filtered data has
|
|
165
|
+
"We can see from the output here that this filtered data has 50804 events, as opposed to the full data which had 64147."
|
|
164
166
|
]
|
|
165
167
|
},
|
|
166
168
|
{
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
The `muon_ref.nxs` file provides a template for a complete muon V2 nexus file. This is used when saving to create a file that can be used by Mantid, by adding missing meta-data with default values.
|
|
Binary file
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
use crate::data::save::sanitise::nexus_data::{get_period_info, save_default};
|
|
2
|
+
use crate::data::{NexusData, SaveFile, WiMDAFile};
|
|
3
|
+
use crate::filters::Filters;
|
|
4
|
+
use crate::stats::Histogram;
|
|
1
5
|
use anyhow::{Error, Result};
|
|
2
6
|
use numpy::{PyArray3, ToPyArray};
|
|
3
7
|
use pyo3::prelude::{pyclass, pymethods, Borrowed, Bound, FromPyObject, PyAny};
|
|
4
8
|
use pyo3::types::{PyInt, PyString};
|
|
5
|
-
|
|
6
|
-
use crate::data::{NexusData, SaveFile, WiMDAFile};
|
|
7
|
-
use crate::filters::Filters;
|
|
8
|
-
use crate::stats::Histogram;
|
|
9
|
+
use std::path::PathBuf;
|
|
9
10
|
|
|
10
11
|
pub type PyHist<'py> = Bound<'py, PyArray3<i32>>;
|
|
11
12
|
|
|
@@ -88,7 +89,7 @@ impl BatchData {
|
|
|
88
89
|
Ok(BatchData {
|
|
89
90
|
dataset,
|
|
90
91
|
results: (0..n_filter_sets)
|
|
91
|
-
.map(|_| Histogram::new(0
|
|
92
|
+
.map(|_| Histogram::new(0, 32768, 2048))
|
|
92
93
|
.collect(),
|
|
93
94
|
filters: (0..n_filter_sets).map(|_| Filters::new()).collect(),
|
|
94
95
|
data_changed: vec![true; n_filter_sets],
|
|
@@ -148,7 +149,8 @@ impl BatchData {
|
|
|
148
149
|
}
|
|
149
150
|
for i in self.resolve_indices(&index)? {
|
|
150
151
|
self.data_changed[i] = true;
|
|
151
|
-
self.results[i] =
|
|
152
|
+
self.results[i] =
|
|
153
|
+
Histogram::new((min_time * 1e3) as u32, (max_time * 1e3) as u32, n_bins);
|
|
152
154
|
}
|
|
153
155
|
Ok(())
|
|
154
156
|
}
|
|
@@ -351,7 +353,30 @@ impl BatchData {
|
|
|
351
353
|
/// an index number will be appended to each filename.
|
|
352
354
|
/// filename: str
|
|
353
355
|
/// The filename for the saved file.
|
|
354
|
-
|
|
356
|
+
/// default: bool
|
|
357
|
+
/// Whether to use default values for the missing meta-data (this is
|
|
358
|
+
/// needed because the event data files has mistakes/problems).
|
|
359
|
+
/// This allows the file to be read by Mantid even if the event file
|
|
360
|
+
/// is incomplete.
|
|
361
|
+
/// autofill: bool
|
|
362
|
+
/// Whether to use automatically fill the file with
|
|
363
|
+
/// default values for the missing meta-data (this is
|
|
364
|
+
/// needed because the event data files have mistakes/problems).
|
|
365
|
+
/// This allows the file to be read by Mantid even if the event file
|
|
366
|
+
/// is incomplete.
|
|
367
|
+
/// ref_file: str
|
|
368
|
+
/// The reference file for the saved file. (must be a Nexus file)
|
|
369
|
+
/// Contains "correct" data that should be copied to the output file.
|
|
370
|
+
/// This is only need it the reference file needed is not the standard
|
|
371
|
+
/// muon nexus v2 file. The ref_file is generated from tools/make_default.py.
|
|
372
|
+
#[pyo3(signature = (index, filename, autofill=true, ref_file = (PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("files/muon_ref.nxs")).display().to_string()))]
|
|
373
|
+
pub fn save(
|
|
374
|
+
&self,
|
|
375
|
+
index: FilterIndex,
|
|
376
|
+
filename: String,
|
|
377
|
+
autofill: bool,
|
|
378
|
+
ref_file: String,
|
|
379
|
+
) -> Result<()> {
|
|
355
380
|
let filename_stem = if filename.to_lowercase().ends_with(".nxs") {
|
|
356
381
|
filename.clone()[..(filename.len() - 4)].to_string()
|
|
357
382
|
} else {
|
|
@@ -367,6 +392,9 @@ impl BatchData {
|
|
|
367
392
|
}
|
|
368
393
|
let wimda_file = WiMDAFile::new(&self.dataset, &self.filters[i], &self.results[i])?;
|
|
369
394
|
wimda_file.save_file(format!("{filename_stem}.nxs"), &self.dataset.file)?;
|
|
395
|
+
if autofill {
|
|
396
|
+
self.save_nexus(format!("{filename_stem}.nxs"), ref_file.clone())?;
|
|
397
|
+
}
|
|
370
398
|
}
|
|
371
399
|
FilterIndex::All => {
|
|
372
400
|
if self.results.iter().any(|r| r.hist.shape() == [0, 0, 0]) {
|
|
@@ -378,6 +406,9 @@ impl BatchData {
|
|
|
378
406
|
let wimda_file =
|
|
379
407
|
WiMDAFile::new(&self.dataset, &self.filters[i], &self.results[i])?;
|
|
380
408
|
wimda_file.save_file(format!("{filename_stem}_{i}.nxs"), &self.dataset.file)?;
|
|
409
|
+
if autofill {
|
|
410
|
+
self.save_nexus(format!("{filename_stem}_{i}.nxs"), ref_file.clone())?;
|
|
411
|
+
}
|
|
381
412
|
}
|
|
382
413
|
}
|
|
383
414
|
}
|
|
@@ -463,6 +494,38 @@ impl BatchData {
|
|
|
463
494
|
fn n_batches(&self) -> usize {
|
|
464
495
|
self.filters.len()
|
|
465
496
|
}
|
|
497
|
+
|
|
498
|
+
/// Save to a Nexus version 2 file that is compatable with
|
|
499
|
+
/// Mantid using provided reference file for data.
|
|
500
|
+
/// This is needed because the event data files has mistakes/problems.
|
|
501
|
+
///
|
|
502
|
+
/// Parameters
|
|
503
|
+
/// ----------
|
|
504
|
+
/// filename: str
|
|
505
|
+
/// The filename for the saved file.
|
|
506
|
+
/// ref_file: str
|
|
507
|
+
/// The reference file for the saved file. (must be a Nexus file)
|
|
508
|
+
/// Contains "correct" data that should be copied to the output file.
|
|
509
|
+
/// This is only need it the reference file needed is not the standard
|
|
510
|
+
/// muon nexus v2 file. The ref_file is generated from tools/make_default.py.
|
|
511
|
+
pub fn save_nexus(&self, filename: String, ref_file: String) -> Result<()> {
|
|
512
|
+
// 1. Read p_info from input file
|
|
513
|
+
let (periods, dwell) = get_period_info(&self.dataset.filename)?;
|
|
514
|
+
|
|
515
|
+
// 2. Setup shapes map
|
|
516
|
+
let mut shapes = std::collections::HashMap::new();
|
|
517
|
+
let n = self.dataset.n_spec;
|
|
518
|
+
shapes.insert("N".to_string(), n);
|
|
519
|
+
shapes.insert("P".to_string(), periods);
|
|
520
|
+
shapes.insert("NP".to_string(), n * periods);
|
|
521
|
+
shapes.insert("PD".to_string(), periods + dwell);
|
|
522
|
+
shapes.insert("NPD".to_string(), n * (periods + dwell));
|
|
523
|
+
|
|
524
|
+
// 3. Run save_default to merge/copy from ref_file
|
|
525
|
+
save_default(&filename, &ref_file, &shapes)?;
|
|
526
|
+
|
|
527
|
+
Ok(())
|
|
528
|
+
}
|
|
466
529
|
}
|
|
467
530
|
|
|
468
531
|
#[cfg(test)]
|
|
@@ -479,7 +542,7 @@ mod tests {
|
|
|
479
542
|
BatchData {
|
|
480
543
|
dataset,
|
|
481
544
|
results: (0..n_filter_sets)
|
|
482
|
-
.map(|_| Histogram::new(0
|
|
545
|
+
.map(|_| Histogram::new(0, 32768, 2048))
|
|
483
546
|
.collect(),
|
|
484
547
|
filters: (0..n_filter_sets).map(|_| Filters::new()).collect(),
|
|
485
548
|
data_changed: vec![true; n_filter_sets],
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//! Constants.
|
|
2
|
+
|
|
3
|
+
pub const S_TO_NS: f64 = 1e9;
|
|
4
|
+
|
|
5
|
+
pub const NS_TO_US: f32 = 1e-3;
|
|
6
|
+
|
|
7
|
+
pub trait ToMicroseconds {
|
|
8
|
+
fn to_micros(&self) -> f32;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
impl ToMicroseconds for u32 {
|
|
12
|
+
fn to_micros(&self) -> f32 {
|
|
13
|
+
*self as f32 * NS_TO_US
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -269,14 +269,16 @@ mod tests {
|
|
|
269
269
|
use super::*;
|
|
270
270
|
use crate::test_utils::MockData;
|
|
271
271
|
|
|
272
|
-
fn test_data() -> NexusData {
|
|
272
|
+
fn test_data() -> (NexusData, std::sync::MutexGuard<'static, ()>) {
|
|
273
|
+
let guard = crate::test_utils::lock_hdf5_test();
|
|
273
274
|
let path = Path::new("./tests/test_data/HIFI00195790.nxs");
|
|
274
|
-
load_data(path, 64, 1048576).unwrap()
|
|
275
|
+
(load_data(path, 64, 1048576).unwrap(), guard)
|
|
275
276
|
}
|
|
276
277
|
|
|
277
278
|
/// Test the program creates data when you load an existing file.
|
|
278
279
|
#[test]
|
|
279
280
|
fn test_file_load() {
|
|
281
|
+
let _guard = crate::test_utils::lock_hdf5_test();
|
|
280
282
|
let path = Path::new("./tests/test_data/HIFI00195790.nxs");
|
|
281
283
|
let data = load_data(path, 64, 1048576);
|
|
282
284
|
|
|
@@ -294,7 +296,7 @@ mod tests {
|
|
|
294
296
|
/// Test the sample log names are correctly loaded in.
|
|
295
297
|
#[test]
|
|
296
298
|
fn test_sample_log_names() {
|
|
297
|
-
let data = test_data();
|
|
299
|
+
let (data, _guard) = test_data();
|
|
298
300
|
|
|
299
301
|
assert_eq!(data.sample_log_names, vec!("Temp".to_string()))
|
|
300
302
|
}
|
|
@@ -302,7 +304,7 @@ mod tests {
|
|
|
302
304
|
/// Test that an existing sample log can be read successfully.
|
|
303
305
|
#[test]
|
|
304
306
|
fn test_load_sample_log() {
|
|
305
|
-
let data = test_data();
|
|
307
|
+
let (data, _guard) = test_data();
|
|
306
308
|
|
|
307
309
|
let log = data.get_sample_log(&"Temp".to_string());
|
|
308
310
|
assert!(log.is_ok());
|
|
@@ -314,7 +316,7 @@ mod tests {
|
|
|
314
316
|
/// Test that a non-real sample log throws an error.
|
|
315
317
|
#[test]
|
|
316
318
|
fn test_load_sample_log_not_found() {
|
|
317
|
-
let data = test_data();
|
|
319
|
+
let (data, _guard) = test_data();
|
|
318
320
|
|
|
319
321
|
let log = data.get_sample_log(&"Lunch".to_string());
|
|
320
322
|
assert!(log.is_err())
|
|
@@ -357,7 +359,7 @@ mod tests {
|
|
|
357
359
|
/// Test that `__repr__` includes the filename.
|
|
358
360
|
#[test]
|
|
359
361
|
fn test_repr_includes_filename() {
|
|
360
|
-
let data = test_data();
|
|
362
|
+
let (data, _guard) = test_data();
|
|
361
363
|
let repr = data.__repr__();
|
|
362
364
|
assert_eq!(
|
|
363
365
|
repr,
|