pyirena 0.3.3__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 (70) hide show
  1. pyirena-0.3.3/CHANGELOG.md +317 -0
  2. pyirena-0.3.3/LICENSE +21 -0
  3. pyirena-0.3.3/MANIFEST.in +18 -0
  4. pyirena-0.3.3/PKG-INFO +247 -0
  5. pyirena-0.3.3/README.md +201 -0
  6. pyirena-0.3.3/pyirena/__init__.py +62 -0
  7. pyirena-0.3.3/pyirena/batch.py +1874 -0
  8. pyirena-0.3.3/pyirena/core/__init__.py +16 -0
  9. pyirena-0.3.3/pyirena/core/data_merge.py +766 -0
  10. pyirena-0.3.3/pyirena/core/distributions.py +609 -0
  11. pyirena-0.3.3/pyirena/core/form_factors.py +644 -0
  12. pyirena-0.3.3/pyirena/core/modeling.py +1110 -0
  13. pyirena-0.3.3/pyirena/core/scattering_contrast.py +679 -0
  14. pyirena-0.3.3/pyirena/core/simple_fits.py +983 -0
  15. pyirena-0.3.3/pyirena/core/sizes.py +1207 -0
  16. pyirena-0.3.3/pyirena/core/unified.py +636 -0
  17. pyirena-0.3.3/pyirena/core/waxs_peakfit.py +1044 -0
  18. pyirena-0.3.3/pyirena/examples/__init__.py +10 -0
  19. pyirena-0.3.3/pyirena/examples/basic_demo.py +386 -0
  20. pyirena-0.3.3/pyirena/gui/__init__.py +26 -0
  21. pyirena-0.3.3/pyirena/gui/contrast_panel.py +1572 -0
  22. pyirena-0.3.3/pyirena/gui/data_merge_panel.py +1594 -0
  23. pyirena-0.3.3/pyirena/gui/data_selector.py +4136 -0
  24. pyirena-0.3.3/pyirena/gui/hdf5viewer/__init__.py +32 -0
  25. pyirena-0.3.3/pyirena/gui/hdf5viewer/collect_window.py +234 -0
  26. pyirena-0.3.3/pyirena/gui/hdf5viewer/export.py +355 -0
  27. pyirena-0.3.3/pyirena/gui/hdf5viewer/file_tree.py +398 -0
  28. pyirena-0.3.3/pyirena/gui/hdf5viewer/graph_window.py +581 -0
  29. pyirena-0.3.3/pyirena/gui/hdf5viewer/hdf5_browser.py +417 -0
  30. pyirena-0.3.3/pyirena/gui/hdf5viewer/main_window.py +569 -0
  31. pyirena-0.3.3/pyirena/gui/hdf5viewer/multi_collect_window.py +201 -0
  32. pyirena-0.3.3/pyirena/gui/hdf5viewer/plot_controls.py +951 -0
  33. pyirena-0.3.3/pyirena/gui/hdf5viewer/pyirena_readers.py +579 -0
  34. pyirena-0.3.3/pyirena/gui/launch.py +27 -0
  35. pyirena-0.3.3/pyirena/gui/modeling_panel.py +2570 -0
  36. pyirena-0.3.3/pyirena/gui/sas_plot.py +660 -0
  37. pyirena-0.3.3/pyirena/gui/simple_fits_panel.py +1439 -0
  38. pyirena-0.3.3/pyirena/gui/sizes_panel.py +2583 -0
  39. pyirena-0.3.3/pyirena/gui/unified_fit.py +3701 -0
  40. pyirena-0.3.3/pyirena/gui/unified_fit_matplotlib_old.py +973 -0
  41. pyirena-0.3.3/pyirena/gui/waxs_peakfit_panel.py +2183 -0
  42. pyirena-0.3.3/pyirena/io/__init__.py +19 -0
  43. pyirena-0.3.3/pyirena/io/contrast_io.py +373 -0
  44. pyirena-0.3.3/pyirena/io/hdf5.py +873 -0
  45. pyirena-0.3.3/pyirena/io/nxcansas_data_merge.py +242 -0
  46. pyirena-0.3.3/pyirena/io/nxcansas_modeling.py +309 -0
  47. pyirena-0.3.3/pyirena/io/nxcansas_simple_fits.py +281 -0
  48. pyirena-0.3.3/pyirena/io/nxcansas_sizes.py +291 -0
  49. pyirena-0.3.3/pyirena/io/nxcansas_unified.py +391 -0
  50. pyirena-0.3.3/pyirena/io/nxcansas_waxs_peakfit.py +334 -0
  51. pyirena-0.3.3/pyirena/io/results.py +347 -0
  52. pyirena-0.3.3/pyirena/plotting/__init__.py +28 -0
  53. pyirena-0.3.3/pyirena/plotting/plot_saxs.py +398 -0
  54. pyirena-0.3.3/pyirena/plotting/unified_plots.py +397 -0
  55. pyirena-0.3.3/pyirena/py.typed +1 -0
  56. pyirena-0.3.3/pyirena/state/__init__.py +9 -0
  57. pyirena-0.3.3/pyirena/state/state_manager.py +654 -0
  58. pyirena-0.3.3/pyirena/tests/__init__.py +6 -0
  59. pyirena-0.3.3/pyirena/tests/test_sizes.py +384 -0
  60. pyirena-0.3.3/pyirena/tests/test_unified.py +172 -0
  61. pyirena-0.3.3/pyirena.egg-info/PKG-INFO +247 -0
  62. pyirena-0.3.3/pyirena.egg-info/SOURCES.txt +68 -0
  63. pyirena-0.3.3/pyirena.egg-info/dependency_links.txt +1 -0
  64. pyirena-0.3.3/pyirena.egg-info/entry_points.txt +6 -0
  65. pyirena-0.3.3/pyirena.egg-info/requires.txt +20 -0
  66. pyirena-0.3.3/pyirena.egg-info/top_level.txt +1 -0
  67. pyirena-0.3.3/pyproject.toml +90 -0
  68. pyirena-0.3.3/requirements.txt +12 -0
  69. pyirena-0.3.3/setup.cfg +4 -0
  70. pyirena-0.3.3/setup.py +11 -0
@@ -0,0 +1,317 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## Released as first beta
9
+
10
+ ## [0.3.2] - 2026-04-05 — First public beta
11
+
12
+ First beta release published to PyPI. Install with `pip install pyirena[gui]`.
13
+
14
+ ### Added
15
+
16
+ #### Cylinder form factors for Modeling tool
17
+ Two new form factor entries for disk-like and rod-like particles:
18
+
19
+ - **Cylinder (Aspect Ratio)** (`cylinder_ar`): half-length L = AR·R, where R is the
20
+ radius from the distribution. Disk-like for AR < 1, rod-like for AR > 1.
21
+ - **Cylinder (Length)** (`cylinder_length`): fixed total height H [Å], independent of
22
+ radius. Volume scales as R² (not R³).
23
+ - Derived quantities (Rg, specific surface) use cylinder geometry.
24
+ - Orientationally-averaged form factor via 50-point Gauss-Legendre quadrature.
25
+
26
+ #### Core-shell form factors for Modeling tool
27
+ Five core-shell form factor variants with three polydispersity modes, following the
28
+ Igor Pro implementation:
29
+
30
+ - **Core-Shell Sphere** — by core R, by shell thickness, or by total R.
31
+ - **Core-Shell Spheroid** — by core R or by total R (with shared aspect ratio).
32
+ - SLD parameters (sld_core, sld_shell, sld_solvent in 10⁻⁶ Å⁻²) replace the scalar
33
+ contrast parameter, which is automatically locked to 1.0 and hidden in the GUI.
34
+ - SLD-contrast-weighted Rg; specific surface based on outer radius (Porod law).
35
+ - Volume convention: `scale` and `volume_fraction` are based on total particle volume
36
+ (core + shell together), not core-only. Documented in code and user guide.
37
+
38
+ #### Modeling GUI — standard buttons
39
+ Added standard buttons matching other tools (Simple Fits, Unified Fit, Sizes):
40
+
41
+ - **Results to graph** (#81c784 green) — annotate I(Q) plot with fitted parameter values.
42
+ - **Save State** (#3498db blue) — save current parameters to state file.
43
+ - **Import Parameters** (lightgreen) — import from pyIrena JSON config file.
44
+ - **Reset to Defaults** (#e67e22 orange) — reset all populations to default values.
45
+ - **Store in File** / **Export Parameters** renamed and recoloured to match standard.
46
+ - Auto-save state on window close (`closeEvent`).
47
+
48
+ ### Fixed
49
+
50
+ - **Modeling "Open..." button**: loading a new file now clears all previous data, model
51
+ curves, distributions, residuals, and annotations from the graph. Previously old items
52
+ persisted because `graph_model()` and `_on_fit_complete()` bypassed the data tracking.
53
+ - **Modeling `load_file()`**: replaced nonexistent `load_nxcansas` import with the correct
54
+ `readGenericNXcanSAS` function from `pyirena.io.hdf5`.
55
+ - **Core-shell G-matrix units**: corrected from `F²×1e-16` to `F²/V_total×1e-4`. The old
56
+ formula double-counted the SLD unit conversion and missed the division by particle
57
+ volume, causing intensities ~10⁶ times too low.
58
+
59
+ ## [0.2.1] - 2026-03-20
60
+
61
+ ### Added
62
+
63
+ #### Modeling tool — parametric size-distribution fitting
64
+ New analysis tool for forward-modelling small-angle scattering data using
65
+ parametric size distributions, Unified Fit levels, and diffraction peaks.
66
+
67
+ - **5 distribution functions**: Gaussian, LogNormal (3-parameter shifted), LSW,
68
+ Schulz-Zimm (Gamma), Ardell — Igor-style CDF-inversion radius grid.
69
+ - **3 population types** combinable in up to 5 simultaneous populations:
70
+ - `SizeDistPopulation`: distribution × form factor (sphere, spheroid) × optional
71
+ structure factor (interferences / hard-sphere Percus-Yevick).
72
+ - `UnifiedLevelPopulation`: Beaucage Unified level G·exp(−q²Rg²/3) + B·Q*⁻ᴾ
73
+ with optional Born-Green correlations.
74
+ - `DiffractionPeakPopulation`: Gaussian, Lorentzian, or pseudo-Voigt peak at Q₀.
75
+ - **Engine** (`pyirena/core/modeling.py`): `ModelingEngine` with G-matrix caching,
76
+ `scipy.optimize.least_squares` (TRF) or Nelder-Mead fitting, and MC uncertainty.
77
+ - **HDF5 I/O** (`pyirena/io/nxcansas_modeling.py`): save/load for all population types.
78
+ - **GUI panel** (`pyirena/gui/modeling_panel.py`): multi-tab population editor,
79
+ I(Q) log-log plot with per-population overlays, distribution preview, Export/Import
80
+ Parameters, and MC uncertainty estimation.
81
+ - **Batch API** (`pyirena/batch.py`): `fit_modeling()` headless fitting function;
82
+ registered in `fit_pyirena()` under the `modeling` config key.
83
+ - **Data Selector** integration: Modeling (GUI/script) buttons at row 4.
84
+
85
+ #### Data Merge tool — SAXS/WAXS merging
86
+ New tool for merging two SAS datasets (e.g. SAXS + WAXS) onto a common Q scale.
87
+
88
+ - **Engine** (`pyirena/core/data_merge.py`): Nelder-Mead optimisation of scale factor,
89
+ flat background (DS1), and optional Q-shift; log-log linear interpolation in the
90
+ overlap region.
91
+ - **HDF5 I/O** (`pyirena/io/nxcansas_data_merge.py`): copies DS1 NXcanSAS file and
92
+ replaces Q/I/Idev/Qdev with merged data; appends `entry/data_merge_results`.
93
+ - **GUI panel** (`pyirena/gui/data_merge_panel.py`): dual dataset loader, SAXS/WAXS
94
+ plot mode toggle, cursor-driven overlap range, optimisation controls, and batch mode.
95
+ - **Batch API**: `merge_data()` headless merge function.
96
+ - **CLI entry point**: `pyirena-datamerge` console script.
97
+
98
+ #### Scattering Contrast Calculator
99
+ New tool for computing X-ray and neutron scattering length densities and contrast.
100
+
101
+ - Compound-level SLD calculation from chemical formula, density, and X-ray energy.
102
+ - Supports neutron SLDs with isotope substitution.
103
+ - Phase-pair contrast (ΔρX)² and (ΔρN)² tables.
104
+ - **GUI panel** (`pyirena/gui/contrast_panel.py`) with compound library, interactive
105
+ crosshair energy cursor, and JPEG export.
106
+ - **CLI entry point**: `pyirena-contrast` console script.
107
+
108
+ ### Fixed
109
+
110
+ - **`fit_modeling` batch function**: previously only deserialized `SizeDistPopulation`
111
+ from config; now correctly rebuilds `UnifiedLevelPopulation` and
112
+ `DiffractionPeakPopulation` via `pop_type` dispatch.
113
+ - **`fit_pyirena`**: `modeling` config key was missing from `_TOOL_REGISTRY`; added
114
+ so `fit_pyirena()` automatically runs `fit_modeling()` when a `modeling` section is
115
+ present in the config file.
116
+ - **`pyirena/__init__.py`**: `__version__` was not updated from 0.1.1; now kept in
117
+ sync with `pyproject.toml`.
118
+
119
+ ## [0.1.2] - 2026-02-22
120
+
121
+ ### Added
122
+
123
+ #### Simple Fits tool — 13 single-model analytical fits
124
+ New analysis tool ported from Igor Pro `IR3_SimpleFits.ipf` and
125
+ `IR3_SystemSpecificModels.ipf`. Provides direct analytical model fitting with
126
+ linearization plots, Monte Carlo uncertainty estimation, and full HDF5 I/O.
127
+
128
+ **Core (`pyirena/core/simple_fits.py`)**
129
+ - `SimpleFitModel` dataclass: holds model name, parameters, limits, and complex-background
130
+ flag; provides `fit(q, I, dI)`, `to_dict()`, `from_dict()`.
131
+ - `MODEL_REGISTRY` dict mapping every model name to its parameter definitions, formula
132
+ function, linearization type, and complex-background flag.
133
+ - 13 supported models (parameter names in parentheses):
134
+
135
+ | Model | Parameters | Linearization |
136
+ |-------|-----------|---------------|
137
+ | Guinier | I0, Rg | ln(I) vs Q² |
138
+ | Guinier Rod | I0, Rc | ln(QI) vs Q² |
139
+ | Guinier Sheet | I0, Rg | ln(Q²I) vs Q² |
140
+ | Porod | Kp, Background | IQ⁴ vs Q⁴ |
141
+ | Power Law | P, Exponent, Background | — |
142
+ | Sphere | Scale, R | — |
143
+ | Spheroid | Scale, R, Beta | — |
144
+ | Debye-Bueche | Prefactor, Eta, CorrLength | — |
145
+ | Treubner-Strey | Prefactor, A, C1, C2 | — |
146
+ | Benedetti-Ciccariello | SolidSLD, VoidSLD, LayerSLD, Sp, t | — |
147
+ | Hermans | B, s, d1, d2, sigma1, sigma2 | — |
148
+ | Hybrid Hermans | Hermans params + G2, Rg2, G3, Rg3, B3, P3 | — |
149
+ | Unified Born Green | G1, Rg1, B1, P1, G2, Rg2, B2, P2, eta, ksi | — |
150
+
151
+ - Optional complex background `BG_A·Q⁻ⁿ + BG_flat` on all models except Porod and
152
+ Power Law (which have an explicit flat Background parameter).
153
+ - Sphere uses Gauss-Legendre quadrature orientational average for efficiency.
154
+ - Treubner-Strey derives correlation length ξ and repeat distance d from fit params.
155
+ - Guinier Sheet derives layer thickness from Rg.
156
+ - `fit()` uses `scipy.optimize.curve_fit`; returns chi², reduced chi², DOF,
157
+ `params_std` (from covariance diagonal), `residuals`, and model-specific `derived`.
158
+
159
+ **HDF5 I/O (`pyirena/io/nxcansas_simple_fits.py`)**
160
+ - `save_simple_fit_results(filepath, result, model_obj, intensity_data, intensity_error)`:
161
+ writes/overwrites `entry/simple_fit_results` NXprocess group.
162
+ - `load_simple_fit_results(filepath)`: loads all fit scalars, arrays, params, params_std,
163
+ and derived quantities.
164
+ - `print_simple_fit_results(result)`: formatted console summary.
165
+
166
+ **GUI panel (`pyirena/gui/simple_fits_panel.py`)**
167
+ - Three-panel layout: I(Q) log-log + model overlay (with cursor-selectable Q range),
168
+ normalised residuals, linearization plot (Guinier/Porod families only).
169
+ - Cursor-driven Q range selection linked to the I(Q) plot.
170
+ - Per-parameter widgets: value, lower/upper limits, "Fit?" checkbox; "No Limits" toggle.
171
+ - Complex background checkbox: adds BG_A, BG_n, BG_flat sub-parameters.
172
+ - **Fit** button: runs `SimpleFitModel.fit()`, displays results with ± uncertainties.
173
+ - **Calculate Uncertainty** button: Monte Carlo loop (configurable N runs); updates ± labels.
174
+ - **Store in File** button: saves results to HDF5.
175
+ - **Export / Import Parameters** buttons: read/write `simple_fits` section in a shared
176
+ `pyirena_config.json` (interoperable with Unified Fit and Sizes config files).
177
+ - Linearization panel shows transformed data + linear fit + intercept annotation for
178
+ Guinier/Porod models; shows "No linearization available" for other models.
179
+ - Highlighted Q-range band on linearization scatter plot.
180
+ - State fully persisted via `StateManager`; stale parameters removed on model change.
181
+
182
+ **Batch API (`pyirena/batch.py`)**
183
+ - `fit_simple(data_file, config, with_uncertainty, n_mc_runs, q_min, q_max)`: headless
184
+ fitting from a `SimpleFitModel` or plain dict config; saves results to HDF5.
185
+ - `fit_simple_from_config(data_file, config_file, save_to_nexus, ...)`: wrapper that
186
+ reads the `simple_fits` section of a `pyirena_config.json` (normalises GUI state-dict
187
+ keys, extracts q_min/q_max) and calls `fit_simple()`.
188
+ - `fit_pyirena()` now dispatches `simple_fits` config sections to `fit_simple_from_config()`.
189
+ - `fit_simple` exported from `pyirena.__init__`.
190
+
191
+ **Data Selector integration (`pyirena/gui/data_selector.py`)**
192
+ - **"Simple Fits"** checkbox added alongside Data / Unified Fit / Size Dist. checkboxes.
193
+ - *Create Graph*: opens `SimpleFitResultsWindow` (I(Q) + model + residuals, matching
194
+ colour scheme to the dataset; model line uses `color.darker(280)` for clear contrast).
195
+ - *Create Report*: loads `simple_fit_results` from HDF5; adds "## Simple Fits" section
196
+ with model name, chi², reduced chi², DOF, Q range, all parameters ± std, derived quantities.
197
+ - *Tabulate Results*: adds `SF_model`, `SF_chi2`, `SF_reduced_chi2`, `SF_dof`,
198
+ `SF_q_min`, `SF_q_max`, `SF_use_complex_bg`, `SF_<param>`, `SF_<param>_std`, and
199
+ `SF_derived_<name>` columns (dynamic — adapts to the parameters of the fitted model).
200
+ - **"Simple Fits (script)"** batch button now correctly calls `fit_simple_from_config()`
201
+ and saves results to the HDF5 file (was falling through to fit_sizes with no save).
202
+
203
+ #### Public API
204
+ - **`load_result(filepath, analysis)`** (`pyirena/io/results.py`) — importable directly
205
+ as `from pyirena import load_result`. Pass a file path and an analysis name
206
+ (`'unified_fit'`, `'size_distribution'`, or `'simple_fits'`) to retrieve a fully
207
+ documented result dict. Returns a safe empty structure (`found=False`) if results
208
+ are absent — no exception raised.
209
+ - `SUPPORTED_ANALYSES` tuple exported from `pyirena`.
210
+
211
+ #### Plot improvements (all panels)
212
+ - **Phantom-point fix** (I(Q) graph, Unified Fit, Size Distribution): error bar tops
213
+ clipped at `min(I·1000, P99(I)·1000)` — prevents cosmic rays or WAXS peaks at
214
+ extreme intensities from driving the y-axis to 10³⁸.
215
+ - **ViewBox hard limits**: y-axis locked to ±3 decades beyond the 99th-percentile data
216
+ range; x-axis locked to the nearest full decade beyond the data Q range ±1 extra
217
+ decade. Prevents accidental zoom-out to empty space.
218
+ - **x-axis zoom constraint**: applied to Simple Fits, Size Distribution, and Unified Fit
219
+ panels. Example: data 0.003–0.8 Å⁻¹ → zoom limits 0.0001–10 Å⁻¹.
220
+
221
+ ### Fixed
222
+ - **Data Selector sort order**: the saved "Sort" pulldown state is now applied to the
223
+ file list immediately on startup (was restored to the combo but the list remained
224
+ alphabetical until the user manually changed the setting).
225
+ - **Report generation** (Size Distribution): section now reads scalar parameters from
226
+ the flat dict returned by `load_sizes_results()` (no longer looks for a non-existent
227
+ nested `'params'` key). Previously all parameters showed as `nan`/`unknown`.
228
+ - **Report generation** (Size Distribution): now includes all stored parameters:
229
+ contrast, aspect ratio, log spacing, background, error scale, power law B/P, Q range,
230
+ n_iterations, plus method-specific sub-tables for MaxEnt, Regularization, TNNLS, and
231
+ Monte Carlo.
232
+
233
+ ## [0.1.1] - 2026-02-19
234
+
235
+ ### Added
236
+
237
+ #### Size Distribution — Complex Background Model
238
+ - `SizesDistribution.compute_complex_background(q)`: evaluates `B·q⁻ᴾ + background`
239
+ for arbitrary q arrays.
240
+ - `SizesDistribution.fit_power_law(q, I, q_min, q_max, fit_B, fit_P)`: fits the
241
+ power-law amplitude B and/or exponent P to a user-selected Q range using
242
+ `scipy.optimize.curve_fit`.
243
+ - `SizesDistribution.fit_background_term(q, I, q_min, q_max)`: estimates the flat
244
+ background by averaging `I − B·q⁻ᴾ` in a selected Q range.
245
+ - New class attributes `power_law_B` and `power_law_P`; `fit()` now subtracts the
246
+ full complex background before inverting, and returns `n_data` in the result dict.
247
+
248
+ #### Size Distribution GUI (`sizes_panel.py`)
249
+ - **Background tab**: new panel tab with "Power-Law Term B·q⁻ᴾ" and "Flat Background"
250
+ groups; each has its own Q-range fields, "Set Q from cursors" button, and individual
251
+ fit buttons ("Fit P/B", "Fit Background").
252
+ - **"Fit Sizes" / "Fit All"** buttons: "Fit All" runs power-law fit → background fit
253
+ → size distribution fit sequentially in one click.
254
+ - **Corrected-data overlay**: I(Q) − complex background shown as blue triangles on the
255
+ main graph, limited to the cursor Q range; complex background shown as a dashed grey
256
+ line.
257
+ - **"Calculate Uncertainty (MC)"** button: runs 10 Monte-Carlo fits on
258
+ Gaussian-perturbed data; reports per-bin mean/std of the distribution as error bars,
259
+ and propagates Rg, Vf, and peak-r uncertainties with ± notation in the Results box.
260
+ - **"Export Parameters" / "Import Parameters"** buttons: save and load all Sizes
261
+ parameters to/from a `pyirena_config.json` file sharing the same `_pyirena_config`
262
+ envelope used by Unified Fit (files are interoperable between tools).
263
+ - **Layout improvements**:
264
+ - Q min and Q max shown on one row in the Q Range group.
265
+ - Number-of-bins spinbox and "Logarithmic spacing" checkbox share one row.
266
+ - MaxEnt, Regularization, and TNNLS sub-controls each condensed to a single row.
267
+ - Results box condensed to two rows (χ²/Vf and Rg/Peak r).
268
+ - **Finer mouse-wheel steps** for Error scale: `ScrubbableLineEdit` now accepts a
269
+ `step_factor` parameter (default 0.1); Error scale uses 0.02 for precise control.
270
+ - **Fit curve** rendered with `width=4` pen and plotted on top of all other items.
271
+ - **Error scale live preview**: changing the Error scale field immediately redraws the
272
+ error bars without requiring a new fit.
273
+
274
+ #### Batch API (`batch.py`)
275
+ - `fit_sizes(data_file, config_file, save_to_nexus=True)`: headless size-distribution
276
+ fitting function analogous to `fit_unified()`. Reads a `'sizes'` group from a
277
+ pyIrena config JSON, applies the saved cursor Q range, runs the fit, optionally saves
278
+ results to NXcanSAS HDF5, and returns a structured result dict.
279
+ - `fit_pyirena()` now automatically dispatches to `fit_sizes()` when a config file
280
+ contains a `'sizes'` group.
281
+ - `fit_sizes` added to the public API (`pyirena.__init__`).
282
+
283
+ #### Data Selector (`data_selector.py`)
284
+ - **"Size Dist." checkbox** added next to the existing "Data" and "Unified Fit"
285
+ checkboxes.
286
+ - *Create Graph*: if checked, opens the Size Distribution panel with the selected
287
+ file's data.
288
+ - *Create Report*: if checked, loads stored size-distribution results from HDF5 and
289
+ includes a "## Size Distribution" section (chi², Vf, Rg, peak r, method, shape,
290
+ residuals stats) in the Markdown report.
291
+
292
+ #### State management (`state_manager.py`)
293
+ - `DEFAULT_STATE["sizes"]` extended with `power_law_B`, `power_law_P`,
294
+ `power_law_q_min`, `power_law_q_max`, `background_q_min`, `background_q_max`.
295
+ - Schema migration from version 1 → 2 resets `n_bins` (50 → 200), `log_spacing`
296
+ (False → True), and initialises `error_scale` on old saved states.
297
+
298
+ ### Changed
299
+ - `SizesDistribution.fit()` now subtracts the complex background `B·q⁻ᴾ + background`
300
+ (previously only the flat background was removed).
301
+ - Default `n_bins` changed from 50 to 200 and `log_spacing` from False to True
302
+ (better resolution for typical SAXS size distributions); old saved states are
303
+ migrated automatically via `schema_version`.
304
+ - Sizes panel minimum width increased to 420 px to accommodate the wider layout.
305
+
306
+ ## [0.1.0] - 2024-02-13
307
+
308
+ ### Added
309
+ - Initial release of pyIrena
310
+ - Unified Fit model for small-angle scattering analysis
311
+ - Support for multi-level hierarchical structures
312
+ - Mass fractal mode
313
+ - Correlation function (Born-Green approximation)
314
+ - Parameter linking capabilities
315
+ - NXcanSAS HDF5 file support
316
+ - Basic plotting and analysis utilities
317
+ - Comprehensive documentation and examples
pyirena-0.3.3/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Jan Ilavsky
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,18 @@
1
+ # Include documentation files
2
+ include README.md
3
+ include LICENSE
4
+ include CHANGELOG.md
5
+ include requirements.txt
6
+
7
+ # Include examples
8
+ recursive-include pyirena/examples *.py *.ipynb *.md
9
+
10
+ # Include tests
11
+ recursive-include pyirena/tests *.py
12
+
13
+ # Exclude unnecessary files
14
+ global-exclude *.pyc
15
+ global-exclude *.pyo
16
+ global-exclude __pycache__
17
+ global-exclude .DS_Store
18
+ global-exclude *.ipf
pyirena-0.3.3/PKG-INFO ADDED
@@ -0,0 +1,247 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyirena
3
+ Version: 0.3.3
4
+ Summary: Python tools for small-angle scattering data analysis.
5
+ Author-email: Jan Ilavsky <ilavsky@anl.gov>
6
+ Maintainer-email: Jan Ilavsky <ilavsky@anl.gov>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/jilavsky/pyirena
9
+ Project-URL: Documentation, https://github.com/jilavsky/pyirena/tree/main/docs
10
+ Project-URL: Repository, https://github.com/jilavsky/pyirena
11
+ Project-URL: Changelog, https://github.com/jilavsky/pyirena/blob/main/CHANGELOG.md
12
+ Project-URL: Bug Tracker, https://github.com/jilavsky/pyirena/issues
13
+ Keywords: SAXS,SANS,USAXS,small-angle scattering,unified fit,Beaucage,X-ray scattering,neutron scattering,SAS,size distribution,core-shell,form factor
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Scientific/Engineering :: Physics
24
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: numpy>=1.22.0
29
+ Requires-Dist: scipy>=1.8.0
30
+ Requires-Dist: h5py>=3.0.0
31
+ Provides-Extra: gui
32
+ Requires-Dist: matplotlib>=3.5.0; extra == "gui"
33
+ Requires-Dist: PySide6>=6.4.0; extra == "gui"
34
+ Requires-Dist: pyqtgraph>=0.13.0; extra == "gui"
35
+ Requires-Dist: xraydb>=4.5; extra == "gui"
36
+ Requires-Dist: periodictable>=1.7; extra == "gui"
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest>=7.0; extra == "dev"
39
+ Requires-Dist: pytest-cov; extra == "dev"
40
+ Requires-Dist: build; extra == "dev"
41
+ Requires-Dist: twine; extra == "dev"
42
+ Provides-Extra: all
43
+ Requires-Dist: pyirena[gui]; extra == "all"
44
+ Requires-Dist: pyirena[dev]; extra == "all"
45
+ Dynamic: license-file
46
+
47
+ # pyIrena
48
+
49
+ > Coded by Claude from SAXS_IgorCode Irena. Planned, defined, debugged and validated by Jan Ilavsky.
50
+
51
+ Python tools for small-angle scattering (SAS) data analysis. A port of the Igor Pro
52
+ [Irena](https://usaxs.xray.aps.anl.gov/software/irena) package. Includes interactive
53
+ GUI tools for fitting, modeling, data merging, and visualization of SAXS/SANS/USAXS data.
54
+
55
+ **Current release: v0.3.2 (first public beta)**
56
+
57
+ [![PyPI version](https://img.shields.io/pypi/v/pyirena.svg)](https://pypi.org/project/pyirena/)
58
+ [![Python Version](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
59
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
60
+
61
+ ---
62
+
63
+ ## Installation
64
+
65
+ **From PyPI (recommended):**
66
+
67
+ ```bash
68
+ pip install pyirena[gui]
69
+ ```
70
+
71
+ This installs pyirena with all GUI dependencies (PySide6, pyqtgraph, etc.). For the
72
+ core library only (no GUI), use `pip install pyirena`.
73
+
74
+ **From source (for development):**
75
+
76
+ ```bash
77
+ git clone https://github.com/jilavsky/pyirena.git
78
+ cd pyirena
79
+ pip install -e ".[gui]"
80
+ ```
81
+
82
+ **With conda:**
83
+
84
+ ```bash
85
+ git clone https://github.com/jilavsky/pyirena.git
86
+ cd pyirena
87
+ conda env create -f environment.yml
88
+ conda activate pyirena
89
+ ```
90
+
91
+ See [docs/installation.md](docs/installation.md) for full details, troubleshooting, and platform notes.
92
+
93
+ ---
94
+
95
+ ## Running the GUI
96
+
97
+ ```bash
98
+ pyirena-gui
99
+ ```
100
+
101
+ This launches the Data Selector, the main entry point for all analysis tools.
102
+ See [docs/gui_quickstart.md](docs/gui_quickstart.md) for a walkthrough.
103
+
104
+ Individual tools can also be launched directly:
105
+
106
+ | Command | Tool |
107
+ |---------|------|
108
+ | `pyirena-gui` | Data Selector (main entry point) |
109
+ | `pyirena-viewer` | HDF5 Viewer / Data Extractor |
110
+ | `pyirena-modeling` | Modeling tool (standalone) |
111
+ | `pyirena-datamerge` | Data Merge tool (standalone) |
112
+ | `pyirena-contrast` | Scattering Contrast Calculator |
113
+
114
+ ---
115
+
116
+ ## Analysis Tools
117
+
118
+ ### Modeling
119
+ Parametric forward-modeling of SAS data. Combine up to 10 populations, each of which
120
+ can be a Size Distribution, Unified Fit Level, or Diffraction Peak. Fits the combined
121
+ model to experimental data using least-squares optimization.
122
+
123
+ - **5 distribution functions**: Gaussian, LogNormal, LSW, Schulz-Zimm, Ardell
124
+ - **9 form factors**: Sphere, Spheroid, Cylinder (aspect ratio / fixed length),
125
+ Core-Shell Sphere and Spheroid (by core R / shell t / total R)
126
+ - **2 structure factors**: Born-Green interferences, Hard Sphere (Percus-Yevick)
127
+ - Monte Carlo uncertainty estimation
128
+ - [Modeling GUI guide](docs/modeling_gui.md)
129
+
130
+ ### Unified Fit
131
+ Beaucage hierarchical model (1995, 1996) with 1-5 structural levels, each combining
132
+ Guinier and power-law contributions. Optional Born-Green correlation function.
133
+
134
+ - [Unified Fit GUI guide](docs/unified_fit_gui.md)
135
+ - [Unified Fit features & parameters](docs/unified_fit_features.md)
136
+
137
+ ### Size Distribution
138
+ Indirect Fourier transform to recover particle size distributions from SAS data.
139
+ Four inversion methods: MaxEnt, Regularization, TNNLS, and Monte Carlo.
140
+
141
+ - [Size Distribution methods](docs/sizes_methods.md)
142
+
143
+ ### Simple Fits
144
+ 13 direct analytical models: Guinier, Guinier-Porod, Porod, Sphere, Spheroid,
145
+ Debye-Bueche, Treubner-Strey, Power Law, and more. Each with linearization plots
146
+ and Monte Carlo uncertainty estimation.
147
+
148
+ - [Simple Fits GUI guide](docs/simple_fits_gui.md)
149
+
150
+ ### WAXS Peak Fit
151
+ Fit diffraction peaks (Gaussian, Lorentzian, Pseudo-Voigt, Log-Normal) on linear
152
+ I vs Q scale. Auto-detect peaks via Savitzky-Golay + `scipy.signal.find_peaks`.
153
+ Simultaneous background fitting (constant, linear, cubic, or 5th-order polynomial).
154
+
155
+ - [WAXS Peak Fit GUI guide](docs/waxs_peakfit_gui.md)
156
+
157
+ ### Data Merge
158
+ Merge two SAS datasets (e.g., SAXS + WAXS) onto a common Q scale. Optimizes scale
159
+ factor, flat background, and optional Q-shift using Nelder-Mead.
160
+
161
+ - [Data Merge GUI guide](docs/data_merge_gui.md)
162
+
163
+ ### HDF5 Viewer / Data Extractor
164
+ Browse NXcanSAS HDF5 files, inspect raw data and analysis results, extract and plot
165
+ datasets. Supports all pyIrena result types (Unified Fit, Sizes, Simple Fits, WAXS
166
+ Peaks, Modeling).
167
+
168
+ - [HDF5 Viewer guide](docs/hdf5_viewer_gui.md)
169
+
170
+ ### Scattering Contrast Calculator
171
+ Look up X-ray and neutron scattering length densities for materials by chemical
172
+ formula. Computes contrast (Delta-rho-squared) between two materials.
173
+
174
+ - [Contrast Calculator guide](docs/scattering_contrast_gui.md)
175
+
176
+ ### Data Selector
177
+ Central GUI panel for managing data files and launching analysis tools. Load HDF5
178
+ files, select datasets, tabulate results across files, and generate reports.
179
+
180
+ ---
181
+
182
+ ## Batch Scripting API
183
+
184
+ All analysis tools can be run headlessly from Python scripts or JSON configuration files:
185
+
186
+ ```python
187
+ from pyirena.batch import fit_pyirena
188
+
189
+ results = fit_pyirena(
190
+ data_file='sample.h5',
191
+ config_file='pyirena_config.json',
192
+ )
193
+ ```
194
+
195
+ Individual functions: `fit_unified`, `fit_sizes`, `fit_simple`, `fit_waxs`,
196
+ `fit_modeling`, `merge_data`.
197
+
198
+ See [docs/batch_api.md](docs/batch_api.md) for the full scripting guide.
199
+
200
+ ---
201
+
202
+ ## NXcanSAS I/O
203
+
204
+ All data and results are stored in HDF5 files using the
205
+ [NXcanSAS](https://www.nexusformat.org/NXcanSAS.html) format. Fit results are saved
206
+ alongside raw data, making files self-contained and shareable.
207
+
208
+ - [NXcanSAS format details](docs/NXcanSAS_UnifiedFit_Format.md)
209
+
210
+ ---
211
+
212
+ ## Documentation
213
+
214
+ | Topic | File |
215
+ |-------|------|
216
+ | Installation | [docs/installation.md](docs/installation.md) |
217
+ | Quick start (GUI) | [docs/gui_quickstart.md](docs/gui_quickstart.md) |
218
+ | Modeling GUI guide | [docs/modeling_gui.md](docs/modeling_gui.md) |
219
+ | Unified Fit GUI guide | [docs/unified_fit_gui.md](docs/unified_fit_gui.md) |
220
+ | Unified Fit features & parameters | [docs/unified_fit_features.md](docs/unified_fit_features.md) |
221
+ | Size Distribution methods | [docs/sizes_methods.md](docs/sizes_methods.md) |
222
+ | Simple Fits GUI guide | [docs/simple_fits_gui.md](docs/simple_fits_gui.md) |
223
+ | WAXS Peak Fit GUI guide | [docs/waxs_peakfit_gui.md](docs/waxs_peakfit_gui.md) |
224
+ | Data Merge GUI guide | [docs/data_merge_gui.md](docs/data_merge_gui.md) |
225
+ | HDF5 Viewer guide | [docs/hdf5_viewer_gui.md](docs/hdf5_viewer_gui.md) |
226
+ | Contrast Calculator guide | [docs/scattering_contrast_gui.md](docs/scattering_contrast_gui.md) |
227
+ | NXcanSAS file format | [docs/NXcanSAS_UnifiedFit_Format.md](docs/NXcanSAS_UnifiedFit_Format.md) |
228
+ | Batch fitting API | [docs/batch_api.md](docs/batch_api.md) |
229
+ | Usage guide (scripting) | [docs/usage_guide.md](docs/usage_guide.md) |
230
+ | Developer: adding form factors | [docs/developer_adding_form_factors.md](docs/developer_adding_form_factors.md) |
231
+ | Developer: adding structure factors | [docs/developer_adding_structure_factors.md](docs/developer_adding_structure_factors.md) |
232
+ | Testing | [docs/testing.md](docs/testing.md) |
233
+ | Distribution / packaging | [docs/distribution.md](docs/distribution.md) |
234
+ | Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) |
235
+ | Changelog | [CHANGELOG.md](CHANGELOG.md) |
236
+
237
+ ---
238
+
239
+ ## License
240
+
241
+ MIT -- see [LICENSE](LICENSE).
242
+
243
+ ## Contact
244
+
245
+ - **Author**: Jan Ilavsky -- ilavsky@aps.anl.gov
246
+ - **Affiliation**: X-ray Science Division, Argonne National Laboratory
247
+ - **Issues**: https://github.com/jilavsky/pyirena/issues