Skip to content

Commit 780a62a

Browse files
authored
Merge pull request #259 from hamogu/small_fixes
Small_fixes and add CircularBaffle
2 parents 87108aa + 2e05096 commit 780a62a

21 files changed

Lines changed: 432 additions & 325 deletions

File tree

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ New Features
55
^^^^^^^^^^^^
66
- Make X3D output compatible with X_ITE. This includes cleanup up of a few pieces
77
that X3DOM is not strict about. [#253]
8+
- Add a new class `marxs.optics.CircularBaffle` that implements a baffle with a circular
9+
hole. [#258]
810

911
API Changes
1012
^^^^^^^^^^^

docs/conventions.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Coordinates, physical units and polarization
77

88
Coordinate system
99
=================
10-
Marxs employs a cartesian coordinate system. All optical elements can be freely placed at any position
10+
Marxs employs a Cartesian coordinate system. All optical elements can be freely placed at any position
1111
and any angle in this space, but we recommend the following conventions for simplicity (examples and
1212
predefined missions in this package follow those conventions as far as possible):
1313

@@ -20,7 +20,7 @@ Marxs uses `homogeneous coordinates <https://en.wikipedia.org/wiki/Homogeneous_c
2020
describe position and direction in a 4 dimensional coordinate space, for example
2121
:math:`[3, 0, 0, 1]` describes a point at x=3, y=0 and z=0; :math:`[3, 0, 0, 0]` describes the
2222
vector from the origin to that point. Homogeneous coordinates have one important advantage compared
23-
with a normal 3-d description of Euklidean space: In homogeneous coordinates, rotation, zoom, and
23+
with a normal 3-d description of Euclidean space: In homogeneous coordinates, rotation, zoom, and
2424
translations together can be described by a :math:`[4, 4]` matrix and several of these operations can
2525
be chained simply by multiplying the matrices.
2626

@@ -139,7 +139,7 @@ polarization.
139139
(2011) <https://doi.org/10.1364/AO.50.002855>`_
140140
141141
.. [Yun_2011] `Polarization Ray Tracing: G. Yun, University of Arizona, dissertation <http://hdl.handle.net/10150/202979>`_
142-
142+
143143
Physical units
144144
==============
145145
MARXS uses `astropy units

docs/newopticalelements.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ Above, we discussed elements that are physically present, such as mirrors or det
7575
... return photons
7676
>>> photons = backupcopy(photons)
7777

78+
.. testcleanup::
79+
80+
>>> import os
81+
>>> os.remove('backup.fits')
82+
7883
Why have we chosen to return a copy of photons here, although no value in the photon list was changed? This allows us to sneak in the new function into a list of optical elements::
7984

8085
>>> from marxs import simulator

marxs/analysis/coords.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def facet_table(container, project_plane=ProjectOntoPlane()):
6464
-------
6565
facettab : `astropy.table.Table`
6666
Table with facet properties.
67-
All output columns are prevaced with "facet_" to avoid a clash with columns likely
67+
All output columns are prefaced with "facet_" to avoid a clash with columns likely
6868
to be found in photon tables. That enables easy merging of facet tables with photon tables
6969
to add the properties of a facet that the photon passed through into the photon table
7070
like so:

marxs/base/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def check_energy_consistent(photons):
194194
class SimulationSequenceElement(MarxsElement):
195195
'''Base class for all elements in a simulation that processes photons.'''
196196

197-
output_columns = []
197+
output_columns: list[str] = []
198198
'''This is a list of strings that names the output properties.
199199
200200
This gives the names of the output properties from this optical
@@ -247,7 +247,7 @@ def __init__(self, **kwargs):
247247
super().__init__(**kwargs)
248248

249249
def add_output_cols(self, photons, colnames=[]):
250-
'''Add output columns to the photon array.
250+
"""Add output columns to the photon array.
251251
252252
This function takes the column names that are added to ``photons`` from
253253
several sources:
@@ -262,12 +262,12 @@ def add_output_cols(self, photons, colnames=[]):
262262
Table columns are added to.
263263
colnames : list of elements
264264
Each element can be a string (in this case a float column with
265-
initial value ``np.nan`` is added) or a dictionay of arguments
266-
for `astropy.table.column.Column`. If the dictionay has a keys
265+
initial value ``np.nan`` is added) or a dictionary of arguments
266+
for `astropy.table.column.Column`. If the dictionary has a keys
267267
"value" then the column will be initialized to that value.
268268
Column names to be added; in addition several object properties can
269269
be used to set the column names, see description above.
270-
'''
270+
"""
271271
for n in self.output_columns + colnames:
272272
if (n is not None) and (n not in photons.colnames):
273273
if not isinstance(n, dict):

marxs/design/bendgratings.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@
2424

2525

2626
def bend_gratings(gratings, radius):
27-
'''Bend gratings to follow the Rowland cirle.
27+
"""Bend gratings to follow the Rowland circle.
2828
2929
Gratings are bend in one direction (the dispersion direction) only.
3030
3131
The numerical procedure used to calculate the bending takes the central ray as
32-
a fixed ppoint assuming that the central ray always goes to the correct position!
32+
a fixed point assuming that the central ray always goes to the correct position!
3333
3434
Parameters
3535
----------
3636
gratings : list
3737
List of gratings to be bend
3838
radius : float
39-
Radius of the newly bend gratings
40-
'''
39+
Radius of the newly bent gratings
40+
"""
4141
for e in gratings:
4242
t, rot, z, s = decompose(e.geometry.pos4d)
4343
d_phi = np.arctan(z[1] / radius)

marxs/design/tolerancing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ def run_tolerances_for_energies2(source, energies, instrum, cls, wigglefunc,
436436
'''
437437
ind = instrum.first_of_class_top_level(cls, subclass_ok)
438438
if ind is None:
439-
raise Exception(f'{cls} nor part of {instrum}')
439+
raise Exception(f"{cls} not part of {instrum}")
440440

441441
tab = run_tolerances_for_energies(source, energies,
442442
Sequence(elements=instrum.elements[:ind]),

marxs/math/geometry.py

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,19 @@ def __init__(self, kwargs={}):
106106
super().__init__(kwargs=kwargs)
107107

108108
def __getitem__(self, key):
109-
'''This function wraps access to the pos4d matrix.
109+
"""This function wraps access to the pos4d matrix.
110110
111111
This is mostly a convenience method that gives access to
112112
vectors from the ``pos4d`` matrix in familiar terms with
113113
string labels:
114114
115-
- ``center``: The ``center`` is the origin of the local coordiante system
116-
of the optical elemement. Typically, if will be the center of the
115+
- ``center``: The ``center`` is the origin of the local coordinate system
116+
of the optical element. Typically, if will be the center of the
117117
active plane, e.g. the center of the mirror surface.
118118
- :math:`\hat v_{y,z}`: The box stretches in the y and z direction for
119119
:math:`\pm \hat v_y` and :math:`\pm \hat v_z`. In optics, the relevant
120120
interaction often happens on a surface, e.g. the surface of a mirror or
121-
of a reflection grating. In the defaul configuration, this surface is in
121+
of a reflection grating. In the default configuration, this surface is in
122122
the yz-plane.
123123
- :math:`\hat v_x`: The thickness of the box is not as important in many
124124
cases,
@@ -138,7 +138,7 @@ def __getitem__(self, key):
138138
mirror does not really have a "plane").
139139
Access through this method is slower than direct indexing of ``self.pos4d``.
140140
141-
'''
141+
"""
142142

143143
if key == 'center':
144144
return self.pos4d[:, 3]
@@ -160,7 +160,7 @@ def __getitem__(self, key):
160160
return val
161161

162162
def intersect(self, dir, pos):
163-
'''Calculate the intersection point between a ray and the element
163+
"""Calculate the intersection point between a ray and the element
164164
165165
Parameters
166166
----------
@@ -177,24 +177,24 @@ def intersect(self, dir, pos):
177177
homogeneous coordinates of the intersection point. Values are set
178178
to ``np.nan`` if no intersection point is found.
179179
interpos_local : `numpy.ndarray` of shape (N, 2)
180-
y and z coordinates in the coordiante system of the active plane.
181-
'''
180+
y and z coordinates in the coordinate system of the active plane.
181+
"""
182182
raise NotImplementedError
183183

184184
def get_local_euklid_bases(self, interpos_local):
185-
'''Obtain a local eukledian base at a set of positions.
185+
"""Obtain a local eucledian base at a set of positions.
186186
187187
Parameters
188188
----------
189189
interpos_local : `numpy.ndarray` of shape (N, 2)
190-
coordinates in the coordiante system of the geometry (e.g. (x, y),
190+
coordinates in the coordinate system of the geometry (e.g. (x, y),
191191
or (r, phi)).
192192
193193
Returns
194194
-------
195195
e_1, e_2, n : `numpy.ndarray` of shape (N, 4)
196196
Vectors pointing in direction 1, 2, and normal to the surface.
197-
'''
197+
"""
198198
raise NotImplementedError
199199

200200

@@ -209,7 +209,7 @@ class FinitePlane(Geometry):
209209
'''name for output columns with interaction point in local coordinates.'''
210210

211211
def intersect(self, dir, pos):
212-
'''Calculate the intersection point between a ray and the element
212+
"""Calculate the intersection point between a ray and the element
213213
214214
Parameters
215215
----------
@@ -226,15 +226,15 @@ def intersect(self, dir, pos):
226226
homogeneous coordinates of the intersection point. Values are set
227227
to ``np.nan`` if no intersection point is found.
228228
interpos_local : `numpy.ndarray` of shape (N, 2)
229-
y and z coordinates in the coordiante system of the active plane
229+
y and z coordinates in the coordinate system of the active plane
230230
(not normalized to the dimensions of the element in question, but
231231
in absolute units).
232-
'''
232+
"""
233233
k_nominator = np.dot(self['center'] - pos, self['e_x'])
234234
k_denom = np.dot(dir, self['e_x'])
235235

236236
is_parallel = k_denom == 0
237-
# To avoid warning for parallel rays, which is handeled expicitly below
237+
# To avoid warning for parallel rays, which is handled explicitly below
238238
with np.errstate(divide='ignore'):
239239
k = k_nominator / k_denom
240240

@@ -261,18 +261,18 @@ def intersect(self, dir, pos):
261261
return intersect, interpos, interpos_local
262262

263263
def get_local_euklid_bases(self, interpos_local):
264-
'''Obtain a local eukledian base at a set of positions.
264+
"""Obtain a local euclidean base at a set of positions.
265265
266266
Parameters
267267
----------
268268
interpos_local : `numpy.ndarray` of shape (N, 2)
269-
coordinates in the coordiante system of the geometry (x, y)
269+
coordinates in the coordinate system of the geometry (x, y)
270270
271271
Returns
272272
-------
273273
e_1, e_2, n : `numpy.ndarray` of shape (N, 4)
274274
Vectors pointing in direction 1, 2, and normal to the surface.
275-
'''
275+
"""
276276

277277
n = interpos_local.shape[0]
278278
x = np.tile(self['e_x'], (n, 1))
@@ -282,28 +282,27 @@ def get_local_euklid_bases(self, interpos_local):
282282

283283

284284
class PlaneWithHole(FinitePlane):
285-
286-
shape = 'triangulation'
287-
outer_factor = 3
285+
shape = "triangulation"
288286
inner_factor = 0
287+
outer_factor = 3
289288

290289
def __init__(self, kwargs):
291290
self._geometry['r_inner'] = kwargs.pop('r_inner', 0.)
292291
super().__init__(kwargs)
293292

294293
def triangulate(self, display={}):
295-
'''Return a triangulation of the aperture hole embedded in a square.
294+
"""Return a triangulation of the aperture hole embedded in a square.
296295
297296
The size of the outer square is determined by the ``'outer_factor'``
298297
element in ``self.display``.
299298
300299
Returns
301300
-------
302301
xyz : np.array
303-
Numpy array of vertex positions in Eukeldian space
302+
Numpy array of vertex positions in Euclidean space
304303
triangles : np.array
305304
Array of index numbers that define triangles
306-
'''
305+
"""
307306
outer_disp = self.outer_display(display)
308307
outer_shape = self.outer_shape(display)
309308

@@ -320,16 +319,16 @@ def triangulate(self, display={}):
320319

321320
return xyz, triangles
322321

323-
def outer_shape(self, diplay):
322+
def outer_shape(self, display):
324323
raise NotImplementedError
325324

326-
def outer_display(self, diplay):
325+
def outer_display(self, display):
327326
raise NotImplementedError
328327

329-
def inner_shape(self, diplay):
328+
def inner_shape(self, display):
330329
raise NotImplementedError
331330

332-
def inner_display(self, diplay):
331+
def inner_display(self, display):
333332
raise NotImplementedError
334333

335334

@@ -356,7 +355,7 @@ def __init__(self, kwargs):
356355
super().__init__(kwargs)
357356

358357
def outer_display(self, display):
359-
'''Return values in Eukledian space.'''
358+
"""Return values in Euclidean space."""
360359
return xyz_circle(self, r_factor=display['outer_factor'])
361360

362361
def outer_shape(self, display):
@@ -374,6 +373,12 @@ def inner_display(self, display):
374373
r_factor=display['inner_factor'] * self['r_inner'] / np.linalg.norm(self['v_y']),
375374
philim=self.phi)
376375

376+
def intersect(self, dir, pos):
377+
intersect, interpos, interpos_local = super().intersect(dir, pos)
378+
r = np.linalg.norm(interpos_local, axis=1)
379+
intersect &= r <= 1.0
380+
return intersect, interpos, interpos_local
381+
377382

378383
class Cylinder(Geometry):
379384
'''A Geometry shaped like a ring or tube.

marxs/missions/mitsnl/catgrating.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,7 @@ def __init__(self, qualityfactor=qualityfactor, **kwargs):
158158
super().__init__(**kwargs)
159159

160160
def specific_process_photons(self, photons, intersect, interpos, intercoos):
161-
return {'probability': self.factor**(photons['order'][intersect]**2)}
162-
return photons
161+
return {"probability": self.factor ** (photons["order"][intersect] ** 2)}
163162

164163

165164
def check_lx_dims(lx_dims):

marxs/optics/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
OrderSelector, EfficiencyFile
77
)
88
from .mirror import ThinLens, PerfectLens
9-
from .baffles import Baffle
9+
from .baffles import Baffle, CircularBaffle
1010
from .scatter import RadialMirrorScatter, RandomGaussianScatter
1111
from .filter import EnergyFilter, GlobalEnergyFilter
1212
from .base import OpticalElement, FlatOpticalElement, FlatStack

0 commit comments

Comments
 (0)