diff --git a/furst_optics/__init__.py b/furst_optics/__init__.py index def3de1..adb9ab5 100644 --- a/furst_optics/__init__.py +++ b/furst_optics/__init__.py @@ -2,6 +2,7 @@ An idealized raytrace model of the FURST optical system. """ +from . import typevars from . import abc from . import sources from . import apertures @@ -10,6 +11,7 @@ from . import detectors __all__ = [ + "typevars", "abc", "sources", "apertures", diff --git a/furst_optics/gratings/__init__.py b/furst_optics/gratings/__init__.py index 572984c..bf42f89 100644 --- a/furst_optics/gratings/__init__.py +++ b/furst_optics/gratings/__init__.py @@ -2,7 +2,9 @@ Models and measurements of the diffraction grating. """ -from ._gratings import Grating +from ._gratings import ( + Grating, +) __all__ = [ "Grating", diff --git a/furst_optics/gratings/_gratings.py b/furst_optics/gratings/_gratings.py index 0d123a7..da84f02 100644 --- a/furst_optics/gratings/_gratings.py +++ b/furst_optics/gratings/_gratings.py @@ -1,3 +1,4 @@ +from typing import Generic import dataclasses import astropy.units as u import named_arrays as na @@ -16,6 +17,11 @@ class Grating( optika.mixins.Pitchable, optika.mixins.Translatable, furst_optics.abc.AbstractRowlandComponent, + Generic[ + furst_optics.typevars.SagT, + furst_optics.typevars.MaterialT, + furst_optics.typevars.RulingT, + ], ): """ A model of the FURST diffraction grating. @@ -48,7 +54,9 @@ class Grating( # Define the grating model grating = furst_optics.gratings.Grating( - radius=-2 * rowland_radius, + sag=optika.sags.SphericalSag( + radius=-2 * rowland_radius, + ), width_clear=na.Cartesian2dVectorArray( x=1000 * u.mm, y=20 * u.mm, @@ -83,6 +91,11 @@ class Grating( The human-readable name of this optic. """ + sag: furst_optics.typevars.SagT = None + """ + The sag profile of the grating surface. + """ + radius: u.Quantity | na.AbstractScalar = 0 * u.mm """ The radius of curvature of the optical surface. @@ -98,13 +111,13 @@ class Grating( The height and width of the grating substrate. """ - material: None | optika.materials.AbstractMaterial = None + material: furst_optics.typevars.MaterialT = None """ The coating material used to make the optic reflective in the target spectral range. """ - rulings: None | optika.rulings.AbstractRulings = None + rulings: furst_optics.typevars.RulingT = None """ A model of the grating ruling spacing and profile. """ @@ -150,9 +163,7 @@ class Grating( def surface(self) -> optika.surfaces.Surface: return optika.surfaces.Surface( name=self.name, - sag=optika.sags.SphericalSag( - radius=self.radius, - ), + sag=self.sag, material=self.material, aperture=optika.apertures.RectangularAperture( half_width=self.width_clear / 2, diff --git a/furst_optics/gratings/_gratings_test.py b/furst_optics/gratings/_gratings_test.py index 4da4cf9..e956ca5 100644 --- a/furst_optics/gratings/_gratings_test.py +++ b/furst_optics/gratings/_gratings_test.py @@ -9,7 +9,9 @@ argnames="a", argvalues=[ furst_optics.gratings.Grating( - radius=1000 * u.mm, + sag=optika.sags.SphericalSag( + radius=1000 * u.mm, + ), width_clear=10 * u.mm, width_mech=15 * u.mm, material=optika.materials.Mirror(), diff --git a/furst_optics/typevars.py b/furst_optics/typevars.py new file mode 100644 index 0000000..85ffd28 --- /dev/null +++ b/furst_optics/typevars.py @@ -0,0 +1,29 @@ +""" +Type variables used by the generic types +in this project. +""" + +from typing import TypeVar +import optika + +__all__ = [ + "SagT", + "MaterialT", + "RulingT", +] + + +#: Sag type variable. +#: Should be :obj:`None` or a subclass of +#: :class:`optika.sags.AbstractSag` +SagT = TypeVar("SagT", bound=None | optika.sags.AbstractSag) + +#: Material type variable. +#: Should be :obj:`None` or a subclass of +#: :class:`optika.materials.AbstractMaterial` +MaterialT = TypeVar("MaterialT", bound=None | optika.materials.AbstractMaterial) + +#: Ruling type variable. +#: Should be :obj:`None` or a subclass of +#: :class:`optika.rulings.AbstractRulings` +RulingT = TypeVar("RulingT", bound=None | optika.rulings.AbstractRulings)