pg-phenotype 0.1.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.
- pg_phenotype-0.1.0/Cargo.lock +316 -0
- pg_phenotype-0.1.0/Cargo.toml +22 -0
- pg_phenotype-0.1.0/LICENSE +21 -0
- pg_phenotype-0.1.0/PKG-INFO +153 -0
- pg_phenotype-0.1.0/README.md +121 -0
- pg_phenotype-0.1.0/crates/core/Cargo.toml +17 -0
- pg_phenotype-0.1.0/crates/core/examples/am_bench.rs +79 -0
- pg_phenotype-0.1.0/crates/core/examples/prep_bench.rs +47 -0
- pg_phenotype-0.1.0/crates/core/examples/score_bench.rs +90 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/bootstrap.rs +666 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/bvn.rs +85 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/cephes.rs +613 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/estimators.rs +423 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/fit.rs +214 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/input.rs +345 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/kernels.rs +1082 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/mod.rs +514 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/permutation.rs +634 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/primitives_parity.rs +100 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/result.rs +379 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/rng.rs +88 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/sample.rs +300 -0
- pg_phenotype-0.1.0/crates/core/src/assortative/sandwich.rs +326 -0
- pg_phenotype-0.1.0/crates/core/src/error.rs +388 -0
- pg_phenotype-0.1.0/crates/core/src/input.rs +76 -0
- pg_phenotype-0.1.0/crates/core/src/lib.rs +49 -0
- pg_phenotype-0.1.0/crates/core/src/lineage.rs +149 -0
- pg_phenotype-0.1.0/crates/core/src/normal.rs +296 -0
- pg_phenotype-0.1.0/crates/core/src/pafgrs/biv.rs +291 -0
- pg_phenotype-0.1.0/crates/core/src/pafgrs/cip.rs +266 -0
- pg_phenotype-0.1.0/crates/core/src/pafgrs/mod.rs +18 -0
- pg_phenotype-0.1.0/crates/core/src/pafgrs/order.rs +64 -0
- pg_phenotype-0.1.0/crates/core/src/pafgrs/pa.rs +55 -0
- pg_phenotype-0.1.0/crates/core/src/pafgrs/prep.rs +764 -0
- pg_phenotype-0.1.0/crates/core/src/pafgrs/triangle.rs +92 -0
- pg_phenotype-0.1.0/crates/core/src/pafgrs/uni.rs +170 -0
- pg_phenotype-0.1.0/crates/core/tests/pg_composition.rs +69 -0
- pg_phenotype-0.1.0/crates/python/Cargo.toml +23 -0
- pg_phenotype-0.1.0/crates/python/src/assortative.rs +258 -0
- pg_phenotype-0.1.0/crates/python/src/lib.rs +314 -0
- pg_phenotype-0.1.0/crates/python/src/test_hooks.rs +13 -0
- pg_phenotype-0.1.0/pg_phenotype/__init__.py +36 -0
- pg_phenotype-0.1.0/pg_phenotype/_errors.py +47 -0
- pg_phenotype-0.1.0/pg_phenotype/_input.py +119 -0
- pg_phenotype-0.1.0/pg_phenotype/_native.pyi +81 -0
- pg_phenotype-0.1.0/pg_phenotype/_threads.py +116 -0
- pg_phenotype-0.1.0/pg_phenotype/_trait.py +123 -0
- pg_phenotype-0.1.0/pg_phenotype/assortative.py +372 -0
- pg_phenotype-0.1.0/pg_phenotype/pafgrs.py +243 -0
- pg_phenotype-0.1.0/pg_phenotype/py.typed +0 -0
- pg_phenotype-0.1.0/pyproject.toml +101 -0
|
@@ -0,0 +1,316 @@
|
|
|
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 = "crossbeam-deque"
|
|
13
|
+
version = "0.8.8"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a"
|
|
16
|
+
dependencies = [
|
|
17
|
+
"crossbeam-epoch",
|
|
18
|
+
"crossbeam-utils",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[[package]]
|
|
22
|
+
name = "crossbeam-epoch"
|
|
23
|
+
version = "0.9.21"
|
|
24
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
25
|
+
checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d"
|
|
26
|
+
dependencies = [
|
|
27
|
+
"crossbeam-utils",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[[package]]
|
|
31
|
+
name = "crossbeam-utils"
|
|
32
|
+
version = "0.8.23"
|
|
33
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
34
|
+
checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6"
|
|
35
|
+
|
|
36
|
+
[[package]]
|
|
37
|
+
name = "either"
|
|
38
|
+
version = "1.19.0"
|
|
39
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
40
|
+
checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be"
|
|
41
|
+
|
|
42
|
+
[[package]]
|
|
43
|
+
name = "heck"
|
|
44
|
+
version = "0.5.0"
|
|
45
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
46
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
47
|
+
|
|
48
|
+
[[package]]
|
|
49
|
+
name = "libc"
|
|
50
|
+
version = "0.2.190"
|
|
51
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
52
|
+
checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78"
|
|
53
|
+
|
|
54
|
+
[[package]]
|
|
55
|
+
name = "libm"
|
|
56
|
+
version = "0.2.16"
|
|
57
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
58
|
+
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
|
59
|
+
|
|
60
|
+
[[package]]
|
|
61
|
+
name = "matrixmultiply"
|
|
62
|
+
version = "0.3.11"
|
|
63
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
64
|
+
checksum = "3f607c237553f086e7043417a51df26b2eb899d3caff94e6a67592ff992fedc7"
|
|
65
|
+
dependencies = [
|
|
66
|
+
"autocfg",
|
|
67
|
+
"rawpointer",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[[package]]
|
|
71
|
+
name = "ndarray"
|
|
72
|
+
version = "0.17.2"
|
|
73
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
74
|
+
checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d"
|
|
75
|
+
dependencies = [
|
|
76
|
+
"matrixmultiply",
|
|
77
|
+
"num-complex",
|
|
78
|
+
"num-integer",
|
|
79
|
+
"num-traits",
|
|
80
|
+
"portable-atomic",
|
|
81
|
+
"portable-atomic-util",
|
|
82
|
+
"rawpointer",
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
[[package]]
|
|
86
|
+
name = "num-bigint"
|
|
87
|
+
version = "0.4.8"
|
|
88
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
89
|
+
checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367"
|
|
90
|
+
dependencies = [
|
|
91
|
+
"num-integer",
|
|
92
|
+
"num-traits",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
[[package]]
|
|
96
|
+
name = "num-complex"
|
|
97
|
+
version = "0.4.6"
|
|
98
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
99
|
+
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
|
100
|
+
dependencies = [
|
|
101
|
+
"num-traits",
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[[package]]
|
|
105
|
+
name = "num-integer"
|
|
106
|
+
version = "0.1.47"
|
|
107
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
108
|
+
checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b"
|
|
109
|
+
dependencies = [
|
|
110
|
+
"num-traits",
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
[[package]]
|
|
114
|
+
name = "num-traits"
|
|
115
|
+
version = "0.2.19"
|
|
116
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
117
|
+
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
|
118
|
+
dependencies = [
|
|
119
|
+
"autocfg",
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
[[package]]
|
|
123
|
+
name = "numpy"
|
|
124
|
+
version = "0.29.0"
|
|
125
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
126
|
+
checksum = "6a5b15d63a5ff39e378daed0e1340d3a5964703ea9712eb09a0dc66fade996f4"
|
|
127
|
+
dependencies = [
|
|
128
|
+
"libc",
|
|
129
|
+
"ndarray",
|
|
130
|
+
"num-complex",
|
|
131
|
+
"num-integer",
|
|
132
|
+
"num-traits",
|
|
133
|
+
"pyo3",
|
|
134
|
+
"pyo3-build-config",
|
|
135
|
+
"rustc-hash",
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
[[package]]
|
|
139
|
+
name = "once_cell"
|
|
140
|
+
version = "1.21.4"
|
|
141
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
142
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
143
|
+
|
|
144
|
+
[[package]]
|
|
145
|
+
name = "pedigree-graph-core"
|
|
146
|
+
version = "0.12.2"
|
|
147
|
+
source = "git+https://github.com/rwaples/pedigree-graph?rev=62c82fa6468aec0f579dc9286c5dbebe7d077500#62c82fa6468aec0f579dc9286c5dbebe7d077500"
|
|
148
|
+
dependencies = [
|
|
149
|
+
"num-bigint",
|
|
150
|
+
"num-integer",
|
|
151
|
+
"num-traits",
|
|
152
|
+
"rayon",
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
[[package]]
|
|
156
|
+
name = "pg-phenotype-core"
|
|
157
|
+
version = "0.1.0"
|
|
158
|
+
dependencies = [
|
|
159
|
+
"libm",
|
|
160
|
+
"pedigree-graph-core",
|
|
161
|
+
"rayon",
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
[[package]]
|
|
165
|
+
name = "pg-phenotype-python"
|
|
166
|
+
version = "0.1.0"
|
|
167
|
+
dependencies = [
|
|
168
|
+
"numpy",
|
|
169
|
+
"pg-phenotype-core",
|
|
170
|
+
"pyo3",
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
[[package]]
|
|
174
|
+
name = "portable-atomic"
|
|
175
|
+
version = "1.15.0"
|
|
176
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
177
|
+
checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
|
|
178
|
+
|
|
179
|
+
[[package]]
|
|
180
|
+
name = "portable-atomic-util"
|
|
181
|
+
version = "0.2.8"
|
|
182
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
183
|
+
checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715"
|
|
184
|
+
dependencies = [
|
|
185
|
+
"portable-atomic",
|
|
186
|
+
]
|
|
187
|
+
|
|
188
|
+
[[package]]
|
|
189
|
+
name = "proc-macro2"
|
|
190
|
+
version = "1.0.107"
|
|
191
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
192
|
+
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
|
193
|
+
dependencies = [
|
|
194
|
+
"unicode-ident",
|
|
195
|
+
]
|
|
196
|
+
|
|
197
|
+
[[package]]
|
|
198
|
+
name = "pyo3"
|
|
199
|
+
version = "0.29.3"
|
|
200
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
201
|
+
checksum = "700d18fa267b73b9b521fd7e13580e2f446916f176cacee1ab63fcc8191f1655"
|
|
202
|
+
dependencies = [
|
|
203
|
+
"libc",
|
|
204
|
+
"once_cell",
|
|
205
|
+
"portable-atomic",
|
|
206
|
+
"pyo3-build-config",
|
|
207
|
+
"pyo3-ffi",
|
|
208
|
+
"pyo3-macros",
|
|
209
|
+
]
|
|
210
|
+
|
|
211
|
+
[[package]]
|
|
212
|
+
name = "pyo3-build-config"
|
|
213
|
+
version = "0.29.3"
|
|
214
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
215
|
+
checksum = "7b3fc0c4d08f6bb10e71fe39dfb9e2f59c6eb6854e22ec8092f50c69a4499adb"
|
|
216
|
+
dependencies = [
|
|
217
|
+
"target-lexicon",
|
|
218
|
+
]
|
|
219
|
+
|
|
220
|
+
[[package]]
|
|
221
|
+
name = "pyo3-ffi"
|
|
222
|
+
version = "0.29.3"
|
|
223
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
224
|
+
checksum = "dfc0b8e19df29aad7086cf977bb0c2a2f143e30567eb113e9cf72b62ca698330"
|
|
225
|
+
dependencies = [
|
|
226
|
+
"libc",
|
|
227
|
+
"pyo3-build-config",
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
[[package]]
|
|
231
|
+
name = "pyo3-macros"
|
|
232
|
+
version = "0.29.3"
|
|
233
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
234
|
+
checksum = "6100e8a4b5eba53afaa5ed078364851a0b2499c553a44c31026b929049b49dc6"
|
|
235
|
+
dependencies = [
|
|
236
|
+
"proc-macro2",
|
|
237
|
+
"pyo3-macros-backend",
|
|
238
|
+
"quote",
|
|
239
|
+
"syn",
|
|
240
|
+
]
|
|
241
|
+
|
|
242
|
+
[[package]]
|
|
243
|
+
name = "pyo3-macros-backend"
|
|
244
|
+
version = "0.29.3"
|
|
245
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
246
|
+
checksum = "6143877a16e82b5a727b7127ff4cd86858a24a28d745d72f43e6f227c7b1bdb3"
|
|
247
|
+
dependencies = [
|
|
248
|
+
"heck",
|
|
249
|
+
"proc-macro2",
|
|
250
|
+
"quote",
|
|
251
|
+
"syn",
|
|
252
|
+
]
|
|
253
|
+
|
|
254
|
+
[[package]]
|
|
255
|
+
name = "quote"
|
|
256
|
+
version = "1.0.47"
|
|
257
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
258
|
+
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
|
259
|
+
dependencies = [
|
|
260
|
+
"proc-macro2",
|
|
261
|
+
]
|
|
262
|
+
|
|
263
|
+
[[package]]
|
|
264
|
+
name = "rawpointer"
|
|
265
|
+
version = "0.2.1"
|
|
266
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
267
|
+
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
|
268
|
+
|
|
269
|
+
[[package]]
|
|
270
|
+
name = "rayon"
|
|
271
|
+
version = "1.12.0"
|
|
272
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
273
|
+
checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
|
|
274
|
+
dependencies = [
|
|
275
|
+
"either",
|
|
276
|
+
"rayon-core",
|
|
277
|
+
]
|
|
278
|
+
|
|
279
|
+
[[package]]
|
|
280
|
+
name = "rayon-core"
|
|
281
|
+
version = "1.13.0"
|
|
282
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
283
|
+
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
|
284
|
+
dependencies = [
|
|
285
|
+
"crossbeam-deque",
|
|
286
|
+
"crossbeam-utils",
|
|
287
|
+
]
|
|
288
|
+
|
|
289
|
+
[[package]]
|
|
290
|
+
name = "rustc-hash"
|
|
291
|
+
version = "2.1.3"
|
|
292
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
293
|
+
checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
|
|
294
|
+
|
|
295
|
+
[[package]]
|
|
296
|
+
name = "syn"
|
|
297
|
+
version = "2.0.119"
|
|
298
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
299
|
+
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
|
300
|
+
dependencies = [
|
|
301
|
+
"proc-macro2",
|
|
302
|
+
"quote",
|
|
303
|
+
"unicode-ident",
|
|
304
|
+
]
|
|
305
|
+
|
|
306
|
+
[[package]]
|
|
307
|
+
name = "target-lexicon"
|
|
308
|
+
version = "0.13.5"
|
|
309
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
310
|
+
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
311
|
+
|
|
312
|
+
[[package]]
|
|
313
|
+
name = "unicode-ident"
|
|
314
|
+
version = "1.0.26"
|
|
315
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
316
|
+
checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[workspace]
|
|
2
|
+
resolver = "2"
|
|
3
|
+
members = ["crates/core", "crates/python"]
|
|
4
|
+
|
|
5
|
+
[workspace.package]
|
|
6
|
+
version = "0.1.0"
|
|
7
|
+
edition = "2021"
|
|
8
|
+
# pedigree-graph-core's floor; the R binding crate states the same.
|
|
9
|
+
rust-version = "1.85"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
repository = "https://github.com/rwaples/pg-phenotype"
|
|
12
|
+
|
|
13
|
+
[workspace.dependencies]
|
|
14
|
+
# Re-pinned on purpose only (ADR 0001): pg-core is unpublished until 1.0.
|
|
15
|
+
# This rev is pedigree-graph v0.12.2.
|
|
16
|
+
pedigree-graph-core = { git = "https://github.com/rwaples/pedigree-graph", rev = "62c82fa6468aec0f579dc9286c5dbebe7d077500" }
|
|
17
|
+
rayon = "1.10"
|
|
18
|
+
|
|
19
|
+
[profile.release]
|
|
20
|
+
opt-level = 3
|
|
21
|
+
debug = 1
|
|
22
|
+
codegen-units = 1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ryan Waples
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pg-phenotype
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Development Status :: 3 - Alpha
|
|
5
|
+
Classifier: Intended Audience :: Science/Research
|
|
6
|
+
Classifier: Operating System :: OS Independent
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
10
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
11
|
+
Requires-Dist: numpy>=2.2,<3
|
|
12
|
+
Requires-Dist: scipy>=1.14,<2 ; extra == 'test'
|
|
13
|
+
Requires-Dist: pedigree-graph>=0.12.2,<0.13 ; extra == 'test'
|
|
14
|
+
Requires-Dist: pytest>=9,<10 ; extra == 'test'
|
|
15
|
+
Requires-Dist: pytest-xdist>=3.8,<4 ; extra == 'test'
|
|
16
|
+
Requires-Dist: ruff>=0.16,<0.17 ; extra == 'test'
|
|
17
|
+
Requires-Dist: hypothesis>=6,<7 ; extra == 'test'
|
|
18
|
+
Requires-Dist: pandas>=3.0,<4 ; extra == 'test'
|
|
19
|
+
Requires-Dist: polars>=1.43.2,<2 ; extra == 'test'
|
|
20
|
+
Requires-Dist: ty==0.0.84 ; extra == 'typecheck'
|
|
21
|
+
Provides-Extra: test
|
|
22
|
+
Provides-Extra: typecheck
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Summary: Phenotypes in the context of a pedigree, on pedigree-graph's Rust core: PA-FGRS and more
|
|
25
|
+
Author: Ryan Waples
|
|
26
|
+
License-Expression: MIT
|
|
27
|
+
Requires-Python: >=3.13
|
|
28
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
29
|
+
Project-URL: Homepage, https://github.com/rwaples/pg-phenotype
|
|
30
|
+
Project-URL: Repository, https://github.com/rwaples/pg-phenotype
|
|
31
|
+
|
|
32
|
+
# pg-phenotype
|
|
33
|
+
|
|
34
|
+
Phenotypes in the context of a pedigree, as an extension of
|
|
35
|
+
[pedigree-graph](https://github.com/rwaples/pedigree-graph): a Rust core with
|
|
36
|
+
Python and R bindings. Relationships and kinship come from pedigree-graph's
|
|
37
|
+
core; each method is a module on top.
|
|
38
|
+
|
|
39
|
+
| Method | Module | Status |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| PA-FGRS family genetic risk scores (Dybdahl Krebs et al., Am J Hum Genet 2024, doi:10.1016/j.ajhg.2024.09.009) | `pg_phenotype.pafgrs` | available |
|
|
42
|
+
| Assortative mating: the Mate Correlation of one or two traits, ported from pedsum #13 | `pg_phenotype.assortative` | available |
|
|
43
|
+
|
|
44
|
+
## Python
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import pg_phenotype as pgp
|
|
48
|
+
from pg_phenotype import pafgrs
|
|
49
|
+
|
|
50
|
+
trait = pgp.Trait(dx, kind="binary") # one value per pedigree row
|
|
51
|
+
prep = pafgrs.prepare(pedigree, ndegree=2) # once per pedigree
|
|
52
|
+
cip = pafgrs.Cip(ages, cip_values) # K is the last value
|
|
53
|
+
scores = pafgrs.score_univariate(prep, trait, age=dx_age, cip=cip, h2=0.4)
|
|
54
|
+
scores.est, scores.var, scores.n_relatives, scores.metadata
|
|
55
|
+
|
|
56
|
+
both = pafgrs.score_bivariate(prep, (t1, t2), age=(a1, a2), cip=(c1, c2), h2=(0.4, 0.6), rg=0.5)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- `pedigree`: columns `id`, `mother`, `father` (`-1` or NA when missing) and
|
|
60
|
+
optional `twin`, `sex` (`0` female, `1` male), as a polars or pandas frame
|
|
61
|
+
or a mapping of arrays. It is validated by pedigree-graph's rules.
|
|
62
|
+
- `Trait(values, kind=None)`: one phenotype column on the pedigree's rows,
|
|
63
|
+
NA where unknown. The kind is continuous, binary, ordinal or categorical,
|
|
64
|
+
inferred when unambiguous.
|
|
65
|
+
- PA-FGRS takes a binary trait. `age` is the onset age for a case and the
|
|
66
|
+
last observed age for a control; a control without an age is unobserved
|
|
67
|
+
and counted.
|
|
68
|
+
- `probands=` restricts the scored rows; relatives are drawn from the whole
|
|
69
|
+
pedigree. Output is one record per proband in input-row order.
|
|
70
|
+
- `configure_threads(n)` or `PG_PHENOTYPE_THREADS` sets the thread budget
|
|
71
|
+
(default 1). Results are identical for every budget.
|
|
72
|
+
|
|
73
|
+
Errors are `pg_phenotype.ValidationError`, `ParameterError` and
|
|
74
|
+
`ResourceError`, each with a stable `.code` and `.fields`.
|
|
75
|
+
|
|
76
|
+
### Assortative mating
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from pg_phenotype.assortative import mate_correlation
|
|
80
|
+
|
|
81
|
+
res = mate_correlation(pedigree, [pgp.Trait(liab), pgp.Trait(dx)], stratum=birth_decade, bootstrap=1000, seed=1)
|
|
82
|
+
cell = res.cell(0, 1) # mothers' trait 0 x fathers' trait 1
|
|
83
|
+
cell.primary.value, cell.primary.ci, cell.primary.permutation.p
|
|
84
|
+
cell.stratified.result.value # within birth-decade strata
|
|
85
|
+
res.within_person["mothers"]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The Mate Correlation is the correlation between the mother's and the
|
|
89
|
+
father's value of a trait over a pedigree's Mating Pairs. Each cell uses
|
|
90
|
+
the estimators its trait kinds call for (Pearson, tetrachoric, polychoric,
|
|
91
|
+
biserial or polyserial, with their closed-form companions), a Mate Network
|
|
92
|
+
sandwich SE, an optional Mate Network bootstrap, and a sequential
|
|
93
|
+
father-permutation p-value. [docs/assortative-mating.md](docs/assortative-mating.md)
|
|
94
|
+
describes the inputs, rules and every result field, and
|
|
95
|
+
[docs/assortative-mating-design.md](docs/assortative-mating-design.md)
|
|
96
|
+
explains the design.
|
|
97
|
+
|
|
98
|
+
## R
|
|
99
|
+
|
|
100
|
+
```r
|
|
101
|
+
library(pgphenotype)
|
|
102
|
+
|
|
103
|
+
dx <- trait(ped$dx, kind = "binary")
|
|
104
|
+
prep <- pafgrs_prepare(ped, ndegree = 2L)
|
|
105
|
+
cip <- pafgrs_cip(ages, cip_values)
|
|
106
|
+
scores <- pafgrs_score_univariate(prep, dx, age = ped$dx_age, cip = cip, h2 = 0.4)
|
|
107
|
+
both <- pafgrs_score_bivariate(prep, list(t1, t2), ages = list(a1, a2),
|
|
108
|
+
cips = list(c1, c2), h2 = c(0.4, 0.6), rg = 0.5)
|
|
109
|
+
am <- assortative_mate_correlation(ped, list(trait(ped$liab), trait(ped$dx)),
|
|
110
|
+
stratum = ped$birth_decade, bootstrap = 1000, seed = 1)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The R package runs the same core as Python and returns the same scores bit
|
|
114
|
+
for bit. Errors are conditions of class `pgphenotype_error` (with
|
|
115
|
+
`pgphenotype_validation_error` and friends) carrying `$code` and `$fields`,
|
|
116
|
+
positions 1-based.
|
|
117
|
+
|
|
118
|
+
## Correctness (PA-FGRS)
|
|
119
|
+
|
|
120
|
+
- Rust against NumPy reference cores (fitACE's, verbatim) given the same
|
|
121
|
+
covariance and order: within 1e-10.
|
|
122
|
+
- Against BioPsyk/PAFGRS's own `pa_fgrs` on stored fixtures: within 1e-10
|
|
123
|
+
(1.1e-15 observed).
|
|
124
|
+
- Every kinship value bit-identical to pedigree-graph's `pair_kinship`.
|
|
125
|
+
|
|
126
|
+
## Correctness (assortative mating)
|
|
127
|
+
|
|
128
|
+
- Against pedsum #13 at `142adf3` on 74 stored cases (28 fixtures, pedsum's
|
|
129
|
+
own benchmark pedigrees at 10^4 pairs, and 40 random pedigrees), every
|
|
130
|
+
count, reason, flag and p-value is identical. Closed-form estimates agree
|
|
131
|
+
within 4.5e-15, and latent ones within 3.2e-10, inside Brent's 1e-7
|
|
132
|
+
tolerance. One case differs on float noise in pedsum. The
|
|
133
|
+
[gate report](docs/gates/assortative-mating/README.md) has the details.
|
|
134
|
+
- On pedsum's benchmark pedigrees at 10^4 to 10^6 pairs and up to 12
|
|
135
|
+
threads, pg-phenotype's median wall time and peak memory are at most
|
|
136
|
+
0.994 and 0.981 of pedsum's
|
|
137
|
+
([benchmark report](docs/gates/assortative-mating/benchmark.md)).
|
|
138
|
+
- The SciPy and C-library functions pedsum calls are ported bit for bit
|
|
139
|
+
([ADR 0005](docs/adr/0005-assortative-mating-reproduces-pedsums-numerics.md)).
|
|
140
|
+
|
|
141
|
+
Design decisions are in `docs/adr/`; vocabulary in `CONTEXT.md`.
|
|
142
|
+
|
|
143
|
+
## Development
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
pixi run test # rebuilds the extension with test hooks, then pytest
|
|
147
|
+
pixi run test-rust
|
|
148
|
+
pixi run -e r r-test
|
|
149
|
+
pixi run test-against-pg ../pedigree-graph # every suite against a pg checkout
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
To release a version, follow [How to release pg-phenotype](docs/releasing.md).
|
|
153
|
+
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# pg-phenotype
|
|
2
|
+
|
|
3
|
+
Phenotypes in the context of a pedigree, as an extension of
|
|
4
|
+
[pedigree-graph](https://github.com/rwaples/pedigree-graph): a Rust core with
|
|
5
|
+
Python and R bindings. Relationships and kinship come from pedigree-graph's
|
|
6
|
+
core; each method is a module on top.
|
|
7
|
+
|
|
8
|
+
| Method | Module | Status |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| PA-FGRS family genetic risk scores (Dybdahl Krebs et al., Am J Hum Genet 2024, doi:10.1016/j.ajhg.2024.09.009) | `pg_phenotype.pafgrs` | available |
|
|
11
|
+
| Assortative mating: the Mate Correlation of one or two traits, ported from pedsum #13 | `pg_phenotype.assortative` | available |
|
|
12
|
+
|
|
13
|
+
## Python
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import pg_phenotype as pgp
|
|
17
|
+
from pg_phenotype import pafgrs
|
|
18
|
+
|
|
19
|
+
trait = pgp.Trait(dx, kind="binary") # one value per pedigree row
|
|
20
|
+
prep = pafgrs.prepare(pedigree, ndegree=2) # once per pedigree
|
|
21
|
+
cip = pafgrs.Cip(ages, cip_values) # K is the last value
|
|
22
|
+
scores = pafgrs.score_univariate(prep, trait, age=dx_age, cip=cip, h2=0.4)
|
|
23
|
+
scores.est, scores.var, scores.n_relatives, scores.metadata
|
|
24
|
+
|
|
25
|
+
both = pafgrs.score_bivariate(prep, (t1, t2), age=(a1, a2), cip=(c1, c2), h2=(0.4, 0.6), rg=0.5)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- `pedigree`: columns `id`, `mother`, `father` (`-1` or NA when missing) and
|
|
29
|
+
optional `twin`, `sex` (`0` female, `1` male), as a polars or pandas frame
|
|
30
|
+
or a mapping of arrays. It is validated by pedigree-graph's rules.
|
|
31
|
+
- `Trait(values, kind=None)`: one phenotype column on the pedigree's rows,
|
|
32
|
+
NA where unknown. The kind is continuous, binary, ordinal or categorical,
|
|
33
|
+
inferred when unambiguous.
|
|
34
|
+
- PA-FGRS takes a binary trait. `age` is the onset age for a case and the
|
|
35
|
+
last observed age for a control; a control without an age is unobserved
|
|
36
|
+
and counted.
|
|
37
|
+
- `probands=` restricts the scored rows; relatives are drawn from the whole
|
|
38
|
+
pedigree. Output is one record per proband in input-row order.
|
|
39
|
+
- `configure_threads(n)` or `PG_PHENOTYPE_THREADS` sets the thread budget
|
|
40
|
+
(default 1). Results are identical for every budget.
|
|
41
|
+
|
|
42
|
+
Errors are `pg_phenotype.ValidationError`, `ParameterError` and
|
|
43
|
+
`ResourceError`, each with a stable `.code` and `.fields`.
|
|
44
|
+
|
|
45
|
+
### Assortative mating
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from pg_phenotype.assortative import mate_correlation
|
|
49
|
+
|
|
50
|
+
res = mate_correlation(pedigree, [pgp.Trait(liab), pgp.Trait(dx)], stratum=birth_decade, bootstrap=1000, seed=1)
|
|
51
|
+
cell = res.cell(0, 1) # mothers' trait 0 x fathers' trait 1
|
|
52
|
+
cell.primary.value, cell.primary.ci, cell.primary.permutation.p
|
|
53
|
+
cell.stratified.result.value # within birth-decade strata
|
|
54
|
+
res.within_person["mothers"]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The Mate Correlation is the correlation between the mother's and the
|
|
58
|
+
father's value of a trait over a pedigree's Mating Pairs. Each cell uses
|
|
59
|
+
the estimators its trait kinds call for (Pearson, tetrachoric, polychoric,
|
|
60
|
+
biserial or polyserial, with their closed-form companions), a Mate Network
|
|
61
|
+
sandwich SE, an optional Mate Network bootstrap, and a sequential
|
|
62
|
+
father-permutation p-value. [docs/assortative-mating.md](docs/assortative-mating.md)
|
|
63
|
+
describes the inputs, rules and every result field, and
|
|
64
|
+
[docs/assortative-mating-design.md](docs/assortative-mating-design.md)
|
|
65
|
+
explains the design.
|
|
66
|
+
|
|
67
|
+
## R
|
|
68
|
+
|
|
69
|
+
```r
|
|
70
|
+
library(pgphenotype)
|
|
71
|
+
|
|
72
|
+
dx <- trait(ped$dx, kind = "binary")
|
|
73
|
+
prep <- pafgrs_prepare(ped, ndegree = 2L)
|
|
74
|
+
cip <- pafgrs_cip(ages, cip_values)
|
|
75
|
+
scores <- pafgrs_score_univariate(prep, dx, age = ped$dx_age, cip = cip, h2 = 0.4)
|
|
76
|
+
both <- pafgrs_score_bivariate(prep, list(t1, t2), ages = list(a1, a2),
|
|
77
|
+
cips = list(c1, c2), h2 = c(0.4, 0.6), rg = 0.5)
|
|
78
|
+
am <- assortative_mate_correlation(ped, list(trait(ped$liab), trait(ped$dx)),
|
|
79
|
+
stratum = ped$birth_decade, bootstrap = 1000, seed = 1)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The R package runs the same core as Python and returns the same scores bit
|
|
83
|
+
for bit. Errors are conditions of class `pgphenotype_error` (with
|
|
84
|
+
`pgphenotype_validation_error` and friends) carrying `$code` and `$fields`,
|
|
85
|
+
positions 1-based.
|
|
86
|
+
|
|
87
|
+
## Correctness (PA-FGRS)
|
|
88
|
+
|
|
89
|
+
- Rust against NumPy reference cores (fitACE's, verbatim) given the same
|
|
90
|
+
covariance and order: within 1e-10.
|
|
91
|
+
- Against BioPsyk/PAFGRS's own `pa_fgrs` on stored fixtures: within 1e-10
|
|
92
|
+
(1.1e-15 observed).
|
|
93
|
+
- Every kinship value bit-identical to pedigree-graph's `pair_kinship`.
|
|
94
|
+
|
|
95
|
+
## Correctness (assortative mating)
|
|
96
|
+
|
|
97
|
+
- Against pedsum #13 at `142adf3` on 74 stored cases (28 fixtures, pedsum's
|
|
98
|
+
own benchmark pedigrees at 10^4 pairs, and 40 random pedigrees), every
|
|
99
|
+
count, reason, flag and p-value is identical. Closed-form estimates agree
|
|
100
|
+
within 4.5e-15, and latent ones within 3.2e-10, inside Brent's 1e-7
|
|
101
|
+
tolerance. One case differs on float noise in pedsum. The
|
|
102
|
+
[gate report](docs/gates/assortative-mating/README.md) has the details.
|
|
103
|
+
- On pedsum's benchmark pedigrees at 10^4 to 10^6 pairs and up to 12
|
|
104
|
+
threads, pg-phenotype's median wall time and peak memory are at most
|
|
105
|
+
0.994 and 0.981 of pedsum's
|
|
106
|
+
([benchmark report](docs/gates/assortative-mating/benchmark.md)).
|
|
107
|
+
- The SciPy and C-library functions pedsum calls are ported bit for bit
|
|
108
|
+
([ADR 0005](docs/adr/0005-assortative-mating-reproduces-pedsums-numerics.md)).
|
|
109
|
+
|
|
110
|
+
Design decisions are in `docs/adr/`; vocabulary in `CONTEXT.md`.
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pixi run test # rebuilds the extension with test hooks, then pytest
|
|
116
|
+
pixi run test-rust
|
|
117
|
+
pixi run -e r r-test
|
|
118
|
+
pixi run test-against-pg ../pedigree-graph # every suite against a pg checkout
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
To release a version, follow [How to release pg-phenotype](docs/releasing.md).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "pg-phenotype-core"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
rust-version.workspace = true
|
|
6
|
+
license.workspace = true
|
|
7
|
+
repository.workspace = true
|
|
8
|
+
publish = false
|
|
9
|
+
description = "Host-neutral phenotype-in-pedigree methods on pedigree-graph-core"
|
|
10
|
+
|
|
11
|
+
[lib]
|
|
12
|
+
name = "pg_phenotype_core"
|
|
13
|
+
|
|
14
|
+
[dependencies]
|
|
15
|
+
pedigree-graph-core.workspace = true
|
|
16
|
+
rayon.workspace = true
|
|
17
|
+
libm = "0.2"
|