Skip to content

Commit

Permalink
Added esis.flights.f1.optics.gratings.rulings.ruling_measurement(). (
Browse files Browse the repository at this point in the history
  • Loading branch information
byrdie authored Jul 20, 2024
1 parent a2fa590 commit 7984544
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 1 deletion.
143 changes: 142 additions & 1 deletion esis/flights/f1/optics/gratings/rulings/_rulings.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import named_arrays as na
import numpy as np
import astropy.units as u
import named_arrays as na
import optika
from esis.flights.f1.optics import gratings

__all__ = [
"ruling_design",
"ruling_measurement",
]


Expand All @@ -13,6 +16,11 @@ def ruling_design(
"""
The as-designed rulings for the ESIS diffraction gratings.
Parameters
----------
num_distribution
The number of Monte Carlo samples to draw when computing uncertainties.
Examples
--------
Expand Down Expand Up @@ -87,10 +95,143 @@ def ruling_design(
depth=na.UniformUncertainScalarArray(
nominal=15 * u.nm,
width=2 * u.nm,
num_distribution=num_distribution,
),
ratio_duty=na.UniformUncertainScalarArray(
nominal=0.5,
width=0.1,
num_distribution=num_distribution,
),
diffraction_order=1,
)


def ruling_measurement(
num_distribution: int = 11,
):
"""
A model of the rulings where the efficiency has been calculated using the
ratio of the total efficiency of the gratings to the efficiency of the
multilayer coatings.
The total efficiency of the gratings is given by
:func:`esis.flights.f1.optics.gratings.efficiencies.efficiency_vs_wavelength()`,
and the efficiency of the multilayer coating is given by
:func:`esis.flights.f1.optics.gratings.materials.multilayer_fit()`.
Parameters
----------
num_distribution
The number of Monte Carlo samples to draw when computing uncertainties.
Examples
--------
Compare the as-designed efficiency of the rulings to the measured efficiency
of the rulings.
.. jupyter-execute::
import numpy as np
import matplotlib.pyplot as plt
import astropy.units as u
import astropy.visualization
import named_arrays as na
import optika
from esis.flights.f1.optics import gratings
# Define an array of wavelengths with which to sample the efficiency
wavelength = na.geomspace(500, 700, axis="wavelength", num=1001) * u.AA
# Define the incidence angle to be the same as the Horiba technical proposal
angle = 1.3 * u.deg
# Define the incident rays from the wavelength array
rays = optika.rays.RayVectorArray(
wavelength=wavelength,
position=0 * u.mm,
direction=na.Cartesian3dVectorArray(
x=np.sin(angle),
y=0,
z=np.cos(angle),
),
)
# Define the surface normal
normal = na.Cartesian3dVectorArray(0, 0, -1)
# Initialize the ESIS diffraction grating ruling model
ruling_design = gratings.rulings.ruling_design(num_distribution=0)
ruling_measurement = gratings.rulings.ruling_measurement(num_distribution=0)
# Compute the efficiency of the grating rulings
efficiency_design = ruling_design.efficiency(
rays=rays,
normal=normal,
)
efficiency_measurement = ruling_measurement.efficiency(
rays=rays,
normal=normal,
)
# Plot the efficiency vs wavelength
fig, ax = plt.subplots(constrained_layout=True)
na.plt.plot(
wavelength,
efficiency_design,
ax=ax,
color="tab:blue",
label="design",
);
na.plt.plot(
wavelength,
efficiency_measurement,
ax=ax,
color="tab:orange",
label="measurement",
);
ax.set_xlabel(f"wavelength ({wavelength.unit:latex_inline})");
ax.set_ylabel("efficiency");
ax.legend();
"""

design = ruling_design(num_distribution=num_distribution)

density = na.UniformUncertainScalarArray(
nominal=2585.5 / u.mm,
width=1 / u.mm,
num_distribution=num_distribution,
)

spacing = design.spacing
spacing.coefficients[0] = 1 / density

efficiency_total = gratings.efficiencies.efficiency_vs_wavelength()

wavelength = efficiency_total.inputs.wavelength
angle = efficiency_total.inputs.direction

coating = gratings.materials.multilayer_fit()

efficiency_coating = coating.efficiency(
rays=optika.rays.RayVectorArray(
wavelength=wavelength,
direction=na.Cartesian3dVectorArray(
x=np.sin(angle),
y=0,
z=np.cos(angle),
),
),
normal=na.Cartesian3dVectorArray(0, 0, -1),
)

efficiency_rulings = na.FunctionArray(
inputs=efficiency_total.inputs,
outputs=efficiency_total.outputs / efficiency_coating,
)

return optika.rulings.MeasuredRulings(
spacing=spacing,
diffraction_order=design.diffraction_order,
efficiency_measured=efficiency_rulings,
)
5 changes: 5 additions & 0 deletions esis/flights/f1/optics/gratings/rulings/_rulings_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@
def test_ruling_design():
r = esis.flights.f1.optics.gratings.rulings.ruling_design()
assert isinstance(r, optika.rulings.AbstractRulings)


def test_ruling_measurement():
r = esis.flights.f1.optics.gratings.rulings.ruling_measurement()
assert isinstance(r, optika.rulings.AbstractRulings)

0 comments on commit 7984544

Please sign in to comment.