anisa 0.0.1b1__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.
- anisa-0.0.1b1/LICENSE +21 -0
- anisa-0.0.1b1/PKG-INFO +184 -0
- anisa-0.0.1b1/README.md +136 -0
- anisa-0.0.1b1/anisa/__init__.py +27 -0
- anisa-0.0.1b1/anisa/__main__.py +5 -0
- anisa-0.0.1b1/anisa/api.py +354 -0
- anisa-0.0.1b1/anisa/cli.py +171 -0
- anisa-0.0.1b1/anisa/core/__init__.py +63 -0
- anisa-0.0.1b1/anisa/core/anisotropy.py +249 -0
- anisa-0.0.1b1/anisa/core/derived.py +62 -0
- anisa-0.0.1b1/anisa/core/engine.py +588 -0
- anisa-0.0.1b1/anisa/core/fitting.py +635 -0
- anisa-0.0.1b1/anisa/core/formfactor.py +212 -0
- anisa-0.0.1b1/anisa/core/geometry.py +80 -0
- anisa-0.0.1b1/anisa/core/model.py +458 -0
- anisa-0.0.1b1/anisa/core/orientation.py +248 -0
- anisa-0.0.1b1/anisa/core/sizedist.py +199 -0
- anisa-0.0.1b1/anisa/demo.py +246 -0
- anisa-0.0.1b1/anisa/gui/__init__.py +6 -0
- anisa-0.0.1b1/anisa/gui/__main__.py +3 -0
- anisa-0.0.1b1/anisa/gui/_qt.py +168 -0
- anisa-0.0.1b1/anisa/gui/anisotropy_tab.py +445 -0
- anisa-0.0.1b1/anisa/gui/app.py +29 -0
- anisa-0.0.1b1/anisa/gui/directions_panel.py +407 -0
- anisa-0.0.1b1/anisa/gui/main_window.py +1155 -0
- anisa-0.0.1b1/anisa/gui/plots.py +318 -0
- anisa-0.0.1b1/anisa/gui/population_editor.py +574 -0
- anisa-0.0.1b1/anisa/gui/state.py +67 -0
- anisa-0.0.1b1/anisa/gui/widgets.py +219 -0
- anisa-0.0.1b1/anisa/gui/workers.py +130 -0
- anisa-0.0.1b1/anisa/io/__init__.py +1 -0
- anisa-0.0.1b1/anisa/io/bernardyn_export.py +106 -0
- anisa-0.0.1b1/anisa/io/data.py +227 -0
- anisa-0.0.1b1/anisa/io/project.py +137 -0
- anisa-0.0.1b1/anisa/io/results.py +421 -0
- anisa-0.0.1b1/anisa/mcp/__init__.py +2 -0
- anisa-0.0.1b1/anisa/mcp/server.py +51 -0
- anisa-0.0.1b1/anisa/mcp/tools.py +163 -0
- anisa-0.0.1b1/anisa/py.typed +0 -0
- anisa-0.0.1b1/anisa/testsets.py +334 -0
- anisa-0.0.1b1/anisa.egg-info/PKG-INFO +184 -0
- anisa-0.0.1b1/anisa.egg-info/SOURCES.txt +62 -0
- anisa-0.0.1b1/anisa.egg-info/dependency_links.txt +1 -0
- anisa-0.0.1b1/anisa.egg-info/entry_points.txt +4 -0
- anisa-0.0.1b1/anisa.egg-info/requires.txt +26 -0
- anisa-0.0.1b1/anisa.egg-info/top_level.txt +1 -0
- anisa-0.0.1b1/pyproject.toml +113 -0
- anisa-0.0.1b1/setup.cfg +4 -0
- anisa-0.0.1b1/tests/test_anisotropy.py +237 -0
- anisa-0.0.1b1/tests/test_bernardyn_export.py +75 -0
- anisa-0.0.1b1/tests/test_cli.py +144 -0
- anisa-0.0.1b1/tests/test_demo.py +182 -0
- anisa-0.0.1b1/tests/test_engine.py +492 -0
- anisa-0.0.1b1/tests/test_fitting.py +324 -0
- anisa-0.0.1b1/tests/test_formfactor.py +161 -0
- anisa-0.0.1b1/tests/test_geometry_orientation.py +182 -0
- anisa-0.0.1b1/tests/test_gui.py +693 -0
- anisa-0.0.1b1/tests/test_io.py +344 -0
- anisa-0.0.1b1/tests/test_mcp.py +127 -0
- anisa-0.0.1b1/tests/test_model_derived.py +216 -0
- anisa-0.0.1b1/tests/test_orientation_resolution.py +90 -0
- anisa-0.0.1b1/tests/test_package.py +108 -0
- anisa-0.0.1b1/tests/test_results.py +128 -0
- anisa-0.0.1b1/tests/test_sizedist.py +124 -0
anisa-0.0.1b1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 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.
|
anisa-0.0.1b1/PKG-INFO
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: anisa
|
|
3
|
+
Version: 0.0.1b1
|
|
4
|
+
Summary: Small-angle scattering modelling of anisotropic particle populations (successor of Igor AnisoSAS).
|
|
5
|
+
Author-email: Jan Ilavsky <ilavsky@anl.gov>
|
|
6
|
+
Maintainer-email: Jan Ilavsky <ilavsky@anl.gov>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/jilavsky/anisa
|
|
9
|
+
Project-URL: Repository, https://github.com/jilavsky/anisa
|
|
10
|
+
Project-URL: Changelog, https://github.com/jilavsky/anisa/blob/main/CHANGELOG.md
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/jilavsky/anisa/issues
|
|
12
|
+
Keywords: SAXS,SANS,USAXS,small-angle scattering,anisotropy,spheroids,orientation distribution,X-ray scattering,neutron scattering,SAS
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: numpy>=2.0
|
|
26
|
+
Requires-Dist: scipy>=1.8.0
|
|
27
|
+
Requires-Dist: h5py>=3.0.0
|
|
28
|
+
Requires-Dist: pyirena<2,>=1.2.1
|
|
29
|
+
Provides-Extra: gui
|
|
30
|
+
Requires-Dist: PySide6!=6.10.*,!=6.9.1,>=6.8; extra == "gui"
|
|
31
|
+
Requires-Dist: pyqtgraph>=0.13.7; extra == "gui"
|
|
32
|
+
Requires-Dist: pyirena[qtplot]<2,>=1.2.1; extra == "gui"
|
|
33
|
+
Provides-Extra: mcp
|
|
34
|
+
Requires-Dist: mcp<2.0,>=1.0.0; extra == "mcp"
|
|
35
|
+
Requires-Dist: matplotlib>=3.5.0; extra == "mcp"
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
38
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-timeout; extra == "dev"
|
|
40
|
+
Requires-Dist: ruff; extra == "dev"
|
|
41
|
+
Requires-Dist: build; extra == "dev"
|
|
42
|
+
Requires-Dist: twine; extra == "dev"
|
|
43
|
+
Provides-Extra: all
|
|
44
|
+
Requires-Dist: anisa[gui]; extra == "all"
|
|
45
|
+
Requires-Dist: anisa[mcp]; extra == "all"
|
|
46
|
+
Requires-Dist: anisa[dev]; extra == "all"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# Anisa
|
|
50
|
+
|
|
51
|
+
Small-angle scattering (SAXS / USAXS / SANS) modelling of **anisotropic particle populations**.
|
|
52
|
+
|
|
53
|
+
Anisa fits populations of spheroids with orientation distributions to several 1D cuts I(Q),
|
|
54
|
+
each measured along a different direction of Q in the sample frame. It is the Python successor
|
|
55
|
+
of the Igor Pro AnisoSAS macros (theory: A. J. Allen, NIST 2001). Compared with the Igor
|
|
56
|
+
version it is faster, uses multiple cores, and has no fixed limit on the number of directions
|
|
57
|
+
or populations.
|
|
58
|
+
|
|
59
|
+
> **Status: beta (0.0.1b1).** The engine, data input, fitting, GUI, results files, command line,
|
|
60
|
+
> MCP server and Bernardyn export are done and tested on synthetic data; it has not yet been
|
|
61
|
+
> validated on real measurements, so expect changes. See
|
|
62
|
+
> [PLAN.md](https://github.com/jilavsky/anisa/blob/main/PLAN.md) for the plan and progress.
|
|
63
|
+
|
|
64
|
+
Anisa is part of the pyIrena family:
|
|
65
|
+
- **[pyIrena](https://github.com/jilavsky/pyirena)** — data input (NXcanSAS HDF5 and ASCII) and
|
|
66
|
+
shared GUI pieces.
|
|
67
|
+
- **[Bernardyn](https://github.com/jilavsky/Bernardyn)** — publication plots.
|
|
68
|
+
- **Aida** — agent workbench, which will use the Anisa MCP server.
|
|
69
|
+
|
|
70
|
+
All of them install into the same Python environment.
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
73
|
+
|
|
74
|
+
Not on PyPI yet. From a source checkout:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
conda env create -f environment.yml # creates the "anisa" environment
|
|
78
|
+
conda activate anisa
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
To add Anisa to an existing pyIrena or Bernardyn environment instead:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install -e ".[gui]"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Python 3.10–3.13. The GUI uses PySide6 (never PyQt6).
|
|
88
|
+
|
|
89
|
+
## Using the GUI
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
anisa-gui # or: python -m anisa.gui
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
1. *File → Create test system* writes a synthetic data set with known parameters (prolate,
|
|
96
|
+
oblate, both with different alignment, interference, spheres, 12 directions; `TRUTH.txt`
|
|
97
|
+
lists the answer) and opens it with perturbed starting values; press **Fit** to see it
|
|
98
|
+
recover them. *Create demo data…* does the same for the three-population coating example. (Or *Add data…* /
|
|
99
|
+
drag files onto the directions table to load your own: NXcanSAS HDF5 or text.)
|
|
100
|
+
2. Give each direction its angles α_Q (from the sample normal) and ω_Q (azimuth) in the table.
|
|
101
|
+
3. Set the particle parameters of each population, tick **Fit?** for those to vary, and press
|
|
102
|
+
**Fit**. The errors appear next to the fitted values; *Uncertainty…* refits re-drawn data for a
|
|
103
|
+
Monte-Carlo estimate; *Revert fit* returns to the values before the fit.
|
|
104
|
+
4. The **Anisotropy** tab shows the model as a function of the direction of Q (polar plots, or
|
|
105
|
+
I(angle)) with your measured cuts on top, which is the quickest check that the orientation
|
|
106
|
+
distributions make sense.
|
|
107
|
+
|
|
108
|
+
After a fit, *File → Save results (HDF5)…* writes one `NAME.anisa.h5` with the data, model
|
|
109
|
+
curves, parameters and errors of all directions (an NXcanSAS entry per direction, so pyIrena
|
|
110
|
+
opens each); *File → Open* reads it back.
|
|
111
|
+
|
|
112
|
+
## Command line
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
anisa testdata folder --system prolate_oblate # synthetic data with known truth
|
|
116
|
+
anisa info folder/prolate_oblate/prolate_oblate_start.anisa.json
|
|
117
|
+
anisa fit folder/prolate_oblate/prolate_oblate_start.anisa.json --mc 20 --text
|
|
118
|
+
anisa calc project.anisa.json --results out.anisa.h5
|
|
119
|
+
anisa export-bernardyn project.anisa.json plot # needs Bernardyn installed
|
|
120
|
+
anisa anisotropy project.anisa.json --sweep alpha --fixed 0 --q 0.01 0.05 --csv scan.csv
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The project file is the one the GUI saves; every command prints JSON (`anisa.api` has the same
|
|
124
|
+
functions for Python).
|
|
125
|
+
|
|
126
|
+
## MCP server (agents)
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
pip install "anisa[mcp]"
|
|
130
|
+
ANISA_DATA_ROOT=/path/to/data anisa-mcp # stdio server
|
|
131
|
+
aida mcp server add anisa --command anisa-mcp # register with Aida
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Tools (`anisa_` prefix): `list_files`, `describe`, `calculate`, `fit`, `anisotropy`,
|
|
135
|
+
`read_results`, `list_test_systems`, `write_test_system`. They are the `anisa.api` functions;
|
|
136
|
+
file access is confined to `ANISA_DATA_ROOT` (default: the working directory).
|
|
137
|
+
|
|
138
|
+
## Example
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
import numpy as np
|
|
142
|
+
from anisa.core import AnisaModel, Direction, Population, Engine
|
|
143
|
+
from anisa.core.orientation import AngularDistribution
|
|
144
|
+
|
|
145
|
+
# oblate disks (beta = 0.2) with their axes along the sample z axis
|
|
146
|
+
pop = Population(radius=800.0, beta=0.2, volume_fraction=0.03, delta_rho=2e11,
|
|
147
|
+
alpha_dist=AngularDistribution(par1=0.0, par2=12.0))
|
|
148
|
+
model = AnisaModel([Direction(alpha_q=0.0), Direction(alpha_q=90.0)], [pop])
|
|
149
|
+
|
|
150
|
+
q = np.geomspace(1e-4, 0.1, 200)
|
|
151
|
+
result = Engine().evaluate(model, [q, q])
|
|
152
|
+
along_z, across_z = (d.intensity for d in result.directions) # I(Q) in 1/cm
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Any number of directions and populations is allowed. Parameters and their Igor names:
|
|
156
|
+
[docs/parameters.md](https://github.com/jilavsky/anisa/blob/main/docs/parameters.md).
|
|
157
|
+
|
|
158
|
+
Synthetic multi-direction data with known parameters, for trying things out:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
python -m anisa.demo demo_data # NXcanSAS files + demo.anisa.json (the truth)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from anisa.core import fit
|
|
166
|
+
from anisa.io.project import load_project
|
|
167
|
+
|
|
168
|
+
model = load_project("demo_data/demo_start.anisa.json") # perturbed start, fit flags set
|
|
169
|
+
result = fit(model) # model now holds the best parameters
|
|
170
|
+
for p in result.parameters:
|
|
171
|
+
print(p.parameter.label, p.value, "+-", p.std)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Units
|
|
175
|
+
|
|
176
|
+
- Q in Å⁻¹.
|
|
177
|
+
- Intensity in cm⁻¹ (absolute).
|
|
178
|
+
- Radii in Å.
|
|
179
|
+
- Scattering contrast Δρ in cm⁻² (Δρ, not Δρ²).
|
|
180
|
+
- Angles in degrees.
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
MIT — see [LICENSE](LICENSE).
|
anisa-0.0.1b1/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Anisa
|
|
2
|
+
|
|
3
|
+
Small-angle scattering (SAXS / USAXS / SANS) modelling of **anisotropic particle populations**.
|
|
4
|
+
|
|
5
|
+
Anisa fits populations of spheroids with orientation distributions to several 1D cuts I(Q),
|
|
6
|
+
each measured along a different direction of Q in the sample frame. It is the Python successor
|
|
7
|
+
of the Igor Pro AnisoSAS macros (theory: A. J. Allen, NIST 2001). Compared with the Igor
|
|
8
|
+
version it is faster, uses multiple cores, and has no fixed limit on the number of directions
|
|
9
|
+
or populations.
|
|
10
|
+
|
|
11
|
+
> **Status: beta (0.0.1b1).** The engine, data input, fitting, GUI, results files, command line,
|
|
12
|
+
> MCP server and Bernardyn export are done and tested on synthetic data; it has not yet been
|
|
13
|
+
> validated on real measurements, so expect changes. See
|
|
14
|
+
> [PLAN.md](https://github.com/jilavsky/anisa/blob/main/PLAN.md) for the plan and progress.
|
|
15
|
+
|
|
16
|
+
Anisa is part of the pyIrena family:
|
|
17
|
+
- **[pyIrena](https://github.com/jilavsky/pyirena)** — data input (NXcanSAS HDF5 and ASCII) and
|
|
18
|
+
shared GUI pieces.
|
|
19
|
+
- **[Bernardyn](https://github.com/jilavsky/Bernardyn)** — publication plots.
|
|
20
|
+
- **Aida** — agent workbench, which will use the Anisa MCP server.
|
|
21
|
+
|
|
22
|
+
All of them install into the same Python environment.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
Not on PyPI yet. From a source checkout:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
conda env create -f environment.yml # creates the "anisa" environment
|
|
30
|
+
conda activate anisa
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
To add Anisa to an existing pyIrena or Bernardyn environment instead:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install -e ".[gui]"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Python 3.10–3.13. The GUI uses PySide6 (never PyQt6).
|
|
40
|
+
|
|
41
|
+
## Using the GUI
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
anisa-gui # or: python -m anisa.gui
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
1. *File → Create test system* writes a synthetic data set with known parameters (prolate,
|
|
48
|
+
oblate, both with different alignment, interference, spheres, 12 directions; `TRUTH.txt`
|
|
49
|
+
lists the answer) and opens it with perturbed starting values; press **Fit** to see it
|
|
50
|
+
recover them. *Create demo data…* does the same for the three-population coating example. (Or *Add data…* /
|
|
51
|
+
drag files onto the directions table to load your own: NXcanSAS HDF5 or text.)
|
|
52
|
+
2. Give each direction its angles α_Q (from the sample normal) and ω_Q (azimuth) in the table.
|
|
53
|
+
3. Set the particle parameters of each population, tick **Fit?** for those to vary, and press
|
|
54
|
+
**Fit**. The errors appear next to the fitted values; *Uncertainty…* refits re-drawn data for a
|
|
55
|
+
Monte-Carlo estimate; *Revert fit* returns to the values before the fit.
|
|
56
|
+
4. The **Anisotropy** tab shows the model as a function of the direction of Q (polar plots, or
|
|
57
|
+
I(angle)) with your measured cuts on top, which is the quickest check that the orientation
|
|
58
|
+
distributions make sense.
|
|
59
|
+
|
|
60
|
+
After a fit, *File → Save results (HDF5)…* writes one `NAME.anisa.h5` with the data, model
|
|
61
|
+
curves, parameters and errors of all directions (an NXcanSAS entry per direction, so pyIrena
|
|
62
|
+
opens each); *File → Open* reads it back.
|
|
63
|
+
|
|
64
|
+
## Command line
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
anisa testdata folder --system prolate_oblate # synthetic data with known truth
|
|
68
|
+
anisa info folder/prolate_oblate/prolate_oblate_start.anisa.json
|
|
69
|
+
anisa fit folder/prolate_oblate/prolate_oblate_start.anisa.json --mc 20 --text
|
|
70
|
+
anisa calc project.anisa.json --results out.anisa.h5
|
|
71
|
+
anisa export-bernardyn project.anisa.json plot # needs Bernardyn installed
|
|
72
|
+
anisa anisotropy project.anisa.json --sweep alpha --fixed 0 --q 0.01 0.05 --csv scan.csv
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The project file is the one the GUI saves; every command prints JSON (`anisa.api` has the same
|
|
76
|
+
functions for Python).
|
|
77
|
+
|
|
78
|
+
## MCP server (agents)
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install "anisa[mcp]"
|
|
82
|
+
ANISA_DATA_ROOT=/path/to/data anisa-mcp # stdio server
|
|
83
|
+
aida mcp server add anisa --command anisa-mcp # register with Aida
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Tools (`anisa_` prefix): `list_files`, `describe`, `calculate`, `fit`, `anisotropy`,
|
|
87
|
+
`read_results`, `list_test_systems`, `write_test_system`. They are the `anisa.api` functions;
|
|
88
|
+
file access is confined to `ANISA_DATA_ROOT` (default: the working directory).
|
|
89
|
+
|
|
90
|
+
## Example
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import numpy as np
|
|
94
|
+
from anisa.core import AnisaModel, Direction, Population, Engine
|
|
95
|
+
from anisa.core.orientation import AngularDistribution
|
|
96
|
+
|
|
97
|
+
# oblate disks (beta = 0.2) with their axes along the sample z axis
|
|
98
|
+
pop = Population(radius=800.0, beta=0.2, volume_fraction=0.03, delta_rho=2e11,
|
|
99
|
+
alpha_dist=AngularDistribution(par1=0.0, par2=12.0))
|
|
100
|
+
model = AnisaModel([Direction(alpha_q=0.0), Direction(alpha_q=90.0)], [pop])
|
|
101
|
+
|
|
102
|
+
q = np.geomspace(1e-4, 0.1, 200)
|
|
103
|
+
result = Engine().evaluate(model, [q, q])
|
|
104
|
+
along_z, across_z = (d.intensity for d in result.directions) # I(Q) in 1/cm
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Any number of directions and populations is allowed. Parameters and their Igor names:
|
|
108
|
+
[docs/parameters.md](https://github.com/jilavsky/anisa/blob/main/docs/parameters.md).
|
|
109
|
+
|
|
110
|
+
Synthetic multi-direction data with known parameters, for trying things out:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python -m anisa.demo demo_data # NXcanSAS files + demo.anisa.json (the truth)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from anisa.core import fit
|
|
118
|
+
from anisa.io.project import load_project
|
|
119
|
+
|
|
120
|
+
model = load_project("demo_data/demo_start.anisa.json") # perturbed start, fit flags set
|
|
121
|
+
result = fit(model) # model now holds the best parameters
|
|
122
|
+
for p in result.parameters:
|
|
123
|
+
print(p.parameter.label, p.value, "+-", p.std)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Units
|
|
127
|
+
|
|
128
|
+
- Q in Å⁻¹.
|
|
129
|
+
- Intensity in cm⁻¹ (absolute).
|
|
130
|
+
- Radii in Å.
|
|
131
|
+
- Scattering contrast Δρ in cm⁻² (Δρ, not Δρ²).
|
|
132
|
+
- Angles in degrees.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Anisa: small-angle scattering modelling of anisotropic particle populations.
|
|
3
|
+
|
|
4
|
+
Python successor of the Igor Pro AnisoSAS macros (J. Ilavsky, theory by A. J. Allen,
|
|
5
|
+
NIST 2001). Populations of axially symmetric spheroids with orientation distributions
|
|
6
|
+
p(alpha) * b(omega) are modelled against 1D cuts measured along several directions of Q
|
|
7
|
+
in the sample frame.
|
|
8
|
+
|
|
9
|
+
Layers:
|
|
10
|
+
core: numerical model (numpy/scipy only)
|
|
11
|
+
io: data input through pyirena.io, project JSON, HDF5 results
|
|
12
|
+
gui: PySide6 GUI (optional extra ``anisa[gui]``)
|
|
13
|
+
|
|
14
|
+
See PLAN.md for the development plan.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
# Single-source the version from the installed package metadata
|
|
18
|
+
# (pyproject.toml is the source of truth).
|
|
19
|
+
from importlib.metadata import PackageNotFoundError
|
|
20
|
+
from importlib.metadata import version as _pkg_version
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
__version__ = _pkg_version("anisa")
|
|
24
|
+
except PackageNotFoundError: # pragma: no cover - only in uninstalled source trees
|
|
25
|
+
__version__ = "0.0.0+unknown"
|
|
26
|
+
|
|
27
|
+
__author__ = "Jan Ilavsky"
|