moreniius 0.6.0__tar.gz → 0.6.2__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.
- moreniius-0.6.2/.github/dependabot.yml +17 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/.github/workflows/pip.yml +4 -9
- {moreniius-0.6.0 → moreniius-0.6.2}/.github/workflows/wheels.yml +4 -4
- {moreniius-0.6.0/src/moreniius.egg-info → moreniius-0.6.2}/PKG-INFO +3 -2
- {moreniius-0.6.0 → moreniius-0.6.2}/pyproject.toml +3 -1
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/mccode/comp.py +77 -14
- {moreniius-0.6.0 → moreniius-0.6.2/src/moreniius.egg-info}/PKG-INFO +3 -2
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius.egg-info/SOURCES.txt +2 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius.egg-info/requires.txt +1 -1
- moreniius-0.6.2/tests/test_elliptic_guide_gravity.py +179 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/.gitignore +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/README.md +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/setup.cfg +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/__init__.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/additions.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/mccode/__init__.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/mccode/instance.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/mccode/instr.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/mccode/mccode.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/mccode/orientation.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/moreniius.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/nexus_structure.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/nxoff.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/utils.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius/writer.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius.egg-info/dependency_links.txt +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius.egg-info/entry_points.txt +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/src/moreniius.egg-info/top_level.txt +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/tests/test_motorized_positions.py +0 -0
- {moreniius-0.6.0 → moreniius-0.6.2}/tests/test_nexus_structure.py +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Please see the documentation for all configuration options:
|
|
2
|
+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
|
3
|
+
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
- package-ecosystem: "github-actions" # See documentation for possible values
|
|
7
|
+
directory: "/" # Location of package manifests
|
|
8
|
+
schedule:
|
|
9
|
+
interval: "weekly"
|
|
10
|
+
- package-ecosystem: "pip"
|
|
11
|
+
directory: "/"
|
|
12
|
+
schedule:
|
|
13
|
+
interval: "daily"
|
|
14
|
+
groups:
|
|
15
|
+
python-packages:
|
|
16
|
+
patterns:
|
|
17
|
+
- "*"
|
|
@@ -15,24 +15,19 @@ jobs:
|
|
|
15
15
|
fail-fast: false
|
|
16
16
|
matrix:
|
|
17
17
|
platform: [windows-latest, macos-latest, ubuntu-latest]
|
|
18
|
-
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
18
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
19
19
|
|
|
20
20
|
steps:
|
|
21
|
-
- uses: actions/checkout@
|
|
21
|
+
- uses: actions/checkout@v6
|
|
22
22
|
|
|
23
|
-
- uses: actions/setup-python@
|
|
23
|
+
- uses: actions/setup-python@v6
|
|
24
24
|
with:
|
|
25
25
|
python-version: ${{ matrix.python-version }}
|
|
26
26
|
|
|
27
|
-
- name: Set min macOS version
|
|
28
|
-
if: runner.os == 'macOS'
|
|
29
|
-
run: |
|
|
30
|
-
echo "MACOS_DEPLOYMENT_TARGET=10.14" >> $GITHUB_ENV
|
|
31
|
-
|
|
32
27
|
- name: Build and install
|
|
33
28
|
run: pip install --verbose .
|
|
34
29
|
|
|
35
30
|
- name: Test
|
|
36
31
|
run: |
|
|
37
|
-
python -m pip install pytest
|
|
32
|
+
python -m pip install pytest mccode-to-kafka
|
|
38
33
|
python -m pytest
|
|
@@ -15,7 +15,7 @@ jobs:
|
|
|
15
15
|
name: Build SDist and Wheel
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v6
|
|
19
19
|
with:
|
|
20
20
|
fetch-depth: 0
|
|
21
21
|
submodules: true
|
|
@@ -26,7 +26,7 @@ jobs:
|
|
|
26
26
|
- name: Check metadata
|
|
27
27
|
run: pipx run twine check dist/*
|
|
28
28
|
|
|
29
|
-
- uses: actions/upload-artifact@
|
|
29
|
+
- uses: actions/upload-artifact@v6
|
|
30
30
|
with:
|
|
31
31
|
path: dist/*
|
|
32
32
|
|
|
@@ -42,9 +42,9 @@ jobs:
|
|
|
42
42
|
if: github.event_name == 'release' && github.event.action == 'published'
|
|
43
43
|
|
|
44
44
|
steps:
|
|
45
|
-
- uses: actions/setup-python@
|
|
45
|
+
- uses: actions/setup-python@v6
|
|
46
46
|
|
|
47
|
-
- uses: actions/download-artifact@
|
|
47
|
+
- uses: actions/download-artifact@v7
|
|
48
48
|
with:
|
|
49
49
|
name: artifact
|
|
50
50
|
path: dist
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: moreniius
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Author-email: Gregory Tucker <gregory.tucker@ess.eu>
|
|
5
5
|
Classifier: License :: OSI Approved :: BSD License
|
|
6
6
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
@@ -10,10 +10,11 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
14
|
Description-Content-Type: text/markdown
|
|
14
15
|
Requires-Dist: zenlog>=1.1
|
|
15
16
|
Requires-Dist: platformdirs>=3.11
|
|
16
|
-
Requires-Dist: mccode-antlr[hdf5]>=0.16.
|
|
17
|
+
Requires-Dist: mccode-antlr[hdf5]>=0.16.2
|
|
17
18
|
Requires-Dist: nexusformat>=1.0.6
|
|
18
19
|
Requires-Dist: networkx
|
|
19
20
|
|
|
@@ -7,7 +7,7 @@ name = "moreniius"
|
|
|
7
7
|
dependencies = [
|
|
8
8
|
'zenlog>=1.1',
|
|
9
9
|
'platformdirs>=3.11',
|
|
10
|
-
'mccode-antlr[hdf5]>=0.16.
|
|
10
|
+
'mccode-antlr[hdf5]>=0.16.2',
|
|
11
11
|
'nexusformat>=1.0.6',
|
|
12
12
|
'networkx'
|
|
13
13
|
]
|
|
@@ -24,6 +24,7 @@ classifiers = [
|
|
|
24
24
|
"Programming Language :: Python :: 3.11",
|
|
25
25
|
"Programming Language :: Python :: 3.12",
|
|
26
26
|
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Programming Language :: Python :: 3.14",
|
|
27
28
|
]
|
|
28
29
|
dynamic = ["version"]
|
|
29
30
|
|
|
@@ -37,6 +38,7 @@ legacy_tox_ini = """
|
|
|
37
38
|
[tox]
|
|
38
39
|
min_version = 4.0
|
|
39
40
|
env_list =
|
|
41
|
+
py314
|
|
40
42
|
py313
|
|
41
43
|
py312
|
|
42
44
|
py311
|
|
@@ -95,27 +95,41 @@ def diskchopper_translator(nxinstance):
|
|
|
95
95
|
return nxinstance.make_nx(NXdisk_chopper, slit_edges=NXfield(nx_slit_edges, units='degrees'), **resolve_parameter_links(pars))
|
|
96
96
|
|
|
97
97
|
|
|
98
|
-
def
|
|
99
|
-
|
|
98
|
+
def _ellipse_vertices_faces(major_x, minor_x, offset_x, major_y, minor_y, offset_y, l, n=10):
|
|
99
|
+
"""
|
|
100
|
+
Create vertices and faces for an elliptical guide with given parameters.
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
major_x : float
|
|
105
|
+
Major axis half-length in the x-direction.
|
|
106
|
+
minor_x : float
|
|
107
|
+
Minor axis half-length in the x-direction.
|
|
108
|
+
offset_x : float
|
|
109
|
+
Offset from the end of the ellipse to the guide entrance in the x-direction.
|
|
110
|
+
major_y : float
|
|
111
|
+
Major axis half-length in the y-direction.
|
|
112
|
+
minor_y : float
|
|
113
|
+
Minor axis half-length in the y-direction.
|
|
114
|
+
offset_y : float
|
|
115
|
+
Offset from the end of the ellipse to the guide entrance in the y-direction.
|
|
116
|
+
l : float
|
|
117
|
+
Length of the guide. l <= 2*major_x - offset_x and l <= 2*major_y - offset_y
|
|
118
|
+
n : int, optional
|
|
119
|
+
Number of segments along the length of the guide. Default is 10.
|
|
120
|
+
"""
|
|
100
121
|
from numpy import arange, sqrt
|
|
101
|
-
from moreniius.nxoff import NXoff
|
|
102
|
-
if not '"mid"' == nxinstance.obj.get_parameter('dimensionsAt'):
|
|
103
|
-
log.warn('Only midpoint geometry supported by Elliptic_guide_gravity translator')
|
|
104
|
-
log.info(f'The current guide has {nxinstance.obj.get_parameter("dimensionsAt")} specified')
|
|
105
122
|
|
|
106
|
-
def ellipse_width(minor,
|
|
107
|
-
major = sqrt((distance / 2) ** 2 + minor ** 2)
|
|
123
|
+
def ellipse_width(minor, major, at):
|
|
108
124
|
return 0 if abs(at) > major else minor * sqrt(1 - (at / major) ** 2)
|
|
109
125
|
|
|
110
|
-
pars = dict(xw='xwidth', xi='linxw', xo='loutxw', yw='yheight', yi='linyh', yo='loutyh', l='l')
|
|
111
|
-
p = {k: nxinstance.parameter(v) for k, v in pars.items()}
|
|
112
|
-
n = 10
|
|
113
126
|
rings = arange(n + 1) / n
|
|
114
127
|
faces, vertices = [], []
|
|
115
128
|
for x in rings:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
129
|
+
z = x * l
|
|
130
|
+
w = ellipse_width(minor_x, major_x, offset_x - minor_x + z)
|
|
131
|
+
h = ellipse_width(minor_y, major_y, offset_y - minor_y + x)
|
|
132
|
+
|
|
119
133
|
vertices.extend([[-w, -h, z], [-w, h, z], [w, h, z], [w, -h, z]])
|
|
120
134
|
|
|
121
135
|
# These are only the guide faces (that is, the inner faces of the sides of the guide housing)
|
|
@@ -124,6 +138,55 @@ def elliptic_guide_gravity_translator(nxinstance):
|
|
|
124
138
|
j0, j1, j2, j3, j4, j5, j6, j7 = [4 * i + k for k in range(8)]
|
|
125
139
|
faces.extend([[j0, j1, j5, j4], [j1, j2, j6, j5], [j2, j3, j7, j6], [j3, j0, j4, j7]])
|
|
126
140
|
|
|
141
|
+
return vertices, faces
|
|
142
|
+
|
|
143
|
+
def _ellipse_parameters_from_widths(nxinstance):
|
|
144
|
+
from numpy import sqrt
|
|
145
|
+
|
|
146
|
+
def parameters(which, w, i, o, l):
|
|
147
|
+
foci = i + l + o
|
|
148
|
+
offset = foci / 2 - i
|
|
149
|
+
if 'mid' in which:
|
|
150
|
+
minor = w / 2
|
|
151
|
+
major = sqrt(foci ** 2 + minor ** 2) / 2
|
|
152
|
+
else:
|
|
153
|
+
t, b = (o, i) if 'entrance' in which else (i, o)
|
|
154
|
+
t += l
|
|
155
|
+
w /= 2
|
|
156
|
+
b = sqrt(b * b + w * w / 4) + sqrt(t * t + w * w / 4)
|
|
157
|
+
major = b / 2
|
|
158
|
+
minor = sqrt(b * b - foci * foci) / 2
|
|
159
|
+
return major, minor, offset
|
|
160
|
+
|
|
161
|
+
pars = dict(xw='xwidth', xi='linxw', xo='loutxw', yw='yheight', yi='linyh', yo='loutyh', l='l')
|
|
162
|
+
p = {k: nxinstance.parameter(v) for k, v in pars.items()}
|
|
163
|
+
|
|
164
|
+
dim_at = str(nxinstance.obj.get_parameter('dimensionsAt').value)
|
|
165
|
+
major_x, minor_x, offset_x = parameters(dim_at, p['xw'], p['xi'], p['xo'], p['l'])
|
|
166
|
+
major_y, minor_y, offset_y = parameters(dim_at, p['yw'], p['yi'], p['yo'], p['l'])
|
|
167
|
+
|
|
168
|
+
return major_x, minor_x, offset_x, major_y, minor_y, offset_y, p['l']
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def elliptic_guide_gravity_translator(nxinstance):
|
|
172
|
+
from nexusformat.nexus import NXguide
|
|
173
|
+
from moreniius.nxoff import NXoff
|
|
174
|
+
|
|
175
|
+
ellipse_pars = [f'{f}{s}' for f in ('majorAxis', 'minorAxis', 'majorAxisOffset') for s in ('xw', 'yh')]
|
|
176
|
+
if all(nxinstance.obj.defines_parameter(p) for p in ellipse_pars):
|
|
177
|
+
# we can use the specified ellipse parameters directly
|
|
178
|
+
major_x = nxinstance.parameter('majorAxisxw')
|
|
179
|
+
minor_x = nxinstance.parameter('minorAxisxw')
|
|
180
|
+
offset_x = nxinstance.parameter('majorAxisOffsetxw')
|
|
181
|
+
major_y = nxinstance.parameter('majorAxisyh')
|
|
182
|
+
minor_y = nxinstance.parameter('minorAxisyh')
|
|
183
|
+
offset_y = nxinstance.parameter('majorAxisOffsetyh')
|
|
184
|
+
l = nxinstance.parameter('l')
|
|
185
|
+
else:
|
|
186
|
+
major_x, minor_x, offset_x, major_y, minor_y, offset_y, l = _ellipse_parameters_from_widths(nxinstance)
|
|
187
|
+
|
|
188
|
+
vertices, faces = _ellipse_vertices_faces(major_x, minor_x, offset_x, major_y, minor_y, offset_y, l, n=10)
|
|
189
|
+
|
|
127
190
|
nx_vertices = [[nxinstance.expr2nx(expr) for expr in vector] for vector in vertices]
|
|
128
191
|
nx_faces = [[nxinstance.expr2nx(expr) for expr in face] for face in faces]
|
|
129
192
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: moreniius
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Author-email: Gregory Tucker <gregory.tucker@ess.eu>
|
|
5
5
|
Classifier: License :: OSI Approved :: BSD License
|
|
6
6
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
@@ -10,10 +10,11 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
14
|
Description-Content-Type: text/markdown
|
|
14
15
|
Requires-Dist: zenlog>=1.1
|
|
15
16
|
Requires-Dist: platformdirs>=3.11
|
|
16
|
-
Requires-Dist: mccode-antlr[hdf5]>=0.16.
|
|
17
|
+
Requires-Dist: mccode-antlr[hdf5]>=0.16.2
|
|
17
18
|
Requires-Dist: nexusformat>=1.0.6
|
|
18
19
|
Requires-Dist: networkx
|
|
19
20
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
.gitignore
|
|
2
2
|
README.md
|
|
3
3
|
pyproject.toml
|
|
4
|
+
.github/dependabot.yml
|
|
4
5
|
.github/workflows/pip.yml
|
|
5
6
|
.github/workflows/wheels.yml
|
|
6
7
|
src/moreniius/__init__.py
|
|
@@ -22,5 +23,6 @@ src/moreniius/mccode/instance.py
|
|
|
22
23
|
src/moreniius/mccode/instr.py
|
|
23
24
|
src/moreniius/mccode/mccode.py
|
|
24
25
|
src/moreniius/mccode/orientation.py
|
|
26
|
+
tests/test_elliptic_guide_gravity.py
|
|
25
27
|
tests/test_motorized_positions.py
|
|
26
28
|
tests/test_nexus_structure.py
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from nexusformat.nexus import NXguide
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def make_elliptic_guide_instrument(use_explicit_ellipse_pars=False):
|
|
6
|
+
"""Create an instrument with an Elliptic_guide_gravity component."""
|
|
7
|
+
from mccode_antlr import Flavor
|
|
8
|
+
from mccode_antlr.assembler import Assembler
|
|
9
|
+
|
|
10
|
+
inst = Assembler('elliptic_guide_test', flavor=Flavor.MCSTAS)
|
|
11
|
+
|
|
12
|
+
inst.component('origin', 'Arm', at=(0, 0, 0))
|
|
13
|
+
inst.component('source', 'Source_simple', at=[(0, 0, 0), 'origin'])
|
|
14
|
+
|
|
15
|
+
if use_explicit_ellipse_pars:
|
|
16
|
+
# Use explicit ellipse axis parameters
|
|
17
|
+
inst.component(
|
|
18
|
+
'elliptic_guide', 'Elliptic_guide_gravity',
|
|
19
|
+
at=[(0, 0, 1), 'source'],
|
|
20
|
+
parameters={
|
|
21
|
+
'l': 2.0,
|
|
22
|
+
'majorAxisxw': 1.5,
|
|
23
|
+
'minorAxisxw': 0.05,
|
|
24
|
+
'majorAxisoffsetxw': 0.5,
|
|
25
|
+
'majorAxisyh': 1.5,
|
|
26
|
+
'minorAxisyh': 0.06,
|
|
27
|
+
'majorAxisoffsetyh': 0.5,
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
else:
|
|
31
|
+
# Use width/height based parameters with dimensionsAt
|
|
32
|
+
inst.component(
|
|
33
|
+
'elliptic_guide', 'Elliptic_guide_gravity',
|
|
34
|
+
at=[(0, 0, 1), 'source'],
|
|
35
|
+
parameters={
|
|
36
|
+
'l': 2.0,
|
|
37
|
+
'xwidth': 0.06,
|
|
38
|
+
'yheight': 0.08,
|
|
39
|
+
'linxw': 1.0,
|
|
40
|
+
'loutxw': 1.0,
|
|
41
|
+
'linyh': 1.0,
|
|
42
|
+
'loutyh': 1.0,
|
|
43
|
+
'dimensionsAt': '"mid"',
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
return inst.instrument
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_elliptic_guide_gravity_translator_from_widths():
|
|
51
|
+
"""Test the elliptic guide translator using width/height parameters."""
|
|
52
|
+
import moreniius
|
|
53
|
+
|
|
54
|
+
instr = make_elliptic_guide_instrument(use_explicit_ellipse_pars=False)
|
|
55
|
+
me = moreniius.MorEniius.from_mccode(
|
|
56
|
+
instr, origin='origin', only_nx=False, absolute_depends_on=True
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
assert me is not None
|
|
60
|
+
assert 'elliptic_guide' in me.nx
|
|
61
|
+
|
|
62
|
+
guide = me.nx['elliptic_guide']
|
|
63
|
+
assert isinstance(guide, NXguide)
|
|
64
|
+
|
|
65
|
+
# Should have OFF_GEOMETRY
|
|
66
|
+
assert 'OFF_GEOMETRY' in guide
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_elliptic_guide_gravity_translator_explicit_pars():
|
|
70
|
+
"""Test the elliptic guide translator using explicit ellipse axis parameters."""
|
|
71
|
+
import moreniius
|
|
72
|
+
|
|
73
|
+
instr = make_elliptic_guide_instrument(use_explicit_ellipse_pars=True)
|
|
74
|
+
me = moreniius.MorEniius.from_mccode(
|
|
75
|
+
instr, origin='origin', only_nx=False, absolute_depends_on=True
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
assert me is not None
|
|
79
|
+
assert 'elliptic_guide' in me.nx
|
|
80
|
+
|
|
81
|
+
guide = me.nx['elliptic_guide']
|
|
82
|
+
assert isinstance(guide, NXguide)
|
|
83
|
+
|
|
84
|
+
# Should have OFF_GEOMETRY
|
|
85
|
+
assert 'OFF_GEOMETRY' in guide
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_elliptic_guide_geometry_has_vertices_and_faces():
|
|
89
|
+
"""Test that the generated geometry has vertices and faces."""
|
|
90
|
+
import moreniius
|
|
91
|
+
|
|
92
|
+
instr = make_elliptic_guide_instrument(use_explicit_ellipse_pars=True)
|
|
93
|
+
me = moreniius.MorEniius.from_mccode(
|
|
94
|
+
instr, origin='origin', only_nx=False, absolute_depends_on=True
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
guide = me.nx['elliptic_guide']
|
|
98
|
+
geometry = guide['OFF_GEOMETRY']
|
|
99
|
+
|
|
100
|
+
# NXoff_geometry should have vertices, faces, and winding_order
|
|
101
|
+
assert 'vertices' in geometry
|
|
102
|
+
assert 'faces' in geometry
|
|
103
|
+
assert 'winding_order' in geometry
|
|
104
|
+
|
|
105
|
+
# Vertices should be a 2D array (n_vertices, 3)
|
|
106
|
+
vertices = geometry['vertices'].nxdata
|
|
107
|
+
assert vertices.ndim == 2
|
|
108
|
+
assert vertices.shape[1] == 3
|
|
109
|
+
|
|
110
|
+
# With n=10 segments, we should have 11 rings of 4 vertices each = 44 vertices
|
|
111
|
+
assert vertices.shape[0] == 44
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_elliptic_guide_nexus_structure():
|
|
115
|
+
"""Test that the elliptic guide is correctly represented in NeXus structure output."""
|
|
116
|
+
import moreniius
|
|
117
|
+
|
|
118
|
+
instr = make_elliptic_guide_instrument(use_explicit_ellipse_pars=True)
|
|
119
|
+
me = moreniius.MorEniius.from_mccode(
|
|
120
|
+
instr, origin='origin', only_nx=False, absolute_depends_on=True
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
ns = me.to_nexus_structure()
|
|
124
|
+
|
|
125
|
+
# Navigate to the instrument level
|
|
126
|
+
assert 'children' in ns
|
|
127
|
+
entry = ns['children'][0]
|
|
128
|
+
assert entry['name'] == 'entry'
|
|
129
|
+
|
|
130
|
+
instrument = entry['children'][0]
|
|
131
|
+
assert instrument['name'] == 'instrument'
|
|
132
|
+
|
|
133
|
+
# Find the elliptic_guide component
|
|
134
|
+
guide_groups = [c for c in instrument['children'] if c.get('name') == 'elliptic_guide']
|
|
135
|
+
assert len(guide_groups) == 1
|
|
136
|
+
|
|
137
|
+
guide = guide_groups[0]
|
|
138
|
+
assert guide['type'] == 'group'
|
|
139
|
+
|
|
140
|
+
# Check that it has the NXguide class attribute
|
|
141
|
+
guide_attrs = guide.get('attributes', [])
|
|
142
|
+
class_attrs = [a for a in guide_attrs if a.get('name') == 'NX_class']
|
|
143
|
+
assert len(class_attrs) == 1
|
|
144
|
+
assert class_attrs[0]['values'] == 'NXguide'
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_ellipse_vertices_faces_function():
|
|
148
|
+
"""Test the _ellipse_vertices_faces helper function directly."""
|
|
149
|
+
from moreniius.mccode.comp import _ellipse_vertices_faces
|
|
150
|
+
|
|
151
|
+
major_x, minor_x, offset_x = 1.5, 0.05, 0.5
|
|
152
|
+
major_y, minor_y, offset_y = 1.5, 0.06, 0.5
|
|
153
|
+
l = 2.0
|
|
154
|
+
n = 5
|
|
155
|
+
|
|
156
|
+
vertices, faces = _ellipse_vertices_faces(
|
|
157
|
+
major_x, minor_x, offset_x,
|
|
158
|
+
major_y, minor_y, offset_y,
|
|
159
|
+
l, n=n
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# Should have (n+1) rings of 4 vertices each
|
|
163
|
+
assert len(vertices) == (n + 1) * 4
|
|
164
|
+
|
|
165
|
+
# Each ring creates 4 faces (top, bottom, left, right of guide)
|
|
166
|
+
# For n segments, we have n * 4 faces
|
|
167
|
+
assert len(faces) == n * 4
|
|
168
|
+
|
|
169
|
+
# Each vertex should have 3 coordinates
|
|
170
|
+
assert all(len(v) == 3 for v in vertices)
|
|
171
|
+
|
|
172
|
+
# Each face should reference 4 vertex indices
|
|
173
|
+
assert all(len(f) == 4 for f in faces)
|
|
174
|
+
|
|
175
|
+
# z-coordinates should range from 0 to l
|
|
176
|
+
z_coords = [v[2] for v in vertices]
|
|
177
|
+
assert min(z_coords) == pytest.approx(0.0)
|
|
178
|
+
assert max(z_coords) == pytest.approx(l)
|
|
179
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|