mariepy 0.0.1__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.
Files changed (211) hide show
  1. mariepy-0.0.1/.gitattributes +11 -0
  2. mariepy-0.0.1/.github/ISSUE_TEMPLATE/bug_report.yml +42 -0
  3. mariepy-0.0.1/.github/ISSUE_TEMPLATE/config.yml +8 -0
  4. mariepy-0.0.1/.github/ISSUE_TEMPLATE/feature_request.yml +31 -0
  5. mariepy-0.0.1/.github/PULL_REQUEST_TEMPLATE.md +24 -0
  6. mariepy-0.0.1/.github/dependabot.yml +39 -0
  7. mariepy-0.0.1/.github/workflows/codeql.yml +31 -0
  8. mariepy-0.0.1/.github/workflows/style.yml +42 -0
  9. mariepy-0.0.1/.github/workflows/tags-release.yml +58 -0
  10. mariepy-0.0.1/.github/workflows/test-ci.yml +56 -0
  11. mariepy-0.0.1/.github/workflows/wheels.yml +66 -0
  12. mariepy-0.0.1/.gitignore +28 -0
  13. mariepy-0.0.1/.pre-commit-config.yaml +27 -0
  14. mariepy-0.0.1/AGENTS.md +72 -0
  15. mariepy-0.0.1/CLAUDE.md +74 -0
  16. mariepy-0.0.1/CMakeLists.txt +72 -0
  17. mariepy-0.0.1/CODE_OF_CONDUCT.md +42 -0
  18. mariepy-0.0.1/CONTRIBUTING.md +45 -0
  19. mariepy-0.0.1/GEMINI.md +74 -0
  20. mariepy-0.0.1/LICENSE +674 -0
  21. mariepy-0.0.1/PKG-INFO +215 -0
  22. mariepy-0.0.1/PLAN.md +727 -0
  23. mariepy-0.0.1/README.md +179 -0
  24. mariepy-0.0.1/SECURITY.md +33 -0
  25. mariepy-0.0.1/THIRD_PARTY.md +54 -0
  26. mariepy-0.0.1/codecov.yml +24 -0
  27. mariepy-0.0.1/doc/milestone1.md +534 -0
  28. mariepy-0.0.1/examples/brainweb.py +303 -0
  29. mariepy-0.0.1/examples/brainweb_tissues.csv +10 -0
  30. mariepy-0.0.1/examples/multilayer_mie.py +104 -0
  31. mariepy-0.0.1/examples/tissue_gabriel.csv +4 -0
  32. mariepy-0.0.1/pyproject.toml +134 -0
  33. mariepy-0.0.1/scripts/format_and_lint.sh +21 -0
  34. mariepy-0.0.1/scripts/sync_agent_docs.sh +29 -0
  35. mariepy-0.0.1/setup.py +5 -0
  36. mariepy-0.0.1/src/cpp/convolution.cpp +294 -0
  37. mariepy-0.0.1/src/cpp/coupling.cpp +199 -0
  38. mariepy-0.0.1/src/cpp/green.hpp +65 -0
  39. mariepy-0.0.1/src/cpp/module.cpp +20 -0
  40. mariepy-0.0.1/src/cpp/volume.cpp +126 -0
  41. mariepy-0.0.1/src/cpp_lgpl/NOTICE.md +59 -0
  42. mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_ea_rwg.cpp +2843 -0
  43. mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_ea_rwg.h +141 -0
  44. mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_st_rwg.cpp +1637 -0
  45. mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_st_rwg.h +132 -0
  46. mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_va_rwg.cpp +1054 -0
  47. mariepy-0.0.1/src/cpp_lgpl/directfn_rwg/direct_ws_va_rwg.h +129 -0
  48. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/QUADRIC_WS_EA.h +36 -0
  49. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/classes.h +420 -0
  50. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/constants.h +67 -0
  51. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/directfn.h +106 -0
  52. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/directfn_ws_ea.h +44 -0
  53. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/directfn_ws_st.h +46 -0
  54. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/directfn_ws_va.h +36 -0
  55. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/quadric_ws_st.h +29 -0
  56. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/include/quadric_ws_va.h +24 -0
  57. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/GL_1D.cpp +4075 -0
  58. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/Kernels.cpp +517 -0
  59. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/A_functions_ws_ea.cpp +64 -0
  60. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/N_functions_ws_ea.cpp +331 -0
  61. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/PSI_limits_ws_ea.cpp +50 -0
  62. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/Simplex_ws_ea.cpp +28 -0
  63. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/THETA_limits_ws_ea.cpp +51 -0
  64. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_EA/quadric_ws_ea.cpp +103 -0
  65. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/a_functions_ws_st.cpp +69 -0
  66. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/lambda_limits_ws_st.cpp +33 -0
  67. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/n_functions_ws_st.cpp +47 -0
  68. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/psi_limits_ws_st.cpp +37 -0
  69. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/quadric_ws_st.cpp +94 -0
  70. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/subtriangles_ws_st.cpp +29 -0
  71. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_ST/u_limits_ws_st.cpp +46 -0
  72. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_VA/quadric_ws_va.cpp +231 -0
  73. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_VA/rho_limits_ws_va.cpp +46 -0
  74. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_VA/theta_p_limits_ws_va.cpp +32 -0
  75. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/WS_VA/theta_q_limits_ws_va.cpp +31 -0
  76. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/classes.h +418 -0
  77. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/create_EA.cpp +27 -0
  78. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/create_ST.cpp +27 -0
  79. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/create_VA.cpp +26 -0
  80. mariepy-0.0.1/src/cpp_lgpl/directfn_vie/src_cpp/directfn.h +106 -0
  81. mariepy-0.0.1/src/cpp_lgpl/module_directfn.cpp +316 -0
  82. mariepy-0.0.1/src/cpp_lgpl/rwg_namespace_ea.cpp +22 -0
  83. mariepy-0.0.1/src/cpp_lgpl/rwg_namespace_st.cpp +22 -0
  84. mariepy-0.0.1/src/cpp_lgpl/rwg_namespace_va.cpp +22 -0
  85. mariepy-0.0.1/src/mariepy/__init__.py +13 -0
  86. mariepy-0.0.1/src/mariepy/_accelerators.py +83 -0
  87. mariepy-0.0.1/src/mariepy/averaging.py +707 -0
  88. mariepy-0.0.1/src/mariepy/basis.py +1193 -0
  89. mariepy-0.0.1/src/mariepy/body.py +357 -0
  90. mariepy-0.0.1/src/mariepy/circuit.py +634 -0
  91. mariepy-0.0.1/src/mariepy/cli.py +321 -0
  92. mariepy-0.0.1/src/mariepy/coil.py +580 -0
  93. mariepy-0.0.1/src/mariepy/constants.py +133 -0
  94. mariepy-0.0.1/src/mariepy/cosim.py +1545 -0
  95. mariepy-0.0.1/src/mariepy/coupling.py +355 -0
  96. mariepy-0.0.1/src/mariepy/fields.py +387 -0
  97. mariepy-0.0.1/src/mariepy/gmres.py +307 -0
  98. mariepy-0.0.1/src/mariepy/implicit.py +829 -0
  99. mariepy-0.0.1/src/mariepy/incident.py +228 -0
  100. mariepy-0.0.1/src/mariepy/inputs.py +180 -0
  101. mariepy-0.0.1/src/mariepy/maps.py +198 -0
  102. mariepy-0.0.1/src/mariepy/mesh.py +547 -0
  103. mariepy-0.0.1/src/mariepy/metrics.py +291 -0
  104. mariepy-0.0.1/src/mariepy/network.py +107 -0
  105. mariepy-0.0.1/src/mariepy/pfft.py +1353 -0
  106. mariepy-0.0.1/src/mariepy/plot.py +599 -0
  107. mariepy-0.0.1/src/mariepy/preconditioner.py +50 -0
  108. mariepy-0.0.1/src/mariepy/quadrature.py +256 -0
  109. mariepy-0.0.1/src/mariepy/sar.py +179 -0
  110. mariepy-0.0.1/src/mariepy/shield.py +289 -0
  111. mariepy-0.0.1/src/mariepy/sie.py +789 -0
  112. mariepy-0.0.1/src/mariepy/solver.py +617 -0
  113. mariepy-0.0.1/src/mariepy/system.py +540 -0
  114. mariepy-0.0.1/src/mariepy/tissue.py +432 -0
  115. mariepy-0.0.1/src/mariepy/tt.py +455 -0
  116. mariepy-0.0.1/src/mariepy/tucker.py +337 -0
  117. mariepy-0.0.1/src/mariepy/vie.py +1664 -0
  118. mariepy-0.0.1/src/mariepy/vop.py +366 -0
  119. mariepy-0.0.1/src/mariepy/wire.py +1068 -0
  120. mariepy-0.0.1/tests/__init__.py +0 -0
  121. mariepy-0.0.1/tests/conftest.py +32 -0
  122. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_x.cpp +266 -0
  123. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_x1.cpp +267 -0
  124. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_x2.cpp +267 -0
  125. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_x3.cpp +267 -0
  126. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_y.cpp +267 -0
  127. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_y1.cpp +267 -0
  128. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_y2.cpp +267 -0
  129. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_y3.cpp +267 -0
  130. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_z.cpp +267 -0
  131. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_z1.cpp +267 -0
  132. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_z2.cpp +267 -0
  133. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_K_z3.cpp +267 -0
  134. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_x.cpp +267 -0
  135. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_x1.cpp +267 -0
  136. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_x2.cpp +267 -0
  137. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_x3.cpp +267 -0
  138. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_y.cpp +267 -0
  139. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_y1.cpp +267 -0
  140. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_y2.cpp +267 -0
  141. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_y3.cpp +267 -0
  142. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_z.cpp +267 -0
  143. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_z1.cpp +267 -0
  144. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_z2.cpp +267 -0
  145. mariepy-0.0.1/tests/marie/Assemble_rwg_coupling_matrix_N_z3.cpp +267 -0
  146. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_x.cpp +262 -0
  147. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_x1.cpp +262 -0
  148. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_x2.cpp +262 -0
  149. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_x3.cpp +262 -0
  150. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_y.cpp +262 -0
  151. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_y1.cpp +262 -0
  152. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_y2.cpp +262 -0
  153. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_y3.cpp +262 -0
  154. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_z.cpp +262 -0
  155. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_z1.cpp +262 -0
  156. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_z2.cpp +262 -0
  157. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_K_z3.cpp +262 -0
  158. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_x.cpp +262 -0
  159. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_x1.cpp +262 -0
  160. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_x2.cpp +262 -0
  161. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_x3.cpp +262 -0
  162. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_y.cpp +262 -0
  163. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_y1.cpp +262 -0
  164. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_y2.cpp +262 -0
  165. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_y3.cpp +262 -0
  166. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_z.cpp +262 -0
  167. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_z1.cpp +262 -0
  168. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_z2.cpp +262 -0
  169. mariepy-0.0.1/tests/marie/wire/Assemble_tri_coupling_matrix_N_z3.cpp +262 -0
  170. mariepy-0.0.1/tests/marie_files.py +126 -0
  171. mariepy-0.0.1/tests/mie.py +392 -0
  172. mariepy-0.0.1/tests/parity.py +310 -0
  173. mariepy-0.0.1/tests/pec.py +53 -0
  174. mariepy-0.0.1/tests/test_averaging.py +420 -0
  175. mariepy-0.0.1/tests/test_basis.py +676 -0
  176. mariepy-0.0.1/tests/test_body.py +248 -0
  177. mariepy-0.0.1/tests/test_circuit.py +248 -0
  178. mariepy-0.0.1/tests/test_cli.py +52 -0
  179. mariepy-0.0.1/tests/test_coil.py +381 -0
  180. mariepy-0.0.1/tests/test_constants.py +66 -0
  181. mariepy-0.0.1/tests/test_cosim.py +473 -0
  182. mariepy-0.0.1/tests/test_coupling.py +301 -0
  183. mariepy-0.0.1/tests/test_directfn.py +246 -0
  184. mariepy-0.0.1/tests/test_docstrings.py +30 -0
  185. mariepy-0.0.1/tests/test_fields.py +317 -0
  186. mariepy-0.0.1/tests/test_gmres.py +292 -0
  187. mariepy-0.0.1/tests/test_implicit.py +361 -0
  188. mariepy-0.0.1/tests/test_incident.py +84 -0
  189. mariepy-0.0.1/tests/test_inputs.py +214 -0
  190. mariepy-0.0.1/tests/test_linear.py +339 -0
  191. mariepy-0.0.1/tests/test_linear_coupled.py +156 -0
  192. mariepy-0.0.1/tests/test_maps.py +66 -0
  193. mariepy-0.0.1/tests/test_mesh.py +231 -0
  194. mariepy-0.0.1/tests/test_metrics.py +132 -0
  195. mariepy-0.0.1/tests/test_mie.py +283 -0
  196. mariepy-0.0.1/tests/test_near.py +341 -0
  197. mariepy-0.0.1/tests/test_network.py +69 -0
  198. mariepy-0.0.1/tests/test_pfft.py +393 -0
  199. mariepy-0.0.1/tests/test_plot.py +176 -0
  200. mariepy-0.0.1/tests/test_quadrature.py +158 -0
  201. mariepy-0.0.1/tests/test_sar.py +121 -0
  202. mariepy-0.0.1/tests/test_shield.py +266 -0
  203. mariepy-0.0.1/tests/test_sie.py +419 -0
  204. mariepy-0.0.1/tests/test_smoke.py +8 -0
  205. mariepy-0.0.1/tests/test_system.py +245 -0
  206. mariepy-0.0.1/tests/test_tissue.py +390 -0
  207. mariepy-0.0.1/tests/test_tt.py +155 -0
  208. mariepy-0.0.1/tests/test_tucker.py +156 -0
  209. mariepy-0.0.1/tests/test_vie.py +422 -0
  210. mariepy-0.0.1/tests/test_vop.py +317 -0
  211. mariepy-0.0.1/tests/test_wire.py +616 -0
@@ -0,0 +1,11 @@
1
+ * text=auto eol=lf
2
+
3
+ *.png binary
4
+ *.jpg binary
5
+ *.npy binary
6
+ *.npz binary
7
+ *.mat binary
8
+ *.h5 binary
9
+
10
+ # Generated: keep them out of diffs and out of the language statistics.
11
+ *.ipynb linguist-documentation=true
@@ -0,0 +1,42 @@
1
+ name: Bug report
2
+ description: Something behaves differently from what it says it does.
3
+ labels: ["bug"]
4
+ body:
5
+ - type: textarea
6
+ id: what-happened
7
+ attributes:
8
+ label: What happened
9
+ description: What did you expect, and what did you get instead?
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: reproduce
15
+ attributes:
16
+ label: Smallest reproduction
17
+ description: >
18
+ Code we can run. Prefer synthetic arrays over a data file; if the shape
19
+ of real data matters, give the shapes and dtypes.
20
+ render: python
21
+ validations:
22
+ required: true
23
+
24
+ - type: textarea
25
+ id: environment
26
+ attributes:
27
+ label: Environment
28
+ description: >
29
+ Output of `python -c "import mariepy, sys, torch;
30
+ print(mariepy.__version__, sys.version, torch.__version__,
31
+ torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'cpu')"`
32
+ render: shell
33
+ validations:
34
+ required: true
35
+
36
+ - type: dropdown
37
+ id: device
38
+ attributes:
39
+ label: Where it happens
40
+ options: ["CPU only", "CUDA only", "Both"]
41
+ validations:
42
+ required: true
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Question or idea
4
+ url: https://github.com/pulserver/mariepy/discussions
5
+ about: Ask about usage, or propose something before it is a bug report.
6
+ - name: Security vulnerability
7
+ url: https://github.com/pulserver/mariepy/security/advisories/new
8
+ about: Report privately. Please do not open a public issue.
@@ -0,0 +1,31 @@
1
+ name: Feature request
2
+ description: Something this package should be able to do and cannot.
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: The problem
9
+ description: What are you trying to do, and where does it stop?
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: proposal
15
+ attributes:
16
+ label: What you have in mind
17
+ description: >
18
+ A sketch of the API, if you have one. If there is a paper or another
19
+ implementation that does this, name it — that is usually the fastest
20
+ way to agree on what is wanted.
21
+ validations:
22
+ required: true
23
+
24
+ - type: textarea
25
+ id: layer
26
+ attributes:
27
+ label: Which layer this belongs to
28
+ description: >
29
+ This package is one of a family with a strict layering (`mrutils` at the
30
+ base, `deepmr` at the top). If the feature needs something from a
31
+ sibling package, say which — that usually means it belongs elsewhere.
@@ -0,0 +1,24 @@
1
+ ## What this changes
2
+
3
+ <!-- One or two sentences. What behaviour is different afterwards? -->
4
+
5
+ ## Why
6
+
7
+ <!-- The problem this solves. Link the issue if there is one. -->
8
+
9
+ ## How it was verified
10
+
11
+ <!-- The commands you ran and what they said. Paste the output, don't
12
+ summarise it. "Tests pass" is not verification. -->
13
+
14
+ ```
15
+ ```
16
+
17
+ ## Checklist
18
+
19
+ - [ ] `bash scripts/format_and_lint.sh` is clean
20
+ - [ ] `pytest -q` passes, and new behaviour has a test whose name states the
21
+ invariant it protects
22
+ - [ ] Anything numerical is exercised on CPU and CUDA, or the CUDA leg is
23
+ marked `@pytest.mark.cuda` and skips cleanly
24
+ - [ ] No comment or docstring describes the code's history
@@ -0,0 +1,39 @@
1
+ version: 2
2
+ updates:
3
+ # The Actions in .github/workflows pin third-party code that runs with
4
+ # repository credentials, so these are the updates worth having weekly.
5
+ - package-ecosystem: github-actions
6
+ directory: "/"
7
+ schedule:
8
+ interval: weekly
9
+ day: monday
10
+ labels: ["dependencies", "ci"]
11
+ commit-message:
12
+ prefix: "ci"
13
+ groups:
14
+ actions:
15
+ patterns: ["*"]
16
+
17
+ # Grouped so the numerical stack arrives as one pull request that can be
18
+ # tested together rather than as several that each need a full suite run.
19
+ - package-ecosystem: pip
20
+ directory: "/"
21
+ schedule:
22
+ interval: weekly
23
+ day: monday
24
+ open-pull-requests-limit: 5
25
+ labels: ["dependencies", "python"]
26
+ commit-message:
27
+ prefix: "deps"
28
+ groups:
29
+ numerical:
30
+ patterns: ["numpy", "scipy", "torch*", "triton", "mri-nufft", "finufft", "cufinufft"]
31
+ mr-stack:
32
+ patterns: ["mrutils", "mrtoeplitz", "mrllr", "mrmotion", "mrdistortion", "torchsolve", "deepinv", "SimpleITK"]
33
+ dev-tooling:
34
+ patterns: ["pytest*", "coverage", "ruff", "pre-commit", "build", "sphinx*"]
35
+ ignore:
36
+ # Torch major bumps move the CUDA runtime under the whole family, so they
37
+ # are a deliberate decision rather than a routine update.
38
+ - dependency-name: "torch"
39
+ update-types: ["version-update:semver-major"]
@@ -0,0 +1,31 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ analyze:
11
+ name: Analyze Python
12
+ runs-on: ubuntu-latest
13
+ # Code scanning on a private repository needs GitHub Advanced Security,
14
+ # and uploading results without it is a hard error rather than a warning.
15
+ # The job stands down while the repository is private and starts working
16
+ # on its own once it is made public.
17
+ if: github.event.repository.visibility == 'public'
18
+ permissions:
19
+ security-events: write
20
+ packages: read
21
+ actions: read
22
+ contents: read
23
+ steps:
24
+ - uses: actions/checkout@v7
25
+ - uses: github/codeql-action/init@v4
26
+ with:
27
+ languages: python
28
+ build-mode: none
29
+ - uses: github/codeql-action/analyze@v4
30
+ with:
31
+ category: "/language:python"
@@ -0,0 +1,42 @@
1
+ name: Style
2
+
3
+ # Runs the same script pre-commit runs, in --check mode: nothing is rewritten
4
+ # and any file that would change fails the job.
5
+
6
+ on:
7
+ # A branch is tested once, through its pull request.
8
+ push:
9
+ branches: [main]
10
+ pull_request:
11
+ workflow_dispatch:
12
+
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ format-and-lint:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v7
22
+ - uses: actions/setup-python@v7
23
+ with:
24
+ python-version: "3.11"
25
+
26
+ # The linter only, taken from the same `dev` extra a contributor's
27
+ # pre-commit installs, so both apply one ruff. Installing the extra whole
28
+ # would download the runtime for a job that never imports it.
29
+ - name: Install ruff
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ python - <<'PY' > "$RUNNER_TEMP/lint-requirements.txt"
33
+ import tomllib
34
+
35
+ with open("pyproject.toml", "rb") as pyproject:
36
+ dev = tomllib.load(pyproject)["project"]["optional-dependencies"]["dev"]
37
+ print("\n".join(line for line in dev if line.startswith("ruff")))
38
+ PY
39
+ python -m pip install -r "$RUNNER_TEMP/lint-requirements.txt"
40
+
41
+ - name: Format and lint (check only)
42
+ run: bash scripts/format_and_lint.sh --check
@@ -0,0 +1,58 @@
1
+ name: Release
2
+
3
+ # Publishes a tagged version: the wheels and sdist from the reusable Wheels
4
+ # workflow, then PyPI and a signed GitHub release. The version comes from the
5
+ # tag via setuptools_scm.
6
+
7
+ on:
8
+ push:
9
+ tags:
10
+ - "v[0-9]+.[0-9]+.[0-9]+"
11
+
12
+ jobs:
13
+ build:
14
+ uses: ./.github/workflows/wheels.yml
15
+ with:
16
+ cibw-build: "cp310-* cp311-* cp312-* cp313-* cp314-*"
17
+
18
+ publish-to-pypi:
19
+ needs: [build]
20
+ runs-on: ubuntu-latest
21
+ environment:
22
+ name: pypi
23
+ url: https://pypi.org/p/mariepy
24
+ permissions:
25
+ id-token: write # trusted publishing (OIDC)
26
+ steps:
27
+ - uses: actions/download-artifact@v8
28
+ with:
29
+ pattern: "{wheels-*,sdist}"
30
+ path: dist
31
+ merge-multiple: true
32
+ - uses: pypa/gh-action-pypi-publish@release/v1
33
+
34
+ github-release:
35
+ needs: [publish-to-pypi]
36
+ runs-on: ubuntu-latest
37
+ permissions:
38
+ contents: write # create the release
39
+ id-token: write # sigstore
40
+ steps:
41
+ - uses: actions/download-artifact@v8
42
+ with:
43
+ pattern: "{wheels-*,sdist}"
44
+ path: dist
45
+ merge-multiple: true
46
+ - uses: sigstore/gh-action-sigstore-python@v3.5.0
47
+ with:
48
+ inputs: |
49
+ ./dist/*.tar.gz
50
+ ./dist/*.whl
51
+ - env:
52
+ GITHUB_TOKEN: ${{ github.token }}
53
+ run: |
54
+ gh release create '${{ github.ref_name }}' \
55
+ --repo '${{ github.repository }}' \
56
+ --title '${{ github.ref_name }}' \
57
+ --generate-notes
58
+ gh release upload '${{ github.ref_name }}' dist/** --repo '${{ github.repository }}'
@@ -0,0 +1,56 @@
1
+ name: Tests
2
+
3
+ on:
4
+ # A branch is tested once, through its pull request.
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+ workflow_dispatch:
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ test:
16
+ name: Python ${{ matrix.python-version }}
17
+ runs-on: ubuntu-latest
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ # The floor and the ceiling of the supported band: an intermediate
22
+ # release that fails on neither is not a plausible failure.
23
+ python-version: ["3.10", "3.14"]
24
+ steps:
25
+ - uses: actions/checkout@v7
26
+ with:
27
+ fetch-depth: 0 # setuptools_scm reads the tags
28
+
29
+ - uses: actions/setup-python@v7
30
+ with:
31
+ python-version: ${{ matrix.python-version }}
32
+ cache: pip
33
+
34
+ # torch's CPU build: PyPI's carries the CUDA libraries, gigabytes this
35
+ # runner has no device for.
36
+ - name: Install
37
+ run: |
38
+ python -m pip install --upgrade pip
39
+ python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
40
+ python -m pip install .[dev]
41
+
42
+ # No device here, so this run is also the check that every CUDA-marked
43
+ # test skips cleanly without one: -rs lists the skips. One worker per
44
+ # core, each held to one thread so the workers do not contend.
45
+ - name: Run the tests
46
+ env:
47
+ OMP_NUM_THREADS: 1
48
+ OPENBLAS_NUM_THREADS: 1
49
+ MKL_NUM_THREADS: 1
50
+ run: pytest -q -rs -n auto --cov --cov-report=xml
51
+
52
+ - uses: codecov/codecov-action@v7
53
+ with:
54
+ fail_ci_if_error: false
55
+ token: ${{ secrets.CODECOV_TOKEN }}
56
+ slug: pulserver/mariepy
@@ -0,0 +1,66 @@
1
+ name: Wheels
2
+
3
+ # Reusable: the release workflow calls this so what is published was built by
4
+ # the same job pull requests exercise.
5
+
6
+ on:
7
+ workflow_call:
8
+ inputs:
9
+ cibw-build:
10
+ description: Interpreters to build, as a CIBW_BUILD pattern.
11
+ type: string
12
+ required: true
13
+ workflow_dispatch:
14
+ inputs:
15
+ cibw-build:
16
+ description: Interpreters to build, as a CIBW_BUILD pattern.
17
+ type: string
18
+ default: "cp310-* cp311-* cp312-* cp313-* cp314-*"
19
+
20
+ jobs:
21
+ wheels:
22
+ name: ${{ matrix.os }}
23
+ runs-on: ${{ matrix.os }}
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ # Linux and macOS only. The kernels' SIMD paths are guarded on GCC and
28
+ # Clang, so a Windows build would take the scalar path; add it when
29
+ # someone needs it rather than paying for it on every release.
30
+ os: [ubuntu-latest, macos-14]
31
+ steps:
32
+ - uses: actions/checkout@v7
33
+ with:
34
+ fetch-depth: 0 # setuptools_scm reads the tags
35
+
36
+ - uses: pypa/cibuildwheel@v4.3.4
37
+ env:
38
+ CIBW_BUILD: ${{ inputs.cibw-build }}
39
+ CIBW_SKIP: "*-musllinux_*"
40
+ CIBW_ARCHS_LINUX: x86_64
41
+ CIBW_ARCHS_MACOS: arm64
42
+ CIBW_TEST_COMMAND: "python -c \"import mariepy; print(mariepy.__version__)\""
43
+
44
+ - uses: actions/upload-artifact@v7
45
+ with:
46
+ name: wheels-${{ matrix.os }}
47
+ path: wheelhouse/*.whl
48
+ if-no-files-found: error
49
+
50
+ sdist:
51
+ runs-on: ubuntu-latest
52
+ steps:
53
+ - uses: actions/checkout@v7
54
+ with:
55
+ fetch-depth: 0
56
+ - uses: actions/setup-python@v7
57
+ with:
58
+ python-version: "3.11"
59
+ - run: |
60
+ python -m pip install --upgrade pip build
61
+ python -m build --sdist
62
+ - uses: actions/upload-artifact@v7
63
+ with:
64
+ name: sdist
65
+ path: dist/*.tar.gz
66
+ if-no-files-found: error
@@ -0,0 +1,28 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.so
4
+ .Python
5
+ build/
6
+ dist/
7
+ wheelhouse/
8
+ *.egg-info/
9
+ .eggs/
10
+
11
+ .venv/
12
+ venv/
13
+ .env
14
+
15
+ .pytest_cache/
16
+ .ruff_cache/
17
+ .mypy_cache/
18
+ .coverage
19
+ .coverage.*
20
+ coverage.xml
21
+ htmlcov/
22
+
23
+ .idea/
24
+ .vscode/
25
+ .DS_Store
26
+
27
+ # Benchmark inputs are fetched, never committed.
28
+ data/
@@ -0,0 +1,27 @@
1
+ # The rules live in scripts/format_and_lint.sh, which the Style workflow also
2
+ # runs (there with --check). One entry point means a commit cannot pass locally
3
+ # and fail in CI on style.
4
+ repos:
5
+ - repo: local
6
+ hooks:
7
+ - id: format-and-lint
8
+ name: format and lint
9
+ entry: bash scripts/format_and_lint.sh
10
+ language: system
11
+ pass_filenames: false
12
+ types_or: [python, markdown]
13
+
14
+ - repo: https://github.com/pre-commit/pre-commit-hooks
15
+ rev: v6.0.0
16
+ hooks:
17
+ - id: check-merge-conflict
18
+ - id: end-of-file-fixer
19
+ - id: trailing-whitespace
20
+ - id: check-yaml
21
+ - id: check-toml
22
+ - id: check-added-large-files
23
+ args: [--maxkb=1024]
24
+ - id: check-symlinks
25
+ - id: destroyed-symlinks
26
+ - id: mixed-line-ending
27
+ args: [--fix=lf]
@@ -0,0 +1,72 @@
1
+ # mariepy — agent instructions
2
+
3
+ <!--
4
+ This file is the SOURCE. CLAUDE.md and GEMINI.md are generated from it by
5
+ scripts/sync_agent_docs.sh, which pre-commit runs. Edit this file, never those.
6
+ -->
7
+
8
+ ## What this package is
9
+
10
+ Electromagnetic simulation of MRI transmit coils and virtual observation points
11
+ (VOPs) for SAR, ported from MARIE 3.0 (<https://github.com/cloudmrhub/marie-tools>,
12
+ MIT).
13
+
14
+ `PLAN.md` is the design brief: scope, the VOP file contract, the port's
15
+ milestones, validation, constraints and later stages. Read it before starting
16
+ work. When a decision it records changes, change `PLAN.md` in the same pull
17
+ request.
18
+
19
+ mariepy stands alone: it depends on torch and numpy, not on other MRI packages.
20
+ Its one external contract is the VOP file that pypulseqpp reads.
21
+
22
+ ## Build and test
23
+
24
+ ```bash
25
+ pip install -e .[dev]
26
+ bash scripts/format_and_lint.sh # rewrites in place; --check to verify only
27
+ pytest -q
28
+ ```
29
+
30
+ Build and test steps are mandatory before reporting a change complete. Run them
31
+ and report the exact output; do not assume success.
32
+
33
+ ## Tests
34
+
35
+ pytest with plain functions and fixtures — never `unittest.TestCase`. A test
36
+ name states the invariant it protects, so a failure reads as a sentence.
37
+
38
+ Anything numerical that can run on CPU and CUDA is parametrised over both, and
39
+ the CUDA leg skips when no device is present. A kernel-layout check that ran on
40
+ CPU only has passed in this codebase while CUDA was 100% wrong.
41
+
42
+ ## Comments and docstrings
43
+
44
+ Write for someone reading the code as it is now, who has no memory of any
45
+ earlier version of it. **Never** write text whose subject is the history of the
46
+ code. Banned in comments, docstrings and prose alike:
47
+
48
+ - "used to", "was once", "no longer", "previously", "now that", "this replaces",
49
+ "the old X", "before the fix"
50
+ - justifying the present shape by contrast with a shape that is gone
51
+ - naming a bug that has been fixed, or the session that fixed it
52
+ - restating what the code plainly says
53
+
54
+ A docstring carries what a caller needs: one line of what, Parameters, Returns,
55
+ Raises. A comment earns its place only by explaining a non-obvious algorithm or
56
+ a choice a reader would otherwise undo — and even then, prefer a well-named
57
+ function or a test whose name states the invariant, because those cannot go
58
+ stale silently. When tempted to explain *why not the other way*, write a test.
59
+
60
+ Stale comments are actively harmful. Deleting an outdated comment is always
61
+ correct; rewriting one to describe the change is not.
62
+
63
+ ## Documentation style
64
+
65
+ The audience is MR scientists. Write in the vocabulary of pulse sequences and
66
+ physics, not of software architecture. Never justify a design by describing the
67
+ design it replaced.
68
+
69
+ Do not print a measured constant that is not guaranteed across releases or
70
+ hardware. Name the symbol and where it comes from, and let the build supply the
71
+ number. Benchmark tables in the README are regenerated by the benchmark script,
72
+ not typed in.
@@ -0,0 +1,74 @@
1
+ <!-- Generated from AGENTS.md by scripts/sync_agent_docs.sh. Do not edit. -->
2
+
3
+ # mariepy — agent instructions
4
+
5
+ <!--
6
+ This file is the SOURCE. CLAUDE.md and GEMINI.md are generated from it by
7
+ scripts/sync_agent_docs.sh, which pre-commit runs. Edit this file, never those.
8
+ -->
9
+
10
+ ## What this package is
11
+
12
+ Electromagnetic simulation of MRI transmit coils and virtual observation points
13
+ (VOPs) for SAR, ported from MARIE 3.0 (<https://github.com/cloudmrhub/marie-tools>,
14
+ MIT).
15
+
16
+ `PLAN.md` is the design brief: scope, the VOP file contract, the port's
17
+ milestones, validation, constraints and later stages. Read it before starting
18
+ work. When a decision it records changes, change `PLAN.md` in the same pull
19
+ request.
20
+
21
+ mariepy stands alone: it depends on torch and numpy, not on other MRI packages.
22
+ Its one external contract is the VOP file that pypulseqpp reads.
23
+
24
+ ## Build and test
25
+
26
+ ```bash
27
+ pip install -e .[dev]
28
+ bash scripts/format_and_lint.sh # rewrites in place; --check to verify only
29
+ pytest -q
30
+ ```
31
+
32
+ Build and test steps are mandatory before reporting a change complete. Run them
33
+ and report the exact output; do not assume success.
34
+
35
+ ## Tests
36
+
37
+ pytest with plain functions and fixtures — never `unittest.TestCase`. A test
38
+ name states the invariant it protects, so a failure reads as a sentence.
39
+
40
+ Anything numerical that can run on CPU and CUDA is parametrised over both, and
41
+ the CUDA leg skips when no device is present. A kernel-layout check that ran on
42
+ CPU only has passed in this codebase while CUDA was 100% wrong.
43
+
44
+ ## Comments and docstrings
45
+
46
+ Write for someone reading the code as it is now, who has no memory of any
47
+ earlier version of it. **Never** write text whose subject is the history of the
48
+ code. Banned in comments, docstrings and prose alike:
49
+
50
+ - "used to", "was once", "no longer", "previously", "now that", "this replaces",
51
+ "the old X", "before the fix"
52
+ - justifying the present shape by contrast with a shape that is gone
53
+ - naming a bug that has been fixed, or the session that fixed it
54
+ - restating what the code plainly says
55
+
56
+ A docstring carries what a caller needs: one line of what, Parameters, Returns,
57
+ Raises. A comment earns its place only by explaining a non-obvious algorithm or
58
+ a choice a reader would otherwise undo — and even then, prefer a well-named
59
+ function or a test whose name states the invariant, because those cannot go
60
+ stale silently. When tempted to explain *why not the other way*, write a test.
61
+
62
+ Stale comments are actively harmful. Deleting an outdated comment is always
63
+ correct; rewriting one to describe the change is not.
64
+
65
+ ## Documentation style
66
+
67
+ The audience is MR scientists. Write in the vocabulary of pulse sequences and
68
+ physics, not of software architecture. Never justify a design by describing the
69
+ design it replaced.
70
+
71
+ Do not print a measured constant that is not guaranteed across releases or
72
+ hardware. Name the symbol and where it comes from, and let the build supply the
73
+ number. Benchmark tables in the README are regenerated by the benchmark script,
74
+ not typed in.