jinwurs 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.
@@ -0,0 +1,269 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
10
+
11
+ [[package]]
12
+ name = "cfg-if"
13
+ version = "1.0.4"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
16
+
17
+ [[package]]
18
+ name = "heck"
19
+ version = "0.5.0"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
22
+
23
+ [[package]]
24
+ name = "indoc"
25
+ version = "2.0.7"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
28
+ dependencies = [
29
+ "rustversion",
30
+ ]
31
+
32
+ [[package]]
33
+ name = "jinwurs"
34
+ version = "0.3.0"
35
+ dependencies = [
36
+ "numpy",
37
+ "pyo3",
38
+ ]
39
+
40
+ [[package]]
41
+ name = "libc"
42
+ version = "0.2.186"
43
+ source = "registry+https://github.com/rust-lang/crates.io-index"
44
+ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
45
+
46
+ [[package]]
47
+ name = "matrixmultiply"
48
+ version = "0.3.10"
49
+ source = "registry+https://github.com/rust-lang/crates.io-index"
50
+ checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
51
+ dependencies = [
52
+ "autocfg",
53
+ "rawpointer",
54
+ ]
55
+
56
+ [[package]]
57
+ name = "memoffset"
58
+ version = "0.9.1"
59
+ source = "registry+https://github.com/rust-lang/crates.io-index"
60
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
61
+ dependencies = [
62
+ "autocfg",
63
+ ]
64
+
65
+ [[package]]
66
+ name = "ndarray"
67
+ version = "0.16.1"
68
+ source = "registry+https://github.com/rust-lang/crates.io-index"
69
+ checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841"
70
+ dependencies = [
71
+ "matrixmultiply",
72
+ "num-complex",
73
+ "num-integer",
74
+ "num-traits",
75
+ "portable-atomic",
76
+ "portable-atomic-util",
77
+ "rawpointer",
78
+ ]
79
+
80
+ [[package]]
81
+ name = "num-complex"
82
+ version = "0.4.6"
83
+ source = "registry+https://github.com/rust-lang/crates.io-index"
84
+ checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
85
+ dependencies = [
86
+ "num-traits",
87
+ ]
88
+
89
+ [[package]]
90
+ name = "num-integer"
91
+ version = "0.1.46"
92
+ source = "registry+https://github.com/rust-lang/crates.io-index"
93
+ checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
94
+ dependencies = [
95
+ "num-traits",
96
+ ]
97
+
98
+ [[package]]
99
+ name = "num-traits"
100
+ version = "0.2.19"
101
+ source = "registry+https://github.com/rust-lang/crates.io-index"
102
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
103
+ dependencies = [
104
+ "autocfg",
105
+ ]
106
+
107
+ [[package]]
108
+ name = "numpy"
109
+ version = "0.23.0"
110
+ source = "registry+https://github.com/rust-lang/crates.io-index"
111
+ checksum = "b94caae805f998a07d33af06e6a3891e38556051b8045c615470a71590e13e78"
112
+ dependencies = [
113
+ "libc",
114
+ "ndarray",
115
+ "num-complex",
116
+ "num-integer",
117
+ "num-traits",
118
+ "pyo3",
119
+ "rustc-hash",
120
+ ]
121
+
122
+ [[package]]
123
+ name = "once_cell"
124
+ version = "1.21.4"
125
+ source = "registry+https://github.com/rust-lang/crates.io-index"
126
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
127
+
128
+ [[package]]
129
+ name = "portable-atomic"
130
+ version = "1.13.1"
131
+ source = "registry+https://github.com/rust-lang/crates.io-index"
132
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
133
+
134
+ [[package]]
135
+ name = "portable-atomic-util"
136
+ version = "0.2.7"
137
+ source = "registry+https://github.com/rust-lang/crates.io-index"
138
+ checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
139
+ dependencies = [
140
+ "portable-atomic",
141
+ ]
142
+
143
+ [[package]]
144
+ name = "proc-macro2"
145
+ version = "1.0.106"
146
+ source = "registry+https://github.com/rust-lang/crates.io-index"
147
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
148
+ dependencies = [
149
+ "unicode-ident",
150
+ ]
151
+
152
+ [[package]]
153
+ name = "pyo3"
154
+ version = "0.23.5"
155
+ source = "registry+https://github.com/rust-lang/crates.io-index"
156
+ checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872"
157
+ dependencies = [
158
+ "cfg-if",
159
+ "indoc",
160
+ "libc",
161
+ "memoffset",
162
+ "once_cell",
163
+ "portable-atomic",
164
+ "pyo3-build-config",
165
+ "pyo3-ffi",
166
+ "pyo3-macros",
167
+ "unindent",
168
+ ]
169
+
170
+ [[package]]
171
+ name = "pyo3-build-config"
172
+ version = "0.23.5"
173
+ source = "registry+https://github.com/rust-lang/crates.io-index"
174
+ checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb"
175
+ dependencies = [
176
+ "once_cell",
177
+ "target-lexicon",
178
+ ]
179
+
180
+ [[package]]
181
+ name = "pyo3-ffi"
182
+ version = "0.23.5"
183
+ source = "registry+https://github.com/rust-lang/crates.io-index"
184
+ checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d"
185
+ dependencies = [
186
+ "libc",
187
+ "pyo3-build-config",
188
+ ]
189
+
190
+ [[package]]
191
+ name = "pyo3-macros"
192
+ version = "0.23.5"
193
+ source = "registry+https://github.com/rust-lang/crates.io-index"
194
+ checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da"
195
+ dependencies = [
196
+ "proc-macro2",
197
+ "pyo3-macros-backend",
198
+ "quote",
199
+ "syn",
200
+ ]
201
+
202
+ [[package]]
203
+ name = "pyo3-macros-backend"
204
+ version = "0.23.5"
205
+ source = "registry+https://github.com/rust-lang/crates.io-index"
206
+ checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028"
207
+ dependencies = [
208
+ "heck",
209
+ "proc-macro2",
210
+ "pyo3-build-config",
211
+ "quote",
212
+ "syn",
213
+ ]
214
+
215
+ [[package]]
216
+ name = "quote"
217
+ version = "1.0.45"
218
+ source = "registry+https://github.com/rust-lang/crates.io-index"
219
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
220
+ dependencies = [
221
+ "proc-macro2",
222
+ ]
223
+
224
+ [[package]]
225
+ name = "rawpointer"
226
+ version = "0.2.1"
227
+ source = "registry+https://github.com/rust-lang/crates.io-index"
228
+ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
229
+
230
+ [[package]]
231
+ name = "rustc-hash"
232
+ version = "2.1.2"
233
+ source = "registry+https://github.com/rust-lang/crates.io-index"
234
+ checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
235
+
236
+ [[package]]
237
+ name = "rustversion"
238
+ version = "1.0.22"
239
+ source = "registry+https://github.com/rust-lang/crates.io-index"
240
+ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
241
+
242
+ [[package]]
243
+ name = "syn"
244
+ version = "2.0.118"
245
+ source = "registry+https://github.com/rust-lang/crates.io-index"
246
+ checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
247
+ dependencies = [
248
+ "proc-macro2",
249
+ "quote",
250
+ "unicode-ident",
251
+ ]
252
+
253
+ [[package]]
254
+ name = "target-lexicon"
255
+ version = "0.12.16"
256
+ source = "registry+https://github.com/rust-lang/crates.io-index"
257
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
258
+
259
+ [[package]]
260
+ name = "unicode-ident"
261
+ version = "1.0.24"
262
+ source = "registry+https://github.com/rust-lang/crates.io-index"
263
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
264
+
265
+ [[package]]
266
+ name = "unindent"
267
+ version = "0.2.4"
268
+ source = "registry+https://github.com/rust-lang/crates.io-index"
269
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
@@ -0,0 +1,16 @@
1
+ [package]
2
+ name = "jinwurs"
3
+ version = "0.3.0"
4
+ edition = "2021"
5
+ description = "Rust-accelerated kernels for jinwu — fast rebinning and X-ray statistics"
6
+ license = "GPL-3.0-or-later"
7
+ repository = "https://github.com/xinxiangsun/JinWu"
8
+ readme = "README.md"
9
+
10
+ [lib]
11
+ name = "jinwurs"
12
+ crate-type = ["cdylib"]
13
+
14
+ [dependencies]
15
+ pyo3 = { version = "0.23", features = ["extension-module", "abi3-py311"] }
16
+ numpy = "0.23"
jinwurs-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,28 @@
1
+ Metadata-Version: 2.4
2
+ Name: jinwurs
3
+ Version: 0.3.0
4
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
5
+ Classifier: Programming Language :: Python :: 3
6
+ Classifier: Programming Language :: Python :: 3 :: Only
7
+ Classifier: Programming Language :: Python :: 3.11
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Classifier: Programming Language :: Rust
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
13
+ Requires-Dist: numpy>=1.24
14
+ Summary: Rust-accelerated kernels for jinwu — fast rebinning and X-ray statistics
15
+ Keywords: astrophysics,transient,x-ray,rebinning,statistics
16
+ Author-email: Xinxiang Sun <sunxx@nao.cas.cn>
17
+ License: GPL-3.0-or-later
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
20
+ Project-URL: Homepage, https://github.com/xinxiangsun/JinWu
21
+ Project-URL: Repository, https://github.com/xinxiangsun/JinWu
22
+
23
+ # jinwurs
24
+
25
+ Rust-accelerated kernels for [JinWu](https://github.com/xinxiangsun/JinWu) — fast rebinning and X-ray statistics.
26
+
27
+ Provides high-performance Rust implementations of core algorithms used in X-ray and gamma-ray astronomy data analysis, exposed as Python extension modules via PyO3.
28
+
@@ -0,0 +1,5 @@
1
+ # jinwurs
2
+
3
+ Rust-accelerated kernels for [JinWu](https://github.com/xinxiangsun/JinWu) — fast rebinning and X-ray statistics.
4
+
5
+ Provides high-performance Rust implementations of core algorithms used in X-ray and gamma-ray astronomy data analysis, exposed as Python extension modules via PyO3.
@@ -0,0 +1,39 @@
1
+ {% set name = "jinwurs" %}
2
+ {% set version = "0.3.0" %}
3
+
4
+ package:
5
+ name: {{ name|lower }}
6
+ version: {{ version }}
7
+
8
+ source:
9
+ url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/jinwurs-{{ version }}.tar.gz
10
+ # No jinwurs 0.3.0 sdist is published; this recipe is not yet submit-ready.
11
+ sha256: placeholder
12
+
13
+ build:
14
+ number: 0
15
+ # ⚠️ 不能 noarch — Rust .so 是平台相关的
16
+ script: {{ PYTHON }} -m pip install . -vv
17
+
18
+ requirements:
19
+ build:
20
+ - {{ compiler('rust') }}
21
+ - maturin >=1.0
22
+ host:
23
+ - python
24
+ - pip
25
+ - maturin
26
+ run:
27
+ - python
28
+
29
+ test:
30
+ imports:
31
+ - jinwurs
32
+ commands:
33
+ - pip check
34
+
35
+ about:
36
+ home: https://github.com/xinxiangsun/jinwu
37
+ license: GPL-3.0-or-later
38
+ license_file: LICENSE
39
+ summary: Rust-accelerated kernels for jinwu — fast rebinning & statistics
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["maturin>=1.5"]
3
+ build-backend = "maturin"
4
+
5
+ [project]
6
+ name = "jinwurs"
7
+ version = "0.3.0"
8
+ description = "Rust-accelerated kernels for jinwu — fast rebinning and X-ray statistics"
9
+ readme = "README.md"
10
+ license = { text = "GPL-3.0-or-later" }
11
+ authors = [
12
+ { name = "Xinxiang Sun", email = "sunxx@nao.cas.cn" }
13
+ ]
14
+ requires-python = ">=3.11"
15
+ dependencies = ["numpy>=1.24"]
16
+ keywords = ["astrophysics", "transient", "x-ray", "rebinning", "statistics"]
17
+ classifiers = [
18
+ "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Programming Language :: Rust",
25
+ "Intended Audience :: Science/Research",
26
+ "Topic :: Scientific/Engineering :: Astronomy",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://github.com/xinxiangsun/JinWu"
31
+ Repository = "https://github.com/xinxiangsun/JinWu"
32
+
33
+ [tool.maturin]
34
+ manifest-path = "Cargo.toml"
35
+ features = ["pyo3/extension-module", "pyo3/abi3-py311"]
36
+ bindings = "pyo3"
@@ -0,0 +1,127 @@
1
+ //! jinwurs — Rust-accelerated kernels for jinwu
2
+
3
+ use numpy::{PyArray1, PyReadonlyArray1};
4
+ use pyo3::prelude::*;
5
+
6
+ /// Core rebinning: distribute original-bin counts into new uniform bins.
7
+ #[pyfunction]
8
+ #[pyo3(signature = (orig_counts, orig_errors, orig_left, orig_right, orig_width, orig_exposure, new_edges))]
9
+ fn rebin_counts_core<'py>(
10
+ py: Python<'py>,
11
+ orig_counts: PyReadonlyArray1<'py, f64>,
12
+ orig_errors: Option<PyReadonlyArray1<'py, f64>>,
13
+ orig_left: PyReadonlyArray1<'py, f64>,
14
+ orig_right: PyReadonlyArray1<'py, f64>,
15
+ orig_width: PyReadonlyArray1<'py, f64>,
16
+ orig_exposure: Option<PyReadonlyArray1<'py, f64>>,
17
+ new_edges: PyReadonlyArray1<'py, f64>,
18
+ ) -> (Py<PyArray1<f64>>, Py<PyArray1<f64>>, Py<PyArray1<f64>>) {
19
+ let oc = orig_counts.as_slice().unwrap();
20
+ let ol = orig_left.as_slice().unwrap();
21
+ let or_ = orig_right.as_slice().unwrap();
22
+ let ow = orig_width.as_slice().unwrap();
23
+ let ne = new_edges.as_slice().unwrap();
24
+
25
+ let oe: Option<&[f64]> = orig_errors.as_ref().map(|a| a.as_slice().unwrap());
26
+ let oexpo: Option<&[f64]> = orig_exposure.as_ref().map(|a| a.as_slice().unwrap());
27
+
28
+ let n_orig = oc.len();
29
+ let m = ne.len().saturating_sub(1);
30
+ let have_exposure = oexpo.is_some();
31
+
32
+ let mut counts = vec![0.0_f64; m];
33
+ let mut var = vec![0.0_f64; m];
34
+ let mut exposure = vec![0.0_f64; m];
35
+
36
+ for i in 0..n_orig {
37
+ let a = ol[i];
38
+ let b = or_[i];
39
+ if b <= ne[0] || a >= ne[m] {
40
+ continue;
41
+ }
42
+
43
+ // binary search for overlapping new-bin range
44
+ let j0 = ne.partition_point(|&e| e <= a).saturating_sub(1);
45
+ let j1 = ne.partition_point(|&e| e < b).saturating_sub(1);
46
+ let j0 = j0.min(m.saturating_sub(1));
47
+ let j1 = j1.min(m.saturating_sub(1));
48
+
49
+ let owi = ow[i];
50
+ let ci = oc[i];
51
+ let ei = oe.map(|e| e[i]).unwrap_or_else(|| ci.max(0.0).sqrt());
52
+
53
+ for j in j0..=j1 {
54
+ let new_l = ne[j];
55
+ let new_r = ne[j + 1];
56
+ let overlap = (b.min(new_r) - a.max(new_l)).max(0.0);
57
+ if overlap <= 0.0 {
58
+ continue;
59
+ }
60
+ let frac = overlap / owi;
61
+ let contrib = ci * frac;
62
+ counts[j] += contrib;
63
+ var[j] += (ei * frac).powi(2);
64
+
65
+ if have_exposure {
66
+ exposure[j] += oexpo.unwrap()[i] * frac;
67
+ } else {
68
+ exposure[j] += overlap;
69
+ }
70
+ }
71
+ }
72
+
73
+ let c = PyArray1::from_vec(py, counts).unbind();
74
+ let v = PyArray1::from_vec(py, var).unbind();
75
+ let e = PyArray1::from_vec(py, exposure).unbind();
76
+ (c, v, e)
77
+ }
78
+
79
+ /// Finalize rebinned counts into counts space or rate space.
80
+ #[pyfunction]
81
+ fn rebin_finalize<'py>(
82
+ py: Python<'py>,
83
+ counts: PyReadonlyArray1<'py, f64>,
84
+ var: PyReadonlyArray1<'py, f64>,
85
+ exposure: PyReadonlyArray1<'py, f64>,
86
+ method: &str,
87
+ empty_nan: bool,
88
+ ) -> (Py<PyArray1<f64>>, Py<PyArray1<f64>>) {
89
+ let c = counts.as_slice().unwrap();
90
+ let v = var.as_slice().unwrap();
91
+ let e = exposure.as_slice().unwrap();
92
+ let m = c.len();
93
+
94
+ let mut value = vec![0.0_f64; m];
95
+ let mut error = vec![0.0_f64; m];
96
+
97
+ if method == "sum" {
98
+ for j in 0..m {
99
+ value[j] = c[j];
100
+ error[j] = v[j].sqrt();
101
+ }
102
+ } else {
103
+ for j in 0..m {
104
+ let denom = if e[j] > 0.0 { e[j] } else { f64::NAN };
105
+ value[j] = c[j] / denom;
106
+ error[j] = v[j].sqrt() / denom;
107
+ }
108
+ }
109
+
110
+ if empty_nan {
111
+ for j in 0..m {
112
+ if e[j] == 0.0 {
113
+ value[j] = f64::NAN;
114
+ error[j] = f64::NAN;
115
+ }
116
+ }
117
+ }
118
+
119
+ (PyArray1::from_vec(py, value).unbind(), PyArray1::from_vec(py, error).unbind())
120
+ }
121
+
122
+ #[pymodule]
123
+ fn jinwurs(m: &Bound<'_, PyModule>) -> PyResult<()> {
124
+ m.add_function(wrap_pyfunction!(rebin_counts_core, m)?)?;
125
+ m.add_function(wrap_pyfunction!(rebin_finalize, m)?)?;
126
+ Ok(())
127
+ }