syncmoss 0.3.0__tar.gz → 0.4.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.
Files changed (182) hide show
  1. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/_Tests.yml +6 -3
  2. {syncmoss-0.3.0 → syncmoss-0.4.0}/.gitignore +8 -0
  3. {syncmoss-0.3.0 → syncmoss-0.4.0}/PKG-INFO +1 -1
  4. {syncmoss-0.3.0 → syncmoss-0.4.0}/pyproject.toml +15 -1
  5. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Calibration.py +10 -4
  6. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/constants.py +20 -0
  7. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/fitting_io.py +4 -2
  8. syncmoss-0.4.0/syncmoss/instrumental_io.py +2002 -0
  9. syncmoss-0.4.0/syncmoss/instrumental_window.py +89 -0
  10. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/main.py +1 -1
  11. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/models.py +27 -5
  12. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/models_positions.py +10 -2
  13. syncmoss-0.4.0/syncmoss/parameters/Calibration.dat +513 -0
  14. syncmoss-0.4.0/syncmoss/parameters/INSexp.txt +1 -0
  15. syncmoss-0.4.0/syncmoss/parameters/INSint.txt +1 -0
  16. syncmoss-0.4.0/syncmoss/parameters/INSth.txt +1 -0
  17. syncmoss-0.4.0/syncmoss/parameters/calibr.png +0 -0
  18. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters/help.md +23 -0
  19. syncmoss-0.4.0/syncmoss/sms_theory.py +2259 -0
  20. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/spectrum_io.py +37 -11
  21. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/spectrum_plotter.py +52 -0
  22. syncmoss-0.4.0/syncmoss/supp_menu.py +683 -0
  23. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/syncmoss_main.py +186 -38
  24. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss.egg-info/PKG-INFO +1 -1
  25. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss.egg-info/SOURCES.txt +12 -0
  26. syncmoss-0.4.0/syncmoss.egg-info/scm_file_list.json +171 -0
  27. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/conftest.py +72 -0
  28. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/syncmoss_test.py +22 -5
  29. syncmoss-0.4.0/tests/test_calibration_path.py +95 -0
  30. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_instrumental_metadata.py +62 -0
  31. syncmoss-0.4.0/tests/test_instrumental_method_choice.py +155 -0
  32. syncmoss-0.4.0/tests/test_instrumental_recentre.py +120 -0
  33. syncmoss-0.4.0/tests/test_instrumental_window.py +121 -0
  34. syncmoss-0.4.0/tests/test_integral_points.py +104 -0
  35. syncmoss-0.4.0/tests/test_search_guards.py +129 -0
  36. syncmoss-0.4.0/tests/test_sms_theory.py +519 -0
  37. syncmoss-0.4.0/tests/test_theory_search.py +152 -0
  38. syncmoss-0.3.0/syncmoss/instrumental_io.py +0 -800
  39. syncmoss-0.3.0/syncmoss/parameters/Calibration.dat +0 -513
  40. syncmoss-0.3.0/syncmoss/parameters/INSexp.txt +0 -1
  41. syncmoss-0.3.0/syncmoss/parameters/INSint.txt +0 -1
  42. syncmoss-0.3.0/syncmoss/parameters/calibr.png +0 -0
  43. syncmoss-0.3.0/syncmoss/supp_menu.py +0 -295
  44. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/Tests.yml +0 -0
  45. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/_MacOS.yml +0 -0
  46. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/_PyPI.yml +0 -0
  47. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/_TagRelease.yml +0 -0
  48. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/_UploadRelease.yml +0 -0
  49. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/_Version.yml +0 -0
  50. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/_Wheels.yml +0 -0
  51. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/_WindowsExe.yml +0 -0
  52. {syncmoss-0.3.0 → syncmoss-0.4.0}/.github/workflows/release.yml +0 -0
  53. {syncmoss-0.3.0 → syncmoss-0.4.0}/.vscode/settings.json +0 -0
  54. {syncmoss-0.3.0 → syncmoss-0.4.0}/COPYING.txt +0 -0
  55. {syncmoss-0.3.0 → syncmoss-0.4.0}/LICENSE +0 -0
  56. {syncmoss-0.3.0 → syncmoss-0.4.0}/Lib_test/test.mdl +0 -0
  57. {syncmoss-0.3.0 → syncmoss-0.4.0}/NOTICE.txt +0 -0
  58. {syncmoss-0.3.0 → syncmoss-0.4.0}/README.md +0 -0
  59. {syncmoss-0.3.0 → syncmoss-0.4.0}/bundle/MacOS.spec +0 -0
  60. {syncmoss-0.3.0 → syncmoss-0.4.0}/bundle/Windows.spec +0 -0
  61. {syncmoss-0.3.0 → syncmoss-0.4.0}/bundle/bundle.py +0 -0
  62. {syncmoss-0.3.0 → syncmoss-0.4.0}/bundle/macos_bundle.py +0 -0
  63. {syncmoss-0.3.0 → syncmoss-0.4.0}/docs/thick_models.md +0 -0
  64. {syncmoss-0.3.0 → syncmoss-0.4.0}/docs/thick_vs_thin.md +0 -0
  65. {syncmoss-0.3.0 → syncmoss-0.4.0}/requirements.txt +0 -0
  66. {syncmoss-0.3.0 → syncmoss-0.4.0}/setup.cfg +0 -0
  67. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Hamiltonian_helper.py +0 -0
  68. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Aegirine.mdl +0 -0
  69. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Akaganeite.mdl +0 -0
  70. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Almandine.mdl +0 -0
  71. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Antitaenite.mdl +0 -0
  72. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Arsenopyrite.mdl +0 -0
  73. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Bornite.mdl +0 -0
  74. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Bridgmanite (Fe,Al-bearing) @100 GPa.mdl +0 -0
  75. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Bridgmanite (Fe,Al-bearing).mdl +0 -0
  76. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Celadonite.mdl +0 -0
  77. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Cementite.mdl +0 -0
  78. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Chalcopyrite.mdl +0 -0
  79. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Clinopyroxene (augite).mdl +0 -0
  80. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Copiapite.mdl +0 -0
  81. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Cubanite.mdl +0 -0
  82. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Epidote.mdl +0 -0
  83. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Fayalite (Fe-olivine).mdl +0 -0
  84. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Ferrihydrite (2-line).mdl +0 -0
  85. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Ferropericlase.mdl +0 -0
  86. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Goethite.mdl +0 -0
  87. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Green rust (fougerite, carbonate).mdl +0 -0
  88. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Haegg carbide.mdl +0 -0
  89. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Hedenbergite.mdl +0 -0
  90. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Hematite.mdl +0 -0
  91. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Heterosite (FePO4).mdl +0 -0
  92. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Ilmenite.mdl +0 -0
  93. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Iron phosphide.mdl +0 -0
  94. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Isocubanite.mdl +0 -0
  95. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Jarosite.mdl +0 -0
  96. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Kamacite.mdl +0 -0
  97. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Lepidocrocite.mdl +0 -0
  98. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Maghemite.mdl +0 -0
  99. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Magnetite.mdl +0 -0
  100. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Marcasite.mdl +0 -0
  101. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Melanterite.mdl +0 -0
  102. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Orthopyroxene (enstatite-ferrosilite).mdl +0 -0
  103. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Prussian blue (ferric ferrocyanide).mdl +0 -0
  104. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Pyrite.mdl +0 -0
  105. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Pyrrhotite.mdl +0 -0
  106. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Rhomboclase.mdl +0 -0
  107. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Roemerite.mdl +0 -0
  108. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Siderite.mdl +0 -0
  109. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Szomolnokite.mdl +0 -0
  110. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Taenite.mdl +0 -0
  111. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Talnakhite.mdl +0 -0
  112. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Tetrataenite.mdl +0 -0
  113. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Triphylite (LiFePO4).mdl +0 -0
  114. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Troilite.mdl +0 -0
  115. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Vivianite.mdl +0 -0
  116. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/Voltaite.mdl +0 -0
  117. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library/alpha-Fe (metallic iron, bcc).mdl +0 -0
  118. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library_io.py +0 -0
  119. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/Library_window.py +0 -0
  120. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/icons/CheckBox.png +0 -0
  121. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/icons/CheckBox_.png +0 -0
  122. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/icons/CheckBox_L.png +0 -0
  123. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/icons/CheckBox_L2.png +0 -0
  124. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/icons/DU.png +0 -0
  125. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/icons/Switch.png +0 -0
  126. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/icons/UD.png +0 -0
  127. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/icons/icon_r.ico +0 -0
  128. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/legacy.py +0 -0
  129. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/minimi_lib.py +0 -0
  130. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/model_io.py +0 -0
  131. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/models_description_window.py +0 -0
  132. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters/ABSorber3.txt +0 -0
  133. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters/Be.txt +0 -0
  134. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters/GCMS.txt +0 -0
  135. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters/INS_APS.txt +0 -0
  136. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters/KB.txt +0 -0
  137. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters/NFS.txt +0 -0
  138. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters/models_description.md +0 -0
  139. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/parameters_table.py +0 -0
  140. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/results_table.py +0 -0
  141. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/support_math.py +0 -0
  142. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/test_graf.txt +0 -0
  143. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/test_param.txt +0 -0
  144. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/theme_dark.json +0 -0
  145. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss/theme_light.json +0 -0
  146. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss.egg-info/dependency_links.txt +0 -0
  147. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss.egg-info/entry_points.txt +0 -0
  148. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss.egg-info/requires.txt +0 -0
  149. {syncmoss-0.3.0 → syncmoss-0.4.0}/syncmoss.egg-info/top_level.txt +0 -0
  150. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/data/Distr_corr.mdl +0 -0
  151. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/data/Distr_distr.mdl +0 -0
  152. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/data/alpha_fe_sms_000.mca +0 -0
  153. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/data/calibration_000_golden.json +0 -0
  154. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/data/generate_cal_fixtures.py +0 -0
  155. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/data/synthetic_alpha_fe_cms_linear.mca +0 -0
  156. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/golden_models.json +0 -0
  157. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_calibration.py +0 -0
  158. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_calibration_helpers.py +0 -0
  159. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_distr_composition.py +0 -0
  160. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_distr_expansion.py +0 -0
  161. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_distr_mdl.py +0 -0
  162. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_distr_targets.py +0 -0
  163. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_expression_validation.py +0 -0
  164. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_golden_models.py +0 -0
  165. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_gui_smoke.py +0 -0
  166. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_hamiltonian_texture.py +0 -0
  167. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_legacy.py +0 -0
  168. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_library_io.py +0 -0
  169. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_model_append.py +0 -0
  170. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_model_io.py +0 -0
  171. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_model_only_mode.py +0 -0
  172. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_nbaseline_results.py +0 -0
  173. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_parameter_links.py +0 -0
  174. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_polarization.py +0 -0
  175. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_recon_composition.py +0 -0
  176. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_recon_mdl.py +0 -0
  177. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_recon_results.py +0 -0
  178. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_reference_shift.py +0 -0
  179. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_sdw_grid.py +0 -0
  180. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_support_math.py +0 -0
  181. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_texture_s1.py +0 -0
  182. {syncmoss-0.3.0 → syncmoss-0.4.0}/tests/test_thick_gui.py +0 -0
@@ -74,7 +74,7 @@ jobs:
74
74
  run: |
75
75
  python -m pip install --upgrade pip
76
76
  pip install wheels/*.whl
77
- pip install pytest
77
+ pip install pytest pytest-xdist
78
78
 
79
79
  - name: Install runtime dependencies + pytest (source checkout)
80
80
  if: inputs.install == 'source'
@@ -82,7 +82,7 @@ jobs:
82
82
  run: |
83
83
  python -m pip install --upgrade pip
84
84
  pip install -r requirements.txt
85
- pip install pytest
85
+ pip install pytest pytest-xdist
86
86
 
87
87
  - name: Run the test-suite
88
88
  shell: bash
@@ -103,4 +103,7 @@ jobs:
103
103
  if [ "$INSTALL" = "wheel" ]; then cd "$(mktemp -d)"; fi
104
104
 
105
105
  python -c "import syncmoss.syncmoss_main as m; print('syncmoss from:', m.__file__)"
106
- python -m pytest "$GITHUB_WORKSPACE/tests" "${args[@]}"
106
+ # -n 0 forces a SERIAL run: pyproject sets -n auto for local use,
107
+ # which oversubscribes a small CI runner. xdist is installed above
108
+ # only so that this flag parses.
109
+ python -m pytest "$GITHUB_WORKSPACE/tests" -n 0 "${args[@]}"
@@ -162,3 +162,11 @@ minimi_optimization_notes.txt
162
162
  # suite still covers the model end-to-end via the SCDW golden case, plus its
163
163
  # param-count and locked-angle checks (test_model_io / test_thick_gui).
164
164
  tests/test_sdw_grid.py
165
+
166
+ # SMS instrumental-function study against the ESRF (temperature, angle) dataset
167
+ # on N:\SL_studies: analysis scripts, cached intermediate fits and the figures
168
+ # they produce. Local-only -- it needs a network share that is not part of the
169
+ # repo, and its outputs are large. The conclusions that matter are tracked in
170
+ # docs/sms_instrumental_function.md; the calibration it produced is in
171
+ # sms_theory.FEBO3_BS_CALIBRATION and instrumental_io.ESRF_STANDARD_LINE_WIDTH.
172
+ sms_study/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syncmoss
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: SYNCmoss — Mössbauer spectroscopy analysis application
5
5
  Author: Sergey Yaroslavtsev
6
6
  License: MIT
@@ -73,7 +73,21 @@ local_scheme = "no-local-version"
73
73
 
74
74
  [tool.pytest.ini_options]
75
75
  testpaths = ["tests"]
76
- addopts = "-q --basetemp=./.pytest_tmp"
76
+ # -n 6: almost every test here spends its time in ONE process doing physics
77
+ # (a fit, a calibration, an instrumental-function search), so a serial run
78
+ # leaves most of the machine idle -- measured 351 s serial against 116 s on 8
79
+ # workers for the calibration + instrumental set.
80
+ #
81
+ # A FIXED 6, not "auto". Each worker builds its own QApplication, PhysicsApp
82
+ # and numba-compiled model, so the suite is limited by MEMORY, not by cores:
83
+ # "auto" resolves to one worker per core (22 here) and dies during start-up
84
+ # with an execnet EOFError once the machine runs out. The same ceiling bit the
85
+ # 83-spectrum study, where 10 parallel fits OOM'd and 6 did not.
86
+ #
87
+ # CI overrides this with -n 0 (see .github/workflows/_Tests.yml): the runners
88
+ # are small, where even 6 oversubscribes. Use -n 0 locally too when debugging,
89
+ # since xdist swallows live output.
90
+ addopts = "-q --basetemp=./.pytest_tmp -n 6"
77
91
  markers = [
78
92
  "gui: builds the PySide6 GUI; runs head-less via QT_QPA_PLATFORM=offscreen (set in tests/conftest.py)",
79
93
  "slow: slow tests (numba compilation / fitting)",
@@ -102,6 +102,7 @@ import numpy as np
102
102
 
103
103
  import syncmoss.minimi_lib as mi
104
104
  import syncmoss.models as m5
105
+ import syncmoss.sms_theory as smst
105
106
  from syncmoss.constants import (number_of_baseline_parameters, ALPHA_FE_FIELD,
106
107
  TESLA_PER_MMS, LINE_RATIO_25, LINE_RATIO_34,
107
108
  NAT_WIDTH)
@@ -532,11 +533,16 @@ def Calibration(dir_path, Cal_file, pool, VVV, INS, JN, x0, MulCo, Vel_start=1,
532
533
  return m5.TI(x, p, model, JN, pool, x0, MulCo, INS, [], [], Norm=Norm)
533
534
 
534
535
  # The multi-line instrumental function displaces the apparent line
535
- # positions by the intensity-weighted sum of the squared line shifts;
536
- # the folded velocity axis is corrected by this at the very end.
536
+ # positions by its first moment (for the legacy sum of unit-area
537
+ # Gaussians: the intensity-weighted sum of the line shifts); the folded
538
+ # velocity axis is corrected by this at the very end. The theoretical
539
+ # SMS shapes compute the same moment in sms_theory.ins_centroid.
537
540
  INS_shift = 0
538
- for i in range(0, int(len(INS) / 3)):
539
- INS_shift += INS[i * 3 + 1] * INS[i * 3 + 2] ** 2
541
+ if smst.ins_kind(INS) == smst.KIND_GAUSS:
542
+ for i in range(0, int(len(INS) / 3)):
543
+ INS_shift += INS[i * 3 + 1] * INS[i * 3 + 2] ** 2
544
+ else:
545
+ INS_shift = smst.ins_centroid(INS)
540
546
  else:
541
547
  raise ValueError(f"unknown experimental method VVV={VVV!r} (expected 1 or 3)")
542
548
 
@@ -56,6 +56,26 @@ TESLA_PER_MMS = 1 / (2 * LINE_SHIFT_16) # 3.1097641 T per mm/s o
56
56
  LINE_RATIO_25 = LINE_SHIFT_25 / LINE_SHIFT_16 # 0.5789752
57
57
  LINE_RATIO_34 = LINE_SHIFT_34 / LINE_SHIFT_16 # 0.1579504
58
58
 
59
+ # --- scattering-side 57Fe quantities (sms_theory.py) -----------------------
60
+ # Everything below is DERIVED from the primitives above plus two new inputs,
61
+ # ALPHA_IC and the universal hc; no 57Fe literal is repeated.
62
+ # ALPHA_IC -- internal conversion coefficient of the 14.4 keV level.
63
+ # HC_EV_A -- h*c = 1239.8419843320026 eV nm (exact in SI since 2019).
64
+ ALPHA_IC = 8.56
65
+ HC_EV_A = 12398.419843320026 # eV * Angstrom
66
+
67
+ MMPS_TO_NEV = E0 / c * 10**9 # 48.0733 neV per (mm/s): E = E0 v/c
68
+ GAMMA0_NEV = NAT_WIDTH * MMPS_TO_NEV # 4.7112 neV, the natural width in neV
69
+ MU_N_NEV_PER_T = mun / (E0_J / E0) * 10**9 # 31.4331 neV/T
70
+ LAMBDA_A = HC_EV_A / E0 # 0.8603 A
71
+ K_VEC_A = 2 * 3.141592653589793 / LAMBDA_A # 7.3035 1/A
72
+ R_E_A = 2.8179403262 * 10**-5 # classical electron radius, A
73
+ # Maximum resonant cross-section from the level scheme:
74
+ # sigma_0 = 2 pi lambdabar^2 (2 I_e + 1)/(2 I_g + 1) / (1 + alpha_ic)
75
+ # equals `sigma` above (2.464e-22 m^2) to 0.02 %; sms_theory.selftest() checks it.
76
+ SIGMA0_A2 = (2 * 3.141592653589793 * (LAMBDA_A / (2 * 3.141592653589793))**2
77
+ * (2 * 1.5 + 1) / (2 * 0.5 + 1) / (1 + ALPHA_IC)) # 0.024644 A^2
78
+
59
79
  # Linear polarization degree of the SMS (synchrotron) beam, 0..1. Only a default:
60
80
  # it is GUI-editable via Supp -> "Set polarization" and travels to the models as
61
81
  # the `pol` / `sms_pol` argument. 0.98 is a realistic synchrotron beam.
@@ -343,7 +343,8 @@ def fit_single_spectrum(app, spectrum_file, pool, background=None, sequence_para
343
343
  # Load and concatenate all spectra
344
344
  A_list, B_list = [], []
345
345
  for i, spec_file in enumerate(spectrum_files):
346
- A_temp, B_temp = load_spectrum(app, spec_file)
346
+ A_temp, B_temp = load_spectrum(
347
+ app, spec_file, calibration_path=app.calibration_path)
347
348
  A_temp, B_temp = A_temp[0], B_temp[0]
348
349
  A_list.append(A_temp)
349
350
  B_list.append(B_temp)
@@ -357,7 +358,8 @@ def fit_single_spectrum(app, spectrum_file, pool, background=None, sequence_para
357
358
 
358
359
  else:
359
360
  # Single spectrum fitting mode
360
- A, B = load_spectrum(app, spectrum_file)
361
+ A, B = load_spectrum(app, spectrum_file,
362
+ calibration_path=app.calibration_path)
361
363
  A, B = A[0], B[0] # Unpack from list
362
364
  A_list, B_list = [A], [B]
363
365